Skip to content

Commit db13448

Browse files
authored
chore: static batch inverses (#17899)
1 parent 96f99d3 commit db13448

File tree

4 files changed

+52
-50
lines changed

4 files changed

+52
-50
lines changed

barretenberg/cpp/src/barretenberg/vm2/tracegen/alu_trace.cpp

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,41 @@
88
#include "barretenberg/numeric/uint256/uint256.hpp"
99
#include "barretenberg/vm2/common/memory_types.hpp"
1010
#include "barretenberg/vm2/common/tagged_value.hpp"
11+
#include "barretenberg/vm2/generated/columns.hpp"
1112
#include "barretenberg/vm2/generated/relations/lookups_alu.hpp"
12-
#include "barretenberg/vm2/simulation/events/alu_event.hpp"
13-
#include "barretenberg/vm2/simulation/events/event_emitter.hpp"
1413
#include "barretenberg/vm2/simulation/lib/uint_decomposition.hpp"
1514
#include "barretenberg/vm2/tracegen/lib/instruction_spec.hpp"
16-
#include "barretenberg/vm2/tracegen/lib/interaction_def.hpp"
1715

1816
namespace bb::avm2::tracegen {
1917

20-
AluTraceBuilder::AluTraceBuilder()
18+
namespace {
19+
20+
// Get tag inverse for a given index using static precomputed inverses.
21+
const FF& get_tag_inverse(size_t index)
2122
{
22-
for (size_t i = 0; i < NUM_TAGS; i++) {
23-
tag_inverses.at(i) = FF(i);
24-
}
25-
FF::batch_invert(tag_inverses);
23+
constexpr size_t NUM_TAGS = static_cast<size_t>(MemoryTag::MAX) + 1;
24+
static const std::array<FF, NUM_TAGS> tag_inverses = []() {
25+
std::array<FF, NUM_TAGS> inverses;
26+
for (size_t i = 0; i < NUM_TAGS; i++) {
27+
inverses.at(i) = FF(i);
28+
}
29+
FF::batch_invert(inverses);
30+
return inverses;
31+
}();
32+
33+
return tag_inverses.at(index);
2634
}
2735

28-
FF AluTraceBuilder::get_tag_diff_inverse(const MemoryTag a_tag, const MemoryTag b_tag) const
36+
FF get_tag_diff_inverse(const MemoryTag a_tag, const MemoryTag b_tag)
2937
{
3038
if (static_cast<uint8_t>(a_tag) >= static_cast<uint8_t>(b_tag)) {
31-
return tag_inverses[static_cast<uint8_t>(a_tag) - static_cast<uint8_t>(b_tag)];
39+
return get_tag_inverse(static_cast<uint8_t>(a_tag) - static_cast<uint8_t>(b_tag));
3240
}
3341

34-
return -tag_inverses[static_cast<uint8_t>(b_tag) - static_cast<uint8_t>(a_tag)];
42+
return -get_tag_inverse(static_cast<uint8_t>(b_tag) - static_cast<uint8_t>(a_tag));
3543
}
3644

37-
std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_columns(
38-
const simulation::AluEvent& event) const
45+
std::vector<std::pair<Column, FF>> get_operation_specific_columns(const simulation::AluEvent& event)
3946
{
4047
const MemoryTag a_tag = event.a.get_tag();
4148
bool is_ff = a_tag == MemoryTag::FF;
@@ -106,7 +113,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
106113
{ Column::alu_helper1, remainder },
107114
{ Column::alu_constant_64, 64 },
108115
{ Column::alu_sel_is_ff, is_ff },
109-
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
116+
{ Column::alu_tag_ff_diff_inv,
117+
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
110118
{ Column::alu_sel_is_u128, is_u128 },
111119
{ Column::alu_tag_u128_diff_inv, get_tag_diff_inverse(a_tag, MemoryTag::U128) },
112120
{ Column::alu_b_inv, div_0_error ? 0 : event.b.as_ff() }, // Will be inverted in batch later
@@ -136,7 +144,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
136144
{ Column::alu_sel_op_fdiv, 1 },
137145
{ Column::alu_op_id, SUBTRACE_INFO_MAP.at(ExecutionOpCode::FDIV).subtrace_operation_id },
138146
{ Column::alu_sel_is_ff, is_ff },
139-
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
147+
{ Column::alu_tag_ff_diff_inv,
148+
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
140149
{ Column::alu_b_inv, div_0_error ? 0 : event.b.as_ff() }, // Will be inverted in batch later
141150
};
142151
}
@@ -160,7 +169,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
160169
{ Column::alu_sel_is_ff, is_ff },
161170
{ Column::alu_sel_ff_lt_ops, is_ff && no_tag_err },
162171
{ Column::alu_sel_int_lt_ops, !is_ff && no_tag_err },
163-
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
172+
{ Column::alu_tag_ff_diff_inv,
173+
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
164174
};
165175
case simulation::AluOperation::LTE:
166176
return {
@@ -174,14 +184,16 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
174184
{ Column::alu_sel_is_ff, is_ff },
175185
{ Column::alu_sel_ff_lt_ops, is_ff && no_tag_err },
176186
{ Column::alu_sel_int_lt_ops, !is_ff && no_tag_err },
177-
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
187+
{ Column::alu_tag_ff_diff_inv,
188+
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
178189
};
179190
case simulation::AluOperation::NOT: {
180191
return {
181192
{ Column::alu_sel_op_not, 1 },
182193
{ Column::alu_op_id, SUBTRACE_INFO_MAP.at(ExecutionOpCode::NOT).subtrace_operation_id },
183194
{ Column::alu_sel_is_ff, is_ff },
184-
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
195+
{ Column::alu_tag_ff_diff_inv,
196+
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
185197
};
186198
}
187199
case simulation::AluOperation::SHL: {
@@ -208,7 +220,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
208220
{ Column::alu_shift_lo_bits, shift_lo_bits },
209221
{ Column::alu_two_pow_shift_lo_bits, static_cast<uint128_t>(1) << shift_lo_bits },
210222
{ Column::alu_sel_is_ff, is_ff },
211-
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
223+
{ Column::alu_tag_ff_diff_inv,
224+
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
212225
{ Column::alu_op_id, SUBTRACE_INFO_MAP.at(ExecutionOpCode::SHL).subtrace_operation_id },
213226
{ Column::alu_helper1, static_cast<uint128_t>(1) << b_num },
214227
};
@@ -237,7 +250,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
237250
{ Column::alu_shift_lo_bits, shift_lo_bits },
238251
{ Column::alu_two_pow_shift_lo_bits, static_cast<uint128_t>(1) << shift_lo_bits },
239252
{ Column::alu_sel_is_ff, is_ff },
240-
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
253+
{ Column::alu_tag_ff_diff_inv,
254+
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
241255
{ Column::alu_op_id, SUBTRACE_INFO_MAP.at(ExecutionOpCode::SHR).subtrace_operation_id },
242256
};
243257
}
@@ -270,7 +284,7 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
270284
}
271285
}
272286

273-
std::vector<std::pair<Column, FF>> AluTraceBuilder::get_tag_error_columns(const simulation::AluEvent& event) const
287+
std::vector<std::pair<Column, FF>> get_tag_error_columns(const simulation::AluEvent& event)
274288
{
275289
const MemoryTag a_tag = event.a.get_tag();
276290
const FF a_tag_ff = static_cast<FF>(static_cast<uint8_t>(a_tag));
@@ -305,6 +319,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_tag_error_columns(const
305319
return {};
306320
}
307321

322+
} // namespace
323+
308324
void AluTraceBuilder::process(const simulation::EventEmitterInterface<simulation::AluEvent>::Container& events,
309325
TraceContainer& trace)
310326
{
Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#pragma once
22

3-
#include "barretenberg/vm2/generated/columns.hpp"
43
#include "barretenberg/vm2/simulation/events/alu_event.hpp"
54
#include "barretenberg/vm2/simulation/events/event_emitter.hpp"
65
#include "barretenberg/vm2/tracegen/lib/interaction_def.hpp"
@@ -10,19 +9,10 @@ namespace bb::avm2::tracegen {
109

1110
class AluTraceBuilder final {
1211
public:
13-
AluTraceBuilder();
1412
void process(const simulation::EventEmitterInterface<simulation::AluEvent>::Container& events,
1513
TraceContainer& trace);
1614

1715
static const InteractionDefinition interactions;
18-
19-
private:
20-
static constexpr size_t NUM_TAGS = static_cast<size_t>(MemoryTag::MAX) + 1;
21-
// Precomputed inverses for tag values.
22-
std::array<FF, NUM_TAGS> tag_inverses;
23-
std::vector<std::pair<Column, FF>> get_operation_specific_columns(const simulation::AluEvent& event) const;
24-
FF get_tag_diff_inverse(const MemoryTag a_tag, const MemoryTag b_tag) const;
25-
std::vector<std::pair<Column, FF>> get_tag_error_columns(const simulation::AluEvent& event) const;
2616
};
2717

2818
} // namespace bb::avm2::tracegen

barretenberg/cpp/src/barretenberg/vm2/tracegen/keccakf1600_trace.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -379,24 +379,23 @@ constexpr std::array<C, AVM_KECCAKF1600_STATE_SIZE> MEM_VAL_COLS = {
379379
},
380380
};
381381

382-
// Precomputed inverses from 0, 1 ... AVM_KECCAKF1600_STATE_SIZE.
383-
std::array<FF, AVM_KECCAKF1600_STATE_SIZE + 1> generate_precomputed_inverses()
382+
// Get inverse for a given index using static precomputed inverses.
383+
const FF& get_precomputed_inverse(size_t index)
384384
{
385-
std::array<FF, AVM_KECCAKF1600_STATE_SIZE + 1> precomputed_inverses;
386-
for (size_t i = 0; i < AVM_KECCAKF1600_STATE_SIZE + 1; i++) {
387-
precomputed_inverses.at(i) = FF(i);
388-
}
389-
FF::batch_invert(precomputed_inverses);
390-
return precomputed_inverses;
385+
static const std::array<FF, AVM_KECCAKF1600_STATE_SIZE + 1> precomputed_inverses = []() {
386+
std::array<FF, AVM_KECCAKF1600_STATE_SIZE + 1> inverses;
387+
for (size_t i = 0; i < AVM_KECCAKF1600_STATE_SIZE + 1; i++) {
388+
inverses.at(i) = FF(i);
389+
}
390+
FF::batch_invert(inverses);
391+
return inverses;
392+
}();
393+
394+
return precomputed_inverses.at(index);
391395
}
392396

393397
} // namespace
394398

395-
KeccakF1600TraceBuilder::KeccakF1600TraceBuilder()
396-
{
397-
precomputed_inverses = generate_precomputed_inverses();
398-
}
399-
400399
// Populate a memory slice read or write operation for the Keccak permutation.
401400
void KeccakF1600TraceBuilder::process_single_slice(const simulation::KeccakF1600Event& event,
402401
bool write,
@@ -450,9 +449,9 @@ void KeccakF1600TraceBuilder::process_single_slice(const simulation::KeccakF1600
450449
{ C::keccak_memory_sel, 1 },
451450
{ C::keccak_memory_clk, event.execution_clk },
452451
{ C::keccak_memory_ctr, i + 1 },
453-
{ C::keccak_memory_ctr_inv, precomputed_inverses.at(i + 1) },
452+
{ C::keccak_memory_ctr_inv, get_precomputed_inverse(i + 1) },
454453
{ C::keccak_memory_state_size_min_ctr_inv,
455-
precomputed_inverses.at(AVM_KECCAKF1600_STATE_SIZE - i - 1) },
454+
get_precomputed_inverse(AVM_KECCAKF1600_STATE_SIZE - i - 1) },
456455
{ C::keccak_memory_start_read, (i == 0 && !write) ? 1 : 0 },
457456
{ C::keccak_memory_start_write, (i == 0 && write) ? 1 : 0 },
458457
{ C::keccak_memory_ctr_end, i == AVM_KECCAKF1600_STATE_SIZE - 1 ? 1 : 0 },
@@ -555,7 +554,7 @@ void KeccakF1600TraceBuilder::process_permutation(
555554
{ C::keccakf1600_dst_addr, event.dst_addr },
556555
{ C::keccakf1600_sel_no_error, error ? 0 : 1 },
557556
{ C::keccakf1600_space_id, event.space_id },
558-
{ C::keccakf1600_round_inv, precomputed_inverses.at(round_idx + 1) },
557+
{ C::keccakf1600_round_inv, get_precomputed_inverse(round_idx + 1) },
559558
} });
560559

561560
// When no out-of-range value occured but a tag value error, we

barretenberg/cpp/src/barretenberg/vm2/tracegen/keccakf1600_trace.hpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ namespace bb::avm2::tracegen {
1010

1111
class KeccakF1600TraceBuilder final {
1212
public:
13-
KeccakF1600TraceBuilder();
1413
void process_permutation(const simulation::EventEmitterInterface<simulation::KeccakF1600Event>::Container& events,
1514
TraceContainer& trace);
1615
void process_memory_slices(const simulation::EventEmitterInterface<simulation::KeccakF1600Event>::Container& events,
@@ -19,8 +18,6 @@ class KeccakF1600TraceBuilder final {
1918
static const InteractionDefinition interactions;
2019

2120
private:
22-
// Precomputed inverses from 0, 1 ... AVM_KECCAKF1600_STATE_SIZE.
23-
std::array<FF, AVM_KECCAKF1600_STATE_SIZE + 1> precomputed_inverses;
2421
void process_single_slice(const simulation::KeccakF1600Event& event,
2522
bool write,
2623
uint32_t& row,

0 commit comments

Comments
 (0)