Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
test_interaction_builder.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <string>
4#include <unordered_set>
5#include <utility>
6
15
16namespace bb::avm2::tracegen {
17
18// Adds checks to a lookup builder. The BaseBuilder needs to be an IndexedLookupTraceBuilder.
19template <typename BaseBuilder> class AddChecksToBuilder : public BaseBuilder {
21 "BaseBuilder must be an IndexedLookupTraceBuilder");
22
23 public:
24 using TupleType = typename BaseBuilder::TupleType;
25 ~AddChecksToBuilder() override = default;
26
27 void init(TraceContainer& trace) override
28 {
29 BaseBuilder::init(trace);
30 this->trace = &trace;
31 }
32
33 uint32_t find_in_dst(const TupleType& src_values) const override
34 {
35 uint32_t dst_row = BaseBuilder::find_in_dst(src_values);
36
37 auto dst_values = trace->get_multiple(BaseBuilder::LookupSettings::DST_COLUMNS, dst_row);
38 if (src_values != dst_values) {
39 throw std::runtime_error("Failed computing counts for " + std::string(BaseBuilder::LookupSettings::NAME) +
40 ". Could not find tuple in destination. " + "SRC tuple: " +
41 column_values_to_string(src_values, BaseBuilder::LookupSettings::SRC_COLUMNS));
42 }
43
44 return dst_row;
45 }
46
47 private:
49};
50
51// Builds a permutation and performs additional checks.
52// Only use in tests and debugging. This is slow and memory intensive.
53template <typename PermutationSettings>
54class CheckingPermutationBuilder : public PermutationBuilder<PermutationSettings> {
55 public:
56 // Use array for storage in map keys (tuples of references can't be stored).
58
59 void process(TraceContainer& trace) override
60 {
62
63 // Collect the source and destination tuples.
64 source_tuples.clear();
65 trace.visit_column(PermutationSettings::SRC_SELECTOR, [&](uint32_t row, const FF&) {
66 auto src_values = trace.get_multiple(PermutationSettings::SRC_COLUMNS, row);
67 source_tuples[to_array(src_values)].insert(row);
68 });
69 destination_tuples.clear();
70 trace.visit_column(PermutationSettings::DST_SELECTOR, [&](uint32_t row, const FF&) {
71 auto dst_values = trace.get_multiple(PermutationSettings::DST_COLUMNS, row);
72 destination_tuples[to_array(dst_values)].insert(row);
73 });
74
75 auto build_error_message =
76 [&](const ArrayTuple& tuple, const auto& columns, const auto& src_rows, const auto& dst_rows) {
77 std::string error = "Failure to build permutation " + std::string(PermutationSettings::NAME) + ".\n";
78 error += format("Tuple ",
79 column_values_to_string(tuple, columns),
80 " has multiplicity ",
81 src_rows.size(),
82 " in the source, but ",
83 dst_rows.size(),
84 " in the destination.\n");
85 error += format("Source rows: ");
86 for (auto row : src_rows) {
87 error += format(row, " ");
88 }
89 error += format("\n");
90 error += format("Destination rows: ");
91 for (auto row : dst_rows) {
92 error += format(row, " ");
93 }
94 return error;
95 };
96
97 // Check that every source tuple is found in the destination with the same multiplicity.
98 for (const auto& [src_tuple, src_rows] : source_tuples) {
99 auto dst_rows = destination_tuples.contains(src_tuple) ? destination_tuples.at(src_tuple)
100 : std::unordered_set<uint32_t>();
101 if (src_rows.size() != dst_rows.size()) {
102 throw std::runtime_error(
103 build_error_message(src_tuple, PermutationSettings::SRC_COLUMNS, src_rows, dst_rows));
104 }
105 }
106 // Check that every destination tuple is found in the source with the same multiplicity.
107 for (const auto& [dst_tuple, dst_rows] : destination_tuples) {
108 auto src_rows =
109 source_tuples.contains(dst_tuple) ? source_tuples.at(dst_tuple) : std::unordered_set<uint32_t>();
110 if (src_rows.size() != dst_rows.size()) {
111 throw std::runtime_error(
112 build_error_message(dst_tuple, PermutationSettings::DST_COLUMNS, src_rows, dst_rows));
113 }
114 }
115 }
116
117 private:
118 // Helper to convert tuple of references to array for storage.
119 template <typename... Ts> static ArrayTuple to_array(const flat_tuple::tuple<Ts...>& tup)
120 {
121 return [&]<size_t... Is>(std::index_sequence<Is...>) {
122 return ArrayTuple{ flat_tuple::get<Is>(tup)... };
123 }(std::make_index_sequence<sizeof...(Ts)>{});
124 }
125
128};
129
130} // namespace bb::avm2::tracegen
uint32_t find_in_dst(const TupleType &src_values) const override
void init(TraceContainer &trace) override
unordered_flat_map< ArrayTuple, std::unordered_set< uint32_t > > destination_tuples
unordered_flat_map< ArrayTuple, std::unordered_set< uint32_t > > source_tuples
std::array< FF, PermutationSettings::COLUMNS_PER_SET > ArrayTuple
static ArrayTuple to_array(const flat_tuple::tuple< Ts... > &tup)
void process(TraceContainer &) override
auto get_multiple(const std::array< ColumnAndShifts, N > &cols, uint32_t row) const
std::string format(Args... args)
Definition log.hpp:24
TestTraceContainer trace
std::string column_values_to_string(const std::array< FF, N > &arr, const std::array< ColumnAndShifts, N > &columns)
Definition stringify.hpp:46
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
TUPLET_INLINE constexpr decltype(auto) get(Tup &&tup)
Definition tuplet.hpp:1021