56 auto selectors = polynomials.get_selectors();
60 auto blocks_array =
builder.blocks.get();
61 const size_t num_blocks = blocks_array.
size();
67 const size_t num_cycles =
builder.get_num_variables();
68 std::vector<uint32_t> cycle_counts(
builder.real_variable_index.size(), 0);
69 for (
auto& block : blocks_array) {
70 const uint32_t block_size =
static_cast<uint32_t
>(block.size());
71 for (uint32_t block_row_idx = 0; block_row_idx < block_size; ++block_row_idx) {
72 for (uint32_t wire_idx = 0; wire_idx < NUM_WIRES; ++wire_idx) {
73 uint32_t var_idx = block.wires[wire_idx][block_row_idx];
77 ++cycle_counts.at(
builder.real_variable_index.at(var_idx));
83 copy_cycles.
offsets.resize(num_cycles + 1);
85 for (
size_t i = 0; i < num_cycles; ++i) {
86 copy_cycles.
offsets[i] = running;
87 running += cycle_counts[i];
89 copy_cycles.
offsets[num_cycles] = running;
90 copy_cycles.
nodes.resize(running);
98 auto& block = blocks_array[block_idx];
99 const uint32_t
offset = block.trace_offset();
100 const uint32_t block_size =
static_cast<uint32_t
>(block.size());
101 auto& local_nodes = per_block_nodes[block_idx];
102 local_nodes.reserve(
static_cast<size_t>(block_size) * NUM_WIRES);
105 for (uint32_t block_row_idx = 0; block_row_idx < block_size; ++block_row_idx) {
106 for (uint32_t wire_idx = 0; wire_idx < NUM_WIRES; ++wire_idx) {
107 uint32_t var_idx = block.wires[wire_idx][block_row_idx];
109 uint32_t real_var_idx =
builder.real_variable_index.at(var_idx);
110 uint32_t trace_row_idx = block_row_idx +
offset;
112 wires[wire_idx].at(trace_row_idx) =
builder.get_variable(var_idx);
113 local_nodes.emplace_back(real_var_idx,
cycle_node{ wire_idx, trace_row_idx });
122 std::vector<uint32_t> cursors(copy_cycles.
offsets.begin(), copy_cycles.
offsets.end() - 1);
123 for (
const auto& block_nodes : per_block_nodes) {
124 for (
const auto& [real_var_idx, node] : block_nodes) {
125 copy_cycles.
nodes[cursors[real_var_idx]++] = node;
137 struct SelectorTask {
139 size_t target_poly_idx;
140 uint32_t trace_offset;
144 const auto& polynomials_ref = polynomials;
145 const size_t num_non_gate = polynomials_ref.get_non_gate_selectors().
size();
148 for (
auto& block : blocks_array) {
149 const uint32_t
offset = block.trace_offset();
150 const uint32_t block_size =
static_cast<uint32_t
>(block.size());
151 auto non_gate = Flavor::Generated::get_block_non_gate_selectors(block);
152 for (
size_t i = 0; i < non_gate.size(); ++i) {
153 selector_tasks.emplace_back(SelectorTask{ &non_gate[i], i,
offset, block_size });
157 auto gate_blocks = Flavor::Generated::get_gate_blocks(
builder.blocks);
158 constexpr auto& gate_kinds = Flavor::Generated::GATE_KINDS;
159 for (
size_t i = 0; i < gate_kinds.size(); ++i) {
160 auto& block = gate_blocks[i];
161 selector_tasks.emplace_back(SelectorTask{ &block.gate_selector_for(gate_kinds[i]),
163 block.trace_offset(),
164 static_cast<uint32_t
>(block.size()) });
167 parallel_for(selector_tasks.size(), [&](
size_t task_idx) {
168 const auto& task = selector_tasks[task_idx];
169 const auto& source = *task.source;
170 auto& poly = selectors[task.target_poly_idx];
174 const size_t dst_begin = std::max<size_t>(task.trace_offset, poly.start_index());
175 const size_t dst_end = std::min<size_t>(task.trace_offset + task.block_size, poly.end_index());
176 if (dst_begin < dst_end) {
177 source.copy_into(&poly.at(dst_begin), dst_begin - task.trace_offset, dst_end - dst_begin);