Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
databus_lookup_relation.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Sergei], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8#include <array>
9#include <tuple>
10
15
16namespace bb {
17
39template <typename FF_, auto ValueId, auto ReadCountsId, auto InversesId, auto IndicatorId, auto SelectorId>
41 public:
42 using FF = FF_;
43
44 static constexpr size_t INVERSE_READ_SUBREL_LENGTH = 6; // deg 5: (I*L*T - 1) * is_read
45 static constexpr size_t INVERSE_WRITE_SUBREL_LENGTH = 6; // deg 4: (I*L*T - 1) * count
46 static constexpr size_t LOOKUP_SUBREL_LENGTH = 6; // deg 4: (is_read*T - count*L) * I
47 static constexpr size_t READ_COUNT_LOCALITY_SUBREL_LENGTH = 3; // deg 2: (1 - indicator) * count
48
55 // (1a)/(1b)/(3) are per-row identities; (2) is a sum across the trace.
56 static constexpr std::array<bool, 4> SUBRELATION_LINEARLY_INDEPENDENT{ true, true, false, true };
57
58 // Marker used by tooling (RelationChecker, etc.) to identify per-bus lookup relations in a
59 // flavor's `Relations_<FF>` tuple without baking the relation's identity into a heuristic.
60 static constexpr bool IS_SINGLE_BUS_LOOKUP = true;
61 static constexpr bool HAS_LOGDERIVATIVE_INVERSE_COMPUTATION = true;
62
63 template <typename AllEntities> inline static bool skip(const AllEntities& in)
64 {
65 // Skip when the row is not a read gate AND has no read counts on this column.
66 return in[AllEntities::EntityId::q_busread].is_zero() && in[ReadCountsId].is_zero();
67 }
68
73 template <typename Accumulator, typename AllEntities> static Accumulator get_read_selector(const AllEntities& in)
74 {
75 using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator;
76 auto q_busread = CoefficientAccumulator(in[AllEntities::EntityId::q_busread]);
77 auto column_selector = CoefficientAccumulator(in[SelectorId]);
78 return Accumulator(q_busread * column_selector);
79 }
80
82 template <typename Accumulator, typename AllEntities, typename Parameters>
83 static Accumulator compute_table_term(const AllEntities& in, const Parameters& params)
84 {
85 using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator;
86 using ParameterCoefficientAccumulator = typename Parameters::DataType::CoefficientAccumulator;
87
88 const auto& id = CoefficientAccumulator(in[AllEntities::EntityId::databus_id]);
89 const auto& value = CoefficientAccumulator(in[ValueId]);
90 const auto& gamma = ParameterCoefficientAccumulator(params.gamma);
91 const auto& beta = ParameterCoefficientAccumulator(params.beta);
92
93 return Accumulator(id * beta + value + gamma);
94 }
95
97 template <typename Accumulator, typename AllEntities, typename Parameters>
98 static Accumulator compute_lookup_term(const AllEntities& in, const Parameters& params)
99 {
100 using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator;
101 using ParameterCoefficientAccumulator = typename Parameters::DataType::CoefficientAccumulator;
102
103 const auto& w_1 = CoefficientAccumulator(in[AllEntities::EntityId::w_l]);
104 const auto& w_2 = CoefficientAccumulator(in[AllEntities::EntityId::w_r]);
105 const auto& gamma = ParameterCoefficientAccumulator(params.gamma);
106 const auto& beta = ParameterCoefficientAccumulator(params.beta);
107
108 return Accumulator((w_2 * beta) + w_1 + gamma);
109 }
110
117 template <typename Polynomials>
118 static void compute_logderivative_inverse(Polynomials& polynomials,
119 auto& relation_parameters,
120 const size_t circuit_size,
121 const size_t start_index = 0)
122 {
123 BB_BENCH_NAME("Databus::compute_logderivative_inverse");
124 auto& inverse_polynomial = polynomials[InversesId];
125 const auto& column_selector = polynomials[SelectorId];
126 const auto& read_counts = polynomials[ReadCountsId];
127
128 const size_t num_rows = circuit_size - start_index;
129 size_t min_iterations_per_thread = 1 << 6;
130 size_t num_threads = bb::calculate_num_threads(num_rows, min_iterations_per_thread);
131
132 parallel_for(num_threads, [&](ThreadChunk chunk) {
133 BB_BENCH_TRACY_NAME("Databus::compute_inverses/chunk");
134 for (size_t j : chunk.range(num_rows)) {
135 size_t i = j + start_index;
136 const bool is_read = polynomials.q_busread()[i] == 1 && column_selector[i] == 1;
137 const bool nonzero_read_count = read_counts[i] > 0;
138 if (is_read || nonzero_read_count) {
139 // TODO(https://github.com/AztecProtocol/barretenberg/issues/940): avoid get_row if possible.
140 auto row = polynomials.get_row(i);
141 auto value = compute_lookup_term<FF>(row, relation_parameters) *
142 compute_table_term<FF>(row, relation_parameters);
143 inverse_polynomial.at(i) = value;
144 }
145 }
146 });
147
148 FF::batch_invert(inverse_polynomial.coeffs());
149 };
150
158 template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
159 static void accumulate(ContainerOverSubrelations& accumulator,
160 const AllEntities& in,
161 const Parameters& params,
162 const FF& scaling_factor)
163 {
165 using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator;
166
167 const auto inverses_m = CoefficientAccumulator(in[InversesId]);
168 const auto read_counts_m = CoefficientAccumulator(in[ReadCountsId]);
169
170 const Accumulator inverses(inverses_m);
171 const Accumulator read_counts(read_counts_m);
172 const auto lookup_term = compute_lookup_term<Accumulator>(in, params);
173 const auto table_term = compute_table_term<Accumulator>(in, params);
174 const auto read_selector = get_read_selector<Accumulator>(in);
175
176 // Shared factor across (1a) and (1b): I·L·T − 1.
177 const auto common = lookup_term * table_term * inverses - FF(1);
178
179 // (1a) (I·L·T − 1) · is_read
180 std::get<0>(accumulator) += (common * read_selector) * scaling_factor;
181 // (1b) (I·L·T − 1) · count
182 std::get<1>(accumulator) += (common * read_counts) * scaling_factor;
183 // (2) (is_read·T − count·L) · I — no scaling factor (linearly dependent).
184 Accumulator tmp = read_selector * table_term;
185 tmp -= read_counts * lookup_term;
186 tmp *= inverses;
187 std::get<2>(accumulator) += tmp;
188
189 // (3) (1 − indicator) · count, in a length-3 accumulator.
190 using ShortAccumulator = typename std::tuple_element_t<3, ContainerOverSubrelations>;
191 const auto indicator_m = CoefficientAccumulator(in[IndicatorId]);
192 const ShortAccumulator indicator_short(indicator_m);
193 const ShortAccumulator read_counts_short(read_counts_m);
194 std::get<3>(accumulator) += (read_counts_short - indicator_short * read_counts_short) * scaling_factor;
195 }
196};
197
198template <typename FF, auto V, auto RC, auto IV, auto IND, auto SEL>
200
201} // namespace bb
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:264
#define BB_BENCH_TRACY_NAME(name)
Definition bb_bench.hpp:256
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
Log-derivative lookup argument for a single DataBus column.
static Accumulator compute_table_term(const AllEntities &in, const Parameters &params)
Write term denominator: value + databus_id·β + γ.
static bool skip(const AllEntities &in)
static constexpr size_t INVERSE_READ_SUBREL_LENGTH
static Accumulator get_read_selector(const AllEntities &in)
Compute scalar for read term in log derivative lookup argument.
static constexpr std::array< size_t, 4 > SUBRELATION_PARTIAL_LENGTHS
static constexpr size_t INVERSE_WRITE_SUBREL_LENGTH
static void accumulate(ContainerOverSubrelations &accumulator, const AllEntities &in, const Parameters &params, const FF &scaling_factor)
Accumulate this column's four subrelation contributions. (1a) (I*L*T - 1) * is_read = 0 (1b) (I*L*T -...
static Accumulator compute_lookup_term(const AllEntities &in, const Parameters &params)
Read term denominator: w_l + w_r·β + γ. Bus-independent.
static void compute_logderivative_inverse(Polynomials &polynomials, auto &relation_parameters, const size_t circuit_size, const size_t start_index=0)
Compute the column's inverse polynomial at active rows.
static constexpr size_t READ_COUNT_LOCALITY_SUBREL_LENGTH
static constexpr std::array< bool, 4 > SUBRELATION_LINEARLY_INDEPENDENT
static constexpr bool HAS_LOGDERIVATIVE_INVERSE_COMPUTATION
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
size_t calculate_num_threads(size_t num_iterations, size_t min_iterations_per_thread)
calculates number of threads to create based on minimum iterations per thread
Definition thread.cpp:233
void parallel_for(size_t num_iterations, const std::function< void(size_t)> &func)
Definition thread.cpp:112
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
auto range(size_t size, size_t offset=0) const
Definition thread.hpp:152
static void batch_invert(C &coeffs) noexcept
Batch invert a collection of field elements using Montgomery's trick.