diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp index e00a97bb14cb..34c8942718e8 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_composer.test.cpp @@ -78,7 +78,7 @@ void complete_proving_key_for_test(bb::RelationParameters& relation_paramete relation_parameters.eccvm_set_permutation_delta = relation_parameters.eccvm_set_permutation_delta.invert(); // Compute z_perm and inverse polynomial for our logarithmic-derivative lookup method - compute_logderivative_inverse( + compute_logderivative_inverse( pk->polynomials, relation_parameters, pk->circuit_size); compute_grand_products(pk->polynomials, relation_parameters); diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp index 2de9bd40f492..b70b2383a7cc 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp @@ -83,7 +83,7 @@ void ECCVMProver::execute_log_derivative_commitments_round() gamma * (gamma + beta_sqr) * (gamma + beta_sqr + beta_sqr) * (gamma + beta_sqr + beta_sqr + beta_sqr); relation_parameters.eccvm_set_permutation_delta = relation_parameters.eccvm_set_permutation_delta.invert(); // Compute inverse polynomial for our logarithmic-derivative lookup method - compute_logderivative_inverse( + compute_logderivative_inverse( key->polynomials, relation_parameters, key->circuit_size); transcript->send_to_verifier(commitment_labels.lookup_inverses, key->commitment_key->commit(key->polynomials.lookup_inverses)); diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_trace_checker.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_trace_checker.cpp index 65c99f076aeb..347b0b6468e6 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_trace_checker.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_trace_checker.cpp @@ -31,7 +31,7 @@ bool ECCVMTraceChecker::check(Builder& builder, numeric::RNG* engine_ptr) ProverPolynomials polynomials(builder); const size_t num_rows = polynomials.get_polynomial_size(); - compute_logderivative_inverse>(polynomials, params, num_rows); + compute_logderivative_inverse>(polynomials, params, num_rows); compute_grand_product>(polynomials, params); polynomials.z_perm_shift = Polynomial(polynomials.z_perm.shifted()); diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp index 940c88c8c6d4..d21dfb454ea5 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/logderivative_library.hpp @@ -1,4 +1,7 @@ #pragma once + +#include "barretenberg/common/constexpr_utils.hpp" + #include namespace bb { @@ -22,10 +25,9 @@ namespace bb { * The specific algebraic relations that define read terms and write terms are defined in Flavor::LookupRelation * */ -template +template void compute_logderivative_inverse(Polynomials& polynomials, auto& relation_parameters, const size_t circuit_size) { - using FF = typename Flavor::FF; using Accumulator = typename Relation::ValueAccumulator0; constexpr size_t READ_TERMS = Relation::READ_TERMS; constexpr size_t WRITE_TERMS = Relation::WRITE_TERMS; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp index d4dd4e638b2e..7406320b1b7b 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/circuit_builder.cpp @@ -883,7 +883,7 @@ bool AvmCircuitBuilder::check_circuit() const using Relation = std::tuple_element_t; checks.push_back([&, num_rows](SignalErrorFn signal_error) { // Check the logderivative relation - bb::compute_logderivative_inverse(polys, params, num_rows); + bb::compute_logderivative_inverse(polys, params, num_rows); typename Relation::SumcheckArrayOfValuesOverSubrelations lookup_result; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp index 7455d3058086..7c093f402020 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/prover.cpp @@ -67,7 +67,7 @@ void AvmProver::execute_log_derivative_inverse_round() using Relation = std::tuple_element_t; tasks.push_back([&]() { AVM_TRACK_TIME(std::string("prove/execute_log_derivative_inverse_round/") + std::string(Relation::NAME), - (compute_logderivative_inverse( + (compute_logderivative_inverse( prover_polynomials, relation_parameters, key->circuit_size))); }); }); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/full_poseidon2.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/full_poseidon2.test.cpp index 1d808d286238..165a3b23ed68 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/full_poseidon2.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/full_poseidon2.test.cpp @@ -88,7 +88,7 @@ TEST(AvmFullPoseidon2, shouldHashCorrectly) using PermRelations = perm_pos2_fixed_pos2_perm_relation; // Check the logderivative relation - bb::compute_logderivative_inverse(polys, params, num_rows); + bb::compute_logderivative_inverse(polys, params, num_rows); typename PermRelations::SumcheckArrayOfValuesOverSubrelations lookup_result; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/merkle_tree.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/merkle_tree.test.cpp index 3b0f1c3cc922..61c0e3308c7a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/merkle_tree.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/merkle_tree.test.cpp @@ -109,7 +109,7 @@ TEST(AvmMerkleTree, shouldCheckMembership) using PermRelations = perm_merkle_poseidon2_relation; // Check the logderivative relation - bb::compute_logderivative_inverse(polys, params, num_rows); + bb::compute_logderivative_inverse(polys, params, num_rows); typename PermRelations::SumcheckArrayOfValuesOverSubrelations lookup_result; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/range_check.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/range_check.test.cpp index 41cdeb28594a..a52a8b686ba9 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/range_check.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/range_check.test.cpp @@ -118,7 +118,7 @@ TEST(AvmRangeCheck, shouldRangeCheck) using LookupRelations = std::tuple_element_t; // Check the logderivative relation - bb::compute_logderivative_inverse(polys, params, num_rows); + bb::compute_logderivative_inverse(polys, params, num_rows); typename LookupRelations::SumcheckArrayOfValuesOverSubrelations lookup_result; diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/check_circuit.cpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/check_circuit.cpp index 591804d61e87..cfe2bf48d8d2 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/check_circuit.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/check_circuit.cpp @@ -57,7 +57,7 @@ void run_check_circuit(AvmFlavor::ProverPolynomials& polys, size_t num_rows) using Relation = std::tuple_element_t; checks.push_back([&, num_rows]() { // Compute logderivs. - bb::compute_logderivative_inverse(polys, params, num_rows); + bb::compute_logderivative_inverse(polys, params, num_rows); // Check the logderivative relation typename Relation::SumcheckArrayOfValuesOverSubrelations lookup_result{}; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/prover.cpp b/barretenberg/cpp/src/barretenberg/vm2/generated/prover.cpp index d46b2056b76c..f9b4a80cb016 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/prover.cpp @@ -67,7 +67,7 @@ void AvmProver::execute_log_derivative_inverse_round() using Relation = std::tuple_element_t; tasks.push_back([&]() { AVM_TRACK_TIME(std::string("prove/execute_log_derivative_inverse_round/") + std::string(Relation::NAME), - (compute_logderivative_inverse( + (compute_logderivative_inverse( prover_polynomials, relation_parameters, key->circuit_size))); }); }); diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_builder.hpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_builder.hpp index eceb0f803a11..3c7f60d34ddc 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen/lib/lookup_builder.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "barretenberg/vm2/common/field.hpp" @@ -54,9 +55,12 @@ template class BaseLookupTraceBuilder : public Intera // This class is used when the lookup is into a non-precomputed table. // It calculates the counts by trying to find the tuple in the destination columns. // It creates an index of the destination columns on init, and uses it to find the tuple efficiently. -template class LookupIntoDynamicTable : public BaseLookupTraceBuilder { +// This class should work for any lookup that is not precomputed. +// However, consider using a more specialized and faster class. +template +class LookupIntoDynamicTableGeneric : public BaseLookupTraceBuilder { public: - virtual ~LookupIntoDynamicTable() = default; + virtual ~LookupIntoDynamicTableGeneric() = default; protected: using LookupSettings = LookupSettings_; @@ -89,6 +93,57 @@ template class LookupIntoDynamicTable : public BaseLo unordered_flat_map row_idx; }; +// This class is used when the lookup is into a non-precomputed table. +// It is optimized for the case when the source and destination tuples +// are expected to be in the same order (possibly with other tuples in the middle +// in the destination table). +// The approach is that for a given source row, you start sequentially looking at the +// destination rows until you find a match. Then you move to the next source row. +// Then you keep looking from the last destination row you found a match. +// WARNING: Do not use this class if you expect to "reuse" destination rows. +// In this case the two tables will likely not be in order. +template class LookupIntoDynamicTableSequential : public InteractionBuilderInterface { + public: + ~LookupIntoDynamicTableSequential() override = default; + + void process(TraceContainer& trace) override + { + uint32_t dst_row = 0; + uint32_t max_dst_row = trace.get_column_rows(LookupSettings::DST_SELECTOR); + + trace.visit_column(LookupSettings::SRC_SELECTOR, [&](uint32_t row, const FF& src_sel_value) { + assert(src_sel_value == 1); + (void)src_sel_value; // Avoid GCC complaining of unused parameter when asserts are disabled. + + auto src_values = trace.get_multiple(LookupSettings::SRC_COLUMNS, row); + + // We set a dummy value in the inverse column so that the size of the column is right. + // The correct value will be set by the prover. + trace.set(LookupSettings::INVERSES, row, 0xdeadbeef); + + // We find the first row in the destination columns where the values match. + while (dst_row < max_dst_row) { + // TODO: As an optimization, we could try to only walk the rows where the selector is active. + // We can't just do a visit because we cannot skip rows with that. + auto dst_selector = trace.get(LookupSettings::DST_SELECTOR, dst_row); + if (dst_selector == 1 && src_values == trace.get_multiple(LookupSettings::DST_COLUMNS, dst_row)) { + trace.set(LookupSettings::COUNTS, dst_row, trace.get(LookupSettings::COUNTS, dst_row) + 1); + return; // Done with this source row. + } + ++dst_row; + } + + throw std::runtime_error("Failed computing counts for " + std::string(LookupSettings::NAME) + + ". Could not find tuple in destination."); + }); + + // We set a dummy value in the inverse column so that the size of the column is right. + // The correct value will be set by the prover. + trace.visit_column(LookupSettings::DST_SELECTOR, + [&](uint32_t row, const FF&) { trace.set(LookupSettings::INVERSES, row, 0xdeadbeef); }); + } +}; + } // namespace bb::avm2::tracegen // Define a hash function for std::array so that it can be used as a key in a std::unordered_map. diff --git a/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp b/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp index 99713a552dcb..1d1df78f742f 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/tracegen_helper.cpp @@ -183,7 +183,7 @@ TraceContainer AvmTraceGenHelper::generate_trace(EventsContainer&& events) { auto jobs_interactions = make_jobs>( std::make_unique>(), - std::make_unique>(), + std::make_unique>(), std::make_unique>(), std::make_unique>(), std::make_unique>(), diff --git a/bb-pilcom/bb-pil-backend/templates/circuit_builder.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/circuit_builder.cpp.hbs index 5a1efc042de4..c172edffe4dd 100644 --- a/bb-pilcom/bb-pil-backend/templates/circuit_builder.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/circuit_builder.cpp.hbs @@ -165,7 +165,7 @@ bool AvmCircuitBuilder::check_circuit() const { using Relation = std::tuple_element_t; checks.push_back([&, num_rows](SignalErrorFn signal_error) { // Check the logderivative relation - bb::compute_logderivative_inverse(polys, params, num_rows); + bb::compute_logderivative_inverse(polys, params, num_rows); typename Relation::SumcheckArrayOfValuesOverSubrelations lookup_result; diff --git a/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs index ce4dd4e37cfc..8c7ad47e6b4f 100644 --- a/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/prover.cpp.hbs @@ -67,7 +67,7 @@ void AvmProver::execute_log_derivative_inverse_round() using Relation = std::tuple_element_t; tasks.push_back([&]() { AVM_TRACK_TIME(std::string("prove/execute_log_derivative_inverse_round/") + std::string(Relation::NAME), - (compute_logderivative_inverse( + (compute_logderivative_inverse( prover_polynomials, relation_parameters, key->circuit_size))); }); });