51 copy_cycles.resize(
builder.get_num_variables());
54 auto selectors = polynomials.get_selectors();
58 auto blocks_array =
builder.blocks.get();
59 const size_t num_blocks = blocks_array.
size();
65 std::vector<uint32_t> cycle_counts(
builder.real_variable_index.size(), 0);
66 for (
auto& block : blocks_array) {
67 const uint32_t block_size =
static_cast<uint32_t
>(block.size());
68 for (uint32_t block_row_idx = 0; block_row_idx < block_size; ++block_row_idx) {
69 for (uint32_t wire_idx = 0; wire_idx < NUM_WIRES; ++wire_idx) {
70 uint32_t var_idx = block.wires[wire_idx][block_row_idx];
74 ++cycle_counts.at(
builder.real_variable_index.at(var_idx));
78 for (
size_t i = 0; i < copy_cycles.size(); ++i) {
79 copy_cycles[i].reserve(cycle_counts[i]);
88 auto& block = blocks_array[block_idx];
89 const uint32_t
offset = block.trace_offset();
90 const uint32_t block_size =
static_cast<uint32_t
>(block.size());
91 auto& local_nodes = per_block_nodes[block_idx];
92 local_nodes.reserve(
static_cast<size_t>(block_size) * NUM_WIRES);
95 for (uint32_t block_row_idx = 0; block_row_idx < block_size; ++block_row_idx) {
96 for (uint32_t wire_idx = 0; wire_idx < NUM_WIRES; ++wire_idx) {
97 uint32_t var_idx = block.wires[wire_idx][block_row_idx];
99 uint32_t real_var_idx =
builder.real_variable_index.at(var_idx);
100 uint32_t trace_row_idx = block_row_idx +
offset;
102 wires[wire_idx].at(trace_row_idx) =
builder.get_variable(var_idx);
103 local_nodes.emplace_back(real_var_idx,
cycle_node{ wire_idx, trace_row_idx });
112 for (
const auto& block_nodes : per_block_nodes) {
113 for (
const auto& [real_var_idx, node] : block_nodes) {
114 copy_cycles[real_var_idx].emplace_back(node);
124 struct SelectorTask {
126 size_t target_poly_idx;
127 uint32_t trace_offset;
131 const size_t num_non_gate_poly = polynomials.get_non_gate_selectors().
size();
132 size_t gate_poly_idx = num_non_gate_poly;
133 for (
auto& block : blocks_array) {
134 const uint32_t off = block.trace_offset();
135 const uint32_t bsz =
static_cast<uint32_t
>(block.size());
136 for (
size_t i = 0; i < num_non_gate_poly; ++i) {
137 selector_tasks.emplace_back(SelectorTask{ &block.non_gate_selectors[i], i, off, bsz });
139 for (
auto& [kind, sel] : block.gate_selectors) {
140 selector_tasks.emplace_back(SelectorTask{ &sel, gate_poly_idx, off, bsz });
144 parallel_for(selector_tasks.size(), [&](
size_t task_idx) {
145 const auto& task = selector_tasks[task_idx];
146 const auto& source = *task.source;
147 for (uint32_t row_idx = 0; row_idx < task.block_size; ++row_idx) {
148 selectors[task.target_poly_idx].set_if_valid_index(row_idx + task.trace_offset, source[row_idx]);
160 auto& ecc_op_selector = polynomials.lagrange_ecc_op;
165 const auto& ecc_op_block =
builder.blocks.ecc_op;
166 const size_t wire_start = ecc_op_block.trace_offset();
167 BB_ASSERT_GTE(wire_start, NUM_ZERO_ROWS,
"ecc_op block must start beyond the zero row");
168 const size_t op_wire_start = wire_start - NUM_ZERO_ROWS;
169 for (
auto [ecc_op_wire, wire] :
zip_view(polynomials.get_ecc_op_wires(), polynomials.get_wires())) {
170 for (
size_t i = 0; i < ecc_op_block.size(); ++i) {
171 ecc_op_wire.at(op_wire_start + i) = wire[wire_start + i];
172 ecc_op_selector.at(op_wire_start + i) = 1;
static void populate(Builder &builder, ProverPolynomials &)
Given a circuit, populate a proving key with wire polys, selector polys, and sigma/id polys.