Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
multi_permutation_builder.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <bit>
5#include <cstddef>
6#include <cstdint>
7#include <stdexcept>
8#include <vector>
9
19
20namespace bb::avm2::tracegen {
21
35template <typename... PermutationSettings_> class MultiPermutationBuilder : public InteractionBuilderInterface {
36 public:
40 ~MultiPermutationBuilder() override = default;
41
43 {
44 // Index the destination columns.
45 init(trace);
46
47 // Set the destination selector for each permutation.
48 (set_destination_selector<PermutationSettings_>(trace), ...);
49
50 // Set all the dummy inverses or whatever else is needed.
52 }
53
54 template <typename PermutationSettings> void set_destination_selector(TraceContainer& trace)
55 {
56 // Find each source tuple in the destination table, and set a 1 in the destination selector.
57 trace.visit_column(PermutationSettings::SRC_SELECTOR, [&](uint32_t row, const FF&) {
58 auto src_values = trace.get_multiple(PermutationSettings::SRC_COLUMNS, row);
59 auto index_it = row_idx.find(src_values);
60 if (index_it == row_idx.end() || index_it->second.empty()) {
61 throw std::runtime_error("Failed setting selectors for " + std::string(PermutationSettings::NAME) +
62 ". Could not find tuple in destination.\nSRC tuple (row " +
63 std::to_string(row) +
64 "): " + column_values_to_string(src_values, PermutationSettings::SRC_COLUMNS));
65 }
66 // Get one of the available rows for the tuple.
67 // TODO: This could be done in parallel, with only a lock on the row vector.
68 std::vector<uint32_t>& possible_dst_rows = index_it->second;
69 uint32_t dst_row = possible_dst_rows.back();
70 trace.set(PermutationSettings::DST_SELECTOR, dst_row, 1);
71 // We remove the used row from the list of possible rows.
72 // Since this is a permutation, you can use a row only once.
73 possible_dst_rows.pop_back();
74 // NOTE: we don't remove the key src_values from the map if it's empty, because that triggers a rehash.
75 });
76 }
77
79 {
80 // Index the destination columns.
81 // For each row in the destination table, extract the value of columns (a, b, c, ...)
82 // and add the row number to the index. See the comment on `row_idx` for more details.
83 row_idx.reserve(trace.get_column_rows(dst_table_selector));
84 trace.visit_column(dst_table_selector, [&](uint32_t row, const FF&) {
85 auto dst_values = trace.get_multiple(DST_COLUMNS, row);
86 row_idx[dst_values].push_back(row);
87 });
88 }
89
90 private:
91 // All permutations are expected to have the same destination columns.
92 using REPRESENTATIVE_PERM = std::tuple_element_t<0, flat_tuple::tuple<PermutationSettings_...>>;
93 static constexpr auto DST_COLUMNS = REPRESENTATIVE_PERM::DST_COLUMNS; // std::array.
94 static constexpr size_t COLUMNS_PER_SET = DST_COLUMNS.size();
95 static_assert(((DST_COLUMNS == PermutationSettings_::DST_COLUMNS) && ...));
96 // The destination selectors, however, are not the same.
97 // We need an extra "destination TABLE selector" which is the selector of the whole table.
99
100 // In a permutation (or lookup) you are trying to find a src suple of values
101 // (a, b, c, ...) in some destination table. That is, you want a row number in the destination table.
102 // The following map contains (a, b, c, ...) -> [row_number_1, row_number_2, ...].
103 // That is, you can efficiently find all the rows in the destination table that match the src tuple.
104 // TODO: Using the whole tuple as the key is not memory efficient.
106 unordered_flat_map<ArrayTuple, /*rows*/ std::vector<uint32_t>> row_idx;
107};
108
109} // namespace bb::avm2::tracegen
std::tuple_element_t< 0, flat_tuple::tuple< PermutationSettings_... > > REPRESENTATIVE_PERM
unordered_flat_map< ArrayTuple, std::vector< uint32_t > > row_idx
void process(TraceContainer &trace) override
TestTraceContainer trace
const auto init
Definition fr.bench.cpp:141
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