Skip to content

Commit

Permalink
Transport #1935 from monorepo. (#9)
Browse files Browse the repository at this point in the history
* Transport #1935 from monorepo.
Respond go Luke's PR review:
* Remove patch artifacts.; Delete unneeded sumcheck_types folder.; Note memory inefficiency of folding.; intebers ~> integers; Rename BarycentricData tests.; Fix bad find&replace in test names.; Removed unneeded include.; Git rid of UnivariateClass hack.; Move BarycentricData out of relations.; Restore health space between blocks.; Add all univariates to transcript.; Fix typo.; Revised comment around polynomial_cache.; Initialize target_total_sum.; edge_extensions ~> extended_edges; Fr ~> FF; Add comments to two sumcheck_round functions.; Fixed typo.
  • Loading branch information
codygunton authored and dbanks12 committed Jan 28, 2023
1 parent e06ecb6 commit a38f45a
Show file tree
Hide file tree
Showing 30 changed files with 1,389 additions and 1,448 deletions.
3 changes: 2 additions & 1 deletion cpp/cmake/toolchains/x86_64-linux-gcc.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
set(CMAKE_C_COMPILER "gcc")
set(CMAKE_CXX_COMPILER "g++")
# TODO(Cody): git rid of this when Adrian's work goes in
add_compile_options(-Wno-uninitialized)
add_compile_options(-Wno-uninitialized)
add_compile_options(-Wno-maybe-uninitialized)
3 changes: 2 additions & 1 deletion cpp/cmake/toolchains/x86_64-linux-gcc10.cmake
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
set(CMAKE_C_COMPILER "gcc-10")
set(CMAKE_CXX_COMPILER "g++-10")
# TODO(Cody): git rid of this when Adrian's work goes in
add_compile_options(-Wno-uninitialized)
add_compile_options(-Wno-uninitialized)
add_compile_options(-Wno-maybe-uninitialized)
40 changes: 40 additions & 0 deletions cpp/src/aztec/honk/flavor/flavor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once
#include <common/log.hpp>

class StandardArithmetization {
public:
enum POLYNOMIAL {
W_L,
W_R,
W_O,
Z_PERM,
Z_PERM_SHIFT,
Q_M,
Q_L,
Q_R,
Q_O,
Q_C,
SIGMA_1,
SIGMA_2,
SIGMA_3,
ID_1,
ID_2,
ID_3,
LAGRANGE_1,
COUNT
};

static constexpr size_t NUM_POLYNOMIALS = POLYNOMIAL::COUNT;
};

namespace honk::sumcheck { // TODO(Cody): get namespaces right here
class StandardHonk {
public:
using Arithmetization = StandardArithmetization;
using MULTIVARIATE = Arithmetization::POLYNOMIAL;
static constexpr size_t MAX_RELATION_LENGTH = 5; // TODO(Cody): increment after fixing add_edge_contribution; kill
// after moving barycentric class out of relations

// TODO(Cody): should extract this from the parameter pack. Maybe that should be done here?
};
} // namespace honk::sumcheck
31 changes: 31 additions & 0 deletions cpp/src/aztec/honk/flavor/flavor.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "flavor.hpp"

#include <gtest/gtest.h>

using namespace honk::sumcheck;
namespace test_flavor {

// // TODO(Cody) This seems like a good idea, but I'm not sure why.
// TEST(Flavor, StandardArithmetization){
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::W_L, 0);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::W_R, 1);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::W_O, 2);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::Z_PERM, 3);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::Z_PERM_SHIFT, 4);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::Q_M, 5);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::Q_L, 6);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::Q_R, 7);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::Q_O, 8);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::Q_C, 9);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::SIGMA_1, 10);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::SIGMA_2, 11);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::SIGMA_3, 12);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::ID_1, 13);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::ID_2, 14);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::ID_3, 15);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::LAGRANGE_1, 16);
// EXPECT_EQ(StandardArithmetization::MULTIVARIATE::COUNT, 17);

// }

} // namespace test_flavor
47 changes: 47 additions & 0 deletions cpp/src/aztec/honk/sumcheck/challenge_container.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once
#include <cstddef> // for size_t, for now
#include <vector>
#include "transcript.hpp"
#include "../flavor/flavor.hpp"

namespace honk::sumcheck {
// TODO(Cody): This is just for present purposes. I think this kind of structure is nice, but for the purpose of getting
// the PoC working we should link this/replace with existing transcript, then refactor later.
//
// TODO(Cody): needs to know number of rounds?
// TODO(Cody): Univariate class should not be provided as a template parameter?
template <class FF, class Transcript, class Univariate> class ChallengeContainer {
public:
Transcript transcript; // TODO(Cody):really a pointer to such a thing?
explicit ChallengeContainer(Transcript transcript)
: transcript(transcript){};

FF get_relation_separator_challenge() { return transcript.get_challenge(); }; // these are powers of a challenge

// FF get_relation_bliding_base(){return transcript.get_challenge(1);} // will get element zeta as well

FF get_challenge_equals_one() { return transcript.get_challenge_equals_one(); };

FF get_grand_product_beta_challenge() { return transcript.get_challenge_equals_one(); };

FF get_grand_product_gamma_challenge() { return transcript.get_challenge_equals_one(); };

FF get_sumcheck_round_challenge(size_t) // NOLINT(readability-named-parameter)
{
return transcript.get_challenge();
};

Univariate get_sumcheck_round_univariate(size_t) // NOLINT(readability-named-parameter)
{
Univariate result;
return result;
};

std::vector<FF> get_sumcheck_purported_evaluations()
{
std::vector<FF> result{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
return result;
};
// TODO(Cody): Leaving how things are added to the transcript as a black box for now.
};
} // namespace honk::sumcheck
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
#pragma once
#include <array>
#include <algorithm>
#include <stddef.h>
#include "univariate.hpp"

#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wunused-parameter"

namespace honk {
namespace sumcheck {
/* IMPROVEMENT(Cody): This could or should be improved in various ways. In no particular order:
1) Edge cases are not considered. One non-use case situation (I forget which) leads to a segfault.
2) This could all be constexpr.
3) Precomputing for all possible size pairs is probably feasible and might be a better solution than instantiating
many instances separately. Then perhaps we could infer input type to `extend`.
4) There should be more thorough testing of this class in isolation.
*/
namespace honk::sumcheck {

/**
* NOTE: We should definitely consider question of optimal choice of domain, but if decide on {0,1,...,t-1} then we can
* simplify the implementation a bit.
* NOTE: if we use this approach in the recursive setting, will use Plookup?
*/
template <class Fr, size_t domain_size, size_t num_evals> class BarycentricData {
public:
static constexpr size_t big_domain_size = std::max(domain_size, num_evals);
// TODO: these should be static, also constexpr, but arrays are not constexpr
// TODO(Cody): these should be static, also constexpr, but arrays are not constexpr
std::array<Fr, big_domain_size> big_domain;
std::array<Fr, domain_size> lagrange_denominators;
std::array<Fr, domain_size * num_evals> precomputed_denominator_inverses;
Expand Down Expand Up @@ -141,5 +150,4 @@ template <class Fr, size_t domain_size, size_t num_evals> class BarycentricData
return result;
};
};
} // namespace sumcheck
} // namespace honk
} // namespace honk::sumcheck
113 changes: 113 additions & 0 deletions cpp/src/aztec/honk/sumcheck/polynomials/multivariates.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#pragma once // just adding these willy-nilly
#include <array>
#include <algorithm>
#include <span>
#include <common/log.hpp>

namespace honk {
namespace sumcheck {

// std::span has no comparison operator, so this is a quick-and-dirty workaround for testing
// IMPROVEMENT(Cody): Move and/or implement as == in some class
bool span_arrays_equal(auto& lhs, auto& rhs)
{
bool result(true);
result = lhs.size() == rhs.size();
if (result) {
for (size_t i = 0; i < lhs.size(); i++) {
result &= std::equal(lhs[i].begin(), lhs[i].end(), rhs[i].begin(), rhs[i].end());
};
}
return result;
}

/**
*
* @brief A container for all of the Honk polynomials (wire and selector polynomials, grand product, and much more).
* These polynomials all low-degree extensions over H^d with H = {0, 1} (where d = ceil(log(number of gates))), hence
* they are multilinear polynomials in d variables. As such, it is efficient to store these polynomials in terms of
* univariate degree-1 polynomials.
* Suppose now the Honk polynomials (multilinear in d variables) are called P_1, ..., P_N. At initialization,
* we think of these as lying in a two-dimensional array, where each column records the value of one P_i on H^d. After
* the first round, the array will be updated ('folded'), so that the first n/2 rows will represent the evaluations
* P_i(X1, ..., X_{d-1}, u_d) as a low-degree extension on H^{d-1}. In reality, we elide copying all of the polynomial-
* defining data by only populating folded_multivariates after the first round. I.e.:
We imagine all of the defining polynomial data in a matrix like this:
| P_1 | P_2 | P_3 | P_4 | ... | P_N | N = number of multivariatesk
|-----------------------------------|
group 0 --| * | * | * | * | ... | * | vertex 0
\-| * | * | * | * | ... | * | vertex 1
group 1 --| * | * | * | * | ... | * | vertex 2
\-| * | * | * | * | ... | * | vertex 3
| * | * | * | * | ... | * |
group m-1 --| * | * | * | * | ... | * | vertex n-2
\-| * | * | * | * | ... | * | vertex n-1
m = n/2
*
Each group consists of N edges |, and our construction of univariates and folding
*
operations naturally operate on these groups of edges
*
* NOTE: With ~40 columns, prob only want to allocate 256 EdgeGroup's at once to keep stack under 1MB?
* TODO(Cody): might want to just do C-style multidimensional array? for guaranteed adjacency?
*/
template <class FF_, size_t num_polys, size_t num_vars> class Multivariates {
public:
using FF = FF_;
const static size_t multivariate_d = num_vars;
const static size_t multivariate_n = 1 << num_vars;
static constexpr size_t num = num_polys;

std::array<std::span<FF>, num_polys> full_polynomials;
// TODO(Cody): adjacency issues with std::array of std::arrays?
// IMPROVEMENT(Cody): for each round after the first, we could release half of the memory reserved by
// folded_polynomials.
std::array<std::array<FF, (multivariate_n >> 1)>, num_polys> folded_polynomials;

Multivariates() = default;

// TODO(Cody): static span extent below more efficient
explicit Multivariates(std::array<std::span<FF>, num_polys> full_polynomials)
: full_polynomials(full_polynomials){};

/**
* @brief Evaluate at the round challenge and prepare class for next round.
* Illustration of layout in example of first round when d==3 (showing just one Honk polynomial,
* i.e., what happens in just one column of our two-dimensional array):
*
* groups vertex terms collected vertex terms groups after folding
* g0 -- v0 (1-X1)(1-X2)(1-X3) --- (v0(1-X3) + v1 X3) (1-X1)(1-X2) ---- (v0(1-u3) + v1 u3) (1-X1)(1-X2)
* \- v1 (1-X1)(1-X2) X3 --/ --- (v2(1-u3) + v3 u3) (1-X1) X2
* g1 -- v2 (1-X1) X2 (1-X3) --- (v1(1-X3) + v2 X3) (1-X1) X2 -/ -- (v4(1-u3) + v5 u3) X1 (1-X2)
* \- v3 (1-X1) X2 X3 --/ / - (v6(1-u3) + v7 u3) X1 X2
* g2 -- v4 X1 (1-X2)(1-X3) --- (v3(1-X3) + v4 X3) X1 (1-X2)-/ /
* \- v5 X1 (1-X2) X3 --/ /
* g3 -- v6 X1 X2 (1-X3) --- (v5(1-X3) + v6 X3) X1 X2 -/
* \- v7 X1 X2 X3 --/
*
* @param challenge
*/

void fold(auto& polynomials, size_t round_size, const FF& round_challenge)
{
// after the first round, operate in place on folded_polynomials
for (size_t j = 0; j < num_polys; ++j) {
for (size_t i = 0; i < round_size; i += 2) {
folded_polynomials[j][i >> 1] =
polynomials[j][i] + round_challenge * (polynomials[j][i + 1] - polynomials[j][i]);
}
}
};

std::array<FF, num_polys> batch_evaluate(std::array<FF, num_vars> input)
{
// TODO(Cody): IOU implementation.
static_cast<void>(input);
return { { 1 } };
};
};
} // namespace sumcheck
} // namespace honk
Loading

0 comments on commit a38f45a

Please sign in to comment.