Skip to content

Commit

Permalink
feat: eccvm translator zk sumcheck (#9199)
Browse files Browse the repository at this point in the history
Turned on ZK Sumcheck in ECCVM and Translator Flavors.

Benching `ClientIvc` with ZK sumcheck turned on in ECCVM and Translator:


| Benchmark | without ZK | with ZK (best result) |with ZK | with ZK
(worst result) | Overhead of Worst zk over non-ZK |

|--------------------------|-------------|----------------|---------------|--------------|-----------------------------|
| **ClientIVCBench/Full/2** | 12,039 ms | 12,512 ms | 12,658 ms | 12,778
ms | 6.14% |
| **ClientIVCBench/Full/6** | 33,258 ms | 34,830 ms | 35,038 ms | 35,452
ms | 6.60% |


**Using non-optimized ZK Sumcheck*
  • Loading branch information
iakovenkos authored Oct 24, 2024
1 parent 763d5b1 commit c7d4572
Show file tree
Hide file tree
Showing 40 changed files with 182 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ void eccvm_prove(State& state) noexcept
};
}

BENCHMARK(eccvm_generate_prover)->Unit(kMillisecond)->DenseRange(10, 20);
BENCHMARK(eccvm_prove)->Unit(kMillisecond)->DenseRange(10, 20);
BENCHMARK(eccvm_generate_prover)->Unit(kMillisecond)->DenseRange(12, 18);
BENCHMARK(eccvm_prove)->Unit(kMillisecond)->DenseRange(12, 18);
} // namespace

BENCHMARK_MAIN();
31 changes: 27 additions & 4 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_flavor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ class ECCVMFlavor {
using RelationSeparator = FF;
using MSM = bb::eccvm::MSM<CycleGroup>;

// Indicates that this flavor runs with non-ZK Sumcheck.
static constexpr bool HasZK = false;
// Indicates that this flavor runs with ZK Sumcheck.
static constexpr bool HasZK = true;
static constexpr size_t NUM_WIRES = 85;

// The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often
Expand All @@ -67,7 +67,8 @@ class ECCVMFlavor {
ECCVMBoolsRelation<FF>>;
using Relations = Relations_<FF>;
using LookupRelation = ECCVMLookupRelation<FF>;
static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length<Relations>();

static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length<Relations, HasZK>();

// BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta`
// random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation
Expand All @@ -78,7 +79,9 @@ class ECCVMFlavor {
// Instantiate the BarycentricData needed to extend each Relation Univariate

// define the containers for storing the contributions from each relation in Sumcheck
using SumcheckTupleOfTuplesOfUnivariates = decltype(create_sumcheck_tuple_of_tuples_of_univariates<Relations>());
using SumcheckTupleOfTuplesOfUnivariates =
decltype(create_sumcheck_tuple_of_tuples_of_univariates<Relations, HasZK>());

using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values<Relations>());

// TODO(https://github.com/AztecProtocol/barretenberg/issues/989): refine access specifiers in flavors, this is
Expand Down Expand Up @@ -933,7 +936,9 @@ class ECCVMFlavor {
Commitment transcript_msm_count_at_transition_inverse_comm;
Commitment z_perm_comm;
Commitment lookup_inverses_comm;
FF libra_sum;
std::vector<bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>> sumcheck_univariates;
std::vector<FF> libra_evaluations;
std::array<FF, NUM_ALL_ENTITIES> sumcheck_evaluations;
std::vector<Commitment> gemini_fold_comms;
std::vector<FF> gemini_fold_evals;
Expand Down Expand Up @@ -1137,11 +1142,20 @@ class ECCVMFlavor {
NativeTranscript::proof_data, num_frs_read);
z_perm_comm = NativeTranscript::template deserialize_from_buffer<Commitment>(NativeTranscript::proof_data,
num_frs_read);

libra_sum =
NativeTranscript::template deserialize_from_buffer<FF>(NativeTranscript::proof_data, num_frs_read);
for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) {
sumcheck_univariates.emplace_back(NativeTranscript::template deserialize_from_buffer<
bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(
NativeTranscript::proof_data, num_frs_read));
}

size_t log_circuit_size = static_cast<size_t>(numeric::get_msb(circuit_size));
for (size_t i = 0; i < log_circuit_size; i++) {
libra_evaluations.emplace_back(
NativeTranscript::template deserialize_from_buffer<FF>(NativeTranscript::proof_data, num_frs_read));
}
sumcheck_evaluations = NativeTranscript::template deserialize_from_buffer<std::array<FF, NUM_ALL_ENTITIES>>(
NativeTranscript::proof_data, num_frs_read);
for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N - 1; ++i) {
Expand Down Expand Up @@ -1183,6 +1197,8 @@ class ECCVMFlavor {
void serialize_full_transcript()
{
size_t old_proof_length = NativeTranscript::proof_data.size();
size_t log_circuit_size = static_cast<size_t>(numeric::get_msb(circuit_size));

NativeTranscript::proof_data.clear();

NativeTranscript::template serialize_to_buffer(circuit_size, NativeTranscript::proof_data);
Expand Down Expand Up @@ -1285,9 +1301,16 @@ class ECCVMFlavor {
NativeTranscript::proof_data);
NativeTranscript::template serialize_to_buffer(lookup_inverses_comm, NativeTranscript::proof_data);
NativeTranscript::template serialize_to_buffer(z_perm_comm, NativeTranscript::proof_data);

NativeTranscript::template serialize_to_buffer(libra_sum, NativeTranscript::proof_data);

for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) {
NativeTranscript::template serialize_to_buffer(sumcheck_univariates[i], NativeTranscript::proof_data);
}

for (size_t i = 0; i < log_circuit_size; ++i) {
NativeTranscript::template serialize_to_buffer(libra_evaluations[i], NativeTranscript::proof_data);
}
NativeTranscript::template serialize_to_buffer(sumcheck_evaluations, NativeTranscript::proof_data);
for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N - 1; ++i) {
NativeTranscript::template serialize_to_buffer(gemini_fold_comms[i], proof_data);
Expand Down
14 changes: 14 additions & 0 deletions barretenberg/cpp/src/barretenberg/eccvm/eccvm_transcript.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ class ECCVMTranscriptTests : public ::testing::Test {
std::string label = "Sumcheck:gate_challenge_" + std::to_string(i);
manifest_expected.add_challenge(round, label);
}
round++;

manifest_expected.add_entry(round, "Libra:Sum", frs_per_Fr);
// get the challenge for the ZK Sumcheck claim
manifest_expected.add_challenge(round, "Libra:Challenge");

for (size_t i = 0; i < CONST_PROOF_SIZE_LOG_N; ++i) {
round++;
Expand All @@ -147,7 +152,15 @@ class ECCVMTranscriptTests : public ::testing::Test {
}

round++;

for (size_t i = 0; i < log_n; i++) {
std::string idx = std::to_string(i);
manifest_expected.add_entry(round, "Libra:evaluation_" + idx, frs_per_Fr);
}
// manifest_expected.add_entry(round, "Libra:evaluation", log_n * frs_per_Fr);

manifest_expected.add_entry(round, "Sumcheck:evaluations", frs_per_evals);

manifest_expected.add_challenge(round, "rho");

round++;
Expand Down Expand Up @@ -256,6 +269,7 @@ TEST_F(ECCVMTranscriptTests, ProverManifestConsistency)
// Check that the prover generated manifest agrees with the manifest hard coded in this suite
auto manifest_expected = this->construct_eccvm_honk_manifest(prover.key->circuit_size);
auto prover_manifest = prover.transcript->get_manifest();

// Note: a manifest can be printed using manifest.print()
for (size_t round = 0; round < manifest_expected.size(); ++round) {
ASSERT_EQ(prover_manifest[round], manifest_expected[round]) << "Prover manifest discrepency in round " << round;
Expand Down
2 changes: 1 addition & 1 deletion barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ bool ECCVMVerifier::verify_proof(const HonkProof& proof)
gate_challenges[idx] = transcript->template get_challenge<FF>("Sumcheck:gate_challenge_" + std::to_string(idx));
}

auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] =
auto [multivariate_challenge, claimed_evaluations, libra_evaluations, sumcheck_verified] =
sumcheck.verify(relation_parameters, alpha, gate_challenges);

// If Sumcheck did not verify, return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
ACCUMULATE(RelationImpl, Flavor, SumcheckArrayOfValuesOverSubrelations, EvaluationEdge) \
ACCUMULATE(RelationImpl, Flavor, SumcheckArrayOfValuesOverSubrelations, EntityEdge)

#define DEFINE_ZK_SUMCHECK_RELATION_CLASS(RelationImpl, Flavor) \
ACCUMULATE(RelationImpl, Flavor, ZKSumcheckTupleOfUnivariatesOverSubrelations, ExtendedEdge) \
ACCUMULATE(RelationImpl, Flavor, SumcheckArrayOfValuesOverSubrelations, EvaluationEdge) \
ACCUMULATE(RelationImpl, Flavor, SumcheckArrayOfValuesOverSubrelations, EntityEdge)

#define DEFINE_SUMCHECK_VERIFIER_RELATION_CLASS(RelationImpl, Flavor) \
ACCUMULATE(RelationImpl, Flavor, SumcheckArrayOfValuesOverSubrelations, EvaluationEdge)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@

namespace bb {
template class ECCVMBoolsRelationImpl<grumpkin::fr>;
DEFINE_SUMCHECK_RELATION_CLASS(ECCVMBoolsRelationImpl, ECCVMFlavor);
DEFINE_ZK_SUMCHECK_RELATION_CLASS(ECCVMBoolsRelationImpl, ECCVMFlavor);
} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ polynomials,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
};

// Max among {SUBRELATION_PARTIAL_LENGTH + SUBRELATION_WITNESS_DEGREE}
static constexpr size_t ZK_RELATION_LENGTH = 5;

template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
static void accumulate(ContainerOverSubrelations& accumulator,
const AllEntities& in,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

namespace bb {
template class ECCVMLookupRelationImpl<grumpkin::fr>;
DEFINE_SUMCHECK_RELATION_CLASS(ECCVMLookupRelationImpl, ECCVMFlavor);
DEFINE_ZK_SUMCHECK_RELATION_CLASS(ECCVMLookupRelationImpl, ECCVMFlavor);
} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ polynomials,
LENGTH - 1 // left-shiftable polynomial sub-relation
};

// Max among {SUBRELATION_PARTIAL_LENGTH + SUBRELATION_WITNESS_DEGREE}
static constexpr size_t ZK_RELATION_LENGTH = 17;

static constexpr std::array<bool, 2> SUBRELATION_LINEARLY_INDEPENDENT = { true, false };

template <typename AllValues> static bool operation_exists_at_row(const AllValues& row)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
namespace bb {

template class ECCVMMSMRelationImpl<grumpkin::fr>;
DEFINE_SUMCHECK_RELATION_CLASS(ECCVMMSMRelationImpl, ECCVMFlavor);
DEFINE_ZK_SUMCHECK_RELATION_CLASS(ECCVMMSMRelationImpl, ECCVMFlavor);

} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,19 @@ namespace bb {
template <typename FF_> class ECCVMMSMRelationImpl {
public:
using FF = FF_;

static constexpr std::array<size_t, 36> SUBRELATION_PARTIAL_LENGTHS{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 };
/**
* @brief For ZK-Flavors: Upper bound on the degrees of subrelations considered as polynomials only in witness
polynomials,
* @brief Upper bound on the degrees of subrelations considered as polynomials only in witness polynomials,
* i.e. all selectors and public polynomials are treated as constants. The subrelation witness degree does not
* exceed the subrelation partial degree given by SUBRELATION_PARTIAL_LENGTH - 1.
*/
static constexpr std::array<size_t, 36> SUBRELATION_WITNESS_DEGREES{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 };
// Max among {SUBRELATION_PARTIAL_LENGTH + SUBRELATION_WITNESS_DEGREE}
static constexpr size_t ZK_RELATION_LENGTH = 15;

template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
static void accumulate(ContainerOverSubrelations& accumulator,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

namespace bb {
template class ECCVMPointTableRelationImpl<grumpkin::fr>;
DEFINE_SUMCHECK_RELATION_CLASS(ECCVMPointTableRelationImpl, ECCVMFlavor);
DEFINE_ZK_SUMCHECK_RELATION_CLASS(ECCVMPointTableRelationImpl, ECCVMFlavor);

} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace bb {
template <typename FF_> class ECCVMPointTableRelationImpl {
public:
using FF = FF_;
static constexpr size_t ZK_RELATION_LENGTH = 11;

static constexpr std::array<size_t, 6> SUBRELATION_PARTIAL_LENGTHS{ 6, 6, 6, 6, 6, 6 };
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace bb {
template class ECCVMSetRelationImpl<grumpkin::fr>;
DEFINE_SUMCHECK_RELATION_CLASS(ECCVMSetRelationImpl, ECCVMFlavor);
DEFINE_ZK_SUMCHECK_RELATION_CLASS(ECCVMSetRelationImpl, ECCVMFlavor);
DEFINE_SUMCHECK_PERMUTATION_CLASS(ECCVMSetRelationImpl, ECCVMFlavor);

} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ template <typename FF_> class ECCVMSetRelationImpl {
using FF = FF_;

static constexpr std::array<size_t, 2> SUBRELATION_PARTIAL_LENGTHS{
21, // grand product construction sub-relation
21 // left-shiftable polynomial sub-relation
22, // grand product construction sub-relation
3 // left-shiftable polynomial sub-relation
};
/**
* @brief For ZK-Flavors: Upper bound on the degrees of subrelations considered as polynomials only in witness
Expand All @@ -23,10 +23,13 @@ polynomials,
* exceed the subrelation partial degree given by SUBRELATION_PARTIAL_LENGTH - 1.
*/
static constexpr std::array<size_t, 2> SUBRELATION_WITNESS_DEGREES{
20, // grand product construction sub-relation
20 // left-shiftable polynomial sub-relation
21, // grand product construction sub-relation
1 // left-shiftable polynomial sub-relation
};

// Max among {SUBRELATION_PARTIAL_LENGTH + SUBRELATION_WITNESS_DEGREE}
static constexpr size_t ZK_RELATION_LENGTH = 43;

template <typename Accumulator> static Accumulator convert_to_wnaf(const auto& s0, const auto& s1)
{
auto t = s0 + s0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,10 @@ Accumulator ECCVMSetRelationImpl<FF>::compute_grand_product_denominator(const Al
// FF endomorphism_base_field_shift = FF::cube_root_of_unity();
FF endomorphism_base_field_shift = FF(bb::fq::cube_root_of_unity());

auto transcript_input1 = transcript_pc + transcript_Px * beta + transcript_Py * beta_sqr + z1 * beta_cube;
auto transcript_input1 =
transcript_pc + transcript_Px * beta + transcript_Py * beta_sqr + z1 * beta_cube; // degree = 1
auto transcript_input2 = (transcript_pc - 1) + transcript_Px * endomorphism_base_field_shift * beta -
transcript_Py * beta_sqr + z2 * beta_cube;
transcript_Py * beta_sqr + z2 * beta_cube; // degree = 2

// | q_mul | z2_zero | z1_zero | base_infinity | lookup |
// | ----- | ------- | ------- | ------------- |----------------------- |
Expand All @@ -326,15 +327,15 @@ Accumulator ECCVMSetRelationImpl<FF>::compute_grand_product_denominator(const Al
// | 1 | 0 | 1 | 1 | 1 |
// | 1 | 1 | 0 | 1 | 1 |
// | 1 | 1 | 1 | 1 | 1 |
transcript_input1 = (transcript_input1 + gamma) * lookup_first + (-lookup_first + 1);
transcript_input2 = (transcript_input2 + gamma) * lookup_second + (-lookup_second + 1);
transcript_input1 = (transcript_input1 + gamma) * lookup_first + (-lookup_first + 1); // degree 2
transcript_input2 = (transcript_input2 + gamma) * lookup_second + (-lookup_second + 1); // degree 3

// transcript_product = degree 3
// transcript_product = degree 6
auto transcript_product = (transcript_input1 * transcript_input2) * (-base_infinity + 1) + base_infinity;

// point_table_init_write = degree 4
// point_table_init_write = degree 7
auto point_table_init_write = transcript_mul * transcript_product + (-transcript_mul + 1);
denominator *= point_table_init_write; // degree-14
denominator *= point_table_init_write; // degree 17

// auto point_table_init_write_1 = transcript_mul * transcript_input1 + (-transcript_mul + 1);
// denominator *= point_table_init_write_1; // degree-11
Expand Down Expand Up @@ -391,25 +392,28 @@ void ECCVMSetRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulator
{
using Accumulator = typename std::tuple_element_t<0, ContainerOverSubrelations>;
using View = typename Accumulator::View;
using ShortView = typename std::tuple_element_t<1, ContainerOverSubrelations>::View;

// degree-11
Accumulator numerator_evaluation = compute_grand_product_numerator<Accumulator>(in, params);

// degree-17
// degree-20
Accumulator denominator_evaluation = compute_grand_product_denominator<Accumulator>(in, params);

const auto& lagrange_first = View(in.lagrange_first);
const auto& lagrange_last = View(in.lagrange_last);
const auto& lagrange_last_short = ShortView(in.lagrange_last);

const auto& z_perm = View(in.z_perm);
const auto& z_perm_shift = View(in.z_perm_shift);
const auto& z_perm_shift_short = ShortView(in.z_perm_shift);

// degree-18
// degree-21
std::get<0>(accumulator) +=
((z_perm + lagrange_first) * numerator_evaluation - (z_perm_shift + lagrange_last) * denominator_evaluation) *
scaling_factor;

// Contribution (2)
std::get<1>(accumulator) += (lagrange_last * z_perm_shift) * scaling_factor;
std::get<1>(accumulator) += lagrange_last_short * z_perm_shift_short * scaling_factor;
}
} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@

namespace bb {
template class ECCVMTranscriptRelationImpl<grumpkin::fr>;
DEFINE_SUMCHECK_RELATION_CLASS(ECCVMTranscriptRelationImpl, ECCVMFlavor);
DEFINE_ZK_SUMCHECK_RELATION_CLASS(ECCVMTranscriptRelationImpl, ECCVMFlavor);
} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,17 @@ template <typename FF_> class ECCVMTranscriptRelationImpl {
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
};
/**
* @brief For ZK-Flavors: Upper bound on the degrees of subrelations considered as polynomials only in witness
polynomials,
* i.e. all selectors and public polynomials are treated as constants. The subrelation witness degree does not
* @brief Upper bound on the degrees of subrelations considered as polynomials only in
witness polynomials,
* i.e. all selectors and public polynomials are treated as constants. The subrelation witness degree does
not
* exceed the subrelation partial degree given by SUBRELATION_PARTIAL_LENGTH - 1.
*/
static constexpr std::array<size_t, 25> SUBRELATION_WITNESS_DEGREES{
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
};

// Max among {SUBRELATION_PARTIAL_LENGTH + SUBRELATION_WITNESS_DEGREE}
static constexpr size_t ZK_RELATION_LENGTH = 15;
template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
static void accumulate(ContainerOverSubrelations& accumulator,
const AllEntities& in,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
namespace bb {

template class ECCVMWnafRelationImpl<grumpkin::fr>;
DEFINE_SUMCHECK_RELATION_CLASS(ECCVMWnafRelationImpl, ECCVMFlavor);
DEFINE_ZK_SUMCHECK_RELATION_CLASS(ECCVMWnafRelationImpl, ECCVMFlavor);

} // namespace bb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ polynomials,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
};

// Max among {SUBRELATION_PARTIAL_LENGTH + SUBRELATION_WITNESS_DEGREE}
static constexpr size_t ZK_RELATION_LENGTH = 9;

template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
static void accumulate(ContainerOverSubrelations& accumulator,
const AllEntities& in,
Expand Down
Loading

1 comment on commit c7d4572

@AztecBot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'C++ Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: c7d4572 Previous: cb58490 Ratio
wasmClientIVCBench/Full/6 92142.76948700001 ms/iter 87461.171806 ms/iter 1.05

This comment was automatically generated by workflow using github-action-benchmark.

CC: @ludamad @codygunton

Please sign in to comment.