Skip to content
Snippets Groups Projects
Commit 392f640a authored by STEVAN Antoine's avatar STEVAN Antoine :crab:
Browse files

add a "fec" bench (dragoon/komodo!93)

this MR adds
- `examples/benches/bench_fec.rs` to the list of example benches
- instructions on how to run the new benchmark and plot the results

## results
![encoding](/uploads/d474aa6f39ea20c6b346fb17d2e7ecdc/encoding.png)
![decoding](/uploads/061944e49f02541ea93ac0de9547ce37/decoding.png)
![e2e](/uploads/bb27f4bb6290c4697a65faa59a0ac4e0/e2e.png)
parent 89c6377d
No related branches found
No related tags found
No related merge requests found
......@@ -78,3 +78,7 @@ path = "examples/benches/linalg.rs"
[[example]]
name = "bench_recoding"
path = "examples/benches/recoding.rs"
[[example]]
name = "bench_fec"
path = "examples/benches/fec.rs"
......@@ -166,3 +166,73 @@ python scripts/plot/plot.py --title "recoding with k = 4" (
| to json
)
```
### FEC
```nushell
let rho = 1 / 2
"" out> fec.ndjson
[3, 5] | each { |k|
cargo run --example bench_fec -- ...[
...[100, 1_000, 10_000]
--encoding vandermonde
-k $k
-n ($k / $rho)
--nb-measurements 100
] | from ndnuon | to ndjson out>> fec.ndjson
}
```
```nushell
python scripts/plot/plot.py --title "encoding" --x-label "nb bytes" --y-label "time (in ms)" (
open fec.ndjson
| update label { from json }
| flatten label
| ns-to-ms times
| compute-stats times
| insert foo { $"($in.name) / ($in.k)" }
| where step == "encode"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| group-by foo --to-table
| rename --column { group: "name", items: "points" }
| to json
)
python scripts/plot/plot.py --title "decoding" --x-label "nb bytes" --y-label "time (in ms)" (
open fec.ndjson
| update label { from json }
| flatten label
| ns-to-ms times
| compute-stats times
| insert foo { $"($in.name) / ($in.k)" }
| where step == "decode"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| group-by foo --to-table
| rename --column { group: "name", items: "points" }
| to json
)
let x = open fec.ndjson
| update label { from json }
| flatten label
| insert foo { $"($in.name) / ($in.k) / ($in.bytes)" }
| group-by foo --to-table
| update items {|it|
$it.items
| update step e2e
| update times { $it.items.0.times | zip $it.items.1.times | each { $in.0 + $in.1 } }
}
| flatten --all
| reject group foo
python scripts/plot/plot.py --title "e2e" --x-label "nb bytes" --y-label "time (in ms)" (
$x
| ns-to-ms times
| compute-stats times
| insert foo { $"($in.name) / ($in.k)" }
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| group-by foo --to-table
| rename --column { group: "name", items: "points" }
| to json
)
```
// see `examples/benches/README.md`
use ark_ff::PrimeField;
use clap::{arg, command, Parser, ValueEnum};
use komodo::{fec, linalg::Matrix};
use plnk::Bencher;
use rand::{rngs::ThreadRng, thread_rng, Rng, RngCore};
fn random_bytes(n: usize, rng: &mut ThreadRng) -> Vec<u8> {
(0..n).map(|_| rng.gen::<u8>()).collect()
}
fn build_encoding_mat<F: PrimeField>(
k: usize,
n: usize,
encoding: &Encoding,
rng: &mut impl RngCore,
) -> Matrix<F> {
match encoding {
Encoding::Random => Matrix::random(k, n, rng),
Encoding::Vandermonde => {
let points: Vec<F> = (0..n)
.map(|i| F::from_le_bytes_mod_order(&i.to_le_bytes()))
.collect();
Matrix::vandermonde_unchecked(&points, k)
}
}
}
fn template<F: PrimeField>(b: &Bencher, nb_bytes: usize, k: usize, n: usize, encoding: &Encoding) {
let mut rng = thread_rng();
let encoding_mat = build_encoding_mat(k, n, encoding, &mut rng);
plnk::bench(
b,
&format!(
r#"{{"bytes": {}, "step": "encode", "k": {}, "n": {}}}"#,
nb_bytes, k, n
),
|| {
let bytes = random_bytes(nb_bytes, &mut rng);
plnk::timeit(|| fec::encode::<F>(&bytes, &encoding_mat).unwrap())
},
);
plnk::bench(
b,
&format!(
r#"{{"bytes": {}, "step": "decode", "k": {}, "n": {}}}"#,
nb_bytes, k, n
),
|| {
let bytes = random_bytes(nb_bytes, &mut rng);
let shards = fec::encode::<F>(&bytes, &encoding_mat).unwrap();
plnk::timeit(|| fec::decode::<F>(shards.clone()).unwrap())
},
);
}
#[derive(ValueEnum, Clone)]
enum Encoding {
Vandermonde,
Random,
}
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
/// the sizes of the data to consider
#[arg(num_args = 1.., value_delimiter = ' ')]
sizes: Vec<usize>,
#[arg(short, long)]
encoding: Encoding,
#[arg(short)]
k: usize,
#[arg(short)]
n: usize,
/// the number of measurements to repeat each case, larger values will reduce the variance of
/// the measurements
#[arg(long)]
nb_measurements: usize,
}
fn main() {
let cli = Cli::parse();
let b = plnk::Bencher::new(cli.nb_measurements);
for n in cli.sizes {
template::<ark_bls12_381::Fr>(&b.with_name("BLS12-381"), n, cli.k, cli.n, &cli.encoding);
template::<ark_bn254::Fr>(&b.with_name("BN-254"), n, cli.k, cli.n, &cli.encoding);
template::<ark_pallas::Fr>(&b.with_name("PALLAS"), n, cli.k, cli.n, &cli.encoding);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment