Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce prover memory usage. #262

Merged
merged 2 commits into from
Dec 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 65 additions & 29 deletions include/nil/crypto3/zk/commitments/detail/polynomial/basic_fri.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ namespace nil {
FRI>::value,
bool>::type = true>
static typename FRI::proof_type proof_eval(
std::map<std::size_t, std::vector<PolynomialType>> &g,
const std::map<std::size_t, std::vector<PolynomialType>> &g,
const PolynomialType combined_Q,
const std::map<std::size_t, typename FRI::precommitment_type> &precommitments,
const typename FRI::precommitment_type &combined_Q_precommitment,
Expand All @@ -609,18 +609,21 @@ namespace nil {
// TODO: add necessary checks
//BOOST_ASSERT(check_initial_precommitment<FRI>(precommitments, fri_params));

// Think about resizing polynomials. Problems with const.
if constexpr (std::is_same<math::polynomial_dfs<typename FRI::field_type::value_type>, PolynomialType>::value) {
for( auto const &it:g ){
auto k = it.first;
for (int i = 0; i < g[k].size(); ++i ){
// If LPC works properly this if is never executed.
if (g[k][i].size() != fri_params.D[0]->size()) {
g[k][i].resize(fri_params.D[0]->size());
}
}
}
}
// This resizes actually happens when called at the end of prover:
// _proof.eval_proof.eval_proof = _commitment_scheme.proof_eval(transcript);
// We DO NOT resize it here, it takes waaay too much RAM, resize it when needed.

//if constexpr (std::is_same<math::polynomial_dfs<typename FRI::field_type::value_type>, PolynomialType>::value) {
// for( auto const &it:g ){
// auto k = it.first;
// for (int i = 0; i < g[k].size(); ++i ){
// // If LPC works properly this if is never executed.
// if (g[k][i].size() != fri_params.D[0]->size()) {
// g[k][i].resize(fri_params.D[0]->size());
// }
// }
// }
//}

// Commit phase
auto f = combined_Q;
Expand Down Expand Up @@ -667,6 +670,26 @@ namespace nil {

// Query phase
std::array<typename FRI::query_proof_type, FRI::lambda> query_proofs;

// If we have DFS polynomials, and we are going to resize them, better convert them to coefficients form,
// and compute their values in those 2 * FRI::lambda points each, which is normally 2 * 20.
// In case lambda becomes much larger than log(2, average polynomial size), then this will not be optimal.
// For lambda = 20 and 2^20 rows in assignment table, it's faster and uses less RAM.
std::map<std::size_t, std::vector<math::polynomial<typename FRI::field_type::value_type>>> g_coeffs;
if constexpr (std::is_same<
math::polynomial_dfs<typename FRI::field_type::value_type>,
PolynomialType>::value
) {
for (const auto &[key, poly_vector]: g) {
for (const auto& poly: poly_vector) {
// All the polynomials have the same size, so we have no bugs here.
if (poly.size() != fri_params.D[0]->size()) {
g_coeffs[key].emplace_back(poly.coefficients());
}
}
}
}

for (std::size_t query_id = 0; query_id < FRI::lambda; query_id++) {
std::size_t domain_size = fri_params.D[0]->size();
std::uint64_t x_index = (transcript.template int_challenge<std::uint64_t>()) % domain_size;
Expand All @@ -679,7 +702,7 @@ namespace nil {

//Initial proof
std::map<std::size_t, typename FRI::initial_proof_type> initial_proof;
for( const auto &it: g ){
for (const auto &it: g) {
auto k = it.first;
initial_proof[k] = {};
initial_proof[k].values.resize(it.second.size());
Expand All @@ -689,25 +712,37 @@ namespace nil {

//Fill values
t = 0;
for (std::size_t polynomial_index = 0; polynomial_index < g[k].size(); ++polynomial_index) {
const auto& g_k = it.second; // g[k]

for (std::size_t polynomial_index = 0; polynomial_index < g_k.size(); ++polynomial_index) {
initial_proof[k].values[polynomial_index].resize(coset_size / FRI::m);
for (std::size_t j = 0; j < coset_size / FRI::m; j++) {
if constexpr (std::is_same<
if constexpr (std::is_same<
math::polynomial_dfs<typename FRI::field_type::value_type>,
PolynomialType>::value
) {
initial_proof[k].values[polynomial_index][j][0] = std::move(g[k][polynomial_index][s_indices[j][0]]);
initial_proof[k].values[polynomial_index][j][1] = std::move(g[k][polynomial_index][s_indices[j][1]]);
if (g_k[polynomial_index].size() == fri_params.D[0]->size()) {
for (std::size_t j = 0; j < coset_size / FRI::m; j++) {
initial_proof[k].values[polynomial_index][j][0] = g_k[polynomial_index][s_indices[j][0]];
initial_proof[k].values[polynomial_index][j][1] = g_k[polynomial_index][s_indices[j][1]];
}
} else {
initial_proof[k].values[polynomial_index][j][0] = g[k][polynomial_index].evaluate(
s[j][0]);
initial_proof[k].values[polynomial_index][j][1] = g[k][polynomial_index].evaluate(
s[j][1]);
// Convert to coefficients form and evaluate. coset_size / FRI::m is usually just 1,
// It makes no sense to resize in dfs form to then use just 2 values in 2 points.
for (std::size_t j = 0; j < coset_size / FRI::m; j++) {
initial_proof[k].values[polynomial_index][j][0] = g_coeffs[k][polynomial_index].evaluate(s[j][0]);
initial_proof[k].values[polynomial_index][j][1] = g_coeffs[k][polynomial_index].evaluate(s[j][1]);
}
}
} else {
// Same for poly in coefficients form.
for (std::size_t j = 0; j < coset_size / FRI::m; j++) {
initial_proof[k].values[polynomial_index][j][0] = g_k[polynomial_index].evaluate(s[j][0]);
initial_proof[k].values[polynomial_index][j][1] = g_k[polynomial_index].evaluate(s[j][1]);
}
}
}

//Fill merkle proofs
// Fill merkle proofs
initial_proof[k].p = make_proof_specialized<FRI>(
get_folded_index<FRI>(x_index, fri_params.D[0]->size(), fri_params.step_list[0]),
fri_params.D[0]->size(), precommitments.at(k)
Expand Down Expand Up @@ -758,13 +793,14 @@ namespace nil {
round_proofs[i].y[0][1] = final_polynomial.evaluate(-x);
}
}
typename FRI::query_proof_type query_proof = {initial_proof, round_proofs};
query_proofs[query_id] = query_proof;
typename FRI::query_proof_type query_proof = {std::move(initial_proof), std::move(round_proofs)};
query_proofs[query_id] = std::move(query_proof);
}

proof.fri_roots = fri_roots;
proof.final_polynomial = final_polynomial;
proof.query_proofs = query_proofs;
proof.fri_roots = std::move(fri_roots);
proof.final_polynomial = std::move(final_polynomial);
proof.query_proofs = std::move(query_proofs);

return proof;//typename FRI::proof_type{fri_roots, final_polynomial, query_proofs};
}

Expand Down
28 changes: 28 additions & 0 deletions include/nil/crypto3/zk/snark/arithmetization/plonk/assignment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ namespace nil {
return _witnesses;
}

witnesses_container_type move_witnesses() {
return std::move(_witnesses);
}

const ColumnType& operator[](std::uint32_t index) const {
if (index < ArithmetizationParams::witness_columns)
return _witnesses[index];
Expand Down Expand Up @@ -147,6 +151,11 @@ namespace nil {
return _public_inputs;
}

public_input_container_type move_public_inputs() {

return std::move(_public_inputs);
}

std::uint32_t constants_amount() const {
return _constants.size();
}
Expand All @@ -164,6 +173,11 @@ namespace nil {
return _constants;
}

constant_container_type move_constants() {

return std::move(_constants);
}

constexpr std::uint32_t selectors_amount() const {
return _selectors.size();
}
Expand All @@ -181,6 +195,11 @@ namespace nil {
return _selectors;
}

selector_container_type move_selectors() {

return std::move(_selectors);
}

void fill_constant(std::uint32_t index, const ColumnType& column) {
BOOST_ASSERT(index < constants_amount());
BOOST_ASSERT(_constants[index].size() == 0);
Expand Down Expand Up @@ -246,6 +265,7 @@ namespace nil {
using selector_container_type = typename public_table_type::selector_container_type;

protected:
// These are normally created by the assigner, or read from a file.
private_table_type _private_table;
public_table_type _public_table;

Expand Down Expand Up @@ -309,10 +329,18 @@ namespace nil {
return _private_table;
}

private_table_type move_private_table() {
return std::move(_private_table);
}

const public_table_type& public_table() const {
return _public_table;
}

public_table_type move_public_table() {
return std::move(_public_table);
}

std::uint32_t size() const {
return _private_table.size() + _public_table.size();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,8 @@ namespace nil {

template<typename FieldType>
math::polynomial_dfs<typename FieldType::value_type>
column_polynomial_dfs(const plonk_column<FieldType> &column_assignment,
std::shared_ptr<math::evaluation_domain<FieldType>>
domain) {
column_polynomial_dfs(plonk_column<FieldType> column_assignment,
std::shared_ptr<math::evaluation_domain<FieldType>> domain) {

std::size_t d = std::distance(column_assignment.begin(), column_assignment.end()) - 1;

Expand All @@ -107,16 +106,15 @@ namespace nil {

template<typename FieldType>
std::vector<math::polynomial_dfs<typename FieldType::value_type>>
column_range_polynomial_dfs(const std::vector<plonk_column<FieldType>> &column_range_assignment,
std::shared_ptr<math::evaluation_domain<FieldType>>
domain) {
column_range_polynomial_dfs(std::vector<plonk_column<FieldType>> column_range_assignment,
std::shared_ptr<math::evaluation_domain<FieldType>> domain) {

std::size_t columns_amount = column_range_assignment.size();
std::vector<math::polynomial_dfs<typename FieldType::value_type>> columns(columns_amount);

for (std::size_t column_index = 0; column_index < columns_amount; column_index++) {
columns[column_index] =
column_polynomial_dfs<FieldType>(column_range_assignment[column_index], domain);
column_polynomial_dfs<FieldType>(std::move(column_range_assignment[column_index]), domain);
}

return columns;
Expand All @@ -125,15 +123,15 @@ namespace nil {
template<typename FieldType, std::size_t columns_amount>
std::array<math::polynomial_dfs<typename FieldType::value_type>, columns_amount>
column_range_polynomial_dfs(
const std::array<plonk_column<FieldType>, columns_amount> &column_range_assignment,
std::array<plonk_column<FieldType>, columns_amount> column_range_assignment,
std::shared_ptr<math::evaluation_domain<FieldType>>
domain) {

std::array<math::polynomial_dfs<typename FieldType::value_type>, columns_amount> columns;

for (std::size_t column_index = 0; column_index < columns_amount; column_index++) {
columns[column_index] =
column_polynomial_dfs<FieldType>(column_range_assignment[column_index], domain);
column_polynomial_dfs<FieldType>(std::move(column_range_assignment[column_index]), domain);
}

return columns;
Expand Down
Loading
Loading