Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 37 additions & 21 deletions barretenberg/cpp/src/barretenberg/vm2/tracegen/alu_trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,41 @@
#include "barretenberg/numeric/uint256/uint256.hpp"
#include "barretenberg/vm2/common/memory_types.hpp"
#include "barretenberg/vm2/common/tagged_value.hpp"
#include "barretenberg/vm2/generated/columns.hpp"
#include "barretenberg/vm2/generated/relations/lookups_alu.hpp"
#include "barretenberg/vm2/simulation/events/alu_event.hpp"
#include "barretenberg/vm2/simulation/events/event_emitter.hpp"
#include "barretenberg/vm2/simulation/lib/uint_decomposition.hpp"
#include "barretenberg/vm2/tracegen/lib/instruction_spec.hpp"
#include "barretenberg/vm2/tracegen/lib/interaction_def.hpp"

namespace bb::avm2::tracegen {

AluTraceBuilder::AluTraceBuilder()
namespace {

// Get tag inverse for a given index using static precomputed inverses.
const FF& get_tag_inverse(size_t index)
{
for (size_t i = 0; i < NUM_TAGS; i++) {
tag_inverses.at(i) = FF(i);
}
FF::batch_invert(tag_inverses);
constexpr size_t NUM_TAGS = static_cast<size_t>(MemoryTag::MAX) + 1;
static const std::array<FF, NUM_TAGS> tag_inverses = []() {
std::array<FF, NUM_TAGS> inverses;
for (size_t i = 0; i < NUM_TAGS; i++) {
inverses.at(i) = FF(i);
}
FF::batch_invert(inverses);
return inverses;
}();

return tag_inverses.at(index);
}

FF AluTraceBuilder::get_tag_diff_inverse(const MemoryTag a_tag, const MemoryTag b_tag) const
FF get_tag_diff_inverse(const MemoryTag a_tag, const MemoryTag b_tag)
{
if (static_cast<uint8_t>(a_tag) >= static_cast<uint8_t>(b_tag)) {
return tag_inverses[static_cast<uint8_t>(a_tag) - static_cast<uint8_t>(b_tag)];
return get_tag_inverse(static_cast<uint8_t>(a_tag) - static_cast<uint8_t>(b_tag));
}

return -tag_inverses[static_cast<uint8_t>(b_tag) - static_cast<uint8_t>(a_tag)];
return -get_tag_inverse(static_cast<uint8_t>(b_tag) - static_cast<uint8_t>(a_tag));
}

std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_columns(
const simulation::AluEvent& event) const
std::vector<std::pair<Column, FF>> get_operation_specific_columns(const simulation::AluEvent& event)
{
const MemoryTag a_tag = event.a.get_tag();
bool is_ff = a_tag == MemoryTag::FF;
Expand Down Expand Up @@ -106,7 +113,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
{ Column::alu_helper1, remainder },
{ Column::alu_constant_64, 64 },
{ Column::alu_sel_is_ff, is_ff },
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
{ Column::alu_tag_ff_diff_inv,
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
{ Column::alu_sel_is_u128, is_u128 },
{ Column::alu_tag_u128_diff_inv, get_tag_diff_inverse(a_tag, MemoryTag::U128) },
{ Column::alu_b_inv, div_0_error ? 0 : event.b.as_ff() }, // Will be inverted in batch later
Expand Down Expand Up @@ -136,7 +144,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
{ Column::alu_sel_op_fdiv, 1 },
{ Column::alu_op_id, SUBTRACE_INFO_MAP.at(ExecutionOpCode::FDIV).subtrace_operation_id },
{ Column::alu_sel_is_ff, is_ff },
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
{ Column::alu_tag_ff_diff_inv,
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
{ Column::alu_b_inv, div_0_error ? 0 : event.b.as_ff() }, // Will be inverted in batch later
};
}
Expand All @@ -160,7 +169,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
{ Column::alu_sel_is_ff, is_ff },
{ Column::alu_sel_ff_lt_ops, is_ff && no_tag_err },
{ Column::alu_sel_int_lt_ops, !is_ff && no_tag_err },
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
{ Column::alu_tag_ff_diff_inv,
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
};
case simulation::AluOperation::LTE:
return {
Expand All @@ -174,14 +184,16 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
{ Column::alu_sel_is_ff, is_ff },
{ Column::alu_sel_ff_lt_ops, is_ff && no_tag_err },
{ Column::alu_sel_int_lt_ops, !is_ff && no_tag_err },
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
{ Column::alu_tag_ff_diff_inv,
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
};
case simulation::AluOperation::NOT: {
return {
{ Column::alu_sel_op_not, 1 },
{ Column::alu_op_id, SUBTRACE_INFO_MAP.at(ExecutionOpCode::NOT).subtrace_operation_id },
{ Column::alu_sel_is_ff, is_ff },
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
{ Column::alu_tag_ff_diff_inv,
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
};
}
case simulation::AluOperation::SHL: {
Expand All @@ -208,7 +220,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
{ Column::alu_shift_lo_bits, shift_lo_bits },
{ Column::alu_two_pow_shift_lo_bits, static_cast<uint128_t>(1) << shift_lo_bits },
{ Column::alu_sel_is_ff, is_ff },
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
{ Column::alu_tag_ff_diff_inv,
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
{ Column::alu_op_id, SUBTRACE_INFO_MAP.at(ExecutionOpCode::SHL).subtrace_operation_id },
{ Column::alu_helper1, static_cast<uint128_t>(1) << b_num },
};
Expand Down Expand Up @@ -237,7 +250,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
{ Column::alu_shift_lo_bits, shift_lo_bits },
{ Column::alu_two_pow_shift_lo_bits, static_cast<uint128_t>(1) << shift_lo_bits },
{ Column::alu_sel_is_ff, is_ff },
{ Column::alu_tag_ff_diff_inv, tag_inverses[static_cast<uint8_t>(a_tag)] }, // Relies on MemoryTag::FF is 0
{ Column::alu_tag_ff_diff_inv,
get_tag_inverse(static_cast<uint8_t>(a_tag)) }, // Relies on MemoryTag::FF is 0
{ Column::alu_op_id, SUBTRACE_INFO_MAP.at(ExecutionOpCode::SHR).subtrace_operation_id },
};
}
Expand Down Expand Up @@ -270,7 +284,7 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_operation_specific_colum
}
}

std::vector<std::pair<Column, FF>> AluTraceBuilder::get_tag_error_columns(const simulation::AluEvent& event) const
std::vector<std::pair<Column, FF>> get_tag_error_columns(const simulation::AluEvent& event)
{
const MemoryTag a_tag = event.a.get_tag();
const FF a_tag_ff = static_cast<FF>(static_cast<uint8_t>(a_tag));
Expand Down Expand Up @@ -305,6 +319,8 @@ std::vector<std::pair<Column, FF>> AluTraceBuilder::get_tag_error_columns(const
return {};
}

} // namespace

void AluTraceBuilder::process(const simulation::EventEmitterInterface<simulation::AluEvent>::Container& events,
TraceContainer& trace)
{
Expand Down
10 changes: 0 additions & 10 deletions barretenberg/cpp/src/barretenberg/vm2/tracegen/alu_trace.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#pragma once

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

class AluTraceBuilder final {
public:
AluTraceBuilder();
void process(const simulation::EventEmitterInterface<simulation::AluEvent>::Container& events,
TraceContainer& trace);

static const InteractionDefinition interactions;

private:
static constexpr size_t NUM_TAGS = static_cast<size_t>(MemoryTag::MAX) + 1;
// Precomputed inverses for tag values.
std::array<FF, NUM_TAGS> tag_inverses;
std::vector<std::pair<Column, FF>> get_operation_specific_columns(const simulation::AluEvent& event) const;
FF get_tag_diff_inverse(const MemoryTag a_tag, const MemoryTag b_tag) const;
std::vector<std::pair<Column, FF>> get_tag_error_columns(const simulation::AluEvent& event) const;
};

} // namespace bb::avm2::tracegen
Original file line number Diff line number Diff line change
Expand Up @@ -379,24 +379,23 @@ constexpr std::array<C, AVM_KECCAKF1600_STATE_SIZE> MEM_VAL_COLS = {
},
};

// Precomputed inverses from 0, 1 ... AVM_KECCAKF1600_STATE_SIZE.
std::array<FF, AVM_KECCAKF1600_STATE_SIZE + 1> generate_precomputed_inverses()
// Get inverse for a given index using static precomputed inverses.
const FF& get_precomputed_inverse(size_t index)
{
std::array<FF, AVM_KECCAKF1600_STATE_SIZE + 1> precomputed_inverses;
for (size_t i = 0; i < AVM_KECCAKF1600_STATE_SIZE + 1; i++) {
precomputed_inverses.at(i) = FF(i);
}
FF::batch_invert(precomputed_inverses);
return precomputed_inverses;
static const std::array<FF, AVM_KECCAKF1600_STATE_SIZE + 1> precomputed_inverses = []() {
std::array<FF, AVM_KECCAKF1600_STATE_SIZE + 1> inverses;
for (size_t i = 0; i < AVM_KECCAKF1600_STATE_SIZE + 1; i++) {
inverses.at(i) = FF(i);
}
FF::batch_invert(inverses);
return inverses;
}();

return precomputed_inverses.at(index);
}

} // namespace

KeccakF1600TraceBuilder::KeccakF1600TraceBuilder()
{
precomputed_inverses = generate_precomputed_inverses();
}

// Populate a memory slice read or write operation for the Keccak permutation.
void KeccakF1600TraceBuilder::process_single_slice(const simulation::KeccakF1600Event& event,
bool write,
Expand Down Expand Up @@ -450,9 +449,9 @@ void KeccakF1600TraceBuilder::process_single_slice(const simulation::KeccakF1600
{ C::keccak_memory_sel, 1 },
{ C::keccak_memory_clk, event.execution_clk },
{ C::keccak_memory_ctr, i + 1 },
{ C::keccak_memory_ctr_inv, precomputed_inverses.at(i + 1) },
{ C::keccak_memory_ctr_inv, get_precomputed_inverse(i + 1) },
{ C::keccak_memory_state_size_min_ctr_inv,
precomputed_inverses.at(AVM_KECCAKF1600_STATE_SIZE - i - 1) },
get_precomputed_inverse(AVM_KECCAKF1600_STATE_SIZE - i - 1) },
{ C::keccak_memory_start_read, (i == 0 && !write) ? 1 : 0 },
{ C::keccak_memory_start_write, (i == 0 && write) ? 1 : 0 },
{ C::keccak_memory_ctr_end, i == AVM_KECCAKF1600_STATE_SIZE - 1 ? 1 : 0 },
Expand Down Expand Up @@ -555,7 +554,7 @@ void KeccakF1600TraceBuilder::process_permutation(
{ C::keccakf1600_dst_addr, event.dst_addr },
{ C::keccakf1600_sel_no_error, error ? 0 : 1 },
{ C::keccakf1600_space_id, event.space_id },
{ C::keccakf1600_round_inv, precomputed_inverses.at(round_idx + 1) },
{ C::keccakf1600_round_inv, get_precomputed_inverse(round_idx + 1) },
} });

// When no out-of-range value occured but a tag value error, we
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ namespace bb::avm2::tracegen {

class KeccakF1600TraceBuilder final {
public:
KeccakF1600TraceBuilder();
void process_permutation(const simulation::EventEmitterInterface<simulation::KeccakF1600Event>::Container& events,
TraceContainer& trace);
void process_memory_slices(const simulation::EventEmitterInterface<simulation::KeccakF1600Event>::Container& events,
Expand All @@ -19,8 +18,6 @@ class KeccakF1600TraceBuilder final {
static const InteractionDefinition interactions;

private:
// Precomputed inverses from 0, 1 ... AVM_KECCAKF1600_STATE_SIZE.
std::array<FF, AVM_KECCAKF1600_STATE_SIZE + 1> precomputed_inverses;
void process_single_slice(const simulation::KeccakF1600Event& event,
bool write,
uint32_t& row,
Expand Down
Loading