-
Notifications
You must be signed in to change notification settings - Fork 270
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(avm): support skippable relations (#7750)
BB supports "skippable relations". If you define `bool Relation::skip(row)` and it returns true, sumcheck will not waste time checking that the accumulations actually sum 0. In this PR I add a way to define this in PIL and generate code to create `Relation::skip` (see poseidon2.pil). * Adds fuzzing test for skippable relations. * Makes poseidon2 relation skippable iff `sel_poseidon_perm = 0`. ---- Skippable relations are great to reclaim time for gadgets, which may have lots of columns (and subrelations) but may seldom be used. In the example below I applied this to poseidon2 which has 200+ columns and 150+ subrelations. On a token transfer, it almost completely reclaimed sumcheck time to how things were before the introduction of poseidon2 constraints. AFTER (1 cpu) ``` proving time minus check circuit = 44s prove/all_ms: 79209 prove/check_circuit_ms: 35276 prove/create_composer_ms: 0 prove/create_prover_ms: 3921 prove/create_verifier_ms: 0 prove/execute_log_derivative_inverse_commitments_round_ms: 8499 prove/execute_log_derivative_inverse_round_ms: 5975 prove/execute_pcs_rounds_ms: 1927 >>> prove/execute_relation_check_rounds_ms: 21324 prove/execute_wire_commitments_round_ms: 554 prove/gen_trace_ms: 1579 ``` BEFORE (1 cpu) ``` proving time minus check circuit = 85s prove/all_ms: 120465 prove/check_circuit_ms: 35002 prove/create_composer_ms: 0 prove/create_prover_ms: 2138 prove/create_verifier_ms: 0 prove/execute_log_derivative_inverse_commitments_round_ms: 8568 prove/execute_log_derivative_inverse_round_ms: 5840 prove/execute_pcs_rounds_ms: 2150 >>> prove/execute_relation_check_rounds_ms: 64416 prove/execute_wire_commitments_round_ms: 551 prove/gen_trace_ms: 1602 ``` BEFORE POSEIDON2 ``` proving time minus check circuit = 38s prove/all_ms: 51309 prove/check_circuit_ms: 13069 prove/create_composer_ms: 0 prove/create_prover_ms: 1294 prove/create_verifier_ms: 0 prove/execute_log_derivative_inverse_commitments_round_ms: 8537 prove/execute_log_derivative_inverse_round_ms: 2704 prove/execute_pcs_rounds_ms: 1673 >>> prove/execute_relation_check_rounds_ms: 22331 prove/execute_wire_commitments_round_ms: 493 prove/gen_trace_ms: 1079 ```
- Loading branch information
Showing
7 changed files
with
151 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
barretenberg/cpp/src/barretenberg/vm/avm/tests/fuzz_skippable.test.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#include "barretenberg/common/thread.hpp" | ||
#include "barretenberg/vm/avm/generated/circuit_builder.hpp" | ||
#include "barretenberg/vm/avm/generated/flavor.hpp" | ||
#include "barretenberg/vm/avm/generated/full_row.hpp" | ||
|
||
#include <gtest/gtest.h> | ||
#include <memory> | ||
#include <vector> | ||
|
||
namespace tests_avm { | ||
|
||
using namespace bb; | ||
using namespace bb::Avm_vm; | ||
|
||
TEST(AvmSkippableTests, shouldSkipCorrectly) | ||
{ | ||
using FF = AvmFlavor::FF; | ||
constexpr size_t TRACE_SIZE = 1 << 15; | ||
|
||
std::vector<AvmFullRow<FF>> trace(TRACE_SIZE); | ||
std::cerr << "Generating trace of size " << TRACE_SIZE << "..." << std::endl; | ||
// This is the most time consuming part of this test! | ||
// In particular, the generation of random fields. | ||
bb::parallel_for(trace.size(), [&](size_t i) { | ||
// The first row needs to be zeroes otherwise shifting doesn't work. | ||
if (i == 0) { | ||
return; | ||
} | ||
AvmFullRow<FF>& row = trace[i]; | ||
|
||
// Fill the row with random values. | ||
auto as_vector = row.as_vector(); | ||
const auto as_vector_size = as_vector.size(); | ||
for (size_t j = 0; j < as_vector_size; j++) { | ||
// FF::random_element(); is so slow! Using std::rand() instead. | ||
const_cast<FF&>(as_vector[j]) = FF(std::rand()); | ||
} | ||
|
||
// Set the conditions for skippable to return true. | ||
row.poseidon2_sel_poseidon_perm = 0; | ||
}); | ||
std::cerr << "Done generating trace..." << std::endl; | ||
|
||
// We build the polynomials needed to run "sumcheck". | ||
AvmCircuitBuilder cb; | ||
cb.set_trace(std::move(trace)); | ||
auto polys = cb.compute_polynomials(); | ||
std::cerr << "Done computing polynomials..." << std::endl; | ||
|
||
// For each skippable relation we will check: | ||
// 1. That Relation::skippable returns true (i.e., we correctly set the conditions) | ||
// 2. That the sumcheck result is zero (i.e., it was ok to skip the relation) | ||
for (size_t ri = 1; ri < TRACE_SIZE; ++ri) { | ||
auto row = polys.get_row(ri); | ||
|
||
bb::constexpr_for<0, std::tuple_size_v<AvmFlavor::Relations>, 1>([&]<size_t i>() { | ||
using Relation = std::tuple_element_t<i, AvmFlavor::Relations>; | ||
|
||
// We only want to test skippable relations. | ||
if constexpr (isSkippable<Relation, AvmFullRow<FF>>) { | ||
typename Relation::SumcheckArrayOfValuesOverSubrelations result; | ||
for (auto& r : result) { | ||
r = 0; | ||
} | ||
|
||
// We set the conditions up there. | ||
auto skip = Relation::skip(row); | ||
EXPECT_TRUE(skip) << "Relation " << Relation::NAME << " was expected to be skippable at row " << ri | ||
<< "."; | ||
|
||
Relation::accumulate(result, row, {}, 1); | ||
|
||
// If the relation is skippable, the result should be zero. | ||
for (size_t j = 0; j < result.size(); ++j) { | ||
if (result[j] != 0) { | ||
EXPECT_EQ(result[j], 0) | ||
<< "Relation " << Relation::NAME << " subrelation " << j << " was expected to be zero."; | ||
GTEST_SKIP(); | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
|
||
} // namespace tests_avm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters