Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
trace_container.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <algorithm>
4#include <array>
5#include <cstddef>
6#include <functional>
7#include <memory>
8#include <shared_mutex>
9#include <span>
10#include <unordered_map>
11
17
18namespace bb::avm2::tracegen {
19
20// This container is thread-safe.
21// Contention can only happen when concurrently accessing the same column.
23 public:
25
26 const FF& get(Column col, uint32_t row) const;
28 {
29 std::array<FF, N> result;
30 for (size_t i = 0; i < N; ++i) {
31 if (!is_shift(cols[i])) {
32 result[i] = get(static_cast<Column>(cols[i]), row);
33 } else {
35 result[i] = get(unshifted_col, row + 1);
36 }
37 }
38 return result;
39 }
40 // Extended version of get that works with shifted columns. More expensive.
42
43 void set(Column col, uint32_t row, const FF& value);
44 // Bulk setting for a given row.
45 void set(uint32_t row, std::span<const std::pair<Column, FF>> values);
46 // Reserve column size. Useful for precomputed columns.
47 void reserve_column(Column col, size_t size);
48
49 // Visits non-zero values in a column.
50 void visit_column(Column col, const std::function<void(uint32_t, const FF&)>& visitor) const;
51 // Returns the number of rows in a column. That is, the maximum non-zero row index + 1.
53 // Maximum number of rows in any column.
54 uint32_t get_num_rows() const;
55 // Maximum number of rows in any column (ignoring clk which is always 2^21).
57 // Number of columns (without shifts).
58 static constexpr size_t num_columns() { return NUM_COLUMNS_WITHOUT_SHIFTS; }
59
60 // Free column memory.
62
63 private:
64 // We use a mutex per column to allow for concurrent writes.
65 // Observe that therefore concurrent write access to different columns is cheap.
66 struct SparseColumn {
67 std::shared_mutex mutex;
68 int64_t max_row_number = -1; // We use -1 to indicate that the column is empty.
69 bool row_number_dirty; // Needs recalculation.
70 // Future memory optimization notes: we can do the same trick as in Operand.
71 // That is, store a variant with a unique_ptr. However, we should benchmark this.
72 // (see serialization.hpp).
74 };
75 // We store the trace as a sparse matrix.
76 // We use a unique_ptr to allocate the array in the heap vs the stack.
77 // Even if the _content_ of each unordered_map is always heap-allocated, if we have 3k columns
78 // we could unnecessarily put strain on the stack with sizeof(unordered_map) * 3k bytes.
80};
81
82} // namespace bb::avm2::tracegen
static constexpr size_t num_columns()
const FF & get(Column col, uint32_t row) const
void reserve_column(Column col, size_t size)
const FF & get_column_or_shift(ColumnAndShifts col, uint32_t row) const
std::array< FF, N > get_multiple(const std::array< ColumnAndShifts, N > &cols, uint32_t row) const
std::unique_ptr< std::array< SparseColumn, NUM_COLUMNS_WITHOUT_SHIFTS > > trace
void visit_column(Column col, const std::function< void(uint32_t, const FF &)> &visitor) const
uint32_t get_column_rows(Column col) const
void set(Column col, uint32_t row, const FF &value)
bool is_shift(ColumnAndShifts c)
std::optional< Column > unshift_column(ColumnAndShifts c)
constexpr auto NUM_COLUMNS_WITHOUT_SHIFTS
Definition columns.hpp:41
ColumnAndShifts
Definition columns.hpp:35
AvmFlavorSettings::FF FF
Definition field.hpp:10
::ankerl::unordered_dense::map< Key, T > unordered_flat_map
Definition map.hpp:15
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13