@@ -239,14 +239,14 @@ namespace nil {
239
239
240
240
void print_lookups_library_file (std::size_t library_id,
241
241
std::vector<std::size_t > const & lookups_list,
242
- std::vector< std::string> const & lookup_codes) {
242
+ std::unordered_map<std:: size_t , std::string> const & lookup_codes) {
243
243
244
244
std::string library_lookups;
245
245
246
246
for (auto const & i: lookups_list) {
247
247
std::string lookup_evaluation = lookup_evaluation_template;
248
248
boost::replace_all (lookup_evaluation, " $LOOKUP_ID$" , to_string (i) );
249
- boost::replace_all (lookup_evaluation, " $LOOKUP_ASSEMBLY_CODE$" , lookup_codes[i] );
249
+ boost::replace_all (lookup_evaluation, " $LOOKUP_ASSEMBLY_CODE$" , lookup_codes. at (i) );
250
250
library_lookups += lookup_evaluation;
251
251
}
252
252
@@ -255,6 +255,7 @@ namespace nil {
255
255
boost::replace_all (result, " $LOOKUP_LIB_ID$" , to_string (library_id));
256
256
boost::replace_all (result, " $LOOKUP_COMPUTATION_CODE$" , library_lookups);
257
257
boost::replace_all (result, " $MODULUS$" , to_string (PlaceholderParams::field_type::modulus));
258
+ boost::replace_all (result, " $STATE$" , " " );
258
259
259
260
std::ofstream out;
260
261
out.open (_folder_name + " /lookup_" + to_string (library_id) + " .sol" );
@@ -281,18 +282,17 @@ namespace nil {
281
282
std::stringstream out;
282
283
283
284
variable_type sel_var (gate.tag_index , 0 , true , variable_type::column_type::selector);
284
- out << " \t\t selector_value=basic_marshalling.get_uint256_be(blob, " << _var_indices.at (sel_var) * 0x20 << " );" << std::endl;
285
- out << " \t\t g = 1;" << std::endl;
285
+ out << " \t\t $STATE$selector_value=basic_marshalling.get_uint256_be(blob, " << _var_indices.at (sel_var) * 0x20 << " );" << std::endl;
286
286
for ( const auto &constraint: gate.constraints ){
287
287
variable_type sel_var (gate.tag_index , 0 , true , variable_type::column_type::selector);
288
- out << " \t\t l = mulmod( " << constraint.table_id << " ,selector_value, modulus);" << std::endl;
289
- out << " \t\t theta_acc= theta;" << std::endl;
288
+ out << " \t\t l = mulmod( " << constraint.table_id << " ,$STATE$ selector_value, modulus);" << std::endl;
289
+ out << " \t\t $STATE$theta_acc=$STATE$ theta;" << std::endl;
290
290
for ( const auto &expression:constraint.lookup_input ){
291
291
out << constraint_computation_code (_var_indices, expression) << std::endl << std::endl;
292
- out << " \t\t l = addmod( l, mulmod( mulmod(theta_acc, selector_value, modulus), sum, modulus), modulus);" << std::endl;
293
- out << " \t\t theta_acc = mulmod(theta_acc, theta, modulus);" << std::endl;
292
+ out << " \t\t l = addmod( l, mulmod( mulmod($STATE$ theta_acc, $STATE$ selector_value, modulus), sum, modulus), modulus);" << std::endl;
293
+ out << " \t\t $STATE$theta_acc = mulmod($STATE$ theta_acc, $STATE$ theta, modulus);" << std::endl;
294
294
}
295
- out << " \t\t g = mulmod(g, mulmod(addmod(1, beta, modulus), addmod(l,gamma, modulus), modulus), modulus);" << std::endl;
295
+ out << " \t\t $STATE$g = mulmod($STATE$ g, mulmod(addmod(1, $STATE$ beta, modulus), addmod(l, $STATE$ gamma, modulus), modulus), modulus);" << std::endl;
296
296
}
297
297
298
298
return out.str ();
@@ -381,6 +381,7 @@ namespace nil {
381
381
if (gate->second + inlined_gate_codes_size < _gates_contract_size_threshold) {
382
382
inlined_gate_codes.insert (gate->first );
383
383
inlined_gate_codes_size += gate->second ;
384
+ std::cout << " gate " << gate->first << " is inlined, cost: " << gate->second << std::endl;
384
385
}
385
386
}
386
387
@@ -401,7 +402,6 @@ namespace nil {
401
402
print_gates_library_file (lib.first , lib.second , gate_codes);
402
403
}
403
404
404
-
405
405
if (inlined_gate_codes.size () > 0 ) {
406
406
gate_argument_str << " \t\t uint256 sum;" << std::endl;
407
407
gate_argument_str << " \t\t uint256 prod;" << std::endl;
@@ -448,7 +448,7 @@ namespace nil {
448
448
std::size_t j = 0 ;
449
449
std::size_t i = 0 ;
450
450
std::size_t cur = 0 ;
451
- std::vector <std::string> lookup_codes (lookup_count) ;
451
+ std::unordered_map <std::size_t , std:: string> lookup_codes;
452
452
std::vector<std::size_t > lookup_ids (lookup_count);
453
453
std::vector<std::pair<std::size_t , std::size_t >> lookup_costs (lookup_count);
454
454
std::vector<std::size_t > lookup_lib (lookup_count);
@@ -461,6 +461,29 @@ namespace nil {
461
461
++i;
462
462
}
463
463
464
+ std::sort (lookup_costs.begin (), lookup_costs.end (),
465
+ [](const std::pair<std::size_t , std::size_t > &a,
466
+ const std::pair<std::size_t , std::size_t > &b) {
467
+ return a.second > b.second ;
468
+ });
469
+
470
+ /* Fill contract inline lookup computation, inline small first */
471
+ std::unordered_set<std::size_t > inlined_lookup_codes;
472
+ std::size_t inlined_lookup_codes_size = 0 ;
473
+ for (auto lookup = lookup_costs.rbegin (); lookup != lookup_costs.rend (); ++lookup) {
474
+ if (lookup->second + inlined_lookup_codes_size < _lookups_contract_size_threshold) {
475
+ inlined_lookup_codes.insert (lookup->first );
476
+ inlined_lookup_codes_size += lookup->second ;
477
+ std::cout << " lookup " << lookup->first << " is inlined, cost: " << lookup->second << std::endl;
478
+ }
479
+ }
480
+
481
+ auto inlined_lookups_end = std::remove_if (lookup_costs.begin (), lookup_costs.end (),
482
+ [&inlined_lookup_codes](const std::pair<std::size_t , std::size_t >& cost) {
483
+ return inlined_lookup_codes.count (cost.first ) == 1 ;
484
+ });
485
+ lookup_costs.erase (inlined_lookups_end, lookup_costs.end ());
486
+
464
487
auto library_lookup_buckets = split_items_into_buckets (lookup_costs, _lookups_library_size_threshold);
465
488
466
489
_lookup_includes = " " ;
@@ -472,55 +495,67 @@ namespace nil {
472
495
print_lookups_library_file (lib.first , lib.second , lookup_codes);
473
496
}
474
497
475
- i = 0 ;
476
- for (const auto &lookup_gate: _constraint_system.lookup_gates ()){
477
- std::string lookup_eval_string = lookup_call_template;
478
- boost::replace_all (lookup_eval_string, " $TEST_NAME$" , _test_name);
479
- boost::replace_all (lookup_eval_string, " $LOOKUP_LIB_ID$" , to_string (lookup_lib[i]));
480
- boost::replace_all (lookup_eval_string, " $LOOKUP_ID$" , to_string (i));
481
- boost::replace_all (lookup_eval_string, " $MODULUS$" , to_string (PlaceholderParams::field_type::modulus));
482
- lookup_str << lookup_eval_string;
483
- ++i;
498
+ if (inlined_lookup_codes.size () > 0 ) {
499
+ lookup_str << " \t\t\t uint256 sum;" << std::endl;
500
+ lookup_str << " \t\t\t uint256 prod;" << std::endl;
484
501
}
485
502
486
- std::ofstream out;
487
- out.open (_folder_name + " /lookup_libs_list.json" );
488
- out << " [" << std::endl;
489
- for (i = 0 ; i < library_lookup_buckets.size ()-1 ; ++i ) {
490
- out << " \" " << " lookup_" << _test_name << " _" << i << " \" ," << std::endl;
503
+ for (i = 0 ; i < _constraint_system.lookup_gates ().size (); ++i) {
504
+ if (inlined_lookup_codes.count (i) == 1 ) {
505
+ boost::replace_all (lookup_codes[i], " $STATE$" , " state." );
506
+ lookup_str << " /* -- lookup " << i << " is inlined -- */" << std::endl;
507
+ lookup_str << lookup_codes[i] << std::endl;
508
+ lookup_str << " /* -- /lookup " << i << " is inlined -- */" << std::endl;
509
+ } else {
510
+ std::string lookup_eval_string = lookup_call_template;
511
+ boost::replace_all (lookup_eval_string, " $TEST_NAME$" , _test_name);
512
+ boost::replace_all (lookup_eval_string, " $LOOKUP_LIB_ID$" , to_string (lookup_lib[i]));
513
+ boost::replace_all (lookup_eval_string, " $LOOKUP_ID$" , to_string (i));
514
+ boost::replace_all (lookup_eval_string, " $MODULUS$" , to_string (PlaceholderParams::field_type::modulus));
515
+ lookup_str << lookup_eval_string;
516
+ }
517
+ }
518
+
519
+ if (library_lookup_buckets.size () > 0 ) {
520
+ std::ofstream out;
521
+ out.open (_folder_name + " /lookup_libs_list.json" );
522
+ out << " [" << std::endl;
523
+ for (i = 0 ; i < library_lookup_buckets.size ()-1 ; ++i ) {
524
+ out << " \" " << " lookup_" << _test_name << " _" << i << " \" ," << std::endl;
525
+ }
526
+ out << " \" " << " lookup_" << _test_name << " _" << library_lookup_buckets.size ()-1 << " \" " << std::endl;
527
+ out << " ]" << std::endl;
528
+ out.close ();
491
529
}
492
- out << " \" " << " lookup_" << _test_name << " _" << library_lookup_buckets.size ()-1 << " \" " << std::endl;
493
- out << " ]" << std::endl;
494
- out.close ();
495
530
496
531
j = 0 ;
497
532
std::size_t table_index = 1 ;
498
533
for (const auto &table: _constraint_system.lookup_tables ()){
499
534
variable_type sel_var (table.tag_index , 0 , true , variable_type::column_type::selector);
500
535
variable_type shifted_sel_var (table.tag_index , 1 , true , variable_type::column_type::selector);
501
- lookup_str << " \t\t state.selector_value= basic_marshalling.get_uint256_be(blob, " << _var_indices.at (sel_var) * 0x20 << " );" << std::endl;
502
- lookup_str << " \t\t state.shifted_selector_value= basic_marshalling.get_uint256_be(blob, " << _var_indices.at (shifted_sel_var) * 0x20 << " );" << std::endl;
536
+ lookup_str << " \t\t\ t state.selector_value = basic_marshalling.get_uint256_be(blob, " << _var_indices.at (sel_var) * 0x20 << " );" << std::endl;
537
+ lookup_str << " \t\t\ t state.shifted_selector_value = basic_marshalling.get_uint256_be(blob, " << _var_indices.at (shifted_sel_var) * 0x20 << " );" << std::endl;
503
538
504
539
for ( const auto &option: table.lookup_options ){
505
540
lookup_str <<
506
- " \t\t\t l= mulmod( " << table_index << " , state.selector_value, modulus);" << std::endl;
541
+ " \t\t\t l = mulmod( " << table_index << " , state.selector_value, modulus);" << std::endl;
507
542
lookup_str <<
508
543
" \t\t\t state.l_shifted = mulmod( " << table_index << " , state.shifted_selector_value, modulus);" << std::endl;
509
544
lookup_str << " \t\t\t state.theta_acc=state.theta;" << std::endl;
510
545
for ( const auto &var: option ){
511
546
lookup_str <<
512
- " \t\t\t l= addmod( l, mulmod(state.selector_value, mulmod( state.theta_acc, basic_marshalling.get_uint256_be(blob, " << _var_indices.at (var) * 0x20 << " ), modulus), modulus), modulus);" << std::endl;
547
+ " \t\t\t l = addmod( l, mulmod(state.selector_value, mulmod( state.theta_acc, basic_marshalling.get_uint256_be(blob, " << _var_indices.at (var) * 0x20 << " ), modulus), modulus), modulus);" << std::endl;
513
548
variable_type shifted_var = var;
514
549
shifted_var.rotation = 1 ;
515
550
lookup_str <<
516
551
" \t\t\t state.l_shifted = addmod( state.l_shifted, mulmod(state.shifted_selector_value, mulmod( state.theta_acc, basic_marshalling.get_uint256_be(blob, " << _var_indices.at (shifted_var) * 0x20 << " ), modulus), modulus), modulus);" << std::endl;
517
552
lookup_str << " \t\t\t state.theta_acc = mulmod(state.theta_acc, state.theta, modulus);" << std::endl;
518
553
}
519
554
lookup_str <<
520
- " \t\t\t l= mulmod( l, state.mask, modulus);" << std::endl;
555
+ " \t\t\t l = mulmod( l, state.mask, modulus);" << std::endl;
521
556
lookup_str <<
522
557
" \t\t\t state.l_shifted = mulmod( state.l_shifted, state.shifted_mask, modulus);" << std::endl;
523
- lookup_str << " \t\t\t state .g = mulmod(state.g, addmod( state.factor, addmod(l, mulmod(state.beta, state.l_shifted, modulus), modulus), modulus), modulus);" << std::endl;
558
+ lookup_str << " \t\t\t state .g = mulmod(state.g, addmod( state.factor, addmod(l, mulmod(state.beta, state.l_shifted, modulus), modulus), modulus), modulus);" << std::endl;
524
559
j++;
525
560
}
526
561
table_index++;
0 commit comments