-
Notifications
You must be signed in to change notification settings - Fork 307
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
feat: swap polys to facilitate dynamic trace overflow #9976
Changes from 32 commits
560373c
981074c
090e720
2eded0b
d06c1e8
b4cb9de
a7231ef
0cf3757
f7e8fc7
35c15a0
515fe8b
e07eb4d
7d4ba63
ba7bfd5
559bb2e
916fc98
b23cd91
864ee3a
bfb2a70
2494af1
531c0d1
0b582eb
d781974
0b714d2
c9e6af0
90277ab
0891578
9f05f0b
c13923b
48052d0
681c1e6
1f79b46
e7d8499
1f4df0f
cd92b66
067cbb0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -72,8 +72,11 @@ struct ExecutionTraceUsageTracker { | |
} | ||
|
||
// The active ranges must also include the rows where the actual databus and lookup table data are stored. | ||
// (Note: lookup tables are constructed at the end of the trace; databus data is constructed at the start). | ||
size_t dyadic_circuit_size = fixed_sizes.get_structured_dyadic_size(); | ||
// (Note: lookup tables are constructed at the end of the trace; databus data is constructed at the start) so we | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment will break if the ordering in the trace structure ever changes--there's little chance that the person changing the structure remembers this comment exists, if they ever knew. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a way to make this more robust is to update the active ranges as we are constructing the DeciderProvingKey so if the position of the rows changes it is obvious that the tracker's active ranges also need to be updated, will add an issue. |
||
// need to determine the dyadic size for this. We call the size function on the current circuit which will have | ||
// the same fixed block sizes but might also have an overflow block potentially influencing the dyadic circuit | ||
// size. | ||
const size_t dyadic_circuit_size = circuit.blocks.get_structured_dyadic_size(); | ||
|
||
// TODO(https://github.com/AztecProtocol/barretenberg/issues/1152): should be able to use simply Range{ 0, | ||
// max_databus_size } but this breaks for certain choices of num_threads. | ||
|
@@ -111,6 +114,13 @@ struct ExecutionTraceUsageTracker { | |
"lookup", | ||
"overflow" }; | ||
|
||
std::vector<std::string> active_ranges_labels = [this] { | ||
maramihali marked this conversation as resolved.
Show resolved
Hide resolved
|
||
std::vector<std::string> result = block_labels; | ||
result.push_back("databus table data"); | ||
result.push_back("lookup table data"); | ||
return result; | ||
}(); | ||
|
||
void print() | ||
{ | ||
info("Minimum required block sizes for structured trace: "); | ||
|
@@ -123,7 +133,17 @@ struct ExecutionTraceUsageTracker { | |
void print_active_ranges() | ||
{ | ||
info("Active regions of accumulator: "); | ||
for (auto [label, range] : zip_view(block_labels, active_ranges)) { | ||
for (auto [label, range] : zip_view(active_ranges_labels, active_ranges)) { | ||
std::cout << std::left << std::setw(20) << (label + ":") << "(" << range.first << ", " << range.second | ||
<< ")" << std::endl; | ||
} | ||
info(""); | ||
} | ||
|
||
void print_previous_active_ranges() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when i was printing the active ranges it wasn't reflecting everything due to the lookup and databus caveat so I think it made sense to refine the labels |
||
{ | ||
info("Active regions of previous accumulator: "); | ||
for (auto [label, range] : zip_view(active_ranges_labels, previous_active_ranges)) { | ||
std::cout << std::left << std::setw(20) << (label + ":") << "(" << range.first << ", " << range.second | ||
<< ")" << std::endl; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#include "relation_checker.hpp" | ||
|
||
// Hack to make the module compile. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
#pragma once | ||
|
||
#include "barretenberg/common/assert.hpp" | ||
#include "barretenberg/common/log.hpp" | ||
#include "barretenberg/stdlib_circuit_builders/mega_flavor.hpp" | ||
#include "barretenberg/stdlib_circuit_builders/ultra_flavor.hpp" | ||
|
||
namespace bb { | ||
|
||
/** | ||
* @brief A debugging utility for checking whether a set of polynomials satisfies the relations for a given Flavor | ||
* | ||
* @tparam Flavor | ||
*/ | ||
template <typename Flavor> class RelationChecker { | ||
public: | ||
/** | ||
* @brief Check that the provided polynomials satisfy all relations for a given Flavor | ||
*/ | ||
static void check_all([[maybe_unused]] const auto& polynomials, [[maybe_unused]] const auto& params) | ||
{ | ||
// default; do nothing | ||
} | ||
|
||
/** | ||
* @brief Check that a single specified relation is satisfied for a set of polynomials | ||
* | ||
* @tparam Relation a linearly independent Relation to be checked | ||
* @param polynomials prover polynomials | ||
* @param params a RelationParameters instance | ||
*/ | ||
template <typename Relation> | ||
static void check(const auto& polynomials, | ||
const auto& params, | ||
bool is_linearly_independent, | ||
std::string label = "Relation") | ||
{ | ||
// Define the appropriate accumulator type for the relation and initialize to zero | ||
typename Relation::SumcheckArrayOfValuesOverSubrelations result; | ||
for (auto& element : result) { | ||
element = 0; | ||
} | ||
|
||
// for (size_t i = 0; i < polynomials.get_polynomial_size(); i++) { | ||
maramihali marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for (size_t i = 0; i < polynomials.w_l.virtual_size(); i++) { | ||
if (is_linearly_independent) { | ||
// Evaluate each constraint in the relation and check that each is satisfied | ||
Relation::accumulate(result, polynomials.get_row(i), params, 1); | ||
size_t subrelation_idx = 0; | ||
for (auto& element : result) { | ||
if (element != 0) { | ||
info("RelationChecker: ", | ||
label, | ||
" relation (subrelation idx: ", | ||
subrelation_idx, | ||
") failed at row idx: ", | ||
i, | ||
"."); | ||
ASSERT(false); | ||
} | ||
subrelation_idx++; | ||
} | ||
} | ||
} | ||
|
||
if (!is_linearly_independent) { | ||
// Result accumulated across entire execution trace should be zero | ||
for (auto& element : result) { | ||
if (element != 0) { | ||
info("RelationChecker: ", label, " relation (linearly indep.) failed."); | ||
ASSERT(false); | ||
} | ||
} | ||
} | ||
} | ||
}; | ||
|
||
// Specialization for Ultra | ||
template <> class RelationChecker<bb::UltraFlavor> : public RelationChecker<void> { | ||
using Base = RelationChecker<void>; | ||
|
||
public: | ||
static void check_all(const auto& polynomials, const auto& params) | ||
{ | ||
using FF = UltraFlavor::FF; | ||
|
||
// Linearly independent relations (must be satisfied at each row) | ||
Base::check<UltraArithmeticRelation<FF>>(polynomials, params, true, "UltraArithmetic"); | ||
Base::check<UltraPermutationRelation<FF>>(polynomials, params, true, "UltraPermutation"); | ||
Base::check<DeltaRangeConstraintRelation<FF>>(polynomials, params, true, "DeltaRangeConstraint"); | ||
Base::check<EllipticRelation<FF>>(polynomials, params, true, "Elliptic"); | ||
Base::check<AuxiliaryRelation<FF>>(polynomials, params, true, "Auxiliary"); | ||
Base::check<Poseidon2ExternalRelation<FF>>(polynomials, params, true, "Poseidon2External"); | ||
Base::check<Poseidon2InternalRelation<FF>>(polynomials, params, true, "Poseidon2Internal"); | ||
|
||
// Linearly dependent relations (must be satisfied as a sum across all rows) | ||
Base::check<LogDerivLookupRelation<FF>>(polynomials, params, false, "LogDerivLookup"); | ||
} | ||
}; | ||
|
||
// Specialization for Mega | ||
template <> class RelationChecker<MegaFlavor> : public RelationChecker<void> { | ||
using Base = RelationChecker<void>; | ||
|
||
public: | ||
static void check_all(const auto& polynomials, const auto& params) | ||
{ | ||
// Check relations that are shared with Ultra | ||
RelationChecker<UltraFlavor>::check_all(polynomials, params); | ||
|
||
using FF = MegaFlavor::FF; | ||
|
||
// Linearly independent relations (must be satisfied at each row) | ||
Base::check<EccOpQueueRelation<FF>>(polynomials, params, true, "EccOpQueue"); | ||
|
||
// Linearly dependent relations (must be satisfied as a sum across all rows) | ||
Base::check<DatabusLookupRelation<FF>>(polynomials, params, false, "DatabusLookup"); | ||
} | ||
}; | ||
|
||
} // namespace bb |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "barretenberg/polynomials/gate_separator.hpp" | ||
#include "barretenberg/protogalaxy/protogalaxy_prover.hpp" | ||
#include "barretenberg/protogalaxy/protogalaxy_prover_internal.hpp" | ||
#include "barretenberg/protogalaxy/protogalaxy_verifier.hpp" | ||
#include "barretenberg/ultra_honk/decider_prover.hpp" | ||
#include "barretenberg/ultra_honk/decider_verifier.hpp" | ||
|
||
namespace bb { | ||
/** | ||
* @brief Utility to manually compute the target sum of an accumulator and compare it to the one produced in Protogalxy | ||
* to attest correctness. | ||
*/ | ||
template <typename Flavor> | ||
static bool check_accumulator_target_sum_manual(const std::shared_ptr<DeciderProvingKey_<Flavor>>& accumulator) | ||
{ | ||
using DeciderProvingKeys = DeciderProvingKeys_<Flavor, 2>; | ||
using PGInternal = ProtogalaxyProverInternal<DeciderProvingKeys>; | ||
|
||
const size_t accumulator_size = accumulator->proving_key.circuit_size; | ||
PGInternal pg_internal; | ||
const auto expected_honk_evals = pg_internal.compute_row_evaluations( | ||
accumulator->proving_key.polynomials, accumulator->alphas, accumulator->relation_parameters); | ||
// Construct pow(\vec{betas*}) as in the paper | ||
GateSeparatorPolynomial expected_gate_separators(accumulator->gate_challenges, accumulator->gate_challenges.size()); | ||
|
||
// Compute the corresponding target sum and create a dummy accumulator | ||
typename Flavor::FF expected_target_sum{ 0 }; | ||
for (size_t idx = 0; idx < accumulator_size; idx++) { | ||
expected_target_sum += expected_honk_evals[idx] * expected_gate_separators[idx]; | ||
} | ||
return accumulator->target_sum == expected_target_sum; | ||
} | ||
} // namespace bb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If small tests structure changes behind the scenes, this test could silently break (i.e., it may continue to pass but cease to test what it's supposed to). Will you please define a new trace structure in this file for use in these two tests only?