Skip to content

Commit

Permalink
Release the size of goblin translator
Browse files Browse the repository at this point in the history
  • Loading branch information
Rumata888 committed Jan 29, 2024
1 parent 12356d9 commit 129d90f
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ template <typename Flavor, typename StorageHandle> void compute_concatenated_pol
// Resulting concatenated polynomials
auto targets = proving_key->get_concatenated_constraints();

// Targets have to be full-sized polynomials. We can comput the mini circuit size from them by dividing by
// concatenation index
const size_t MINI_CIRCUIT_SIZE = targets[0].size() / Flavor::CONCATENATION_INDEX;
ASSERT(MINI_CIRCUIT_SIZE * Flavor::CONCATENATION_INDEX == targets[0].size());
// A function that produces 1 concatenated polynomial
// TODO(#756): This can be rewritten to use more cores. Currently uses at maximum the number of concatenated
// polynomials (4 in Goblin Translator)
Expand All @@ -202,8 +206,8 @@ template <typename Flavor, typename StorageHandle> void compute_concatenated_pol
for (size_t j = 0; j < my_group.size(); j++) {
auto starting_write_offset = current_target.begin();
auto finishing_read_offset = my_group[j].begin();
std::advance(starting_write_offset, j * Flavor::MINI_CIRCUIT_SIZE);
std::advance(finishing_read_offset, Flavor::MINI_CIRCUIT_SIZE);
std::advance(starting_write_offset, j * MINI_CIRCUIT_SIZE);
std::advance(finishing_read_offset, MINI_CIRCUIT_SIZE);
// Copy into appropriate position in the concatenated polynomial
std::copy(my_group[j].begin(), finishing_read_offset, starting_write_offset);
}
Expand Down Expand Up @@ -234,16 +238,17 @@ template <typename Flavor, typename StorageHandle> void compute_concatenated_pol
* @param proving_key
*/
template <typename Flavor, typename StorageHandle>
void compute_goblin_translator_range_constraint_ordered_polynomials(StorageHandle* proving_key)
void compute_goblin_translator_range_constraint_ordered_polynomials(StorageHandle* proving_key,
size_t mini_circuit_dyadic_size)
{

using FF = typename Flavor::FF;

// Get constants
constexpr auto sort_step = Flavor::SORT_STEP;
constexpr auto num_concatenated_wires = Flavor::NUM_CONCATENATED_WIRES;
constexpr auto full_circuit_size = Flavor::FULL_CIRCUIT_SIZE;
constexpr auto mini_circuit_size = Flavor::MINI_CIRCUIT_SIZE;
const auto mini_circuit_size = mini_circuit_dyadic_size;
const auto full_circuit_size = mini_circuit_dyadic_size * Flavor::CONCATENATION_INDEX;

// The value we have to end polynomials with
constexpr uint32_t max_value = (1 << Flavor::MICRO_LIMB_BITS) - 1;
Expand All @@ -252,7 +257,7 @@ void compute_goblin_translator_range_constraint_ordered_polynomials(StorageHandl
constexpr size_t sorted_elements_count = (max_value / sort_step) + 1 + (max_value % sort_step == 0 ? 0 : 1);

// Check if we can construct these polynomials
static_assert((num_concatenated_wires + 1) * sorted_elements_count < full_circuit_size);
ASSERT((num_concatenated_wires + 1) * sorted_elements_count < full_circuit_size);

// First use integers (easier to sort)
std::vector<size_t> sorted_elements(sorted_elements_count);
Expand All @@ -279,7 +284,7 @@ void compute_goblin_translator_range_constraint_ordered_polynomials(StorageHandl
// Get the group and the main target vector
auto my_group = concatenation_groups[i];
auto& current_vector = ordered_vectors_uint[i];
current_vector.resize(Flavor::FULL_CIRCUIT_SIZE);
current_vector.resize(full_circuit_size);

// Calculate how much space there is for values from the original polynomials
auto free_space_before_runway = full_circuit_size - sorted_elements_count;
Expand Down Expand Up @@ -363,12 +368,14 @@ void compute_goblin_translator_range_constraint_ordered_polynomials(StorageHandl
* contains 5 MAX_VALUE, 5 (MAX_VALUE-STEP),... values
*
* @param key Proving key where we will save the polynomials
* @param dyadic_circuit_size The full size of the circuit
*/
template <typename Flavor> inline void compute_extra_range_constraint_numerator(auto proving_key)
template <typename Flavor>
inline void compute_extra_range_constraint_numerator(auto proving_key, size_t dyadic_circuit_size)
{

// Get the full goblin circuits size (this is the length of concatenated range constraint polynomials)
auto full_circuit_size = Flavor::FULL_CIRCUIT_SIZE;
auto full_circuit_size = dyadic_circuit_size;
auto sort_step = Flavor::SORT_STEP;
auto num_concatenated_wires = Flavor::NUM_CONCATENATED_WIRES;

Expand Down Expand Up @@ -404,8 +411,10 @@ template <typename Flavor> inline void compute_extra_range_constraint_numerator(
* @brief Compute odd and even largrange polynomials (up to mini_circuit length) and put them in the polynomial cache
*
* @param key Proving key where we will save the polynomials
* @param mini_circuit_dyadic_size The size of the part of the circuit where the computation of translated value happens
*/
template <typename Flavor> inline void compute_lagrange_polynomials_for_goblin_translator(auto proving_key)
template <typename Flavor>
inline void compute_lagrange_polynomials_for_goblin_translator(auto proving_key, size_t mini_circuit_dyadic_size)

{
const size_t n = proving_key->circuit_size;
Expand All @@ -414,15 +423,15 @@ template <typename Flavor> inline void compute_lagrange_polynomials_for_goblin_t
typename Flavor::Polynomial lagrange_polynomial_second(n);
typename Flavor::Polynomial lagrange_polynomial_second_to_last_in_minicircuit(n);

for (size_t i = 1; i < Flavor::MINI_CIRCUIT_SIZE - 1; i += 2) {
for (size_t i = 1; i < mini_circuit_dyadic_size - 1; i += 2) {
lagrange_polynomial_odd_in_minicircuit[i] = 1;
lagrange_polynomial_even_in_minicircut[i + 1] = 1;
}
proving_key->lagrange_odd_in_minicircuit = lagrange_polynomial_odd_in_minicircuit.share();

proving_key->lagrange_even_in_minicircuit = lagrange_polynomial_even_in_minicircut.share();
lagrange_polynomial_second[1] = 1;
lagrange_polynomial_second_to_last_in_minicircuit[Flavor::MINI_CIRCUIT_SIZE - 2] = 1;
lagrange_polynomial_second_to_last_in_minicircuit[mini_circuit_dyadic_size - 2] = 1;
proving_key->lagrange_second_to_last_in_minicircuit = lagrange_polynomial_second_to_last_in_minicircuit.share();
proving_key->lagrange_second = lagrange_polynomial_second.share();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ class GoblinTranslatorCircuitBuilder : public CircuitBuilderBase<bb::fr> {

};

// Basic goblin translator has the minicircuit size of 2048, so optimize for that case
// Basic goblin translator has the minimum minicircuit size of 16384, so optimize for that case
// For context, minicircuit is the part of the final polynomials fed into the proving system, where we have all the
// arithmetic logic. However, the full circuit is several times larger (we use a trick to bring down the degree of
// the permutation argument)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,7 @@ using Transcript = typename Flavor::Transcript;

void GoblinTranslatorComposer::compute_circuit_size_parameters(CircuitBuilder& circuit_builder)
{
const size_t num_gates = circuit_builder.num_gates;

// number of populated rows in the execution trace
size_t num_rows_populated_in_execution_trace = num_gates;

// Goblin translator circuits always have a predefined size and are structured as a VM (no concept of selectors)
ASSERT(MINI_CIRCUIT_SIZE >= num_rows_populated_in_execution_trace);

total_num_gates = std::max(MINI_CIRCUIT_SIZE, num_rows_populated_in_execution_trace);
total_num_gates = std::max(circuit_builder.num_gates, MINIMUM_MINI_CIRCUIT_SIZE);

// Next power of 2
mini_circuit_dyadic_size = circuit_builder.get_circuit_subgroup_size(total_num_gates);
Expand Down Expand Up @@ -189,7 +181,7 @@ void GoblinTranslatorComposer::compute_witness(CircuitBuilder& circuit_builder)
// We also contruct ordered polynomials, which have the same values as concatenated ones + enough values to bridge
// the range from 0 to maximum range defined by the range constraint.
bb::honk::permutation_library::compute_goblin_translator_range_constraint_ordered_polynomials<Flavor>(
proving_key.get());
proving_key.get(), mini_circuit_dyadic_size);

computed_witness = true;
}
Expand Down Expand Up @@ -273,11 +265,13 @@ std::shared_ptr<typename Flavor::ProvingKey> GoblinTranslatorComposer::compute_p

// Compute polynomials with odd and even indices set to 1 up to the minicircuit margin + lagrange polynomials at
// second and second to last indices in the minicircuit
bb::honk::permutation_library::compute_lagrange_polynomials_for_goblin_translator<Flavor>(proving_key.get());
bb::honk::permutation_library::compute_lagrange_polynomials_for_goblin_translator<Flavor>(proving_key.get(),
mini_circuit_dyadic_size);

// Compute the numerator for the permutation argument with several repetitions of steps bridging 0 and maximum range
// constraint
bb::honk::permutation_library::compute_extra_range_constraint_numerator<Flavor>(proving_key.get());
bb::honk::permutation_library::compute_extra_range_constraint_numerator<Flavor>(proving_key.get(),
dyadic_circuit_size);

return proving_key;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ class GoblinTranslatorComposer {
using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey;
using Polynomial = typename Flavor::Polynomial;
using Transcript = BaseTranscript;
static constexpr size_t MINI_CIRCUIT_SIZE = Flavor::MINI_CIRCUIT_SIZE;

static constexpr std::string_view NAME_STRING = "GoblinTranslator";
static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES;
// The minimum size of the mini-circuit (or sorted constraints won't work)
static constexpr size_t MINIMUM_MINI_CIRCUIT_SIZE = 2048;
std::shared_ptr<ProvingKey> proving_key;
std::shared_ptr<VerificationKey> verification_key;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ class GoblinTranslatorProver {
using Curve = typename Flavor::Curve;
using Transcript = typename Flavor::Transcript;

static size_t constexpr MINI_CIRCUIT_SIZE = Flavor::MINI_CIRCUIT_SIZE;
static size_t constexpr FULL_CIRCUIT_SIZE = Flavor::FULL_CIRCUIT_SIZE;

public:
explicit GoblinTranslatorProver(const std::shared_ptr<ProvingKey>& input_key,
const std::shared_ptr<CommitmentKey>& commitment_key,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,8 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorPermutationRelationCorrectness)
using Polynomial = bb::Polynomial<FF>;
using namespace bb::honk::permutation_library;
auto& engine = numeric::get_debug_randomness();
auto circuit_size = Flavor::MINI_CIRCUIT_SIZE * Flavor::CONCATENATION_INDEX;
const size_t mini_circuit_size = 2048;
auto full_circuit_size = mini_circuit_size * Flavor::CONCATENATION_INDEX;

// We only need gamma, because permutationr elation only uses gamma
FF gamma = FF::random_element();
Expand All @@ -391,16 +392,16 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorPermutationRelationCorrectness)
// Create storage for polynomials
ProverPolynomials prover_polynomials;
for (Polynomial& prover_poly : prover_polynomials.get_all()) {
prover_poly = Polynomial{ circuit_size };
prover_poly = Polynomial{ full_circuit_size };
}

// Fill in lagrange polynomials used in the permutation relation
prover_polynomials.lagrange_first[0] = 1;
prover_polynomials.lagrange_last[circuit_size - 1] = 1;
prover_polynomials.lagrange_last[full_circuit_size - 1] = 1;

// Put random values in all the non-concatenated constraint polynomials used to range constrain the values
auto fill_polynomial_with_random_14_bit_values = [&](auto& polynomial) {
for (size_t i = 0; i < Flavor::MINI_CIRCUIT_SIZE; i++) {
for (size_t i = 0; i < mini_circuit_size; i++) {
polynomial[i] = engine.get_random_uint16() & ((1 << Flavor::MICRO_LIMB_BITS) - 1);
}
};
Expand Down Expand Up @@ -470,23 +471,23 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorPermutationRelationCorrectness)
fill_polynomial_with_random_14_bit_values(prover_polynomials.relation_wide_limbs_range_constraint_3);

// Compute ordered range constraint polynomials that go in the denominator of the grand product polynomial
compute_goblin_translator_range_constraint_ordered_polynomials<Flavor>(&prover_polynomials);
compute_goblin_translator_range_constraint_ordered_polynomials<Flavor>(&prover_polynomials, mini_circuit_size);

// Compute the fixed numerator (part of verification key)
compute_extra_range_constraint_numerator<Flavor>(&prover_polynomials);
compute_extra_range_constraint_numerator<Flavor>(&prover_polynomials, full_circuit_size);

// Compute concatenated polynomials (4 polynomials produced from other constraint polynomials by concatenation)
compute_concatenated_polynomials<Flavor>(&prover_polynomials);

// Compute the grand product polynomial
grand_product_library::compute_grand_product<Flavor, bb::GoblinTranslatorPermutationRelation<FF>>(
circuit_size, prover_polynomials, params);
full_circuit_size, prover_polynomials, params);
prover_polynomials.z_perm_shift = prover_polynomials.z_perm.shifted();

using Relations = typename Flavor::Relations;

// Check that permutation relation is satisfied across each row of the prover polynomials
check_relation<Flavor, std::tuple_element_t<0, Relations>>(circuit_size, prover_polynomials, params);
check_relation<Flavor, std::tuple_element_t<0, Relations>>(full_circuit_size, prover_polynomials, params);
}

TEST_F(RelationCorrectnessTests, GoblinTranslatorGenPermSortRelationCorrectness)
Expand All @@ -496,8 +497,8 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorGenPermSortRelationCorrectness)
using ProverPolynomials = typename Flavor::ProverPolynomials;
using Polynomial = bb::Polynomial<FF>;
auto& engine = numeric::get_debug_randomness();

const auto circuit_size = Flavor::FULL_CIRCUIT_SIZE;
const size_t mini_circuit_size = 2048;
const auto circuit_size = Flavor::CONCATENATION_INDEX * mini_circuit_size;
const auto sort_step = Flavor::SORT_STEP;
const auto max_value = (1 << Flavor::MICRO_LIMB_BITS) - 1;

Expand Down Expand Up @@ -579,8 +580,8 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorExtraRelationsCorrectness)

auto& engine = numeric::get_debug_randomness();

auto circuit_size = Flavor::FULL_CIRCUIT_SIZE;
auto mini_circuit_size = Flavor::MINI_CIRCUIT_SIZE;
const size_t mini_circuit_size = 2048;
const auto circuit_size = Flavor::CONCATENATION_INDEX * mini_circuit_size;

// We only use accumulated_result from relation parameters in this relation
RelationParameters<FF> params;
Expand Down Expand Up @@ -681,7 +682,8 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorDecompositionRelationCorrectnes
using Polynomial = bb::Polynomial<FF>;
auto& engine = numeric::get_debug_randomness();

auto circuit_size = Flavor::FULL_CIRCUIT_SIZE;
constexpr size_t mini_circuit_size = 2048;
const auto circuit_size = Flavor::CONCATENATION_INDEX * mini_circuit_size;

// Decomposition relation doesn't use any relation parameters
RelationParameters<FF> params;
Expand Down Expand Up @@ -723,7 +725,7 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorDecompositionRelationCorrectnes
}

// Fill in lagrange odd polynomial (the only non-witness one we are using)
for (size_t i = 1; i < Flavor::MINI_CIRCUIT_SIZE - 1; i += 2) {
for (size_t i = 1; i < mini_circuit_size - 1; i += 2) {
prover_polynomials.lagrange_odd_in_minicircuit[i] = 1;
}

Expand Down Expand Up @@ -811,7 +813,7 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorDecompositionRelationCorrectnes
};

// Put random values in all the non-concatenated constraint polynomials used to range constrain the values
for (size_t i = 1; i < Flavor::MINI_CIRCUIT_SIZE - 1; i += 2) {
for (size_t i = 1; i < mini_circuit_size - 1; i += 2) {
// P.x
prover_polynomials.x_lo_y_hi[i] = FF(engine.get_random_uint256() & ((uint256_t(1) << LOW_WIDE_LIMB_WIDTH) - 1));
prover_polynomials.x_hi_z_1[i] = FF(engine.get_random_uint256() & ((uint256_t(1) << HIGH_WIDE_LIMB_WIDTH) - 1));
Expand Down Expand Up @@ -1055,15 +1057,15 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorNonNativeRelationCorrectness)
using Polynomial = bb::Polynomial<FF>;

constexpr size_t NUM_LIMB_BITS = Flavor::NUM_LIMB_BITS;
constexpr auto circuit_size = Flavor::FULL_CIRCUIT_SIZE;
constexpr auto mini_circuit_size = Flavor::MINI_CIRCUIT_SIZE;
constexpr auto mini_circuit_size = 2048;
constexpr auto circuit_size = Flavor::CONCATENATION_INDEX * mini_circuit_size;

auto& engine = numeric::get_debug_randomness();

auto op_queue = std::make_shared<bb::ECCOpQueue>();

// Generate random EccOpQueue actions
for (size_t i = 0; i < ((Flavor::MINI_CIRCUIT_SIZE >> 1) - 1); i++) {
for (size_t i = 0; i < ((mini_circuit_size >> 1) - 1); i++) {
switch (engine.get_random_uint8() & 3) {
case 0:
op_queue->empty_row();
Expand Down

0 comments on commit 129d90f

Please sign in to comment.