Skip to content
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

test: add fri opening benchmark #533

Merged
merged 12 commits into from
Sep 11, 2024
2 changes: 1 addition & 1 deletion benchmark/fft_batch/fft_batch_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class FFTBatchRunner {
Domain::Create(static_cast<size_t>(input.rows()));
base::TimeTicks start = base::TimeTicks::Now();
if (run_coset_lde) {
domain->CosetLDEBatch(result, 0, F::Zero());
result = domain->CosetLDEBatch(result, 0, F::Zero());
} else {
domain->FFTBatch(result);
}
Expand Down
4 changes: 3 additions & 1 deletion benchmark/fft_batch/plonky3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ pub extern "C" fn run_coset_lde_batch_plonky3_baby_bear(

let start = Instant::now();
let shift = BabyBear::zero();
let dft_result = dft.coset_lde_batch(messages, 0, shift).to_row_major_matrix();
let dft_result = dft
.coset_lde_batch(messages, 0, shift)
.to_row_major_matrix();
unsafe {
duration.write(start.elapsed().as_micros() as u64);
}
Expand Down
12 changes: 6 additions & 6 deletions benchmark/fri/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ CPU Caches:
```

```shell
bazel run -c opt --//:has_openmp --//:has_rtti --//:has_matplotlib //benchmark/fri:fri_benchmark -- -k 18 -k 19 -k 20 -k 21 -k 22 --batch_size 100 --input_num 4 --log_blowup 2 --vendor plonky3 --check_results
bazel run -c opt --//:has_openmp --//:has_rtti --//:has_matplotlib //benchmark/fri:fri_benchmark -- -k 18 -k 19 -k 20 -k 21 -k 22 --batch_size 100 --input_num 4 --round_num 4 --log_blowup 2 --vendor plonky3 --check_results
```

## On Intel i9-13900K

| Exponent | Tachyon | Plonky3 |
| :------- | ----------- | ------- |
| 18 | **1.49223** | 1.70032 |
| 19 | **2.84027** | 3.45716 |
| 20 | **5.77075** | 6.91221 |
| 21 | **11.6113** | 13.8407 |
| 22 | **23.3140** | 27.9832 |
| 18 | **2.97871** | 3.73433 |
| 19 | **5.76021** | 7.22556 |
| 20 | **11.2744** | 14.3306 |
| 21 | **22.5167** | 28.8935 |
| 22 | **47.6511** | 58.5402 |

![image](/benchmark/fri/fri_benchmark_ubuntu_i9.png)

Expand Down
22 changes: 12 additions & 10 deletions benchmark/fri/fri_benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@
namespace tachyon::benchmark {

extern "C" tachyon_baby_bear* run_fri_plonky3_baby_bear(
const tachyon_baby_bear* data, const size_t* raw_degrees,
size_t num_of_degrees, size_t batch_size, uint32_t log_blowup,
const tachyon_baby_bear* data, size_t input_num, size_t round_num,
size_t max_degree, size_t batch_size, uint32_t log_blowup,
uint64_t* duration);

template <typename Commitment>
void CheckResult(bool check_results, const Commitment& tachyon_result,
const Commitment& vendor_result) {
template <typename Result>
void CheckResult(bool check_results, const Result& tachyon_result,
const Result& vendor_result) {
if (check_results) {
CHECK_EQ(tachyon_result, vendor_result) << "Results not matched";
}
Expand Down Expand Up @@ -70,7 +70,7 @@ void Run(const FRIConfig& config) {
using Challenger = crypto::DuplexChallenger<Poseidon2, 16, kRate>;
using MyPCS = crypto::TwoAdicFRI<ExtF, MMCS, ChallengeMMCS, Challenger>;

PackedF::Init();
ExtF::Init();
ExtPackedF::Init();

crypto::Poseidon2Config<F> poseidon2_config =
Expand All @@ -95,6 +95,7 @@ void Run(const FRIConfig& config) {
crypto::FRIConfig<ChallengeMMCS> fri_config{config.log_blowup(), 10, 8,
challenge_mmcs};
MyPCS pcs = MyPCS(std::move(mmcs), std::move(fri_config));
Challenger challenger = Challenger(std::move(sponge));

SimpleReporter reporter;
std::string name;
Expand All @@ -106,7 +107,7 @@ void Run(const FRIConfig& config) {
config.exponents(),
[](uint32_t exponent) { return base::NumberToString(exponent); }));

FRIRunner runner(reporter, config, pcs);
FRIRunner runner(reporter, config, pcs, challenger);

std::vector<size_t> degrees = config.GetDegrees();

Expand All @@ -119,16 +120,17 @@ void Run(const FRIConfig& config) {
math::RowMajorMatrix<F> input =
math::RowMajorMatrix<F>::Random(degree, config.batch_size());

F tachyon_commit = runner.Run(Vendor::Tachyon(), input);
ExtF tachyon_result, vendor_result;
for (const Vendor vendor : config.vendors()) {
if (vendor.value() == Vendor::kPlonky3) {
F vendor_commit =
vendor_result =
runner.RunExternal(vendor, run_fri_plonky3_baby_bear, input);
CheckResult(config.check_results(), tachyon_commit, vendor_commit);
} else {
NOTREACHED();
}
}
tachyon_result = runner.Run(Vendor::Tachyon(), input);
CheckResult(config.check_results(), tachyon_result, vendor_result);
}

reporter.Show();
Expand Down
Binary file modified benchmark/fri/fri_benchmark_ubuntu_i9.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions benchmark/fri/fri_config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ FRIConfig::FRIConfig() {
.set_default_value(4)
.set_help(
"Specify the number of inputs in a single round. By default, 4.");
parser_.AddFlag<base::Flag<size_t>>(&round_num_)
.set_short_name("-r")
.set_long_name("--round_num")
.set_default_value(4)
.set_help("Specify the number of rounds. By default, 4.");
parser_.AddFlag<base::Flag<uint32_t>>(&log_blowup_)
.set_short_name("-l")
.set_long_name("--log_blowup")
Expand Down
2 changes: 2 additions & 0 deletions benchmark/fri/fri_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class FRIConfig : public Config {
const std::vector<uint32_t>& exponents() const { return exponents_; }
size_t batch_size() const { return batch_size_; }
size_t input_num() const { return input_num_; }
size_t round_num() const { return round_num_; }
uint32_t log_blowup() const { return log_blowup_; }

std::vector<size_t> GetDegrees() const;
Expand All @@ -32,6 +33,7 @@ class FRIConfig : public Config {
std::vector<uint32_t> exponents_;
size_t batch_size_;
size_t input_num_;
size_t round_num_;
uint32_t log_blowup_;
};

Expand Down
107 changes: 72 additions & 35 deletions benchmark/fri/fri_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,70 +23,107 @@ template <typename PCS>
class FRIRunner {
public:
using F = typename PCS::F;
using Domain = crypto::TwoAdicMultiplicativeCoset<F>;
using ExtF = typename PCS::ExtF;
using Domain = typename PCS::Domain;
using Challenger = typename PCS::Challenger;
using Commitment = typename PCS::Commitment;
using ProverData = typename PCS::ProverData;
using FRIProof = typename PCS::FRIProof;
using OpenedValues = typename PCS::OpenedValues;

typedef tachyon_baby_bear* (*ExternalFn)(const tachyon_baby_bear* data,
const size_t* degrees,
size_t num_of_degrees,
size_t batch_size,
size_t input_num, size_t round_num,
size_t max_degree, size_t batch_size,
uint32_t log_blowup,
uint64_t* duration);

FRIRunner(SimpleReporter& reporter, const FRIConfig& config, PCS& pcs)
: reporter_(reporter), config_(config), pcs_(pcs) {}
FRIRunner(SimpleReporter& reporter, const FRIConfig& config, PCS& pcs,
Challenger& challenger)
: reporter_(reporter),
config_(config),
pcs_(pcs),
challenger_(challenger) {}

F Run(Vendor vendor, const math::RowMajorMatrix<F>& input) {
ExtF Run(Vendor vendor, const math::RowMajorMatrix<F>& input) {
size_t max_degree = static_cast<size_t>(input.rows());
std::vector<size_t> degrees = GetInputDegrees(max_degree);

std::vector<math::RowMajorMatrix<F>> inner_polys =
base::Map(degrees, [this, input](size_t degree) {
math::RowMajorMatrix<F> ret =
Eigen::Map<const math::RowMajorMatrix<F>>(
&input.data()[0], degree, config_.batch_size());
return ret;
});

std::vector<Domain> inner_domains =
base::Map(degrees, [this](size_t degree) {
return this->pcs_.GetNaturalDomainForDegree(degree);
});
std::vector<Commitment> commits_by_round(config_.round_num());
std::vector<ProverData> data_by_round(config_.round_num());
std::vector<std::vector<Domain>> domains_by_round(config_.round_num());
std::vector<std::vector<math::RowMajorMatrix<F>>> inner_polys_by_round(
config_.round_num());

Challenger p_challenger = challenger_;

for (size_t round = 0; round < config_.round_num(); round++) {
std::vector<size_t> degrees = GetInputDegrees(max_degree, round);

domains_by_round[round] = base::Map(degrees, [this](size_t degree) {
return this->pcs_.GetNaturalDomainForDegree(degree);
});

inner_polys_by_round[round] =
base::Map(degrees, [this, round, input](size_t degree) {
math::RowMajorMatrix<F> ret =
Eigen::Map<const math::RowMajorMatrix<F>>(
&input.data()[round], degree, config_.batch_size());
return ret;
});
}

base::TimeTicks start = base::TimeTicks::Now();
typename PCS::Commitment commit;
typename PCS::ProverData prover_data;
CHECK(pcs_.Commit(inner_domains, inner_polys, &commit, &prover_data));
for (size_t round = 0; round < config_.round_num(); round++) {
CHECK(pcs_.Commit(domains_by_round[round], inner_polys_by_round[round],
&commits_by_round[round], &data_by_round[round]));
}
p_challenger.ObserveContainer2D(commits_by_round);
ExtF zeta = p_challenger.template SampleExtElement<ExtF>();

std::vector<std::vector<std::vector<ExtF>>> points_by_round(
config_.round_num());
for (size_t round = 0; round < config_.round_num(); ++round) {
points_by_round[round] =
std::vector<std::vector<ExtF>>(config_.input_num(), {zeta});
}
OpenedValues openings;
FRIProof fri_proof;
CHECK(pcs_.CreateOpeningProof(data_by_round, points_by_round, p_challenger,
&openings, &fri_proof, pow_witness_));
reporter_.AddTime(vendor, base::TimeTicks::Now() - start);
return commit[1];
return fri_proof.final_eval;
}

F RunExternal(Vendor vendor, ExternalFn fn,
const math::RowMajorMatrix<F>& input) {
ExtF RunExternal(Vendor vendor, ExternalFn fn,
const math::RowMajorMatrix<F>& input) {
size_t max_degree = static_cast<size_t>(input.rows());
std::vector<size_t> degrees = GetInputDegrees(max_degree);

uint64_t duration_in_us = 0;
tachyon_baby_bear* data =
fn(c::base::c_cast(input.data()), &degrees[0], degrees.size(),
config_.batch_size(), config_.log_blowup(), &duration_in_us);
fn(c::base::c_cast(input.data()), config_.input_num(),
config_.round_num(), max_degree, config_.batch_size(),
config_.log_blowup(), &duration_in_us);
reporter_.AddTime(vendor, base::Microseconds(duration_in_us));
return c::base::native_cast(data)[1];
pow_witness_ = c::base::native_cast(data)[0];
ExtF final_eval{
c::base::native_cast(data)[1], c::base::native_cast(data)[2],
c::base::native_cast(data)[3], c::base::native_cast(data)[4]};
return final_eval;
}

private:
std::vector<size_t> GetInputDegrees(size_t max_degree) {
std::vector<size_t> GetInputDegrees(size_t max_degree, size_t round) {
std::vector<size_t> degrees;
degrees.reserve(config_.input_num());
for (size_t d = max_degree >> (config_.input_num() - 1); d <= max_degree;
d <<= 1) {
degrees.push_back(d);
for (size_t i = 0; i < config_.input_num(); ++i) {
degrees.push_back(max_degree >> (i + round));
}
return degrees;
}

SimpleReporter& reporter_;
const FRIConfig& config_;
PCS& pcs_;
Challenger& challenger_;
std::optional<F> pow_witness_;
};

} // namespace tachyon::benchmark
Expand Down
Loading