@@ -330,7 +330,18 @@ ConstraintProfile profile_constraint_type(ConstraintType representative, Handler
330330void prepare_builder_from_profiles (UltraCircuitBuilder& builder, const std::vector<ConstraintProfile>& profiles)
331331{
332332 // Register all constants from all profiles
333- for (const auto & profile : profiles) {
333+ for (size_t p = 0 ; p < profiles.size (); p++) {
334+ const auto & profile = profiles[p];
335+ info (" profile[" ,
336+ p,
337+ " ]: blk2=" ,
338+ profile.block_sizes .block_sizes [2 ],
339+ " vars=" ,
340+ profile.block_sizes .num_variables ,
341+ " constants=" ,
342+ profile.constants .size (),
343+ " range_targets=" ,
344+ profile.range_list_targets .size ());
334345 for (const auto & value : profile.constants ) {
335346 builder.put_constant_variable (value);
336347 }
@@ -388,8 +399,30 @@ void build_constraints_parallel(UltraCircuitBuilder& builder,
388399
389400 profile_and_collect (constraints.quad_constraints ,
390401 [](UltraCircuitBuilder& b, QuadConstraint& c) { create_quad_constraint (b, c); });
391- profile_and_collect (constraints.big_quad_constraints ,
392- [](UltraCircuitBuilder& b, BigQuadConstraint& c) { create_big_quad_constraint (b, c); });
402+ // BigQuad constraints must be grouped by size() since different sizes produce different gate counts.
403+ {
404+ std::map<size_t , std::vector<size_t >> big_quad_groups;
405+ for (size_t i = 0 ; i < constraints.big_quad_constraints .size (); i++) {
406+ big_quad_groups[constraints.big_quad_constraints [i].size ()].push_back (i);
407+ }
408+ auto handler = [](UltraCircuitBuilder& b, BigQuadConstraint& c) { create_big_quad_constraint (b, c); };
409+ for (auto & [sz, indices] : big_quad_groups) {
410+ auto & representative = constraints.big_quad_constraints [indices[0 ]];
411+ auto profile = profile_constraint_type (representative, handler, num_witnesses);
412+ size_t profile_idx = profiles.size ();
413+ profiles.push_back (profile);
414+ auto sizes = profile.block_sizes ;
415+ sizes.num_rom_arrays = profile.num_rom_arrays_per_instance ;
416+ sizes.num_ram_arrays = profile.num_ram_arrays_per_instance ;
417+ for (size_t idx : indices) {
418+ tasks.emplace_back ([handler, &constraints, idx](UltraCircuitBuilder& b) {
419+ handler (b, constraints.big_quad_constraints [idx]);
420+ });
421+ task_sizes.push_back (sizes);
422+ task_profile_indices.push_back (profile_idx);
423+ }
424+ }
425+ }
393426 profile_and_collect (constraints.logic_constraints , [](UltraCircuitBuilder& b, const LogicConstraint& c) {
394427 create_logic_gate (b, c.a , c.b , c.result , c.num_bits , c.is_xor_gate );
395428 });
0 commit comments