20#ifdef CHECK_CIRCUIT_STACKTRACES
21#include <backward.hpp>
26#ifdef CHECK_CIRCUIT_STACKTRACES
27struct BbStackTrace : backward::StackTrace {
28 BbStackTrace() { load_here(32); }
32 void populate() { stack_traces.emplace_back(); }
33 void print(
size_t gate_idx)
const { backward::Printer{}.print(stack_traces.at(gate_idx)); }
35 bool operator==(
const StackTraces& other)
const
37 static_cast<void>(other);
74template <
typename FF,
size_t NUM_WIRES>
struct GateRow {
75 std::array<uint32_t, NUM_WIRES>
wires{};
95static constexpr size_t GATE_TILE_SIZE = 8;
98static constexpr size_t GATE_TILE_MASK = GATE_TILE_SIZE - 1;
100template <
typename FF,
size_t NUM_WIRES>
struct GateTile {
102 std::array<FF, GATE_TILE_SIZE>
q_m{};
103 std::array<FF, GATE_TILE_SIZE>
q_c{};
104 std::array<FF, GATE_TILE_SIZE>
q_1{};
105 std::array<FF, GATE_TILE_SIZE>
q_2{};
106 std::array<FF, GATE_TILE_SIZE>
q_3{};
107 std::array<FF, GATE_TILE_SIZE>
q_4{};
108 std::array<FF, GATE_TILE_SIZE>
q_5{};
133template <
typename FF,
size_t NUM_WIRES>
180 virtual size_t size()
const = 0;
187 virtual void copy_into(
FF* dst,
size_t start,
size_t count)
const = 0;
210 return ((*
tiles_)[i >> GATE_TILE_SHIFT].*
field_)[i & GATE_TILE_MASK];
217 void copy_into(
FF* dst,
size_t start,
size_t count)
const override
220 while (i < count && ((start + i) & GATE_TILE_MASK) != 0) {
221 dst[i] = (*this)[start + i];
224 for (; i + GATE_TILE_SIZE <= count; i += GATE_TILE_SIZE) {
225 const auto& run = (*tiles_)[(start + i) >> GATE_TILE_SHIFT].*
field_;
226 memcpy(
static_cast<void*
>(dst + i),
static_cast<const void*
>(run.data()),
sizeof(
FF) * GATE_TILE_SIZE);
228 for (; i < count; ++i) {
229 dst[i] = (*this)[start + i];
259 Tile& tile = (*tiles_)[idx >> GATE_TILE_SHIFT];
260 const size_t slot = idx & GATE_TILE_MASK;
265 "GateSelectorColumn: overwriting an active gate selector of another kind");
273 const Tile& tile = (*tiles_)[i >> GATE_TILE_SHIFT];
274 const size_t slot = i & GATE_TILE_MASK;
282 void copy_into(
FF* dst,
size_t start,
size_t count)
const override
285 while (i < count && ((start + i) & GATE_TILE_MASK) != 0) {
286 dst[i] = (*this)[start + i];
289 for (; i + GATE_TILE_SIZE <= count; i += GATE_TILE_SIZE) {
290 const Tile& tile = (*tiles_)[(start + i) >> GATE_TILE_SHIFT];
293 for (; i < count; ++i) {
294 dst[i] = (*this)[start + i];
303 static const FF zero{};
329 return (*
tiles_)[i >> GATE_TILE_SHIFT].wires[
wire_idx_][i & GATE_TILE_MASK];
377 using Wires = std::array<WireType, NUM_WIRES>;
404 if (
this == &other) {
436#ifdef CHECK_CIRCUIT_STACKTRACES
438 StackTraces stack_traces;
440#ifdef TRACY_HACK_GATES_AS_MEMORY
441 std::vector<size_t> allocated_gates;
445#ifdef TRACY_HACK_GATES_AS_MEMORY
449 allocated_gates.push_back(GLOBAL_GATE);
480#ifdef CHECK_CIRCUIT_STACKTRACES
481 this->stack_traces.populate();
485 "ExecutionTraceBlock: block does not own this gate kind.");
491 for (
const auto& sel : NON_GATE_SELECTORS<FF, NUM_WIRES>) {
492 (tile.*sel.tile_field)[
slot] = row.*sel.row_field;
502 void reserve(
size_t num_rows) {
tiles.reserve((num_rows + GATE_TILE_SIZE - 1) >> GATE_TILE_SHIFT); }
507 if (col.kind() == kind) {
519 kinds.push_back(col.kind());
531 if (col.kind() == kind) {
535 throw_or_abort(
"ExecutionTraceBlock: block does not own this gate kind");
555#ifdef TRACY_HACK_GATES_AS_MEMORY
559 for ([[maybe_unused]]
size_t gate : allocated_gates) {
560 if (!FREED_GATES.contains(gate)) {
562 FREED_GATES.insert(gate);
577 tiles.shrink_to_fit();
620 return tiles.emplace_back();
625 template <
size_t... Is>
629 &
tiles, &
num_rows_, NON_GATE_SELECTORS<FF, NUM_WIRES>[Is].tile_field }... };
645template <
typename FF,
size_t NUM_WIRES>
648 if (idx >= block.
size()) {
651 const auto& tile = block.
tiles[idx >> GATE_TILE_SHIFT];
652 const size_t slot = idx & GATE_TILE_MASK;
653 return tile.gate_selector_or_zero(
slot, kind);
#define BB_ASSERT(expression,...)
#define BB_ASSERT_DEBUG(expression,...)
bb::field< bb::Bn254FrParams > FF
Row-major storage for the gates of one execution trace block: one vector of GateRow....
std::vector< Tile > tiles
std::array< WireType, NUM_WIRES > Wires
SelectorColumn< FF, NUM_WIRES > & q_5()
static constexpr size_t NUM_WIRES
std::vector< GateKind > owned_gate_kinds() const
bool operator==(const ExecutionTraceBlock &other) const
SelectorColumn< FF, NUM_WIRES > & q_3()
SelectorColumn< FF, NUM_WIRES > & q_c()
ExecutionTraceBlock & operator=(ExecutionTraceBlock &&other) noexcept
void reserve(size_t num_rows)
Reserve capacity for num_rows gates.
SelectorColumn< FF, NUM_WIRES > & q_m()
uint32_t trace_offset() const
GateSelectorColumn< FF, NUM_WIRES > & gate_selector_for(GateKind kind)
Reference to this block's selector view for kind; aborts if the block does not own it....
void copy_gate_columns_from(const ExecutionTraceBlock &other)
ExecutionTraceBlock()=default
RefVector< Selector< FF > > get_selectors()
All selectors of this block: the non-gate selectors followed by the owned gate selectors.
void free_data()
Release gate memory. Caches block size so size() still works.
std::vector< GateSelectorColumn< FF, NUM_WIRES > > gate_columns_
ExecutionTraceBlock(ExecutionTraceBlock &&other) noexcept
~ExecutionTraceBlock()=default
std::array< SelectorColumn< FF, NUM_WIRES >, NUM_NON_GATE_SELECTORS > columns_
static constexpr size_t NUM_NON_GATE_SELECTORS
ExecutionTraceBlock(std::initializer_list< GateKind > kinds)
Construct a block that owns the listed gate kinds.
SelectorColumn< FF, NUM_WIRES > & q_2()
void append_gate(const Row &row)
Append one complete gate: wires, non-gate selectors, and the (single) active gate selector.
ExecutionTraceBlock & operator=(const ExecutionTraceBlock &other)
SelectorColumn< FF, NUM_WIRES > & q_1()
std::array< SelectorColumn< FF, NUM_WIRES >, NUM_NON_GATE_SELECTORS > make_selector_columns(std::index_sequence< Is... >)
bool owns_gate_kind(GateKind kind) const
ExecutionTraceBlock(const ExecutionTraceBlock &other)
SelectorColumn< FF, NUM_WIRES > & q_4()
Column view over the gate selector of one kind in the row-major gate storage: rows whose gate_kind ma...
std::vector< Tile > Tiles
const FF & operator[](size_t i) const override
Get value at specified index.
bool empty() const override
GateSelectorColumn(Tiles *tiles, const size_t *num_rows, GateKind kind)
void set(size_t idx, int value) override
Set the value at index using integer.
void set(size_t idx, const FF &value) override
Set the value at index using a field element.
void copy_into(FF *dst, size_t start, size_t count) const override
Bulk-copy count values of this column starting at start into dst (tile-wise, avoiding a virtual call ...
size_t size() const override
static const FF & zero_value()
const FF & back() const override
Get the last value in the selector.
A template class for a reference vector. Behaves as if std::vector<T&> was possible.
Column view over one non-gate selector field of the row-major gate storage.
bool empty() const override
const FF & operator[](size_t i) const override
Get value at specified index.
void set(size_t idx, const FF &value) override
Set the value at index using a field element.
GateTile< FF, NUM_WIRES > Tile
void copy_into(FF *dst, size_t start, size_t count) const override
Bulk-copy count values of this column starting at start into dst (tile-wise, avoiding a virtual call ...
SelectorColumn(Tiles *tiles, const size_t *num_rows, Field field)
std::array< FF, GATE_TILE_SIZE > Tile::* Field
std::vector< Tile > Tiles
const FF & back() const override
Get the last value in the selector.
void set(size_t idx, int value) override
Set the value at index using integer.
size_t size() const override
Read (and targeted-write) interface over one selector column.
virtual size_t size() const =0
virtual void copy_into(FF *dst, size_t start, size_t count) const =0
Bulk-copy count values of this column starting at start into dst (tile-wise, avoiding a virtual call ...
virtual ~Selector()=default
virtual const FF & back() const =0
Get the last value in the selector.
Selector(Selector &&)=delete
virtual void set(size_t idx, int value)=0
Set the value at index using integer.
virtual bool empty() const =0
Selector & operator=(const Selector &)=default
Selector & operator=(Selector &&)=delete
virtual void set(size_t idx, const FF &value)=0
Set the value at index using a field element.
virtual const FF & operator[](size_t index) const =0
Get value at specified index.
Selector(const Selector &)=default
bool operator!=(const const_iterator &other) const
const_iterator & operator++()
const uint32_t & operator*() const
const_iterator(const WireColumn *col, size_t i)
Mutable view over one wire column of the row-major gate storage.
const_iterator end() const
WireColumn(Tiles *tiles, const size_t *num_rows, size_t wire_idx)
const_iterator begin() const
const uint32_t & back() const
const uint32_t & operator[](size_t i) const
std::vector< Tile > Tiles
uint32_t & operator[](size_t i)
#define TRACY_GATE_ALLOC(t)
#define TRACY_GATE_FREE(t)
bool operator==(schnorr_signature const &lhs, schnorr_signature const &rhs)
Entry point for Barretenberg command-line interface.
constexpr std::array NON_GATE_SELECTORS
FF read_gate_selector(const ExecutionTraceBlock< FF, NUM_WIRES > &block, GateKind kind, size_t idx)
Gate-selector value at (block, idx) for kind, returning zero if the block does not own this kind or t...
GateKind
Tag identifying which gate selector a block owns. Used by cross-block readers to decide whether (bloc...
@ Poseidon2QuadIntTerminal
@ Poseidon2TransitionEntry
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
One gate: its wire indices, the non-gate selectors present on every block (see NON_GATE_SELECTORS),...
bool operator==(const GateRow &other) const =default
std::array< uint32_t, NUM_WIRES > wires
std::array< FF, GATE_TILE_SIZE > q_m
std::array< FF, GATE_TILE_SIZE > gate_value
std::array< FF, GATE_TILE_SIZE > q_c
FF gate_selector_or_zero(size_t slot, GateKind kind) const
std::array< GateKind, GATE_TILE_SIZE > gate_kind
std::array< FF, GATE_TILE_SIZE > q_4
bool operator==(const GateTile &other) const =default
std::array< std::array< uint32_t, GATE_TILE_SIZE >, NUM_WIRES > wires
std::array< FF, GATE_TILE_SIZE > q_1
std::array< FF, GATE_TILE_SIZE > q_3
std::array< FF, GATE_TILE_SIZE > q_2
std::array< FF, GATE_TILE_SIZE > q_5
The (GateRow field, GateTile field) pair of one non-gate selector.
void throw_or_abort(std::string const &err)