Skip to content

Commit

Permalink
chore(avm): vm2 followup cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
fcarreiro committed Jan 13, 2025
1 parent e494f6b commit 6641dae
Show file tree
Hide file tree
Showing 17 changed files with 83 additions and 81 deletions.
6 changes: 3 additions & 3 deletions barretenberg/cpp/pil/vm2/addressing.pil
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// This is a virtual gadget, which is part of the execution trace.
namespace execution(256);
namespace execution;

pol commit stack_pointer_val;
pol commit stack_pointer_tag;
pol commit base_address_val;
pol commit base_address_tag;
pol commit sel_addressing_error; // true if any error type
pol commit addressing_error_kind; // TODO: might need to be selectors
pol commit addressing_error_idx; // operand index for error, if any
Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/pil/vm2/alu.pil
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace alu(256);
namespace alu;

pol commit sel_op_add;
pol commit ia;
Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/pil/vm2/execution.pil
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ include "alu.pil";
include "addressing.pil";
include "precomputed.pil";

namespace execution(256);
namespace execution;

pol commit sel; // subtrace selector

Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/pil/vm2/precomputed.pil
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// General/shared precomputed columns.
namespace precomputed(256);
namespace precomputed;

// From 0 and incrementing up to the size of the circuit (2^21).
pol constant clk;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace bb::avm2::constraining {

// This is a version of check circuit that runs on the prover polynomials.
// Better versions could be done, but since this is for debugging only, it is enough for now.
// It is the closest to "real proving" that we can get without actually running the prover.
void run_check_circuit(AvmFlavor::ProverPolynomials& polys, size_t num_rows);

} // namespace bb::avm2::constraining
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace bb::avm2 {
// The entities that will be used in the flavor.
// clang-format off
#define AVM2_PRECOMPUTED_ENTITIES precomputed_bitwise_input_a, precomputed_bitwise_input_b, precomputed_bitwise_op_id, precomputed_bitwise_output, precomputed_clk, precomputed_first_row, precomputed_sel_bitwise
#define AVM2_WIRE_ENTITIES execution_input, alu_dst_addr, alu_ia, alu_ia_addr, alu_ib, alu_ib_addr, alu_ic, alu_op, alu_sel_op_add, execution_addressing_error_idx, execution_addressing_error_kind, execution_clk, execution_ex_opcode, execution_indirect, execution_last, execution_op1, execution_op1_after_relative, execution_op2, execution_op2_after_relative, execution_op3, execution_op3_after_relative, execution_op4, execution_op4_after_relative, execution_pc, execution_rop1, execution_rop2, execution_rop3, execution_rop4, execution_sel, execution_sel_addressing_error, execution_sel_op1_is_address, execution_sel_op2_is_address, execution_sel_op3_is_address, execution_sel_op4_is_address, execution_stack_pointer_tag, execution_stack_pointer_val, lookup_dummy_precomputed_counts, lookup_dummy_dynamic_counts
#define AVM2_WIRE_ENTITIES execution_input, alu_dst_addr, alu_ia, alu_ia_addr, alu_ib, alu_ib_addr, alu_ic, alu_op, alu_sel_op_add, execution_addressing_error_idx, execution_addressing_error_kind, execution_base_address_tag, execution_base_address_val, execution_clk, execution_ex_opcode, execution_indirect, execution_last, execution_op1, execution_op1_after_relative, execution_op2, execution_op2_after_relative, execution_op3, execution_op3_after_relative, execution_op4, execution_op4_after_relative, execution_pc, execution_rop1, execution_rop2, execution_rop3, execution_rop4, execution_sel, execution_sel_addressing_error, execution_sel_op1_is_address, execution_sel_op2_is_address, execution_sel_op3_is_address, execution_sel_op4_is_address, lookup_dummy_precomputed_counts, lookup_dummy_dynamic_counts
#define AVM2_DERIVED_WITNESS_ENTITIES perm_dummy_dynamic_inv, lookup_dummy_precomputed_inv, lookup_dummy_dynamic_inv
#define AVM2_SHIFTED_ENTITIES execution_sel_shift
#define AVM2_TO_BE_SHIFTED(e) e.execution_sel
Expand Down
58 changes: 29 additions & 29 deletions barretenberg/cpp/src/barretenberg/vm2/generated/flavor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,31 @@ AvmFlavor::AllConstRefValues::AllConstRefValues(
, alu_sel_op_add(il[15])
, execution_addressing_error_idx(il[16])
, execution_addressing_error_kind(il[17])
, execution_clk(il[18])
, execution_ex_opcode(il[19])
, execution_indirect(il[20])
, execution_last(il[21])
, execution_op1(il[22])
, execution_op1_after_relative(il[23])
, execution_op2(il[24])
, execution_op2_after_relative(il[25])
, execution_op3(il[26])
, execution_op3_after_relative(il[27])
, execution_op4(il[28])
, execution_op4_after_relative(il[29])
, execution_pc(il[30])
, execution_rop1(il[31])
, execution_rop2(il[32])
, execution_rop3(il[33])
, execution_rop4(il[34])
, execution_sel(il[35])
, execution_sel_addressing_error(il[36])
, execution_sel_op1_is_address(il[37])
, execution_sel_op2_is_address(il[38])
, execution_sel_op3_is_address(il[39])
, execution_sel_op4_is_address(il[40])
, execution_stack_pointer_tag(il[41])
, execution_stack_pointer_val(il[42])
, execution_base_address_tag(il[18])
, execution_base_address_val(il[19])
, execution_clk(il[20])
, execution_ex_opcode(il[21])
, execution_indirect(il[22])
, execution_last(il[23])
, execution_op1(il[24])
, execution_op1_after_relative(il[25])
, execution_op2(il[26])
, execution_op2_after_relative(il[27])
, execution_op3(il[28])
, execution_op3_after_relative(il[29])
, execution_op4(il[30])
, execution_op4_after_relative(il[31])
, execution_pc(il[32])
, execution_rop1(il[33])
, execution_rop2(il[34])
, execution_rop3(il[35])
, execution_rop4(il[36])
, execution_sel(il[37])
, execution_sel_addressing_error(il[38])
, execution_sel_op1_is_address(il[39])
, execution_sel_op2_is_address(il[40])
, execution_sel_op3_is_address(il[41])
, execution_sel_op4_is_address(il[42])
, lookup_dummy_precomputed_counts(il[43])
, lookup_dummy_dynamic_counts(il[44])
, perm_dummy_dynamic_inv(il[45])
Expand Down Expand Up @@ -88,6 +88,8 @@ AvmFlavor::AllConstRefValues AvmFlavor::ProverPolynomials::get_row(size_t row_id
alu_sel_op_add[row_idx],
execution_addressing_error_idx[row_idx],
execution_addressing_error_kind[row_idx],
execution_base_address_tag[row_idx],
execution_base_address_val[row_idx],
execution_clk[row_idx],
execution_ex_opcode[row_idx],
execution_indirect[row_idx],
Expand All @@ -111,8 +113,6 @@ AvmFlavor::AllConstRefValues AvmFlavor::ProverPolynomials::get_row(size_t row_id
execution_sel_op2_is_address[row_idx],
execution_sel_op3_is_address[row_idx],
execution_sel_op4_is_address[row_idx],
execution_stack_pointer_tag[row_idx],
execution_stack_pointer_val[row_idx],
lookup_dummy_precomputed_counts[row_idx],
lookup_dummy_dynamic_counts[row_idx],
perm_dummy_dynamic_inv[row_idx],
Expand Down Expand Up @@ -141,6 +141,8 @@ AvmFlavor::CommitmentLabels::CommitmentLabels()
Base::alu_sel_op_add = "ALU_SEL_OP_ADD";
Base::execution_addressing_error_idx = "EXECUTION_ADDRESSING_ERROR_IDX";
Base::execution_addressing_error_kind = "EXECUTION_ADDRESSING_ERROR_KIND";
Base::execution_base_address_tag = "EXECUTION_BASE_ADDRESS_TAG";
Base::execution_base_address_val = "EXECUTION_BASE_ADDRESS_VAL";
Base::execution_clk = "EXECUTION_CLK";
Base::execution_ex_opcode = "EXECUTION_EX_OPCODE";
Base::execution_indirect = "EXECUTION_INDIRECT";
Expand All @@ -164,8 +166,6 @@ AvmFlavor::CommitmentLabels::CommitmentLabels()
Base::execution_sel_op2_is_address = "EXECUTION_SEL_OP2_IS_ADDRESS";
Base::execution_sel_op3_is_address = "EXECUTION_SEL_OP3_IS_ADDRESS";
Base::execution_sel_op4_is_address = "EXECUTION_SEL_OP4_IS_ADDRESS";
Base::execution_stack_pointer_tag = "EXECUTION_STACK_POINTER_TAG";
Base::execution_stack_pointer_val = "EXECUTION_STACK_POINTER_VAL";
Base::perm_dummy_dynamic_inv = "PERM_DUMMY_DYNAMIC_INV";
Base::lookup_dummy_precomputed_inv = "LOOKUP_DUMMY_PRECOMPUTED_INV";
Base::lookup_dummy_dynamic_inv = "LOOKUP_DUMMY_DYNAMIC_INV";
Expand Down
8 changes: 4 additions & 4 deletions barretenberg/cpp/src/barretenberg/vm2/generated/full_row.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ template <typename FF> std::vector<std::string> AvmFullRow<FF>::names()
"alu_sel_op_add",
"execution_addressing_error_idx",
"execution_addressing_error_kind",
"execution_base_address_tag",
"execution_base_address_val",
"execution_clk",
"execution_ex_opcode",
"execution_indirect",
Expand All @@ -60,8 +62,6 @@ template <typename FF> std::vector<std::string> AvmFullRow<FF>::names()
"execution_sel_op2_is_address",
"execution_sel_op3_is_address",
"execution_sel_op4_is_address",
"execution_stack_pointer_tag",
"execution_stack_pointer_val",
"perm_dummy_dynamic_inv",
"lookup_dummy_precomputed_inv",
"lookup_dummy_dynamic_inv",
Expand Down Expand Up @@ -90,6 +90,8 @@ template <typename FF> RefVector<const FF> AvmFullRow<FF>::as_vector() const
alu_sel_op_add,
execution_addressing_error_idx,
execution_addressing_error_kind,
execution_base_address_tag,
execution_base_address_val,
execution_clk,
execution_ex_opcode,
execution_indirect,
Expand All @@ -113,8 +115,6 @@ template <typename FF> RefVector<const FF> AvmFullRow<FF>::as_vector() const
execution_sel_op2_is_address,
execution_sel_op3_is_address,
execution_sel_op4_is_address,
execution_stack_pointer_tag,
execution_stack_pointer_val,
perm_dummy_dynamic_inv,
lookup_dummy_precomputed_inv,
lookup_dummy_dynamic_inv,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ template <typename FF_> struct AvmFullRow {
const FF& get_column(ColumnAndShifts col) const
{
static_assert(sizeof(*this) == sizeof(FF) * static_cast<size_t>(ColumnAndShifts::NUM_COLUMNS));
return reinterpret_cast<FF*>(this)[static_cast<size_t>(col)];
return reinterpret_cast<const FF*>(this)[static_cast<size_t>(col)];
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ template <typename FF_> class executionImpl {
{
using Accumulator = typename std::tuple_element_t<2, ContainerOverSubrelations>;
auto tmp =
(new_term.execution_sel * ((FF(1) - new_term.execution_sel_shift) * (FF(1) - new_term.execution_last)));
((new_term.execution_sel * (FF(1) - new_term.execution_sel_shift)) * (FF(1) - new_term.execution_last));
tmp *= scaling_factor;
std::get<2>(evals) += typename Accumulator::View(tmp);
}
Expand Down
12 changes: 6 additions & 6 deletions barretenberg/cpp/src/barretenberg/vm2/simulation/addressing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,20 @@ std::vector<Operand> Addressing::resolve(const Instruction& instruction, MemoryI
// We retrieve, cache first because this is probably what we'll do in the circuit.
// However, we can't check the value and tag yet! This should be done only if it's used.
// This is because the first few instructions might not YET have a valid stack pointer.
auto stack_pointer = memory.get(0);
event.stack_pointer_tag = stack_pointer.tag;
event.stack_pointer_val = stack_pointer.value;
auto base_address = memory.get(0);
event.base_address_tag = base_address.tag;
event.base_address_val = base_address.value;

// First process relative addressing for all the addresses.
event.after_relative = instruction.operands;
for (size_t i = 0; i < spec.num_addresses; ++i) {
if ((instruction.indirect >> i) & 1) {
if (!memory.is_valid_address(stack_pointer)) {
throw AddressingException(AddressingEventError::STACK_POINTER_INVALID_ADDRESS, i);
if (!memory.is_valid_address(base_address)) {
throw AddressingException(AddressingEventError::BASE_ADDRESS_INVALID_ADDRESS, i);
}

MemoryValue offset(event.after_relative[i]);
offset += stack_pointer.value;
offset += base_address.value;
event.after_relative[i] = Operand::ff(offset);
if (!memory.is_valid_address(offset)) {
throw AddressingException(AddressingEventError::RELATIVE_COMPUTATION_OOB, i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
namespace bb::avm2::simulation {

enum class AddressingEventError {
STACK_POINTER_INVALID_ADDRESS,
BASE_ADDRESS_INVALID_ADDRESS,
RELATIVE_COMPUTATION_OOB,
INDIRECT_INVALID_ADDRESS,
FINAL_ADDRESS_INVALID,
Expand All @@ -35,8 +35,8 @@ struct AddressingEvent {
Instruction instruction;
std::vector<Operand> after_relative;
std::vector<Operand> resolved_operands;
MemoryValue stack_pointer_val;
MemoryTag stack_pointer_tag;
MemoryValue base_address_val;
MemoryTag base_address_tag;
const InstructionSpec* spec = nullptr;
std::optional<AddressingException> error;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

namespace bb::avm2::simulation {

// Question: ideally we'd avoid exploding the whole thing here, but we could if needed to.
// TODO: Implement tracegen for this. This event might need to change. Ideally we'd
// avoid having an event for each iteration of the hashing.
// It really depends on how we want to separate the concerns between simulation and tracegen.
// And wether we want to allow events to explode vertically in tracegen.
struct BytecodeHashingEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@ ContractInstance HintedRawDataDB::get_contract_instance(const AztecAddress& addr
.contract_class_id = contract_instance_hint.contractClassId,
.initialisation_hash = contract_instance_hint.initializationHash,
.public_keys =
[](const auto& pk) {
return PublicKeys{
.nullifier_key = pk.masterNullifierPublicKey,
.incoming_viewing_key = pk.masterIncomingViewingPublicKey,
.outgoing_viewing_key = pk.masterOutgoingViewingPublicKey,
.tagging_key = pk.masterTaggingPublicKey,
};
}(contract_instance_hint.publicKeys),
PublicKeys{
.nullifier_key = contract_instance_hint.publicKeys.masterNullifierPublicKey,
.incoming_viewing_key = contract_instance_hint.publicKeys.masterIncomingViewingPublicKey,
.outgoing_viewing_key = contract_instance_hint.publicKeys.masterOutgoingViewingPublicKey,
.tagging_key = contract_instance_hint.publicKeys.masterTaggingPublicKey,
},
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ void ExecutionTraceBuilder::process(
trace.set(
row,
{ {
{ C::execution_stack_pointer_val, addr_event.stack_pointer_val },
{ C::execution_stack_pointer_tag, static_cast<size_t>(addr_event.stack_pointer_tag) },
{ C::execution_base_address_val, addr_event.base_address_val },
{ C::execution_base_address_tag, static_cast<size_t>(addr_event.base_address_tag) },
{ C::execution_sel_addressing_error, addr_event.error.has_value() ? 1 : 0 },
{ C::execution_addressing_error_idx, addr_event.error.has_value() ? addr_event.error->operand_idx : 0 },
{ C::execution_addressing_error_kind,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
**Current state**

- Both lookups and permutations are supported.
- When you lookup into a precomputed table, you need to define a fast way to find the row for a tuple. See bitwise example.
- When you lookup into a precomputed table, you need to define a fast way to find the row for a tuple (`find_dst_row`). See bitwise example.
- When you lookup into a non-precomputed (dynamic) table, you can use the class `LookupIntoDynamicTable`. There is an example.
- For permutations you need to use the `PermutationBuilder` class.
- Lookups and permutations work but you need to manually create a LookupInto class and add it to the tracehelper. You can use the autogenerated `lookup_settings` class to specify the columns, etc. See examples.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <array>
#include <bit>
#include <cstddef>
#include <stdexcept>

Expand Down Expand Up @@ -58,6 +59,7 @@ template <typename LookupSettings_> class LookupIntoDynamicTable : public BaseLo

protected:
using LookupSettings = LookupSettings_;
using ArrayTuple = std::array<FF, LookupSettings::LOOKUP_TUPLE_SIZE>;

void init(TraceContainer& trace) override
{
Expand All @@ -67,13 +69,13 @@ template <typename LookupSettings_> class LookupIntoDynamicTable : public BaseLo
(void)dst_sel_value; // Avoid GCC complaining of unused parameter when asserts are disabled.

auto dst_values = trace.get_multiple(LookupSettings::DST_COLUMNS, row);
row_idx.insert({ get_key(dst_values), row });
row_idx.insert({ dst_values, row });
});
}

uint32_t find_in_dst(const std::array<FF, LookupSettings::LOOKUP_TUPLE_SIZE>& tup) const override
uint32_t find_in_dst(const ArrayTuple& tup) const override
{
auto it = row_idx.find(get_key(tup));
auto it = row_idx.find(tup);
if (it != row_idx.end()) {
return it->second;
}
Expand All @@ -83,20 +85,21 @@ template <typename LookupSettings_> class LookupIntoDynamicTable : public BaseLo
}

private:
FF get_key(const std::array<FF, LookupSettings::LOOKUP_TUPLE_SIZE>& tup) const
// TODO: Using the whole tuple as the key is not memory efficient.
unordered_flat_map<ArrayTuple, uint32_t> row_idx;
};

} // namespace bb::avm2::tracegen

// Define a hash function for std::array so that it can be used as a key in a std::unordered_map.
template <typename T, size_t SIZE> struct std::hash<std::array<T, SIZE>> {
std::size_t operator()(const std::array<T, SIZE>& arr) const noexcept
{
FF acc = 0;
for (const auto& el : tup) {
acc = acc * beta + el;
std::size_t hash = 0;
for (const auto& elem : arr) {
hash = std::rotl(hash, 1);
hash ^= std::hash<T>{}(elem);
}
return acc + gamma;
return hash;
}

// We use an RLC for the key instead of the tuple, to save memory.
// FIXME: reconsider, what if beta is 0.
unordered_flat_map<FF, uint32_t> row_idx;
FF beta = FF::random_element();
FF gamma = FF::random_element();
};

} // namespace bb::avm2::tracegen
};

0 comments on commit 6641dae

Please sign in to comment.