Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • dragoon/komodo
  • a.stevan/komodo
  • c.heme/komodo
3 results
Show changes
Commits on Source (3)
.PHONY: fmt fmt-check check clippy test example show
.PHONY: fmt fmt-check check clippy test example show build-examples
DEFAULT_GOAL: fmt-check check clippy test
......@@ -32,3 +32,6 @@ show:
doc:
cargo doc --document-private-items --no-deps --open
build-examples:
cargo build --examples --release
......@@ -8,8 +8,8 @@ use scripts/formats.nu *
## atomic operations
```nushell
cargo run --example bench_field_operations -- --nb-measurements 1000 out> field.ndjson
cargo run --example bench_curve_group_operations -- --nb-measurements 1000 out> curve_group.ndjson
cargo run --release --example bench_field_operations -- --nb-measurements 1000 out> field.ndjson
cargo run --release --example bench_curve_group_operations -- --nb-measurements 1000 out> curve_group.ndjson
```
```nushell
use scripts/parse.nu read-atomic-ops
......@@ -39,7 +39,7 @@ gplt multi_bar --title "complex curve group operations" -l "time (in ns)" (
## linear algebra
```nushell
let sizes = seq 0 7 | each { 2 ** $in }
cargo run --example bench_linalg -- --nb-measurements 10 ...$sizes out> linalg.ndjson
cargo run --release --example bench_linalg -- --nb-measurements 10 ...$sizes out> linalg.ndjson
| save --force linalg.ndjson
```
```nushell
......@@ -78,7 +78,7 @@ for graph in [
## trusted setup
```nushell
let degrees = seq 0 13 | each { 2 ** $in }
cargo run --example bench_setup -- --nb-measurements 10 ...$degrees out> setup.ndjson
cargo run --release --example bench_setup -- --nb-measurements 10 ...$degrees out> setup.ndjson
```
```nushell
gplt plot ...[
......@@ -116,7 +116,7 @@ gplt plot ...[
## commit
```nushell
let degrees = seq 0 15 | each { 2 ** $in }
cargo run --example bench_commit -- --nb-measurements 10 ...$degrees out> commit.ndjson
cargo run --release --example bench_commit -- --nb-measurements 10 ...$degrees out> commit.ndjson
```
```nushell
gplt plot ...[
......@@ -147,76 +147,47 @@ gplt plot ...[
```
## end-to-end benchmarks
```nushell
use scripts/plot.nu [
into-duration-tick-labels,
into-filesize-tick-labels,
into-axis-options,
COMMON_OPTIONS,
]
```
### recoding
```nushell
"" out> recoding.ndjson
[2, 4, 8, 16] | each { |k|
cargo run --example bench_recoding -- ...[
cargo run --release --example bench_recoding -- ...[
--nb-measurements 10
...[100, 1_000, 10_000]
...(seq 0 18 | each { 512 * 2 ** $in })
--shards $k
--ks $k
] | from ndnuon | to ndjson out>> recoding.ndjson
}
```
```nushell
gplt plot --title "k-recoding with k = #shards" --x-label '\#bytes' --y-label "time (in ms)" (
open recoding.ndjson
| ns-to-ms $.times
| compute-stats $.times
| update label { from nuon }
| flatten --all label
| insert case { $"($in.name) / ($in.shards)" }
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| group-by case --to-table
| rename --column { group: "name", items: "points" }
| insert style {|it|
let g = $it.name | parse "{c} / {s}" | into record | into int s
let c = match $g.c {
"BLS12-381" => "blue"
"BN-254" => "orange"
"PALLAS" => "green"
_ => "gray"
}
let t = match $g.s {
2 => "dotted"
4 => "dashdot"
8 => "dashed"
16 => "solid"
_ => "loosely dotted"
}
{ color: $c, line: { type: $t } }
}
| to json
)
```
an alternate plot
```nushell
gplt plot ...[
# --title "k-recoding with k = #shards"
--x-label '\#bytes'
--y-label "time (in ms)"
(
open recoding.ndjson
| ns-to-ms $.times
| compute-stats $.times
| update label { from nuon }
| flatten --all label
| where name == "BLS12-381"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| select shards x y e
| group-by shards --to-table
| reject items.shards
| rename --column { group: "name", items: "points" }
| update name { $"$k = ($in)$"}
| to json
)
--fullscreen
--dpi 150
--fig-size ...[16, 9]
--font ({ size: 30, family: serif, sans-serif: Helvetica } | to json)
--use-tex
let graphs = open recoding.ndjson
| ns-to-ms $.times
| compute-stats $.times
| update label { from nuon }
| flatten --all label
| where name == "BLS12-381"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| select shards x y e
| group-by shards --to-table
| reject items.shards
| rename --column { group: "name", items: "points" }
| update name { $"$k = ($in)$"}
gplt plot ($graphs | to json) ...[
# --y-label "time (in ms)"
...($graphs.points | flatten | into-axis-options)
--no-legend
...$COMMON_OPTIONS
# --save recoding.pdf
]
```
......@@ -226,71 +197,61 @@ gplt plot ...[
"" out> fec.ndjson
[2, 4, 8, 16] | each { |k|
cargo run --example bench_fec -- ...[
...[100, 1_000, 10_000]
cargo run --release --example bench_fec -- ...[
...(seq 0 18 | each { 512 * 2 ** $in })
--encoding vandermonde
-k $k
-n 1
--nb-measurements 100
--nb-measurements 10
] | from ndnuon | to ndjson out>> fec.ndjson
}
```
```nushell
gplt plot ...[
let graphs = open fec.ndjson
| update label { from json }
| flatten label
| ns-to-ms times
| compute-stats times
| where name == "BLS12-381" and step == "encode"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| select k x y e
| sort-by x
| group-by k --to-table
| reject items.k
| rename --column { group: "name", items: "points" }
| update name { $"$k = ($in)$" }
gplt plot ($graphs | to json) ...[
# --title "1-encoding"
--x-label '\#bytes'
--y-label "time (in ms)"
(
open fec.ndjson
| update label { from json }
| flatten label
| ns-to-ms times
| compute-stats times
| where name == "BLS12-381" and step == "encode"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| select k x y e
| group-by k --to-table
| reject items.k
| rename --column { group: "name", items: "points" }
| update name { $"$k = ($in)$" }
| to json
)
--fullscreen
--dpi 150
--fig-size ...[16, 9]
--font ({ size: 30, family: serif, sans-serif: Helvetica } | to json)
--use-tex
...($graphs.points | flatten | into-axis-options -y "duration")
...$COMMON_OPTIONS
# --save encoding.pdf
]
gplt plot ...[
# --title "k-encoding"
--x-label '\#bytes'
let graphs = open fec.ndjson
| update label { from json }
| flatten label
| ns-to-ms times
| compute-stats times
| where name == "BLS12-381" and step == "decode"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| select k x y e
| sort-by x
| group-by k --to-table
| reject items.k
| rename --column { group: "name", items: "points" }
| update name { $"$k = ($in)$" }
gplt plot ($graphs | to json) ...[
# --title "k-decoding"
--y-label "time (in ms)"
(
open fec.ndjson
| update label { from json }
| flatten label
| ns-to-ms times
| compute-stats times
| where name == "BLS12-381" and step == "decode"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| select k x y e
| group-by k --to-table
| reject items.k
| rename --column { group: "name", items: "points" }
| update name { $"$k = ($in)$" }
| to json
)
--fullscreen
--dpi 150
--fig-size ...[16, 9]
--font ({ size: 30, family: serif, sans-serif: Helvetica } | to json)
--use-tex
...($graphs.points | flatten | into-axis-options -y "duration")
--no-legend
...$COMMON_OPTIONS
# --save decoding.pdf
]
let x = open fec.ndjson
let graphs = open fec.ndjson
| update label { from json }
| flatten label
| insert foo { $"($in.name) / ($in.k) / ($in.bytes)" }
......@@ -302,30 +263,183 @@ let x = open fec.ndjson
}
| flatten --all
| reject group foo
| ns-to-ms times
| compute-stats times
| reject times
| where name == "BLS12-381"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| select k x y e
| sort-by x
| group-by k --to-table
| reject items.k
| rename --column { group: "name", items: "points" }
| update name { $"$k = ($in)$" }
gplt plot ...[
gplt plot ($graphs | to json) ...[
# --title "e2e: k-decoding + 1-encoding"
--x-label '\#bytes'
--y-label "time (in ms)"
(
$x
| ns-to-ms times
| compute-stats times
| reject times
| where name == "BLS12-381"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| select k x y e
| group-by k --to-table
| reject items.k
| rename --column { group: "name", items: "points" }
| update name { $"$k = ($in)$" }
| to json
)
--fullscreen
--dpi 150
--fig-size ...[16, 9]
--font ({ size: 30, family: serif, sans-serif: Helvetica } | to json)
--use-tex
...($graphs.points | flatten | into-axis-options -y "duration")
--no-legend
...$COMMON_OPTIONS
# --save e2e.pdf
]
```
combined graph
```nushell
let true_recoding_graphs = open recoding.ndjson
| ns-to-ms $.times
| compute-stats $.times
| update label { from nuon }
| flatten --all label
| where name == "BLS12-381"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| select shards x y e
| sort-by x
| group-by shards --to-table
| insert style.color {|it|
match $it.items.shards.0 {
2 => "tab:blue"
4 => "tab:orange"
8 => "tab:green"
16 => "tab:red"
_ => "tab:grey"
}
}
| reject items.shards
| insert style.line.type "solid"
| rename --column { group: "name", items: "points" }
| update name { $"$k = ($in)$" }
let naive_recoding_graphs = open fec.ndjson
| update label { from json }
| flatten label
| insert key { $"($in.name) / ($in.k) / ($in.bytes)" }
| group-by key --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 key
| ns-to-ms times
| compute-stats times
| reject times
| where name == "BLS12-381"
| rename --column { bytes: "x", mean: "y", stddev: "e" }
| select k x y e
| sort-by x
| group-by k --to-table
| insert style.color {|it|
match $it.items.k.0 {
2 => "tab:blue"
4 => "tab:orange"
8 => "tab:green"
16 => "tab:red"
_ => "tab:grey"
}
}
| insert style.line.type "dashed"
| reject items.k
| rename --column { group: "name", items: "points" }
| reject name
let graphs = $true_recoding_graphs
| append $naive_recoding_graphs
| append {
name: "naive recoding ($k$-decoding + $1$-encoding)",
legend: "second",
points: [],
style: {
color: "grey",
line: {
type: "dashed",
marker: {
size: 0,
},
},
},
}
| append {
name: "true recoding ($k$-recoding)",
legend: "second",
points: [],
style: {
color: "grey",
line: {
type: "solid",
marker: {
size: 0,
},
},
},
}
gplt plot ($graphs | to json) ...[
...($graphs.points | flatten | into-axis-options -y "duration")
...$COMMON_OPTIONS
--legend-loc "upper left" "lower right"
# --save comparison.png
]
```
ratio graph
```nushell
let true_recoding_graphs = open recoding.ndjson
| ns-to-ms times
| compute-stats $.times
| update label { from nuon }
| flatten --all label
| where name == "BLS12-381"
| select shards bytes mean
| rename --column { shards: "k" }
let naive_recoding_graphs = open fec.ndjson
| update label { from json }
| flatten label
| insert key { $"($in.name) / ($in.k) / ($in.bytes)" }
| group-by key --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 key
| ns-to-ms times
| compute-stats times
| where name == "BLS12-381"
| select k bytes mean
| uniq
let graphs = $true_recoding_graphs
| rename --column { mean: "true" }
| insert key { $"($in.k) ($in.bytes)" }
| join ($naive_recoding_graphs | rename --column { mean: "naive" } | insert key { $"($in.k) ($in.bytes)" }) key
| select k bytes $.true naive
| sort-by k bytes
| insert cmp { $in.naive / $in.true }
| rename --column { bytes: "x", cmp: "y" }
| select k x y
| group-by k --to-table
| insert style.color {|it|
match $it.items.k.0 {
2 => "tab:blue"
4 => "tab:orange"
8 => "tab:green"
16 => "tab:red"
_ => "tab:grey"
}
}
| reject items.k
| rename --column { group: "name", items: "points" }
| update name { $"$k = ($in)$" }
gplt plot ($graphs | to json) ...[
...($graphs.points | flatten | into-axis-options)
...$COMMON_OPTIONS
--legend-loc "upper right"
# --save ratio.png
]
```
......@@ -17,6 +17,7 @@
//! | ark_bw6_761 | 761 | 377 | 50.5 |
//! | ark_cp6_782 | 782 | 377 | 51.8 |
//! | ark_curve25519 | 255 | 253 | 0.8 |
//! | ark_ed25519 | 255 | 253 | 0.8 |
//! | ark_ed_on_bls12_377 | 253 | 251 | 0.8 |
//! | ark_ed_on_bls12_381 | 255 | 252 | 1.2 |
//! | ark_ed_on_bls12_381_bandersnatch | 255 | 253 | 0.8 |
......@@ -25,7 +26,6 @@
//! | ark_ed_on_cp6_782 | 377 | 374 | 0.8 |
//! | ark_ed_on_mnt4_298 | 298 | 296 | 0.7 |
//! | ark_ed_on_mnt4_753 | 753 | 750 | 0.4 |
//! | ark_ed25519 | 255 | 253 | 0.8 |
//! | ark_mnt4_298 | 298 | 298 | 0 |
//! | ark_mnt4_753 | 753 | 753 | 0 |
//! | ark_mnt6_298 | 298 | 298 | 0 |
......
/// # Example
/// - build the example for best performance
/// ```shell
/// cargo build --release --example inbreeding
/// ```
/// - run the experiment
/// ```nushell
/// const NB_BYTES = 1_024 * 10
/// const K = 10
/// const N = 2 * $K
/// const NB_MEASUREMENTS = 1_000
/// const MEASUREMENT_SCHEDULE = 1
/// const MAX_T = 150
///
/// cargo run --example inbreeding -- ...[
/// ./target/release/examples/inbreeding ...[
/// $NB_BYTES,
/// -k $K
/// -n $N
/// --nb-measurements $NB_MEASUREMENTS
/// --measurement-schedule $MEASUREMENT_SCHEDULE
/// -t $MAX_T
/// --test-case end-to-end
/// ] | lines | into float | save --force baseline.nuon
///
/// seq 2 $K | reverse | each {|r|
/// let inbreeding = cargo run --example inbreeding -- ...[
/// seq 1 $K | reverse | each {|r|
/// let inbreeding = ./target/release/examples/inbreeding ...[
/// $NB_BYTES,
/// -k $K
/// -n $N
/// --nb-measurements $NB_MEASUREMENTS
/// --measurement-schedule $MEASUREMENT_SCHEDULE
/// -t $MAX_T
/// --test-case recoding
/// -r $r
......@@ -49,26 +56,26 @@
/// $smooth
/// | insert name {|it|
/// let r = if $it.r == $k { "k" } else { $"k - ($k - $it.r)" }
/// $"$r = ($r)$"
/// $"$\\sigma = ($r)$"
/// }
/// # | append ($raw | insert name null | insert style { line: { alpha: 0.1 } })
/// | update inbreeding {|it|
/// let l = $it.inbreeding | length
/// $it.inbreeding | wrap y | merge (seq 1 $l | wrap x) | insert e 0
/// $it.inbreeding | wrap y | merge (seq 0 $l | wrap x) | insert e 0
/// }
/// | rename --column { inbreeding: "points" }
/// | insert style.color {|it|
/// match $it.r {
/// 10 => "red",
/// 9 => "orange",
/// 8 => "yellow",
/// 7 => "blue",
/// 6 => "purple",
/// 5 => "green",
/// 4 => "cyan",
/// 3 => "black",
/// 2 => "magenta",
/// _ => "gray",
/// 10 => "tab:red",
/// 9 => "tab:orange",
/// 8 => "tab:olive",
/// 7 => "tab:blue",
/// 6 => "tab:purple",
/// 5 => "tab:green",
/// 4 => "tab:cyan",
/// 3 => "tab:brown",
/// 2 => "tab:pink",
/// _ => "tab:gray",
/// }
/// }
/// | reject r
......@@ -85,7 +92,7 @@
/// --fullscreen
/// # --title "diversity over time when recoding shards $r$ shards"
/// --x-label "time (in nb of steps)"
/// --y-label "diversity"
/// --y-label "diversity $\\delta$"
/// --dpi 150
/// --fig-size ...[16, 5]
/// --font ({ size: 15, family: serif, sans-serif: Helvetica } | to json)
......@@ -99,7 +106,7 @@ use std::process::exit;
use ark_ff::PrimeField;
use clap::{Parser, ValueEnum};
use indicatif::ProgressBar;
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use komodo::{
error::KomodoError,
fec::{self, Shard},
......@@ -125,36 +132,56 @@ fn measure_inbreeding<F: PrimeField>(
shards: &[Shard<F>],
k: usize,
nb_measurements: usize,
mp: &MultiProgress,
sty: &ProgressStyle,
rng: &mut impl RngCore,
) -> f64 {
let mut s: Vec<_> = shards.to_vec();
let mut count = 0;
let pb = mp.add(ProgressBar::new(nb_measurements as u64));
pb.set_style(sty.clone());
pb.set_message("measure");
for _ in 0..nb_measurements {
// get any k of the shards
s.shuffle(rng);
if fec::decode(s.iter().take(k).cloned().collect()).is_ok() {
count += 1;
}
pb.inc(1);
}
count as f64 / nb_measurements as f64
}
fn end_to_end<F: PrimeField>(
fn end_to_end<F, Fun>(
bytes: &[u8],
k: usize,
n: usize,
max_t: usize,
nb_measurements: usize,
measurement_schedule: Fun,
rng: &mut impl RngCore,
) -> Result<(), KomodoError> {
) -> Result<(), KomodoError>
where
F: PrimeField,
Fun: Fn(usize) -> bool,
{
let original_shards = setup(bytes, k, n)?;
let mut shards = original_shards.clone();
let pb = ProgressBar::new(max_t as u64);
for _ in 0..max_t {
let inbreeding = measure_inbreeding(&shards, k, nb_measurements, rng);
println!("{}", inbreeding);
let mp = MultiProgress::new();
let sty = ProgressStyle::with_template("{msg}: {bar:40.cyan/blue} {pos:>7}/{len:7}")
.unwrap()
.progress_chars("##-");
let pb = mp.add(ProgressBar::new(max_t as u64));
pb.set_style(sty.clone());
pb.set_message("main");
for t in 0..=max_t {
if measurement_schedule(t) {
let inbreeding = measure_inbreeding(&shards, k, nb_measurements, &mp, &sty, rng);
println!("{}", inbreeding);
}
// decode the data
let data = fec::decode(original_shards.clone())?;
......@@ -171,26 +198,40 @@ fn end_to_end<F: PrimeField>(
Ok(())
}
fn recoding<F: PrimeField>(
#[allow(clippy::too_many_arguments)]
fn recoding<F, Fun>(
bytes: &[u8],
k: usize,
n: usize,
max_t: usize,
nb_shards_to_recode: usize,
nb_measurements: usize,
measurement_schedule: Fun,
rng: &mut impl RngCore,
) -> Result<(), KomodoError> {
let mut shards = setup(bytes, k, n)?;
) -> Result<(), KomodoError>
where
F: PrimeField,
Fun: Fn(usize) -> bool,
{
let mut shards = setup::<F>(bytes, k, n)?;
let pb = ProgressBar::new(max_t as u64);
for _ in 0..max_t {
let inbreeding = measure_inbreeding(&shards, k, nb_measurements, rng);
println!("{}", inbreeding);
let mp = MultiProgress::new();
let sty = ProgressStyle::with_template("{msg}: {bar:40.cyan/blue} {pos:>7}/{len:7}")
.unwrap()
.progress_chars("##-");
let pb = mp.add(ProgressBar::new(max_t as u64));
pb.set_style(sty.clone());
pb.set_message("main");
for t in 0..=max_t {
if measurement_schedule(t) {
let inbreeding = measure_inbreeding(&shards, k, nb_measurements, &mp, &sty, rng);
println!("{}", inbreeding);
}
// recode a new random shard
let coeffs: Vec<F> = (0..nb_shards_to_recode).map(|_| F::rand(rng)).collect();
shards.shuffle(rng);
let s: Vec<_> = shards.iter().take(nb_shards_to_recode).cloned().collect();
let new_shard = fec::recode_with_coeffs(&s, &coeffs).unwrap();
let new_shard = fec::recode_random(&s, rng).unwrap().unwrap();
shards.push(new_shard);
pb.inc(1);
......@@ -228,6 +269,9 @@ struct Cli {
/// the measurements
#[arg(long)]
nb_measurements: usize,
#[arg(long)]
measurement_schedule: usize,
}
fn main() {
......@@ -245,14 +289,22 @@ fn main() {
let bytes = random_bytes(cli.nb_bytes, &mut rng);
eprintln!(
"diversity will be measured every {} steps",
cli.measurement_schedule
);
let measurement_schedule = |t| t % cli.measurement_schedule == 0;
match cli.test_case {
TestCase::EndToEnd => {
let _ = end_to_end::<ark_pallas::Fr>(
eprintln!("naive: k = {}, n = {}", cli.k, cli.n);
let _ = end_to_end::<ark_pallas::Fr, _>(
&bytes,
cli.k,
cli.n,
cli.t,
cli.nb_measurements,
measurement_schedule,
&mut rng,
);
}
......@@ -262,13 +314,20 @@ fn main() {
exit(1);
}
let _ = recoding::<ark_pallas::Fr>(
eprintln!(
"true: k = {}, n = {}, sigma = {}",
cli.k,
cli.n,
cli.r.unwrap(),
);
let _ = recoding::<ark_pallas::Fr, _>(
&bytes,
cli.k,
cli.n,
cli.t,
cli.r.unwrap(),
cli.nb_measurements,
measurement_schedule,
&mut rng,
);
}
......
export const COMMON_OPTIONS = [
--x-scale log
--x-scale-base 2
--y-scale log
--x-ticks-rotation 45
--fullscreen
--dpi 150
--fig-size ...[16, 9]
--font '{ "size": 30, "family": "serif", "sans-serif": "Helvetica" }'
--use-tex
]
export def into-duration-tick-labels []: list<int> -> list<string> {
each { $in * 1ms } | each { to text }
}
export def into-filesize-tick-labels []: list<int> -> list<string> {
into filesize
| each {
if $in < 1000b {
format filesize iB
} else if $in < 1000000b {
format filesize KiB
} else {
format filesize MiB
}
}
| each { to text | str replace ".0 " " " }
}
export def into-axis-options [-y: string]: table<x: float, y: float> -> list<string> {
let input = $in
let xs = $input | flatten | get x | uniq
let options = [
--x-lim ($xs | first) ($xs | last)
--x-ticks ...$xs
--x-tick-labels ...($xs | into-filesize-tick-labels)
]
let ys = $input | flatten | get y
let y_ticks = seq ($ys | math min | math log 10 | math ceil | $in - 1) ($ys | math max | math log 10 | math floor)
| into float
| each { 10 ** $in }
let y_tick_labels = match $y {
"duration" => ($y_ticks | into-duration-tick-labels),
"plain" => $y_ticks,
_ => {
print $"warning: ($y) option is unknown for -y"
$y_ticks
},
}
$options | append [
--y-ticks ...$y_ticks
--y-tick-labels ...$y_tick_labels
]
}