Skip to content

Commit

Permalink
Fix tabs and add some comments.
Browse files Browse the repository at this point in the history
martun committed Jan 3, 2025
1 parent b89d3b1 commit a50f8fe
Showing 1 changed file with 80 additions and 76 deletions.
156 changes: 80 additions & 76 deletions crypto3/libs/blueprint/test/bbf/gate_optimizer.cpp
Original file line number Diff line number Diff line change
@@ -50,47 +50,47 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_bbf_gates_optimizer_shifting_test) {
using value_type = typename field_type::value_type;

using assignment_description_type = nil::crypto3::zk::snark::plonk_table_description<field_type>;
using constraint_type = zk::snark::plonk_constraint<field_type>;
using constraint_type = zk::snark::plonk_constraint<field_type>;
using context_type = bbf::context<field_type, bbf::GenerationStage::CONSTRAINTS>;

// Create just 1 of each column type, and 0 already used rows.
assignment_description_type desc(1, 1, 1, 1, 0, 0);
// Create just 1 of each column type, and 0 already used rows.
assignment_description_type desc(1, 1, 1, 1, 0, 0);

// Create a context that can use all 6 rows.
context_type c(desc, 6);
constraint_type X1, X2, X3, X4, X5, X6;
c.allocate(X1, 0, 0, bbf::column_type::witness);
c.constrain(X1*(1-X1), "Left Constraint");
// Create a context that can use all 6 rows.
context_type c(desc, 6);
constraint_type X1, X2, X3, X4, X5, X6;
c.allocate(X1, 0, 0, bbf::column_type::witness);
c.constrain(X1*(1-X1), "Left Constraint");

// Same thing on row 2.
c.allocate(X2, 0, 3, bbf::column_type::witness);
c.constrain(X2*(1-X2), "Left Constraint 2");
// Same thing on row 2.
c.allocate(X2, 0, 3, bbf::column_type::witness);
c.constrain(X2*(1-X2), "Left Constraint 2");

c.allocate(X3, 0, 1, bbf::column_type::witness);
c.constrain(X3*(2-X3), "Middle constraint 1");
c.allocate(X3, 0, 1, bbf::column_type::witness);
c.constrain(X3*(2-X3), "Middle constraint 1");

c.allocate(X4, 0, 4, bbf::column_type::witness);
c.constrain(X4*(2-X4), "Middle constraint 2");
c.allocate(X4, 0, 4, bbf::column_type::witness);
c.constrain(X4*(2-X4), "Middle constraint 2");

c.allocate(X5, 0, 2, bbf::column_type::witness);
c.constrain(X5*(3-X5), "Right constraint 1");
c.allocate(X5, 0, 2, bbf::column_type::witness);
c.constrain(X5*(3-X5), "Right constraint 1");

c.allocate(X6, 0, 5, bbf::column_type::witness);
c.constrain(X6*(3-X6), "Right constraint 2");
c.allocate(X6, 0, 5, bbf::column_type::witness);
c.constrain(X6*(3-X6), "Right constraint 2");

bbf::gates_optimizer<field_type> optimizer(std::move(c));
bbf::optimized_gates<field_type> gates = optimizer.optimize_gates();
bbf::gates_optimizer<field_type> optimizer(std::move(c));
bbf::optimized_gates<field_type> gates = optimizer.optimize_gates();

// We must have just 1 selector here, since these constraints can be shifted to match the same selector.
BOOST_CHECK_EQUAL(gates.selectors_.size(), 1);
// We must have just 1 selector here, since these constraints can be shifted to match the same selector.
BOOST_CHECK_EQUAL(gates.selectors_.size(), 1);

bbf::row_selector<> expected(8);
expected.set_row(1);
expected.set_row(4);
bbf::row_selector<> expected(8);
expected.set_row(1);
expected.set_row(4);

// This must be selector [1,4], since it's in the middle and the other 2 can be switched to that one.
BOOST_CHECK_EQUAL(gates.selectors_.begin()->first, expected);
// This must be selector [1,4], since it's in the middle and the other 2 can be switched to that one.
BOOST_CHECK_EQUAL(gates.selectors_.begin()->first, expected);
}

// This test checks how the gate optizimer groups selectors used in lookups if they don't intersect.
@@ -100,17 +100,17 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_bbf_gates_optimizer_lookup_selector_groupin
using value_type = typename field_type::value_type;

using assignment_description_type = nil::crypto3::zk::snark::plonk_table_description<field_type>;
using constraint_type = zk::snark::plonk_constraint<field_type>;
using constraint_type = zk::snark::plonk_constraint<field_type>;
using context_type = bbf::context<field_type, bbf::GenerationStage::CONSTRAINTS>;
using lookup_constraint_type = typename context_type::lookup_constraint_type;
using lookup_input_constraints_type = typename context_type::lookup_input_constraints_type;

// Create 3 witness columns, and just 1 of each other column type, and 0 already used rows.
assignment_description_type desc(3, 1, 1, 1, 0, 0);
// Create 3 witness columns, and just 1 of each other column type, and 0 already used rows.
assignment_description_type desc(3, 1, 1, 1, 0, 0);

// Create a context that can use all 6 rows.
context_type c(desc, 16);
constraint_type X, Y, Z;
// Create a context that can use all 6 rows.
context_type c(desc, 16);
constraint_type X, Y, Z;
c.allocate(X, 0, 0, bbf::column_type::witness);
c.allocate(Y, 1, 0, bbf::column_type::witness);
c.allocate(Z, 2, 0, bbf::column_type::witness);
@@ -119,40 +119,42 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_bbf_gates_optimizer_lookup_selector_groupin
auto c2 = c.relativize(std::vector<constraint_type>({Z * Z}), 0);
auto c3 = c.relativize(std::vector<constraint_type>({(X - 1) * (X - 1), (Y - 1) * (Y - 1)}), 0);

c.relative_lookup(c1, "Squares Table", 0, 5);
c.relative_lookup(c2, "Squares Table", 2, 8);
c.relative_lookup(c3, "Squares Table", 6, 9);
// We don't actually need to create the "Squares table" lookup table for this test, we can just create the
// lookups and optimize them.
c.relative_lookup(c1, "Squares Table", 0, 5);
c.relative_lookup(c2, "Squares Table", 2, 8);
c.relative_lookup(c3, "Squares Table", 6, 9);

bbf::gates_optimizer<field_type> optimizer(std::move(c));
bbf::optimized_gates<field_type> gates = optimizer.optimize_gates();
bbf::gates_optimizer<field_type> optimizer(std::move(c));
bbf::optimized_gates<field_type> gates = optimizer.optimize_gates();

// Lookups 1 and 3 will be grouped, and the 2nd will stay as it is.
BOOST_CHECK_EQUAL(gates.lookup_constraints.size(), 1);
// Lookups 1 and 3 will be grouped, and the 2nd will stay as it is.
BOOST_CHECK_EQUAL(gates.lookup_constraints.size(), 1);
// We have a group lookup to a single table.
BOOST_CHECK_EQUAL(gates.grouped_lookups.size(), 1);
BOOST_CHECK_EQUAL(gates.grouped_lookups.size(), 1);
// And we have just 1 group inside.
BOOST_CHECK_EQUAL(gates.grouped_lookups["Squares Table"].size(), 1);
BOOST_CHECK_EQUAL(gates.grouped_lookups["Squares Table"].size(), 1);
// The only group must have 2 selectors inside.
BOOST_CHECK_EQUAL(gates.grouped_lookups["Squares Table"].begin()->second.size(), 2);
BOOST_CHECK_EQUAL(gates.grouped_lookups["Squares Table"].begin()->second.size(), 2);

// Check that 2-nd constraint did not get grouped.
bbf::row_selector<> expected_selector_for_2nd(16);
expected_selector_for_2nd.set_interval(2, 8);
bbf::row_selector<> expected_selector_for_2nd(16);
expected_selector_for_2nd.set_interval(2, 8);

size_t selector_id_for_2nd_constraint = gates.lookup_constraints.begin()->first;
BOOST_CHECK_EQUAL(gates.selectors_[expected_selector_for_2nd], selector_id_for_2nd_constraint);
BOOST_CHECK(
BOOST_CHECK_EQUAL(gates.selectors_[expected_selector_for_2nd], selector_id_for_2nd_constraint);
BOOST_CHECK(
gates.lookup_constraints.begin()->second ==
std::vector<lookup_constraint_type>({
std::make_pair("Squares Table", c2)
})
);

// Check the grouped selectors.
bbf::row_selector<> expected_selector_for_1st(16);
expected_selector_for_1st.set_interval(0 ,5);
bbf::row_selector<> expected_selector_for_3rd(16);
expected_selector_for_3rd.set_interval(6, 9);
bbf::row_selector<> expected_selector_for_1st(16);
expected_selector_for_1st.set_interval(0 ,5);
bbf::row_selector<> expected_selector_for_3rd(16);
expected_selector_for_3rd.set_interval(6, 9);

for (auto [selector_id, li] : gates.grouped_lookups["Squares Table"].begin()->second) {
if (selector_id == gates.selectors_[expected_selector_for_1st]) {
@@ -172,17 +174,17 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_bbf_gates_optimizer_lookup_selector_larger_
using value_type = typename field_type::value_type;

using assignment_description_type = nil::crypto3::zk::snark::plonk_table_description<field_type>;
using constraint_type = zk::snark::plonk_constraint<field_type>;
using constraint_type = zk::snark::plonk_constraint<field_type>;
using context_type = bbf::context<field_type, bbf::GenerationStage::CONSTRAINTS>;
using lookup_constraint_type = typename context_type::lookup_constraint_type;
using lookup_input_constraints_type = typename context_type::lookup_input_constraints_type;

// Create 3 witness columns, and just 1 of each other column type, and 0 already used rows.
assignment_description_type desc(3, 1, 1, 1, 0, 0);
// Create 3 witness columns, and just 1 of each other column type, and 0 already used rows.
assignment_description_type desc(3, 1, 1, 1, 0, 0);

// Create a context that can use all 6 rows.
context_type c(desc, 16);
constraint_type X, Y, Z;
// Create a context that can use all 6 rows.
context_type c(desc, 16);
constraint_type X, Y, Z;
c.allocate(X, 0, 0, bbf::column_type::witness);
c.allocate(Y, 1, 0, bbf::column_type::witness);
c.allocate(Z, 2, 0, bbf::column_type::witness);
@@ -197,26 +199,28 @@ BOOST_AUTO_TEST_CASE(blueprint_plonk_bbf_gates_optimizer_lookup_selector_larger_

// We want a wheel graph, a circle with a node in the middle. selector for 'c1' will intersect every other constraint,
// while each other one will only intersect with the one to the left and right of it.
c.relative_lookup(c1, "Squares Table", 0, 14);
c.relative_lookup(c2, "Squares Table", 0, 2);
c.relative_lookup(c3, "Squares Table", 2, 4);
c.relative_lookup(c4, "Squares Table", 4, 6);
c.relative_lookup(c5, "Squares Table", 6, 8);
c.relative_lookup(c6, "Squares Table", 8, 10);

c.relative_lookup(c7, "Squares Table", 10, 12);
c.relative_lookup(c7, "Squares Table", 0);

bbf::gates_optimizer<field_type> optimizer(std::move(c));
bbf::optimized_gates<field_type> gates = optimizer.optimize_gates();

// Lookups 'c1' will stay single.
BOOST_CHECK_EQUAL(gates.lookup_constraints.size(), 1);
// We don't actually need to create the "Squares table" lookup table for this test, we can just create the
// lookups and optimize them.
c.relative_lookup(c1, "Squares Table", 0, 14);
c.relative_lookup(c2, "Squares Table", 0, 2);
c.relative_lookup(c3, "Squares Table", 2, 4);
c.relative_lookup(c4, "Squares Table", 4, 6);
c.relative_lookup(c5, "Squares Table", 6, 8);
c.relative_lookup(c6, "Squares Table", 8, 10);

c.relative_lookup(c7, "Squares Table", 10, 12);
c.relative_lookup(c7, "Squares Table", 0);

bbf::gates_optimizer<field_type> optimizer(std::move(c));
bbf::optimized_gates<field_type> gates = optimizer.optimize_gates();

// Lookups 'c1' will stay single.
BOOST_CHECK_EQUAL(gates.lookup_constraints.size(), 1);
// We have a group lookup to a single table.
BOOST_CHECK_EQUAL(gates.grouped_lookups.size(), 1);
BOOST_CHECK_EQUAL(gates.grouped_lookups.size(), 1);

// And we have just 2 groups inside, [c2, c4, c6] and [c3, c5, c7].
BOOST_CHECK_EQUAL(gates.grouped_lookups["Squares Table"].size(), 2);
BOOST_CHECK_EQUAL(gates.grouped_lookups["Squares Table"].size(), 2);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit a50f8fe

Please sign in to comment.