Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
memory_trace.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <array>
5#include <cstdint>
6
12
13// Permutations.
24
25namespace bb::avm2::tracegen {
26
36 TraceContainer& trace)
37{
40
41 // Create a vector of pointers to avoid copying the events.
43 const size_t trace_size = events.size();
44 event_ptrs.reserve(trace_size);
45
46 for (const auto& event : events) {
47 event_ptrs.push_back(&event);
48 }
49
50 std::ranges::sort(event_ptrs, [](const auto* lhs, const auto* rhs) { return lhs->operator<(*rhs); });
51
52 using C = Column;
53
54 // We rely on the following assert in computing C::memory_tag_ff_diff_inv value
55 // below. Namely: (tag - MemoryTag::FF).invert() == tag.invert().
56 static_assert(static_cast<uint8_t>(MemoryTag::FF) == 0);
57
58 // We pre-compute the inverses for the tag values.
59 // It serves to speed up trace generation of column C::memory_tag_ff_diff_inv values.
60 constexpr size_t NUM_TAGS = static_cast<size_t>(MemoryTag::MAX) + 1;
61 // Precomputed inverses from 0, 1 ... NUM_TAGS.
62 std::array<FF, NUM_TAGS> tag_inverts;
63 for (size_t i = 0; i < NUM_TAGS; i++) {
64 tag_inverts.at(i) = FF(i);
65 }
66 FF::batch_invert(tag_inverts);
67
68 // We use shift in this trace and keep the first row empty.
69 uint32_t row = 1;
70
71 for (uint32_t i = 0; i < trace_size; i++) {
72 const auto& event = *event_ptrs[i];
73 const bool is_last = i + 1 == trace_size;
74 const bool sel_tag_is_ff = event.value.get_tag() == MemoryTag::FF;
75 const uint64_t global_addr = (static_cast<uint64_t>(event.space_id) << 32) + event.addr;
76 const uint64_t timestamp =
77 (static_cast<uint64_t>(event.execution_clk) << 1) + static_cast<uint64_t>(event.mode);
78
79 uint64_t diff = 0; // keep it 0 for the last row.
80 bool last_access = true; // keep it true for the last row.
81 uint64_t global_addr_diff = 0;
82
83 if (!is_last) {
84 const auto& next_event = *event_ptrs[i + 1];
85 const uint64_t next_global_addr = (static_cast<uint64_t>(next_event.space_id) << 32) + next_event.addr;
86 const uint64_t next_timestamp =
87 (static_cast<uint64_t>(next_event.execution_clk) << 1) + static_cast<uint64_t>(next_event.mode);
88 const uint64_t two_consecutive_writes =
89 static_cast<uint64_t>(event.mode) * static_cast<uint64_t>(next_event.mode);
90 global_addr_diff = next_global_addr - global_addr;
91 last_access = global_addr != next_global_addr;
92 diff = last_access ? global_addr_diff : (next_timestamp - timestamp - two_consecutive_writes);
93
94 // Defensive: diff must fit in 48 bits for the 3x16-bit limb decomposition.
95 BB_ASSERT(diff < (1ULL << 48));
96 }
97
98 trace.set(row,
99 { {
100 { C::memory_sel, 1 },
101 { C::memory_value, event.value },
102 { C::memory_tag, static_cast<uint8_t>(event.value.get_tag()) },
103 { C::memory_space_id, event.space_id },
104 { C::memory_address, event.addr },
105 { C::memory_clk, event.execution_clk },
106 { C::memory_rw, event.mode == MemoryMode::WRITE ? 1 : 0 },
107 { C::memory_sel_rng_chk, is_last ? 0 : 1 },
108 { C::memory_last_access, last_access },
109 { C::memory_glob_addr_diff_inv, global_addr_diff }, // Will be inverted in batch later
110 { C::memory_diff, diff },
111 { C::memory_limb_0_, diff & 0xFFFF },
112 { C::memory_limb_1_, (diff >> 16) & 0xFFFF },
113 { C::memory_limb_2_, (diff >> 32) },
114 { C::memory_sel_tag_is_ff, sel_tag_is_ff ? 1 : 0 },
115 { C::memory_tag_ff_diff_inv, tag_inverts.at(static_cast<uint8_t>(event.value.get_tag())) },
116 { C::memory_sel_rng_write, (event.mode == MemoryMode::WRITE && !sel_tag_is_ff) ? 1 : 0 },
117 { C::memory_max_bits, get_tag_bits(event.value.get_tag()) },
118 } });
119 row++;
120 }
121
122 // Batch invert the columns.
123 trace.invert_columns({ { C::memory_glob_addr_diff_inv } });
124}
125
129 // Addressing.
138 // Registers.
145 // Data Copy.
148 // Get Contract Instance.
151 // Public Log.
153 // Poseidon2.
162 // Keccak.
164 // Sha256.
174 // ECADD
178 // To Radix.
180 // Others.
181 >(Column::memory_sel)
182 .add<lookup_memory_range_check_limb_0_settings, InteractionType::LookupIntoIndexedByRow>()
184 .add<lookup_memory_range_check_limb_2_settings, InteractionType::LookupIntoIndexedByRow>()
186 .add<lookup_memory_range_check_write_tagged_value_settings, InteractionType::LookupGeneric>(
187 Column::range_check_sel);
188
189} // namespace bb::avm2::tracegen
#define BB_ASSERT(expression,...)
Definition assert.hpp:70
InteractionDefinition & add(auto &&... args)
static const InteractionDefinition interactions
void process(const simulation::EventEmitterInterface< simulation::MemoryEvent >::Container &events, TraceContainer &trace)
Processes memory events into the memory subtrace.
TestTraceContainer trace
permutation_settings< perm_sha256_mem_mem_op_6_settings_ > perm_sha256_mem_mem_op_6_settings
permutation_settings< perm_registers_mem_op_4_settings_ > perm_registers_mem_op_4_settings
permutation_settings< perm_sha256_mem_mem_input_read_settings_ > perm_sha256_mem_mem_input_read_settings
permutation_settings< perm_poseidon2_mem_pos_write_mem_2_settings_ > perm_poseidon2_mem_pos_write_mem_2_settings
permutation_settings< perm_poseidon2_mem_pos_read_mem_1_settings_ > perm_poseidon2_mem_pos_read_mem_1_settings
permutation_settings< perm_ecc_mem_write_mem_1_settings_ > perm_ecc_mem_write_mem_1_settings
permutation_settings< perm_registers_mem_op_3_settings_ > perm_registers_mem_op_3_settings
permutation_settings< perm_registers_mem_op_1_settings_ > perm_registers_mem_op_1_settings
permutation_settings< perm_addressing_indirect_from_memory_3_settings_ > perm_addressing_indirect_from_memory_3_settings
permutation_settings< perm_addressing_indirect_from_memory_5_settings_ > perm_addressing_indirect_from_memory_5_settings
permutation_settings< perm_poseidon2_mem_pos_read_mem_3_settings_ > perm_poseidon2_mem_pos_read_mem_3_settings
lookup_settings< lookup_memory_range_check_limb_1_settings_ > lookup_memory_range_check_limb_1_settings
permutation_settings< perm_addressing_base_address_from_memory_settings_ > perm_addressing_base_address_from_memory_settings
permutation_settings< perm_sha256_mem_mem_op_2_settings_ > perm_sha256_mem_mem_op_2_settings
permutation_settings< perm_addressing_indirect_from_memory_1_settings_ > perm_addressing_indirect_from_memory_1_settings
permutation_settings< perm_poseidon2_mem_pos_write_mem_0_settings_ > perm_poseidon2_mem_pos_write_mem_0_settings
permutation_settings< perm_sha256_mem_mem_op_4_settings_ > perm_sha256_mem_mem_op_4_settings
AvmFlavorSettings::FF FF
Definition field.hpp:10
permutation_settings< perm_poseidon2_mem_pos_write_mem_1_settings_ > perm_poseidon2_mem_pos_write_mem_1_settings
permutation_settings< perm_sha256_mem_mem_op_3_settings_ > perm_sha256_mem_mem_op_3_settings
permutation_settings< perm_emit_public_log_read_mem_settings_ > perm_emit_public_log_read_mem_settings
permutation_settings< perm_addressing_indirect_from_memory_0_settings_ > perm_addressing_indirect_from_memory_0_settings
permutation_settings< perm_get_contract_instance_mem_write_contract_instance_member_settings_ > perm_get_contract_instance_mem_write_contract_instance_member_settings
permutation_settings< perm_addressing_indirect_from_memory_2_settings_ > perm_addressing_indirect_from_memory_2_settings
permutation_settings< perm_poseidon2_mem_pos_write_mem_3_settings_ > perm_poseidon2_mem_pos_write_mem_3_settings
permutation_settings< perm_ecc_mem_write_mem_0_settings_ > perm_ecc_mem_write_mem_0_settings
permutation_settings< perm_data_copy_mem_read_settings_ > perm_data_copy_mem_read_settings
permutation_settings< perm_keccak_memory_slice_to_mem_settings_ > perm_keccak_memory_slice_to_mem_settings
permutation_settings< perm_get_contract_instance_mem_write_contract_instance_exists_settings_ > perm_get_contract_instance_mem_write_contract_instance_exists_settings
uint8_t get_tag_bits(ValueTag tag)
permutation_settings< perm_sha256_mem_mem_op_0_settings_ > perm_sha256_mem_mem_op_0_settings
permutation_settings< perm_sha256_mem_mem_op_1_settings_ > perm_sha256_mem_mem_op_1_settings
permutation_settings< perm_registers_mem_op_0_settings_ > perm_registers_mem_op_0_settings
permutation_settings< perm_registers_mem_op_2_settings_ > perm_registers_mem_op_2_settings
permutation_settings< perm_sha256_mem_mem_op_7_settings_ > perm_sha256_mem_mem_op_7_settings
lookup_settings< lookup_memory_tag_max_bits_settings_ > lookup_memory_tag_max_bits_settings
permutation_settings< perm_addressing_indirect_from_memory_4_settings_ > perm_addressing_indirect_from_memory_4_settings
permutation_settings< perm_addressing_indirect_from_memory_6_settings_ > perm_addressing_indirect_from_memory_6_settings
permutation_settings< perm_registers_mem_op_5_settings_ > perm_registers_mem_op_5_settings
permutation_settings< perm_ecc_mem_write_mem_2_settings_ > perm_ecc_mem_write_mem_2_settings
permutation_settings< perm_poseidon2_mem_pos_read_mem_0_settings_ > perm_poseidon2_mem_pos_read_mem_0_settings
permutation_settings< perm_poseidon2_mem_pos_read_mem_2_settings_ > perm_poseidon2_mem_pos_read_mem_2_settings
permutation_settings< perm_data_copy_mem_write_settings_ > perm_data_copy_mem_write_settings
permutation_settings< perm_sha256_mem_mem_op_5_settings_ > perm_sha256_mem_mem_op_5_settings
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
simulation::PublicDataTreeReadWriteEvent event
static void batch_invert(C &coeffs) noexcept
Batch invert a collection of field elements using Montgomery's trick.