Skip to content

Commit

Permalink
feat: Separate arithmetic gate in sort with edges (#4866)
Browse files Browse the repository at this point in the history
Removes another optimization that is incompatible with execution trace
sorting.

Method `create_sort_constraint_with_edges`, adds gates for batch range
checking a set of elements using the generalized permutation argument
(`q_sort`). The first and last gates are arithmetic gates that ensure
the first/last element in your batch is equal to the lower/upper bound
of the range being checked. Previously, the first gate was
simultaneously an arithmetic gate and a `q_sort` gate. This PR separates
this into two gates so that the "lower bound check" is separated out
into a single arithmetic gate. (Note: the final gate was already split
in this way for a different reason: each sort gate looks into the wire
values of the next row. The dummy gate provides this "next row" and
breaks the cycle).

Note: this adds an additional 1 gate per batched range check via
`create_sort_constraint_with_edges`. This results in a vkey change hence
the join split test update.

```
--------------------------------------------------------------------------------
Benchmark                      Time             CPU   Iterations UserCounters...
--------------------------------------------------------------------------------
ClientIVCBench/Full/6      32579 ms        26658 ms 
```
  • Loading branch information
ledwards2225 authored Feb 29, 2024
1 parent 15c5399 commit 40adc5c
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ TEST_F(join_split_tests, test_0_input_notes_and_detect_circuit_change)
// The below part detects any changes in the join-split circuit
constexpr uint32_t CIRCUIT_GATE_COUNT = 49492;
constexpr uint32_t GATES_NEXT_POWER_OF_TWO = 65535;
const uint256_t VK_HASH("c1032f787036ac943a5f064e599772d255423a221bba2af98ebce3baf2b53f56");
const uint256_t VK_HASH("893b71911c19c3a06a2658f0ef5f66f6e23455af7c8771a67c80addb060a479c");

auto number_of_gates_js = result.number_of_gates;
std::cout << get_verification_key()->sha256_hash() << std::endl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1012,8 +1012,8 @@ void UltraCircuitBuilder_<Arithmetization>::create_sort_constraint_with_edges(
ASSERT(variable_index.size() % gate_width == 0 && variable_index.size() > gate_width);
this->assert_valid_variables(variable_index);

// enforce range checks of first row and starting at start
blocks.main.populate_wires(variable_index[0], variable_index[1], variable_index[2], variable_index[3]);
// Add an arithmetic gate to ensure the first input is equal to the start value of the range being checked
blocks.main.populate_wires(variable_index[0], this->zero_idx, this->zero_idx, this->zero_idx);
++this->num_gates;
blocks.main.q_m().emplace_back(0);
blocks.main.q_1().emplace_back(1);
Expand All @@ -1022,16 +1022,17 @@ void UltraCircuitBuilder_<Arithmetization>::create_sort_constraint_with_edges(
blocks.main.q_c().emplace_back(-start);
blocks.main.q_arith().emplace_back(1);
blocks.main.q_4().emplace_back(0);
blocks.main.q_sort().emplace_back(1);
blocks.main.q_sort().emplace_back(0);
blocks.main.q_elliptic().emplace_back(0);
blocks.main.q_lookup_type().emplace_back(0);
blocks.main.q_aux().emplace_back(0);
if constexpr (HasAdditionalSelectors<Arithmetization>) {
blocks.main.pad_additional();
}
check_selector_length_consistency();
// enforce range check for middle rows
for (size_t i = gate_width; i < variable_index.size() - gate_width; i += gate_width) {

// enforce range check for all but the final row
for (size_t i = 0; i < variable_index.size() - gate_width; i += gate_width) {

blocks.main.populate_wires(
variable_index[i], variable_index[i + 1], variable_index[i + 2], variable_index[i + 3]);
Expand Down

0 comments on commit 40adc5c

Please sign in to comment.