Skip to content

Commit

Permalink
poc
Browse files Browse the repository at this point in the history
  • Loading branch information
Rumata888 committed Apr 17, 2024
1 parent f8efb46 commit 1482721
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 10 deletions.
20 changes: 20 additions & 0 deletions barretenberg/cpp/src/barretenberg/flavor/flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,26 @@ static constexpr auto create_protogalaxy_tuple_of_tuples_of_univariates()
}
}

/**
* @brief Recursive utility function to construct a container for the subrelation accumulators of Protogalaxy folding.
* @details The size of the outer tuple is equal to the number of relations. Each relation contributes an inner tuple of
* univariates whose size is equal to the number of subrelations of the relation. The length of a univariate in an inner
* tuple is determined by the corresponding subrelation length and the number of instances to be folded.
*/
template <typename Tuple, size_t NUM_INSTANCES, size_t Index = 0>
static constexpr auto create_optimised_protogalaxy_tuple_of_tuples_of_univariates()
{
if constexpr (Index >= std::tuple_size<Tuple>::value) {
return std::tuple<>{}; // Return empty when reach end of the tuple
} else {
using UnivariateTuple = typename std::tuple_element_t<Index, Tuple>::
template OptimisedProtogalaxyTupleOfUnivariatesOverSubrelations<NUM_INSTANCES>;
return std::tuple_cat(
std::tuple<UnivariateTuple>{},
create_optimised_protogalaxy_tuple_of_tuples_of_univariates<Tuple, NUM_INSTANCES, Index + 1>());
}
}

/**
* @brief Recursive utility function to construct a container for the subrelation accumulators of sumcheck proving.
* @details The size of the outer tuple is equal to the number of relations. Each relation contributes an inner tuple of
Expand Down
15 changes: 12 additions & 3 deletions barretenberg/cpp/src/barretenberg/polynomials/univariate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ template <class Fr, size_t domain_end, size_t domain_start = 0> class Univariate
* subtraction: setting Δ = v1-v0, the values of f(X) are f(0)=v0, f(1)= v0 + Δ, v2 = f(1) + Δ, v3 = f(2) + Δ...
*
*/
template <size_t EXTENDED_DOMAIN_END> Univariate<Fr, EXTENDED_DOMAIN_END> extend_to() const
template <size_t EXTENDED_DOMAIN_END, bool optimised = false> Univariate<Fr, EXTENDED_DOMAIN_END> extend_to() const
{
const size_t EXTENDED_LENGTH = EXTENDED_DOMAIN_END - domain_start;
using Data = BarycentricData<Fr, LENGTH, EXTENDED_LENGTH>;
Expand All @@ -282,11 +282,20 @@ template <class Fr, size_t domain_end, size_t domain_start = 0> class Univariate
std::copy(evaluations.begin(), evaluations.end(), result.evaluations.begin());

static constexpr Fr inverse_two = Fr(2).invert();
// static_assert(!optimised || (LENGTH <= 2));
if constexpr (LENGTH == 2) {
Fr delta = value_at(1) - value_at(0);
static_assert(EXTENDED_LENGTH != 0);
for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) {
result.value_at(idx + 1) = result.value_at(idx) + delta;
if constexpr (optimised) {
Fr current = result.value_at(1);
for (size_t idx = domain_end - 2; idx < EXTENDED_DOMAIN_END - 1; idx++) {
current += delta;
result.value_at(idx + 1) = current;
}
} else {
for (size_t idx = domain_end - 1; idx < EXTENDED_DOMAIN_END - 1; idx++) {
result.value_at(idx + 1) = result.value_at(idx) + delta;
}
}
return result;
} else if constexpr (LENGTH == 3) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,21 @@ template <class ProverInstances_> class ProtoGalaxyProver_ {
// The length of ExtendedUnivariate is the largest length (==max_relation_degree + 1) of a univariate polynomial
// obtained by composing a relation with folded instance + relation parameters .
using ExtendedUnivariate = Univariate<FF, (Flavor::MAX_TOTAL_RELATION_LENGTH - 1) * (ProverInstances::NUM - 1) + 1>;
using OptimisedExtendedUnivariate =
Univariate<FF, (Flavor::MAX_TOTAL_RELATION_LENGTH - 2) * (ProverInstances::NUM - 1) + 1>;
// Represents the total length of the combiner univariate, obtained by combining the already folded relations with
// the folded relation batching challenge.
using ExtendedUnivariateWithRandomization =
Univariate<FF,
(Flavor::MAX_TOTAL_RELATION_LENGTH - 1 + ProverInstances::NUM - 1) * (ProverInstances::NUM - 1) + 1>;
using ExtendedUnivariates = typename Flavor::template ProverUnivariates<ExtendedUnivariate::LENGTH>;
using OptimisedExtendedUnivariates =
typename Flavor::template ProverUnivariates<ExtendedUnivariate::LENGTH - (1 * (ProverInstances::NUM - 1))>;

using TupleOfTuplesOfUnivariates =
typename Flavor::template ProtogalaxyTupleOfTuplesOfUnivariates<ProverInstances::NUM>;
using OptimisedTupleOfTuplesOfUnivariates =
typename Flavor::template OptimisedProtogalaxyTupleOfTuplesOfUnivariates<ProverInstances::NUM>;
using RelationEvaluations = typename Flavor::TupleOfArraysOfValues;

static constexpr size_t NUM_SUBRELATIONS = ProverInstances::NUM_SUBRELATIONS;
Expand Down Expand Up @@ -291,9 +297,27 @@ template <class ProverInstances_> class ProtoGalaxyProver_ {
}
}

/**
* @brief Prepare a univariate polynomial for relation execution in one step of the main loop in folded instance
* construction.
* @details For a fixed prover polynomial index, extract that polynomial from each instance in Instances. From each
* polynomial, extract the value at row_idx. Use these values to create a univariate polynomial, and then extend
* (i.e., compute additional evaluations at adjacent domain values) as needed.
* @todo TODO(https://github.com/AztecProtocol/barretenberg/issues/751) Optimize memory
*/
void optimised_extend_univariates(OptimisedExtendedUnivariates& extended_univariates,
const ProverInstances& instances,
const size_t row_idx)
{
auto base_univariates = instances.row_to_univariates(row_idx);
for (auto [extended_univariate, base_univariate] : zip_view(extended_univariates.get_all(), base_univariates)) {
extended_univariate = base_univariate.template extend_to<OptimisedExtendedUnivariate::LENGTH, true>();
}
}

template <typename Parameters, size_t relation_idx = 0>
void accumulate_relation_univariates(TupleOfTuplesOfUnivariates& univariate_accumulators,
const ExtendedUnivariates& extended_univariates,
void accumulate_relation_univariates(OptimisedTupleOfTuplesOfUnivariates& univariate_accumulators,
const OptimisedExtendedUnivariates& extended_univariates,
const Parameters& relation_parameters,
const FF& scaling_factor)
{
Expand Down Expand Up @@ -329,14 +353,14 @@ template <class ProverInstances_> class ProtoGalaxyProver_ {
num_threads = num_threads > 0 ? num_threads : 1; // ensure num threads is >= 1
size_t iterations_per_thread = common_instance_size / num_threads; // actual iterations per thread
// Construct univariate accumulator containers; one per thread
std::vector<TupleOfTuplesOfUnivariates> thread_univariate_accumulators(num_threads);
std::vector<OptimisedTupleOfTuplesOfUnivariates> thread_univariate_accumulators(num_threads);
for (auto& accum : thread_univariate_accumulators) {
// just normal relation lengths
Utils::zero_univariates(accum);
}

// Construct extended univariates containers; one per thread
std::vector<ExtendedUnivariates> extended_univariates;
std::vector<OptimisedExtendedUnivariates> extended_univariates;
extended_univariates.resize(num_threads);

// Accumulate the contribution from each sub-relation
Expand All @@ -346,7 +370,7 @@ template <class ProverInstances_> class ProtoGalaxyProver_ {

for (size_t idx = start; idx < end; idx++) {
// No need to initialise extended_univariates to 0, it's assigned to
extend_univariates(extended_univariates[thread_idx], instances, idx);
optimised_extend_univariates(extended_univariates[thread_idx], instances, idx);

FF pow_challenge = pow_betas[idx];

Expand All @@ -360,15 +384,36 @@ template <class ProverInstances_> class ProtoGalaxyProver_ {
pow_challenge);
}
});

OptimisedTupleOfTuplesOfUnivariates optimised_univariate_accumulators;
Utils::zero_univariates(optimised_univariate_accumulators);
// Accumulate the per-thread univariate accumulators into a single set of accumulators
for (auto& accumulators : thread_univariate_accumulators) {
Utils::add_nested_tuples(univariate_accumulators, accumulators);
Utils::add_nested_tuples(optimised_univariate_accumulators, accumulators);
}
deoptimise_univariates(optimised_univariate_accumulators, univariate_accumulators);
// Batch the univariate contributions from each sub-relation to obtain the round univariate
return batch_over_relations(univariate_accumulators, instances.alphas);
}

static void deoptimise_univariates(OptimisedTupleOfTuplesOfUnivariates& optimised_univariate_accumulators,
TupleOfTuplesOfUnivariates& univariate_accumulators

)
{
auto deoptimise = [&]<size_t outer_idx, size_t inner_idx>(auto& element) {
auto& optimised_element = std::get<inner_idx>(std::get<outer_idx>(optimised_univariate_accumulators));
static_assert(std::remove_reference_t<decltype(optimised_element)>::LENGTH + (ProverInstances::NUM - 1) ==
std::remove_reference_t<decltype(element)>::LENGTH);
element.evaluations[0] = optimised_element.evaluations[0];
element.evaluations[1] = FF(0);
for (size_t i = 1; i < std::remove_reference_t<decltype(optimised_element)>::LENGTH; i++) {
element.evaluations[i + 1] = optimised_element.evaluations[i];
}
};

Utils::template apply_to_tuple_of_tuples<0, 0>(univariate_accumulators, deoptimise);
}

static ExtendedUnivariateWithRandomization batch_over_relations(TupleOfTuplesOfUnivariates& univariate_accumulators,
const CombinedRelationSeparator& alpha)
{
Expand All @@ -378,6 +423,7 @@ template <class ProverInstances_> class ProtoGalaxyProver_ {
size_t idx = 0;
auto scale_and_sum = [&]<size_t outer_idx, size_t inner_idx>(auto& element) {
auto extended = element.template extend_to<ProverInstances::BATCHED_EXTENDED_LENGTH>();
// info("Relation ", outer_idx, ".", inner_idx, "[", 0, "] = ", extended.value_at(0));
extended *= alpha[idx];
result += extended;
idx++;
Expand Down
27 changes: 27 additions & 0 deletions barretenberg/cpp/src/barretenberg/relations/relation_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,28 @@ consteval std::array<size_t, NUM_SUBRELATIONS> compute_composed_subrelation_part
return SUBRELATION_PARTIAL_LENGTHS;
};

/**
* @brief Get the subrelation accumulators for the Protogalaxy combiner calculation.
* @details A subrelation of degree D, when evaluated on polynomials of degree N, gives a polynomial of degree D
* * N. In the context of Protogalaxy, N = NUM_INSTANCES-1. Hence, given a subrelation of length x, its
* evaluation on such polynomials will have degree (x-1) * (NUM_INSTANCES-1), and the length of this evaluation
* will be one greater than this.
* @tparam NUM_INSTANCES
* @tparam NUM_SUBRELATIONS
* @param SUBRELATION_PARTIAL_LENGTHS The array of subrelation lengths supplied by a relation.
* @return The transformed subrelation lenths
*/
template <size_t NUM_INSTANCES, size_t NUM_SUBRELATIONS>
consteval std::array<size_t, NUM_SUBRELATIONS> compute_optimised_composed_subrelation_partial_lengths(
std::array<size_t, NUM_SUBRELATIONS> SUBRELATION_PARTIAL_LENGTHS)
{
std::transform(SUBRELATION_PARTIAL_LENGTHS.begin(),
SUBRELATION_PARTIAL_LENGTHS.end(),
SUBRELATION_PARTIAL_LENGTHS.begin(),
[](const size_t x) { return (x - 2) * (NUM_INSTANCES - 1) + 1; });
return SUBRELATION_PARTIAL_LENGTHS;
};

/**
* @brief The templates defined herein facilitate sharing the relation arithmetic between the prover and the
* verifier.
Expand Down Expand Up @@ -134,6 +156,11 @@ template <typename RelationImpl> class Relation : public RelationImpl {
template <size_t NUM_INSTANCES>
using ProtogalaxyTupleOfUnivariatesOverSubrelations =
TupleOfUnivariates<FF, compute_composed_subrelation_partial_lengths<NUM_INSTANCES>(SUBRELATION_TOTAL_LENGTHS)>;
template <size_t NUM_INSTANCES>
using OptimisedProtogalaxyTupleOfUnivariatesOverSubrelations =
TupleOfUnivariates<FF,
compute_optimised_composed_subrelation_partial_lengths<NUM_INSTANCES>(
SUBRELATION_TOTAL_LENGTHS)>;
using SumcheckTupleOfUnivariatesOverSubrelations =
TupleOfUnivariates<FF, RelationImpl::SUBRELATION_PARTIAL_LENGTHS>;
using SumcheckArrayOfValuesOverSubrelations = ArrayOfValues<FF, RelationImpl::SUBRELATION_PARTIAL_LENGTHS>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ class GoblinUltraFlavor {
template <size_t NUM_INSTANCES>
using ProtogalaxyTupleOfTuplesOfUnivariates =
decltype(create_protogalaxy_tuple_of_tuples_of_univariates<Relations, NUM_INSTANCES>());

template <size_t NUM_INSTANCES>
using OptimisedProtogalaxyTupleOfTuplesOfUnivariates =
decltype(create_optimised_protogalaxy_tuple_of_tuples_of_univariates<Relations, NUM_INSTANCES>());
using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates<Relations>());
using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values<Relations>());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ class UltraFlavor {
template <size_t NUM_INSTANCES>
using ProtogalaxyTupleOfTuplesOfUnivariates =
decltype(create_protogalaxy_tuple_of_tuples_of_univariates<Relations, NUM_INSTANCES>());
template <size_t NUM_INSTANCES>
using OptimisedProtogalaxyTupleOfTuplesOfUnivariates =
decltype(create_optimised_protogalaxy_tuple_of_tuples_of_univariates<Relations, NUM_INSTANCES>());
using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates<Relations>());
using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values<Relations>());

Expand Down
3 changes: 3 additions & 0 deletions barretenberg/cpp/src/barretenberg/vm/generated/avm_flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ class AvmFlavor {
template <size_t NUM_INSTANCES>
using ProtogalaxyTupleOfTuplesOfUnivariates =
decltype(create_protogalaxy_tuple_of_tuples_of_univariates<Relations, NUM_INSTANCES>());
template <size_t NUM_INSTANCES>
using OptimisedProtogalaxyTupleOfTuplesOfUnivariates =
decltype(create_optimised_protogalaxy_tuple_of_tuples_of_univariates<Relations, NUM_INSTANCES>());
using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates<Relations>());
using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values<Relations>());

Expand Down

0 comments on commit 1482721

Please sign in to comment.