Skip to content
This repository was archived by the owner on Feb 17, 2025. It is now read-only.

Commit 0587463

Browse files
committed
Done with lookups inlining #24
1 parent 325bdde commit 0587463

File tree

3 files changed

+90
-40
lines changed

3 files changed

+90
-40
lines changed

include/nil/blueprint/transpiler/evm_verifier_gen.hpp

+69-34
Original file line numberDiff line numberDiff line change
@@ -239,14 +239,14 @@ namespace nil {
239239

240240
void print_lookups_library_file(std::size_t library_id,
241241
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) {
243243

244244
std::string library_lookups;
245245

246246
for(auto const& i: lookups_list) {
247247
std::string lookup_evaluation = lookup_evaluation_template;
248248
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));
250250
library_lookups += lookup_evaluation;
251251
}
252252

@@ -255,6 +255,7 @@ namespace nil {
255255
boost::replace_all(result, "$LOOKUP_LIB_ID$", to_string(library_id));
256256
boost::replace_all(result, "$LOOKUP_COMPUTATION_CODE$", library_lookups);
257257
boost::replace_all(result, "$MODULUS$", to_string(PlaceholderParams::field_type::modulus));
258+
boost::replace_all(result, "$STATE$", "");
258259

259260
std::ofstream out;
260261
out.open(_folder_name + "/lookup_" + to_string(library_id) + ".sol");
@@ -281,18 +282,17 @@ namespace nil {
281282
std::stringstream out;
282283

283284
variable_type sel_var(gate.tag_index, 0, true, variable_type::column_type::selector);
284-
out << "\t\tselector_value=basic_marshalling.get_uint256_be(blob, " << _var_indices.at(sel_var) * 0x20 << ");" << std::endl;
285-
out << "\t\tg = 1;" << std::endl;
285+
out << "\t\t$STATE$selector_value=basic_marshalling.get_uint256_be(blob, " << _var_indices.at(sel_var) * 0x20 << ");" << std::endl;
286286
for( const auto &constraint: gate.constraints ){
287287
variable_type sel_var(gate.tag_index, 0, true, variable_type::column_type::selector);
288-
out << "\t\tl = mulmod( " << constraint.table_id << ",selector_value, modulus);" << std::endl;
289-
out << "\t\ttheta_acc=theta;" << std::endl;
288+
out << "\t\tl = mulmod( " << constraint.table_id << ",$STATE$selector_value, modulus);" << std::endl;
289+
out << "\t\t$STATE$theta_acc=$STATE$theta;" << std::endl;
290290
for( const auto &expression:constraint.lookup_input ){
291291
out << constraint_computation_code(_var_indices, expression) << std::endl << std::endl;
292-
out << "\t\tl = addmod( l, mulmod( mulmod(theta_acc, selector_value, modulus), sum, modulus), modulus);" << std::endl;
293-
out << "\t\ttheta_acc = mulmod(theta_acc, theta, modulus);" << std::endl;
292+
out << "\t\tl = 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;
294294
}
295-
out << "\t\tg = 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;
296296
}
297297

298298
return out.str();
@@ -381,6 +381,7 @@ namespace nil {
381381
if (gate->second + inlined_gate_codes_size < _gates_contract_size_threshold) {
382382
inlined_gate_codes.insert(gate->first);
383383
inlined_gate_codes_size += gate->second;
384+
std::cout << "gate " << gate->first << " is inlined, cost: " << gate->second << std::endl;
384385
}
385386
}
386387

@@ -401,7 +402,6 @@ namespace nil {
401402
print_gates_library_file(lib.first, lib.second, gate_codes);
402403
}
403404

404-
405405
if (inlined_gate_codes.size() > 0) {
406406
gate_argument_str << "\t\tuint256 sum;" << std::endl;
407407
gate_argument_str << "\t\tuint256 prod;" << std::endl;
@@ -448,7 +448,7 @@ namespace nil {
448448
std::size_t j = 0;
449449
std::size_t i = 0;
450450
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;
452452
std::vector<std::size_t> lookup_ids(lookup_count);
453453
std::vector<std::pair<std::size_t, std::size_t>> lookup_costs(lookup_count);
454454
std::vector<std::size_t> lookup_lib(lookup_count);
@@ -461,6 +461,29 @@ namespace nil {
461461
++i;
462462
}
463463

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+
464487
auto library_lookup_buckets = split_items_into_buckets(lookup_costs, _lookups_library_size_threshold);
465488

466489
_lookup_includes = "";
@@ -472,55 +495,67 @@ namespace nil {
472495
print_lookups_library_file(lib.first, lib.second, lookup_codes);
473496
}
474497

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\tuint256 sum;" << std::endl;
500+
lookup_str << "\t\t\tuint256 prod;" << std::endl;
484501
}
485502

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();
491529
}
492-
out << "\"" << "lookup_" << _test_name << "_" << library_lookup_buckets.size()-1 << "\"" << std::endl;
493-
out << "]" << std::endl;
494-
out.close();
495530

496531
j = 0;
497532
std::size_t table_index = 1;
498533
for(const auto &table: _constraint_system.lookup_tables()){
499534
variable_type sel_var(table.tag_index, 0, true, variable_type::column_type::selector);
500535
variable_type shifted_sel_var(table.tag_index, 1, true, variable_type::column_type::selector);
501-
lookup_str << "\t\tstate.selector_value=basic_marshalling.get_uint256_be(blob, " << _var_indices.at(sel_var) * 0x20 << ");" << std::endl;
502-
lookup_str << "\t\tstate.shifted_selector_value=basic_marshalling.get_uint256_be(blob, " << _var_indices.at(shifted_sel_var) * 0x20 << ");" << std::endl;
536+
lookup_str << "\t\t\tstate.selector_value = basic_marshalling.get_uint256_be(blob, " << _var_indices.at(sel_var) * 0x20 << ");" << std::endl;
537+
lookup_str << "\t\t\tstate.shifted_selector_value = basic_marshalling.get_uint256_be(blob, " << _var_indices.at(shifted_sel_var) * 0x20 << ");" << std::endl;
503538

504539
for( const auto &option: table.lookup_options ){
505540
lookup_str <<
506-
"\t\t\tl= mulmod( " << table_index << ", state.selector_value, modulus);" << std::endl;
541+
"\t\t\tl = mulmod( " << table_index << ", state.selector_value, modulus);" << std::endl;
507542
lookup_str <<
508543
"\t\t\tstate.l_shifted = mulmod( " << table_index << ", state.shifted_selector_value, modulus);" << std::endl;
509544
lookup_str << "\t\t\tstate.theta_acc=state.theta;" << std::endl;
510545
for( const auto &var: option ){
511546
lookup_str <<
512-
"\t\t\tl= 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\tl = 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;
513548
variable_type shifted_var = var;
514549
shifted_var.rotation = 1;
515550
lookup_str <<
516551
"\t\t\tstate.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;
517552
lookup_str << "\t\t\tstate.theta_acc = mulmod(state.theta_acc, state.theta, modulus);" << std::endl;
518553
}
519554
lookup_str <<
520-
"\t\t\tl= mulmod( l, state.mask, modulus);" << std::endl;
555+
"\t\t\tl = mulmod( l, state.mask, modulus);" << std::endl;
521556
lookup_str <<
522557
"\t\t\tstate.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\tstate.g = mulmod(state.g, addmod( state.factor, addmod(l, mulmod(state.beta, state.l_shifted, modulus), modulus), modulus), modulus);" << std::endl;
524559
j++;
525560
}
526561
table_index++;

include/nil/blueprint/transpiler/templates/external_lookup.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ namespace nil {
1818
uint256 sum;
1919
uint256 prod;
2020
21+
g = 1;
22+
2123
$LOOKUP_ASSEMBLY_CODE$
24+
2225
return( g, theta_acc );
2326
}
2427
)";

test/transpiler.cpp

+18-6
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,9 @@ BOOST_FIXTURE_TEST_CASE(transpiler_test, test_initializer) {
241241
columns_with_copy_constraints.size(),
242242
"circuit1",
243243
26, /* gates library size threshold */
244-
60 /* lookups library size threshold */
244+
60, /* lookups library size threshold */
245+
13, /* gates inline size threshold */
246+
15 /* lookups inline size threshold */
245247
);
246248
printer.print();
247249
}
@@ -328,7 +330,9 @@ BOOST_FIXTURE_TEST_CASE(transpiler_test, test_initializer) {
328330
columns_with_copy_constraints.size(),
329331
"circuit2",
330332
26, /* gates library size threshold */
331-
60 /* lookups library size threshold */
333+
60, /* lookups library size threshold */
334+
13, /* gates inline size threshold */
335+
15 /* lookups inline size threshold */
332336
);
333337
printer.print();
334338
}
@@ -405,7 +409,9 @@ BOOST_FIXTURE_TEST_CASE(transpiler_test, test_initializer) {
405409
columns_with_copy_constraints.size(),
406410
"circuit3",
407411
26, /* gates library size threshold */
408-
60 /* lookups library size threshold */
412+
60, /* lookups library size threshold */
413+
13, /* gates inline size threshold */
414+
15 /* lookups inline size threshold */
409415
);
410416
printer.print();
411417
}
@@ -480,7 +486,9 @@ BOOST_FIXTURE_TEST_CASE(transpiler_test, test_initializer) {
480486
columns_with_copy_constraints.size(),
481487
"circuit4",
482488
26, /* gates library size threshold */
483-
60 /* lookups library size threshold */
489+
60, /* lookups library size threshold */
490+
13, /* gates inline size threshold */
491+
15 /* lookups inline size threshold */
484492
);
485493
printer.print();
486494
}
@@ -557,7 +565,9 @@ BOOST_FIXTURE_TEST_CASE(transpiler_test, test_initializer) {
557565
columns_with_copy_constraints.size(),
558566
"circuit6",
559567
26, /* gates library size threshold */
560-
60 /* lookups library size threshold */
568+
60, /* lookups library size threshold */
569+
13, /* gates inline size threshold */
570+
15 /* lookups inline size threshold */
561571
);
562572
printer.print();
563573
}
@@ -634,7 +644,9 @@ BOOST_FIXTURE_TEST_CASE(transpiler_test, test_initializer) {
634644
columns_with_copy_constraints.size(),
635645
"circuit7",
636646
26, /* gates library size threshold */
637-
60 /* lookups library size threshold */
647+
60, /* lookups library size threshold */
648+
13, /* gates inline size threshold */
649+
15 /* lookups inline size threshold */
638650
);
639651
printer.print();
640652
}

0 commit comments

Comments
 (0)