Skip to content

Commit a663be3

Browse files
authored
feat: merge-train/barretenberg (#17971)
BEGIN_COMMIT_OVERRIDE fix: make vm2_sim sources mutually exclusive and conditional linking (#17969) fix(build/avm): vm2_sim as dependency chore: improved prover polynomial allocation (#17956) END_COMMIT_OVERRIDE
2 parents d84e501 + bc98bae commit a663be3

File tree

6 files changed

+85
-63
lines changed

6 files changed

+85
-63
lines changed

barretenberg/cpp/src/barretenberg/client_ivc/sumcheck_client_ivc.test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ TEST_F(SumcheckClientIVCTests, TestCircuitSizes)
9898
*/
9999
TEST_F(SumcheckClientIVCTests, Basic)
100100
{
101-
const size_t NUM_APP_CIRCUITS = 5;
101+
const size_t NUM_APP_CIRCUITS = 2;
102102
auto [proof, vk] = accumulate_and_prove_ivc(NUM_APP_CIRCUITS);
103103

104104
EXPECT_TRUE(SumcheckClientIVC::verify(proof, vk));

barretenberg/cpp/src/barretenberg/constants.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ static constexpr uint32_t MEGA_AVM_LOG_N = 21;
2929

3030
static constexpr uint32_t CONST_ECCVM_LOG_N = 16;
3131

32-
static constexpr uint32_t MAX_DATABUS_SIZE = 10000;
33-
3432
// The number of last rows in ProverPolynomials that are randomized to mask
3533
// 1) witness commitments,
3634
// 2) multilinear evaluations of witness polynomials in Sumcheck

barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ template <typename Fr> class Polynomial {
108108
{
109109
return Polynomial(/*actual size*/ virtual_size - 1, virtual_size, /*shiftable offset*/ 1);
110110
}
111+
/**
112+
* @brief Utility to create a shiftable polynomial of given size and virtual size.
113+
*/
114+
static Polynomial shiftable(size_t size, size_t virtual_size)
115+
{
116+
return Polynomial(/*actual size*/ size - 1, virtual_size, /*shiftable offset*/ 1);
117+
}
111118
// Allow polynomials to be entirely reset/dormant
112119
Polynomial() = default;
113120

barretenberg/cpp/src/barretenberg/ultra_honk/prover_instance.cpp

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -40,41 +40,35 @@ template <IsUltraOrMegaHonk Flavor> void ProverInstance_<Flavor>::allocate_wires
4040
{
4141
BB_BENCH_NAME("allocate_wires");
4242

43-
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1555):Wires can be allocated based on final active row
44-
// rather than dyadic size.
43+
// Allocate only enough memory for the active range; wires are zero outside this range
4544
for (auto& wire : polynomials.get_wires()) {
46-
wire = Polynomial::shiftable(dyadic_size());
45+
wire = Polynomial::shiftable(final_active_wire_idx + 1, dyadic_size());
4746
}
4847
}
4948

5049
template <IsUltraOrMegaHonk Flavor> void ProverInstance_<Flavor>::allocate_permutation_argument_polynomials()
5150
{
5251
BB_BENCH_NAME("allocate_permutation_argument_polynomials");
5352

54-
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1555): Sigma and id polynomials can be allocated based
55-
// on final active row rather than dyadic size.
53+
// Allocate only enough memory for the active range; permutation polynomials are zero outside this range
5654
for (auto& sigma : polynomials.get_sigmas()) {
57-
sigma = Polynomial(dyadic_size());
55+
sigma = Polynomial::shiftable(final_active_wire_idx + 1, dyadic_size());
5856
}
5957
for (auto& id : polynomials.get_ids()) {
60-
id = Polynomial(dyadic_size());
58+
id = Polynomial::shiftable(final_active_wire_idx + 1, dyadic_size());
6159
}
62-
polynomials.z_perm = Polynomial::shiftable(dyadic_size());
60+
polynomials.z_perm = Polynomial::shiftable(final_active_wire_idx + 1, dyadic_size());
6361
}
6462

6563
template <IsUltraOrMegaHonk Flavor> void ProverInstance_<Flavor>::allocate_lagrange_polynomials()
6664
{
6765
BB_BENCH_NAME("allocate_lagrange_polynomials");
6866

69-
// First and last lagrange polynomials (in the full circuit size)
7067
polynomials.lagrange_first = Polynomial(
7168
/* size=*/1, /*virtual size=*/dyadic_size(), /*start_index=*/0);
7269

73-
// Even though lagrange_last has a single non-zero element, we cannot set its size to 0 as different
74-
// instances being folded might have lagrange_last set at different indexes and folding does not work
75-
// correctly unless the polynomial is allocated in the correct range to accomodate this
7670
polynomials.lagrange_last = Polynomial(
77-
/* size=*/dyadic_size(), /*virtual size=*/dyadic_size(), /*start_index=*/0);
71+
/* size=*/1, /*virtual size=*/dyadic_size(), /*start_index=*/final_active_wire_idx);
7872
}
7973

8074
template <IsUltraOrMegaHonk Flavor> void ProverInstance_<Flavor>::allocate_selectors(const Circuit& circuit)
@@ -98,28 +92,25 @@ void ProverInstance_<Flavor>::allocate_table_lookup_polynomials(const Circuit& c
9892
BB_BENCH_NAME("allocate_table_lookup_and_lookup_read_polynomials");
9993

10094
size_t table_offset = circuit.blocks.lookup.trace_offset();
101-
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1555): Can allocate table polynomials based on genuine
102-
// lookup table sizes in all cases. Same applies to read_counts/tags, except for ZK case.
103-
const size_t max_tables_size = dyadic_size() - table_offset;
104-
BB_ASSERT_GT(dyadic_size(), max_tables_size);
95+
const size_t tables_size = circuit.get_tables_size(); // cumulative size of all lookup tables used in the circuit
96+
BB_ASSERT_GT(dyadic_size(), tables_size);
10597

10698
// Allocate the polynomials containing the actual table data
107-
if constexpr (IsUltraOrMegaHonk<Flavor>) {
108-
for (auto& poly : polynomials.get_tables()) {
109-
poly = Polynomial(max_tables_size, dyadic_size(), table_offset);
110-
}
99+
for (auto& poly : polynomials.get_tables()) {
100+
poly = Polynomial(tables_size, dyadic_size(), table_offset);
111101
}
112102

113103
// Allocate the read counts and tags polynomials
114-
polynomials.lookup_read_counts = Polynomial(max_tables_size, dyadic_size(), table_offset);
115-
polynomials.lookup_read_tags = Polynomial(max_tables_size, dyadic_size(), table_offset);
104+
polynomials.lookup_read_counts = Polynomial(tables_size, dyadic_size(), table_offset);
105+
polynomials.lookup_read_tags = Polynomial(tables_size, dyadic_size(), table_offset);
116106

107+
// Determine end index for the lookup block and the tables themselves
108+
// Note that the start of the tables is aligned with the start of the lookup block in the trace
117109
const size_t lookup_block_end =
118110
static_cast<size_t>(circuit.blocks.lookup.trace_offset()) + circuit.blocks.lookup.size();
119-
const auto tables_end = circuit.blocks.lookup.trace_offset() + max_tables_size;
111+
const auto tables_end = circuit.blocks.lookup.trace_offset() + tables_size;
120112

121113
// Allocate the lookup_inverses polynomial
122-
123114
const size_t lookup_inverses_start = table_offset;
124115
const size_t lookup_inverses_end = std::max(lookup_block_end, tables_end);
125116

@@ -146,25 +137,26 @@ void ProverInstance_<Flavor>::allocate_databus_polynomials(const Circuit& circui
146137
requires HasDataBus<Flavor>
147138
{
148139
BB_BENCH_NAME("allocate_databus_and_lookup_inverse_polynomials");
149-
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1555): Each triple of databus polynomials can be
150-
// allocated based on the size of the corresponding column (except for ZK case).
151-
const size_t poly_size = std::min(static_cast<size_t>(MAX_DATABUS_SIZE), dyadic_size());
152-
polynomials.calldata = Polynomial(poly_size, dyadic_size());
153-
polynomials.calldata_read_counts = Polynomial(poly_size, dyadic_size());
154-
polynomials.calldata_read_tags = Polynomial(poly_size, dyadic_size());
155-
polynomials.secondary_calldata = Polynomial(poly_size, dyadic_size());
156-
polynomials.secondary_calldata_read_counts = Polynomial(poly_size, dyadic_size());
157-
polynomials.secondary_calldata_read_tags = Polynomial(poly_size, dyadic_size());
158-
polynomials.return_data = Polynomial(poly_size, dyadic_size());
159-
polynomials.return_data_read_counts = Polynomial(poly_size, dyadic_size());
160-
polynomials.return_data_read_tags = Polynomial(poly_size, dyadic_size());
161140

162-
// Allocate log derivative lookup argument inverse polynomials
163-
const size_t q_busread_end = circuit.blocks.busread.trace_offset() + circuit.blocks.busread.size();
164141
const size_t calldata_size = circuit.get_calldata().size();
165142
const size_t secondary_calldata_size = circuit.get_secondary_calldata().size();
166143
const size_t return_data_size = circuit.get_return_data().size();
167144

145+
polynomials.calldata = Polynomial(calldata_size, dyadic_size());
146+
polynomials.calldata_read_counts = Polynomial(calldata_size, dyadic_size());
147+
polynomials.calldata_read_tags = Polynomial(calldata_size, dyadic_size());
148+
149+
polynomials.secondary_calldata = Polynomial(secondary_calldata_size, dyadic_size());
150+
polynomials.secondary_calldata_read_counts = Polynomial(secondary_calldata_size, dyadic_size());
151+
polynomials.secondary_calldata_read_tags = Polynomial(secondary_calldata_size, dyadic_size());
152+
153+
polynomials.return_data = Polynomial(return_data_size, dyadic_size());
154+
polynomials.return_data_read_counts = Polynomial(return_data_size, dyadic_size());
155+
polynomials.return_data_read_tags = Polynomial(return_data_size, dyadic_size());
156+
157+
// Allocate log derivative lookup argument inverse polynomials
158+
const size_t q_busread_end = circuit.blocks.busread.trace_offset() + circuit.blocks.busread.size();
159+
168160
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1555): Size of databus_id can always be set to max size
169161
// between the three databus columns. It currently uses dyadic_size because its values are later set based on its
170162
// size(). This means when we naively construct all ProverPolynomials with dyadic size (e.g. for ZK), we get a

barretenberg/cpp/src/barretenberg/ultra_honk/prover_instance.hpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ template <IsUltraOrMegaHonk Flavor_> class ProverInstance_ {
7979
using Polynomial = typename Flavor::Polynomial;
8080
using SubrelationSeparator = typename Flavor::SubrelationSeparator;
8181

82-
MetaData metadata; // circuit size and public inputs metadata
83-
size_t final_active_wire_idx{ 0 }; // idx of last non-trivial wire value in the trace
82+
MetaData metadata; // circuit size and public inputs metadata
83+
// index of the last constrained wire in the execution trace; initialize to size_t::max to indicate uninitialized
84+
size_t final_active_wire_idx{ std::numeric_limits<size_t>::max() };
8485

8586
public:
8687
using Trace = TraceToPolynomials<Flavor>;
@@ -115,7 +116,12 @@ template <IsUltraOrMegaHonk Flavor_> class ProverInstance_ {
115116
return metadata.num_public_inputs;
116117
}
117118
MetaData get_metadata() const { return metadata; }
118-
size_t get_final_active_wire_idx() const { return final_active_wire_idx; }
119+
size_t get_final_active_wire_idx() const
120+
{
121+
BB_ASSERT(final_active_wire_idx != std::numeric_limits<size_t>::max(),
122+
"final_active_wire_idx has not been initialized");
123+
return final_active_wire_idx;
124+
}
119125

120126
Flavor::PrecomputedData get_precomputed()
121127
{
@@ -133,17 +139,10 @@ template <IsUltraOrMegaHonk Flavor_> class ProverInstance_ {
133139
if (!circuit.circuit_finalized) {
134140
circuit.finalize_circuit(/* ensure_nonzero = */ true);
135141
}
136-
137-
// If using a structured trace, set fixed block sizes, check their validity, and set the dyadic circuit size
138-
if constexpr (std::same_as<Circuit, UltraCircuitBuilder>) {
139-
metadata.dyadic_size = compute_dyadic_size(circuit); // set dyadic size directly from circuit block sizes
140-
} else if (std::same_as<Circuit, MegaCircuitBuilder>) {
141-
metadata.dyadic_size = compute_dyadic_size(circuit); // set dyadic based on circuit block sizes
142-
}
143-
144-
circuit.blocks.compute_offsets(); // compute offset of each block within the trace
142+
metadata.dyadic_size = compute_dyadic_size(circuit);
145143

146144
// Find index of last non-trivial wire value in the trace
145+
circuit.blocks.compute_offsets(); // compute offset of each block within the trace
147146
for (auto& block : circuit.blocks.get()) {
148147
if (block.size() > 0) {
149148
final_active_wire_idx = block.trace_offset() + block.size() - 1;
Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,49 @@
1-
if(NOT DISABLE_AZTEC_VM)
2-
barretenberg_module(vm2 sumcheck stdlib_honk_verifier stdlib_goblin_verifier world_state)
3-
endif()
4-
5-
# Include only simulation-related sources from vm2
1+
# Collect simulation-related sources (for vm2_sim module)
62
file(GLOB_RECURSE VM2_SIM_SOURCE_FILES
73
simulation/*.cpp
84
common/*.cpp
95
tooling/*.cpp
106
)
117

8+
# Add top-level sim-related files
9+
list(APPEND VM2_SIM_SOURCE_FILES
10+
${CMAKE_CURRENT_SOURCE_DIR}/simulation_helper.cpp
11+
${CMAKE_CURRENT_SOURCE_DIR}/avm_sim_api.cpp
12+
)
13+
1214
# Exclude test, bench, and fuzzer files
1315
list(FILTER VM2_SIM_SOURCE_FILES EXCLUDE REGEX ".*\\.(test|bench|fuzzer)\\.cpp$")
1416

15-
# TODO: this isn't a proper module. We should look into creating something we actually link.
16-
# This can be done by using barretenberg_module_with_sources above, linking this, but with the these files explicitly excluded.
17+
# Build vm2_sim module (for nodejs bindings)
1718
barretenberg_module_with_sources(
1819
vm2_sim
1920
SOURCE_FILES ${VM2_SIM_SOURCE_FILES}
20-
simulation_helper.cpp
21-
avm_sim_api.cpp
2221
DEPENDENCIES world_state
2322
)
23+
24+
# Build vm2 module with sources mutually exclusive from vm2_sim
25+
if(NOT DISABLE_AZTEC_VM)
26+
# Collect all source files
27+
file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp)
28+
file(GLOB_RECURSE TEST_SOURCE_FILES *.test.cpp)
29+
file(GLOB_RECURSE BENCH_SOURCE_FILES *.bench.cpp)
30+
file(GLOB_RECURSE FUZZERS_SOURCE_FILES *.fuzzer.cpp)
31+
32+
# Start with all sources, then exclude test/bench/fuzzer files
33+
set(VM2_SOURCE_FILES ${ALL_SOURCE_FILES})
34+
list(FILTER VM2_SOURCE_FILES EXCLUDE REGEX ".*\\.(test|bench|fuzzer)\\.cpp$")
35+
36+
# Make vm2 and vm2_sim sources mutually exclusive
37+
foreach(SIM_FILE ${VM2_SIM_SOURCE_FILES})
38+
list(REMOVE_ITEM VM2_SOURCE_FILES ${SIM_FILE})
39+
endforeach()
40+
41+
barretenberg_module_with_sources(
42+
vm2
43+
SOURCE_FILES ${VM2_SOURCE_FILES}
44+
TEST_SOURCE_FILES ${TEST_SOURCE_FILES}
45+
BENCH_SOURCE_FILES ${BENCH_SOURCE_FILES}
46+
FUZZERS_SOURCE_FILES ${FUZZERS_SOURCE_FILES}
47+
DEPENDENCIES sumcheck stdlib_honk_verifier stdlib_goblin_verifier world_state vm2_sim
48+
)
49+
endif()

0 commit comments

Comments
 (0)