Skip to content

Commit

Permalink
test(benchmark): include FRI opening in benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
batzor committed Sep 5, 2024
1 parent 3d515ac commit 18cf9d5
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 61 deletions.
7 changes: 4 additions & 3 deletions benchmark/fri/fri_benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
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>
Expand Down Expand Up @@ -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 Down
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
94 changes: 63 additions & 31 deletions benchmark/fri/fri_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,70 +23,102 @@ 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) {
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));
reporter_.AddTime(vendor, base::TimeTicks::Now() - start);
return commit[1];
return commits_by_round[0][1];
}

F 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];
}

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_;
};

} // namespace tachyon::benchmark
Expand Down
87 changes: 60 additions & 27 deletions benchmark/fri/plonky3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,10 @@ fn get_pcs(log_blowup: usize, log_n: usize) -> (MyPcs, Challenger) {
}

fn do_test_fri<Val, Challenge, Challenger, P>(
(pcs, _challenger): &(P, Challenger),
degrees: Vec<usize>,
data: Vec<RowMajorMatrix<Val>>,
(pcs, challenger): &(P, Challenger),
degrees_by_round: Vec<Vec<usize>>,
data: *const Val,
batch_size: usize,
duration: *mut u64,
) -> *mut CppBabyBear
where
Expand All @@ -97,46 +98,78 @@ where
Challenger: Clone + CanObserve<P::Commitment> + FieldChallenger<Val>,
<P as Pcs<Challenge, Challenger>>::Commitment: Debug,
{
let domains: Vec<_> = degrees
let num_rounds = degrees_by_round.len();
let mut p_challenger = challenger.clone();

let domains_and_polys_by_round: Vec<Vec<_>> = degrees_by_round
.iter()
.map(|&degree| pcs.natural_domain_for_degree(degree))
.enumerate()
.map(|(r, degrees)| {
degrees
.iter()
.map(|&degree| {
let size = degree * batch_size;
let values: Vec<Val> = unsafe {
std::slice::from_raw_parts(data.add(r) as *mut Val, size).to_vec()
};
(
pcs.natural_domain_for_degree(degree),
RowMajorMatrix::<Val>::new(values, batch_size),
)
})
.collect()
})
.collect();
let domains_and_polys: Vec<(P::Domain, RowMajorMatrix<Val>)> =
domains.into_iter().zip(data.into_iter()).collect();

let start = Instant::now();
let (commit, _data) = pcs.commit(domains_and_polys);
let (commits_by_round, data_by_round): (Vec<_>, Vec<_>) = domains_and_polys_by_round
.iter()
.map(|domains_and_polys| pcs.commit(domains_and_polys.clone()))
.unzip();
assert_eq!(commits_by_round.len(), num_rounds);
assert_eq!(data_by_round.len(), num_rounds);
p_challenger.observe_slice(&commits_by_round);

let zeta: Challenge = p_challenger.sample_ext_element();

let points_by_round: Vec<_> = degrees_by_round
.iter()
.map(|log_degrees| vec![vec![zeta]; log_degrees.len()])
.collect();
let data_and_points = data_by_round.iter().zip(points_by_round).collect();
let (_opening_by_round, _proof) = pcs.open(data_and_points, &mut p_challenger);
unsafe {
duration.write(start.elapsed().as_micros() as u64);
}
Box::into_raw(Box::new(commit)) as *mut CppBabyBear
//TODO(batzor): return proof here for comparing results
Box::into_raw(Box::new(commits_by_round[0].clone())) as *mut CppBabyBear
}

#[no_mangle]
pub extern "C" fn run_fri_plonky3_baby_bear(
data: *const BabyBear,
raw_degrees: *const usize,
num_of_degrees: usize,
input_num: usize,
round_num: usize,
max_degree: usize,
batch_size: usize,
log_blowup: u32,
duration: *mut u64,
) -> *mut CppBabyBear {
let degrees =
unsafe { std::slice::from_raw_parts(raw_degrees as *mut usize, num_of_degrees).to_vec() };

let (pcs, challenger) = get_pcs(
log_blowup as usize,
log2_strict_usize(*degrees.last().unwrap()),
);

let polys: Vec<RowMajorMatrix<Val>> = degrees
.iter()
.map(|&degree| {
let size = degree * batch_size;
let values: Vec<BabyBear> =
unsafe { std::slice::from_raw_parts(data as *mut BabyBear, size).to_vec() };
RowMajorMatrix::<BabyBear>::new(values, batch_size)
let degrees_by_round: Vec<Vec<usize>> = (0..round_num)
.map(|r| {
(0..input_num)
.map(|i| max_degree >> (r + i))
.collect::<Vec<_>>()
})
.collect();
do_test_fri(&(pcs, challenger), degrees, polys, duration)

let (pcs, challenger) = get_pcs(log_blowup as usize, log2_strict_usize(max_degree));

do_test_fri(
&(pcs, challenger),
degrees_by_round,
data,
batch_size,
duration,
)
}

0 comments on commit 18cf9d5

Please sign in to comment.