From dad69f2c98b008b012f44764197d4ec6b4a9f1e0 Mon Sep 17 00:00:00 2001 From: STEVAN Antoine <antoine.stevan@isae-supaero.fr> Date: Fri, 12 Jul 2024 09:43:13 +0000 Subject: [PATCH] refactor the Nushell modules (dragoon/komodo!158) this MR is two-fold - it restructures the two main Nushell modules so that they are easier to read and use - it improves the "run" and "plot" modules for the benchmarks ## changelog - `.nushell/` is now renamed to `nu-utils/` - `benchmarks/` is now a valid Nushell module which exports a bunch of modules - `benchmarks linalg`: measure and plot linear algebra operations - `benchmarks setup`: measure and plot trusted setup building - `benchmarks commit`: measure and plot crafting commitments - `benchmarks recoding`: measure and plot the recoding of shards - `benchmarks fec`: measure and plot FEC operations, such as encoding and recoding, and allow combining these results with the pure recoding ones - the submodules of `benchmarks` typically have a `run` and a `plot` command, whith the exception of `benchmarks fec` which has a `run` module and multiple "plot" commands in `benchmarks fec plot` - the "run" commands will create a random temp file by default and ask for confirmation otherwise if the output file already exists, unless `--force` is used - snippetds in `benchmarks/README.md` have been updated --- .env.nu | 7 +- README.md | 2 +- benchmarks/.nushell/commit/plot.nu | 56 -------- benchmarks/.nushell/commit/run.nu | 20 --- benchmarks/.nushell/fec/run.nu | 28 ---- benchmarks/.nushell/recoding/plot.nu | 31 ----- benchmarks/.nushell/recoding/run.nu | 27 ---- benchmarks/.nushell/setup/run.nu | 20 --- benchmarks/README.md | 111 ++++----------- benchmarks/mod.nu | 5 + benchmarks/nu-lib/commit.nu | 106 +++++++++++++++ benchmarks/nu-lib/fec/mod.nu | 2 + benchmarks/{.nushell => nu-lib}/fec/plot.nu | 63 ++++++--- benchmarks/nu-lib/fec/run.nu | 54 ++++++++ benchmarks/nu-lib/linalg.nu | 127 ++++++++++++++++++ benchmarks/nu-lib/recoding.nu | 88 ++++++++++++ .../setup/plot.nu => nu-lib/setup.nu} | 60 ++++++++- examples/cli.nu | 2 +- komodo.nu | 2 +- {.nushell => nu-utils}/binary.nu | 0 {.nushell => nu-utils}/cargo.nu | 0 {.nushell => nu-utils}/color.nu | 0 {.nushell => nu-utils}/error.nu | 0 {.nushell => nu-utils}/formats.nu | 0 {.nushell => nu-utils}/fs.nu | 0 nu-utils/log.nu | 7 + {.nushell => nu-utils}/math.nu | 0 {.nushell => nu-utils}/mod.nu | 1 + {.nushell => nu-utils}/parse.nu | 0 {.nushell => nu-utils}/plot.nu | 0 tests/binary.nu | 2 +- tests/cli.nu | 2 +- tests/color.nu | 2 +- 33 files changed, 526 insertions(+), 299 deletions(-) delete mode 100644 benchmarks/.nushell/commit/plot.nu delete mode 100644 benchmarks/.nushell/commit/run.nu delete mode 100644 benchmarks/.nushell/fec/run.nu delete mode 100644 benchmarks/.nushell/recoding/plot.nu delete mode 100644 benchmarks/.nushell/recoding/run.nu delete mode 100644 benchmarks/.nushell/setup/run.nu create mode 100644 benchmarks/mod.nu create mode 100644 benchmarks/nu-lib/commit.nu create mode 100644 benchmarks/nu-lib/fec/mod.nu rename benchmarks/{.nushell => nu-lib}/fec/plot.nu (79%) create mode 100644 benchmarks/nu-lib/fec/run.nu create mode 100644 benchmarks/nu-lib/linalg.nu create mode 100644 benchmarks/nu-lib/recoding.nu rename benchmarks/{.nushell/setup/plot.nu => nu-lib/setup.nu} (51%) rename {.nushell => nu-utils}/binary.nu (100%) rename {.nushell => nu-utils}/cargo.nu (100%) rename {.nushell => nu-utils}/color.nu (100%) rename {.nushell => nu-utils}/error.nu (100%) rename {.nushell => nu-utils}/formats.nu (100%) rename {.nushell => nu-utils}/fs.nu (100%) create mode 100644 nu-utils/log.nu rename {.nushell => nu-utils}/math.nu (100%) rename {.nushell => nu-utils}/mod.nu (90%) rename {.nushell => nu-utils}/parse.nu (100%) rename {.nushell => nu-utils}/plot.nu (100%) diff --git a/.env.nu b/.env.nu index cb49bb3a..300f5abf 100644 --- a/.env.nu +++ b/.env.nu @@ -1,6 +1,7 @@ const MODULES = [ - ".nushell/math.nu", - ".nushell/formats.nu", + "nu-utils/math.nu", + "nu-utils/formats.nu", + "benchmarks/", ] def log-load [m: string] { @@ -11,3 +12,5 @@ log-load $MODULES.0 use $MODULES.0 * log-load $MODULES.1 use $MODULES.1 * +log-load $MODULES.2 +use $MODULES.2 diff --git a/README.md b/README.md index cbbd5afb..010f179d 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Komodo provides a bunch of other binaries that might be interesting of useful to The easiest is to use the `cargo.nu` Nushell module as follows ```bash -use .nushell cargo "cargo bin" +use nu-utils cargo "cargo bin" help cargo bin ``` diff --git a/benchmarks/.nushell/commit/plot.nu b/benchmarks/.nushell/commit/plot.nu deleted file mode 100644 index 201f7d5d..00000000 --- a/benchmarks/.nushell/commit/plot.nu +++ /dev/null @@ -1,56 +0,0 @@ -use ../../../.nushell math * -use ../../../.nushell fs check-file -use ../../../.nushell plot [ into-axis-options, COMMON_OPTIONS, gplt ] - -export def main [data: path, --save: path] { - check-file $data --span (metadata $data).span - - let raw = open $data - | where name !~ '^SEC' - | ns-to-ms $.times - | compute-stats $.times - | insert degree { get label | parse "degree {d}" | into record | get d | into int } - let graphs = $raw - | rename --column { degree: "x", mean: "y", stddev: "e" } - | select name x y e - | group-by name --to-table - | reject items.name - | rename --column { group: "name", items: "points" } - | insert style.color {|it| - match $it.name { - "BLS12-381" => "tab:blue" - "PALLAS" => "tab:green" - "BN254" => "tab:orange" - "CP6-782" => "tab:olive" - "ED-MNT4-298" => "tab:pink" - "MNT4-753" => "tab:red" - _ => "tab:grey" - } - } - | insert style.line.marker.shape {|it| - match $it.name { - "BLS12-381" => "s" - "PALLAS" => "o" - "BN254" => "^" - "CP6-782" => "*" - "ED-MNT4-298" => "X" - "MNT4-753" => "d" - _ => null - } - } - | insert style.line.marker.size { 10 } - | sort-by name - - let options = [ - # --title "time to create trusted setups for certain curves" - --x-label '$\log_2 d$' - # --y-label "time" - ...($graphs.points | flatten | into-axis-options -x "plain" -y "duration") - ...$COMMON_OPTIONS - (if $save != null { [ --save $save ] }) - --x-tick-labels ($raw.degree | uniq | math log 2) - --x-ticks-rotation 0 - ] - - gplt plot ($graphs | to json) ...($options | flatten | compact) -} diff --git a/benchmarks/.nushell/commit/run.nu b/benchmarks/.nushell/commit/run.nu deleted file mode 100644 index dca9727f..00000000 --- a/benchmarks/.nushell/commit/run.nu +++ /dev/null @@ -1,20 +0,0 @@ -export def main [ - --output: path = "./commit.ndjson", - --nb-measurements: int = 10, - --curves: list<string>, -]: list<int> -> nothing { - let input = $in - - if ($input | is-empty) or ($curves | is-empty) { - print "nothing to do" - return - } - - cargo run --release --package benchmarks --bin commit -- ...[ - --nb-measurements $nb_measurements - ...$input - --curves ...$curves - ] out> $output - - print $"results saved to `($output)`" -} diff --git a/benchmarks/.nushell/fec/run.nu b/benchmarks/.nushell/fec/run.nu deleted file mode 100644 index ceafe8ad..00000000 --- a/benchmarks/.nushell/fec/run.nu +++ /dev/null @@ -1,28 +0,0 @@ -use ../../../.nushell formats * - -export def main [ - --output: path = "./fec.ndjson", - --nb-measurements: int = 10, - --ks: list<int>, - --curves: list<string>, -]: list<int> -> nothing { - let input = $in - - if ($ks | is-empty) or ($input | is-empty) or ($curves | is-empty) { - print "nothing to do" - return - } - - "" out> $output - - for k in $ks { - cargo run --release --package benchmarks --bin fec -- ...[ - --nb-measurements $nb_measurements - ...$input - --encoding vandermonde - -k $k - -n 1 - --curves ...$curves - ] | from ndnuon | to ndjson out>> $output - } -} diff --git a/benchmarks/.nushell/recoding/plot.nu b/benchmarks/.nushell/recoding/plot.nu deleted file mode 100644 index ccc32ec2..00000000 --- a/benchmarks/.nushell/recoding/plot.nu +++ /dev/null @@ -1,31 +0,0 @@ -use ../../../.nushell math * -use ../../../.nushell plot [ into-axis-options, COMMON_OPTIONS ] -use ../../../.nushell fs check-file -use ../../../.nushell plot gplt - -export def main [data: path, --save: path] { - check-file $data --span (metadata $data).span - - let graphs = open $data - | 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)$"} - - let options = [ - # --y-label "time (in ms)" - ...($graphs.points | flatten | into-axis-options -x "filesize" -y "duration") - --no-legend - ...$COMMON_OPTIONS - (if $save != null { [ --save $save ] }) - ] - - gplt plot ($graphs | to json) ...($options | flatten | compact) -} diff --git a/benchmarks/.nushell/recoding/run.nu b/benchmarks/.nushell/recoding/run.nu deleted file mode 100644 index 9b42ae72..00000000 --- a/benchmarks/.nushell/recoding/run.nu +++ /dev/null @@ -1,27 +0,0 @@ -use ../../../.nushell formats * - -export def main [ - --output: path = "./recoding.ndjson", - --nb-measurements: int = 10, - --ks: list<int>, - --curves: list<string>, -]: list<int> -> nothing { - let input = $in - - if ($ks | is-empty) or ($input | is-empty) or ($curves | is-empty) { - print "nothing to do" - return - } - - "" out> $output - - for k in $ks { - cargo run --release --package benchmarks --bin recoding -- ...[ - --nb-measurements $nb_measurements - ...$input - --shards $k - --ks $k - --curves ...$curves - ] | from ndnuon | to ndjson out>> $output - } -} diff --git a/benchmarks/.nushell/setup/run.nu b/benchmarks/.nushell/setup/run.nu deleted file mode 100644 index 50862c3d..00000000 --- a/benchmarks/.nushell/setup/run.nu +++ /dev/null @@ -1,20 +0,0 @@ -export def main [ - --output: path = "./setup.ndjson", - --nb-measurements: int = 10, - --curves: list<string>, -]: list<int> -> nothing { - let input = $in - - if ($input | is-empty) or ($curves | is-empty) { - print "nothing to do" - return - } - - cargo run --release --package benchmarks --bin setup -- ...[ - --nb-measurements $nb_measurements - ...$input - --curves ...$curves - ] out> $output - - print $"results saved to `($output)`" -} diff --git a/benchmarks/README.md b/benchmarks/README.md index a99b6dfe..d9445e8d 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -39,108 +39,43 @@ 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 --release --package benchmarks --bin linalg -- --nb-measurements 10 ...$sizes out> linalg.ndjson -``` -```nushell -use .nushell/plot.nu [ "into-axis-options", COMMON_OPTIONS ] - -let linalg = open linalg.ndjson - | ns-to-ms $.times - | compute-stats $.times - | update label { parse "{op} {n}"} - | flatten --all label - | into int n -for graph in [ - [op, title]; +let out_linalg = $sizes | benchmarks linalg run - ["inverse", "time to inverse an $n \\times n$ matrix"], - ["transpose", "time to transpose an $n \\times n$ matrix"], - ["mul", "time to multiply two $n \\times n$ matrices"] -] { - let graphs = $linalg - | where op == $graph.op - | rename --column { n: "x", mean: "y", stddev: "e" } - | group-by name --to-table - | rename --column { group: "name", items: "points" } - | insert style.color {|it| - match $it.name { - "BLS12-381" => "tab:blue" - "PALLAS" => "tab:green" - "BN254" => "tab:orange" - "CP6-782" => "tab:olive" - "ED-MNT4-298" => "tab:pink" - "MNT4-753" => "tab:red" - _ => "tab:grey" - } - } - | insert style.line.marker.shape {|it| - match $it.name { - "BLS12-381" => "s" - "PALLAS" => "o" - "BN254" => "^" - "CP6-782" => "*" - "ED-MNT4-298" => "X" - "MNT4-753" => "d" - _ => null - } - } - | insert style.line.marker.size { 10 } - gplt plot ...[ - --title $graph.title - --x-label "n" - --use-tex - ($graphs | to json) - ...$COMMON_OPTIONS - ...($graphs.points | flatten | into-axis-options -x "plain" -y "duration") - --x-ticks-rotation 0 - ] -} +benchmarks linalg plot $out_linalg inverse ``` -## trusted setup -```nushell -use .nushell/setup/run.nu; seq 0 13 | each { 2 ** $in } | run --output setup.ndjson --curves [ bls12381, pallas, bn254 ] -``` +## trusted setup and commit ```nushell -use ./.nushell/setup/plot.nu; plot setup.ndjson -``` +let degrees = seq 0 13 | each { 2 ** $in } +let curves = [ bls12381, pallas, bn254 ] -## commit -```nushell -use .nushell/commit/run.nu; seq 0 13 | each { 2 ** $in } | run --output commit.ndjson --curves [bls12381, pallas, bn254 ] -``` -```nushell -use ./.nushell/commit/plot.nu; plot commit.ndjson -``` +let out_setup = $degrees | benchmarks setup run --curves $curves +let out_commit = $degrees | benchmarks commit run --curves $curves -## end-to-end benchmarks -### recoding -```nushell -use .nushell/recoding/run.nu -seq 0 18 | each { 512 * 2 ** $in } | run --ks [2, 4, 8, 16] --output recoding.ndjson --curves [ bls12381 ] -``` -```nushell -use ./.nushell/recoding/plot.nu; plot recoding.ndjson +benchmarks setup plot $out_setup +benchmarks commit plot $out_commit ``` -### FEC -```nushell -use .nushell/fec/run.nu -seq 0 18 | each { 512 * 2 ** $in } | run --ks [2, 4, 8, 16] --output fec.ndjson --curves [ bls12381 ] -``` +## end-to-end benchmarks ```nushell -use ./.nushell/fec/plot.nu; plot encoding fec.ndjson -use ./.nushell/fec/plot.nu; plot decoding fec.ndjson -use ./.nushell/fec/plot.nu; plot e2e fec.ndjson +let sizes = seq 0 18 | each { 512 * 2 ** $in } +let ks = [2, 4, 8, 16] +let curves = [ bls12381 ] ``` -## combined graph +### run ```nushell -use ./.nushell/fec/plot.nu; plot combined fec.ndjson --recoding recoding.ndjson +let out_recoding = $sizes | benchmarks recoding run --ks $ks --curves $curves +let out_fec = $sizes | benchmarks fec run --ks $ks --curves $curves ``` -## ratio graph +### plot ```nushell -use ./.nushell/fec/plot.nu; plot ratio fec.ndjson --recoding recoding.ndjson +benchmarks recoding plot $out_recoding +benchmarks fec plot encoding $out_fec +benchmarks fec plot decoding $out_fec +benchmarks fec plot e2e $out_fec +benchmarks fec plot combined $out_fec --recoding $out_recoding +benchmarks fec plot ratio $out_fec --recoding $out_recoding ``` diff --git a/benchmarks/mod.nu b/benchmarks/mod.nu new file mode 100644 index 00000000..6ea142d0 --- /dev/null +++ b/benchmarks/mod.nu @@ -0,0 +1,5 @@ +export module nu-lib/setup.nu +export module nu-lib/commit.nu +export module nu-lib/fec/ +export module nu-lib/recoding.nu +export module nu-lib/linalg.nu diff --git a/benchmarks/nu-lib/commit.nu b/benchmarks/nu-lib/commit.nu new file mode 100644 index 00000000..f43ef527 --- /dev/null +++ b/benchmarks/nu-lib/commit.nu @@ -0,0 +1,106 @@ +use ../../nu-utils log +use ../../nu-utils math * +use ../../nu-utils fs check-file +use ../../nu-utils plot [ into-axis-options, COMMON_OPTIONS, gplt ] + +use std formats * + +# run the "commit" benchmarks +# +# - input: the list of polynomial degrees +# - output: the output path, as NDJSON +export def run [ + --output: path, # the output path (defaults to a random file in $nu.temp-path) + --curves: list<string>, # the curves to benchmark + --force, # does not ask for confirmation if the output file already exists, it will be overwritten + --nb-measurements: int = 10, # the number of measurements per benchmark run +]: list<int> -> path { + let input = $in + + if ($input | is-empty) or ($curves | is-empty) { + print "nothing to do" + return + } + + let new_file = $output == null + let output = $output | default (mktemp --tmpdir komodo_commit.XXXXXX) + let pretty_output = $"(ansi purple)($output)(ansi reset)" + if ($output | path exists) and not $new_file { + log warning $"($pretty_output) already exists" + if not $force { + let res = ["no", "yes"] | input list $"Do you want to overwrite ($pretty_output)?" + if $res == null or $res == "no" { + log info "aborting" + return + } + + } + } + + cargo run --release --package benchmarks --bin commit -- ...[ + --nb-measurements $nb_measurements + ...$input + --curves ...$curves + ] out> $output + + log info $"results saved to ($pretty_output)" + $output +} + +# plot the "commit" benchmark results +export def plot [ + data: path, # where to load the data from + --save: path, # an optional path where to save the figure (defaults to showing the figure interactively) +] { + check-file $data --span (metadata $data).span + + let raw = open --raw $data + | from ndjson + | where name !~ '^SEC' + | ns-to-ms $.times + | compute-stats $.times + | insert degree { get label | parse "degree {d}" | into record | get d | into int } + let graphs = $raw + | rename --column { degree: "x", mean: "y", stddev: "e" } + | select name x y e + | group-by name --to-table + | reject items.name + | rename --column { group: "name", items: "points" } + | insert style.color {|it| + match $it.name { + "BLS12-381" => "tab:blue" + "PALLAS" => "tab:green" + "BN254" => "tab:orange" + "CP6-782" => "tab:olive" + "ED-MNT4-298" => "tab:pink" + "MNT4-753" => "tab:red" + _ => "tab:grey" + } + } + | insert style.line.marker.shape {|it| + match $it.name { + "BLS12-381" => "s" + "PALLAS" => "o" + "BN254" => "^" + "CP6-782" => "*" + "ED-MNT4-298" => "X" + "MNT4-753" => "d" + _ => null + } + } + | insert style.line.marker.size { 10 } + | sort-by name + + let options = [ + # --title "time to create trusted setups for certain curves" + --x-label '$\log_2 d$' + # --y-label "time" + ...($graphs.points | flatten | into-axis-options -x "plain" -y "duration") + ...$COMMON_OPTIONS + (if $save != null { [ --save $save ] }) + --x-tick-labels ($raw.degree | uniq | math log 2) + --x-ticks-rotation 0 + ] + + gplt plot ($graphs | to json) ...($options | flatten | compact) +} diff --git a/benchmarks/nu-lib/fec/mod.nu b/benchmarks/nu-lib/fec/mod.nu new file mode 100644 index 00000000..cb999a34 --- /dev/null +++ b/benchmarks/nu-lib/fec/mod.nu @@ -0,0 +1,2 @@ +export module run.nu +export module plot.nu diff --git a/benchmarks/.nushell/fec/plot.nu b/benchmarks/nu-lib/fec/plot.nu similarity index 79% rename from benchmarks/.nushell/fec/plot.nu rename to benchmarks/nu-lib/fec/plot.nu index 56147f24..615fc3a9 100644 --- a/benchmarks/.nushell/fec/plot.nu +++ b/benchmarks/nu-lib/fec/plot.nu @@ -1,12 +1,19 @@ -use ../../../.nushell math * -use ../../../.nushell plot [ into-axis-options, COMMON_OPTIONS ] -use ../../../.nushell fs check-file -use ../../../.nushell plot gplt +use ../../../nu-utils math * +use ../../../nu-utils plot [ into-axis-options, COMMON_OPTIONS ] +use ../../../nu-utils fs check-file +use ../../../nu-utils plot gplt -export def encoding [data: path, --save: path] { +use std formats * + +# plot the "encoding" benchmark results +export def encoding [ + data: path, # where to load the data from + --save: path, # an optional path where to save the figure (defaults to showing the figure interactively) +] { check-file $data --span (metadata $data).span - let graphs = open $data + let graphs = open --raw $data + | from ndjson | update label { from json } | flatten label | ns-to-ms times @@ -30,10 +37,15 @@ export def encoding [data: path, --save: path] { gplt plot ($graphs | to json) ...($options | flatten | compact) } -export def decoding [data: path, --save: path] { +# plot the "decoding" benchmark results +export def decoding [ + data: path, # where to load the data from + --save: path, # an optional path where to save the figure (defaults to showing the figure interactively) +] { check-file $data --span (metadata $data).span - let graphs = open $data + let graphs = open --raw $data + | from ndjson | update label { from json } | flatten label | ns-to-ms times @@ -58,10 +70,15 @@ export def decoding [data: path, --save: path] { gplt plot ($graphs | to json) ...($options | flatten | compact) } -export def e2e [data: path, --save: path] { +# plot the "end to end" benchmark results, i.e. a $k$-decoding and a $1$-encoding +export def e2e [ + data: path, # where to load the data from + --save: path, # an optional path where to save the figure (defaults to showing the figure interactively) +] { check-file $data --span (metadata $data).span - let graphs = open $data + let graphs = open --raw $data + | from ndjson | update label { from json } | flatten label | insert foo { $"($in.name) / ($in.k) / ($in.bytes)" } @@ -96,11 +113,17 @@ export def e2e [data: path, --save: path] { gplt plot ($graphs | to json) ...($options | flatten | compact) } -export def combined [data: path, --recoding: path, --save: path] { +# plot the "combined" benchmark results, i.e. the "end to end" and "recoding" plots on the same figure +export def combined [ + data: path, # where to load the "fec" data from + --recoding: path, # where to load the "recoding" data from + --save: path, # an optional path where to save the figure (defaults to showing the figure interactively) +] { check-file $data --span (metadata $data).span check-file $recoding --span (metadata $recoding).span - let recoding_graphs = open $recoding + let recoding_graphs = open --raw $recoding + | from ndjson | ns-to-ms $.times | compute-stats $.times | update label { from nuon } @@ -124,7 +147,8 @@ export def combined [data: path, --recoding: path, --save: path] { | rename --column { group: "name", items: "points" } | update name { $"$k = ($in)$" } - let re_encoding_graphs = open $data + let re_encoding_graphs = open --raw $data + | from ndjson | update label { from json } | flatten label | insert key { $"($in.name) / ($in.k) / ($in.bytes)" } @@ -199,11 +223,17 @@ export def combined [data: path, --recoding: path, --save: path] { gplt plot ($graphs | to json) ...($options | flatten | compact) } -export def ratio [data: path, --recoding: path, --save: path] { +# plot the "ratio" benchmark results, i.e. the ratio between "end to end" and "recoding" +export def ratio [ + data: path, # where to load the "fec" data from + --recoding: path, # where to load the "recoding" data from + --save: path, # an optional path where to save the figure (defaults to showing the figure interactively) +] { check-file $data --span (metadata $data).span check-file $recoding --span (metadata $recoding).span - let recoding_graphs = open $recoding + let recoding_graphs = open --raw $recoding + | from ndjson | ns-to-ms times | compute-stats $.times | update label { from nuon } @@ -212,7 +242,8 @@ export def ratio [data: path, --recoding: path, --save: path] { | select shards bytes mean | rename --column { shards: "k" } - let re_encoding_graphs = open $data + let re_encoding_graphs = open --raw $data + | from ndjson | update label { from json } | flatten label | insert key { $"($in.name) / ($in.k) / ($in.bytes)" } diff --git a/benchmarks/nu-lib/fec/run.nu b/benchmarks/nu-lib/fec/run.nu new file mode 100644 index 00000000..1b600189 --- /dev/null +++ b/benchmarks/nu-lib/fec/run.nu @@ -0,0 +1,54 @@ +use ../../../nu-utils log +use ../../../nu-utils formats * + +use std formats * + +# run the "fec" benchmarks +# +# - input: the list of input file sizes +# - output: the output path, as NDJSON +export def main [ + --output: path, # the output path (defaults to a random file in $nu.temp-path) + --ks: list<int>, # the values of $k$ to benchmark + --curves: list<string>, # the curves to benchmark + --force, # does not ask for confirmation if the output file already exists, it will be overwritten + --nb-measurements: int = 10, # the number of measurements per benchmark run +]: list<int> -> path { + let input = $in + + if ($ks | is-empty) or ($input | is-empty) or ($curves | is-empty) { + print "nothing to do" + return + } + + let new_file = $output == null + let output = $output | default (mktemp --tmpdir komodo_fec.XXXXXX) + let pretty_output = $"(ansi purple)($output)(ansi reset)" + if ($output | path exists) and not $new_file { + log warning $"($pretty_output) already exists" + if not $force { + let res = ["no", "yes"] | input list $"Do you want to overwrite ($pretty_output)?" + if $res == null or $res == "no" { + log info "aborting" + return + } + + } + } + + "" out> $output + + for k in $ks { + cargo run --release --package benchmarks --bin fec -- ...[ + --nb-measurements $nb_measurements + ...$input + --encoding vandermonde + -k $k + -n 1 + --curves ...$curves + ] | from ndnuon | to ndjson out>> $output + } + + log info $"results saved to ($pretty_output)" + $output +} diff --git a/benchmarks/nu-lib/linalg.nu b/benchmarks/nu-lib/linalg.nu new file mode 100644 index 00000000..8699334b --- /dev/null +++ b/benchmarks/nu-lib/linalg.nu @@ -0,0 +1,127 @@ +use ../../nu-utils log +use ../../nu-utils math * +use ../../nu-utils fs check-file +use ../../nu-utils plot [ into-axis-options, COMMON_OPTIONS, gplt ] + +use std formats * + +# run the "linear algebra" benchmarks +# +# - input: the list of matrix sizes +# - output: the output path, as NDJSON +export def run [ + --output: path, # the output path (defaults to a random file in $nu.temp-path) + --force, # does not ask for confirmation if the output file already exists, it will be overwritten + --nb-measurements: int = 10, # the number of measurements per benchmark run +]: list<int> -> path { + let input = $in + + if ($input | is-empty) { + print "nothing to do" + return + } + + let new_file = $output == null + let output = $output | default (mktemp --tmpdir komodo_linalg.XXXXXX) + let pretty_output = $"(ansi purple)($output)(ansi reset)" + if ($output | path exists) and not $new_file { + log warning $"($pretty_output) already exists" + if not $force { + let res = ["no", "yes"] | input list $"Do you want to overwrite ($pretty_output)?" + if $res == null or $res == "no" { + log info "aborting" + return + } + + } + } + + cargo run --release --package benchmarks --bin linalg -- ...[ + --nb-measurements $nb_measurements + ...$input + ] out> $output + + log info $"results saved to ($pretty_output)" + $output +} + +def load-linalg-data [data: path, --span: record<start: int, end: int>]: [ nothing -> table ] { + check-file $data --span $span + + open --raw $data + | from ndjson + | ns-to-ms $.times + | compute-stats $.times + | update label { parse "{op} {n}"} + | flatten --all label + | into int n +} + +def linalg-operations []: [ nothing -> list<string> ] { + [ "inverse", "transpose", "mul" ] +} + +# plot the "linear algebra" benchmark results +export def plot [ + data: path, # where to load the data from + op: string@linalg-operations, + --save: path, # an optional path where to save the figure (defaults to showing the figure interactively) +] { + check-file $data --span (metadata $data).span + if $op not-in (linalg-operations) { + error make { + msg: $"(ansi red_bold)invalid_linalg_op(ansi reset)", + label: { + text: $"invalid linear algebra operation '(ansi yellow)($op)(ansi purple)'(ansi reset)", + span: (metadata $op).span, + }, + help: $"please choose one of (ansi cyan)(linalg-operations)(ansi reset)" + } + } + + let graphs = open --raw $data + | from ndjson + | ns-to-ms $.times + | compute-stats $.times + | update label { parse "{op} {n}"} + | flatten --all label + | into int n + | where op == $op + | rename --column { n: "x", mean: "y", stddev: "e" } + | group-by name --to-table + | rename --column { group: "name", items: "points" } + | insert style.color {|it| + match $it.name { + "BLS12-381" => "tab:blue" + "PALLAS" => "tab:green" + "BN254" => "tab:orange" + "CP6-782" => "tab:olive" + "ED-MNT4-298" => "tab:pink" + "MNT4-753" => "tab:red" + _ => "tab:grey" + } + } + | insert style.line.marker.shape {|it| + match $it.name { + "BLS12-381" => "s" + "PALLAS" => "o" + "BN254" => "^" + "CP6-782" => "*" + "ED-MNT4-298" => "X" + "MNT4-753" => "d" + _ => null + } + } + | insert style.line.marker.size { 10 } + + let options = [ + --x-label "n" + --use-tex + ...$COMMON_OPTIONS + ...($graphs.points | flatten | into-axis-options -x "plain" -y "duration") + (if $save != null { [ --save $save ] }) + --x-ticks-rotation 0 + ] + + gplt plot ($graphs | to json) ...($options | flatten | compact) +} diff --git a/benchmarks/nu-lib/recoding.nu b/benchmarks/nu-lib/recoding.nu new file mode 100644 index 00000000..34eca661 --- /dev/null +++ b/benchmarks/nu-lib/recoding.nu @@ -0,0 +1,88 @@ +use ../../nu-utils log +use ../../nu-utils formats * +use ../../nu-utils math * +use ../../nu-utils plot [ into-axis-options, COMMON_OPTIONS, gplt ] +use ../../nu-utils fs check-file + +use std formats * + +# run the "recoding" benchmarks +# +# - input: the list of input file sizes +# - output: the output path, as NDJSON +export def run [ + --output: path, # the output path (defaults to a random file in $nu.temp-path) + --ks: list<int>, # the values of $k$ to benchmark + --curves: list<string>, # the curves to benchmark + --force, # does not ask for confirmation if the output file already exists, it will be overwritten + --nb-measurements: int = 10, # the number of measurements per benchmark run +]: list<int> -> path { + let input = $in + + if ($ks | is-empty) or ($input | is-empty) or ($curves | is-empty) { + print "nothing to do" + return + } + + let new_file = $output == null + let output = $output | default (mktemp --tmpdir komodo_recoding.XXXXXX) + let pretty_output = $"(ansi purple)($output)(ansi reset)" + if ($output | path exists) and not $new_file { + log warning $"($pretty_output) already exists" + if not $force { + let res = ["no", "yes"] | input list $"Do you want to overwrite ($pretty_output)?" + if $res == null or $res == "no" { + log info "aborting" + return + } + + } + } + + "" out> $output + + for k in $ks { + cargo run --release --package benchmarks --bin recoding -- ...[ + --nb-measurements $nb_measurements + ...$input + --shards $k + --ks $k + --curves ...$curves + ] | from ndnuon | to ndjson out>> $output + } + + log info $"results saved to ($pretty_output)" + $output +} + +# plot the "recoding" benchmark results +export def plot [ + data: path, # where to load the data from + --save: path, # an optional path where to save the figure (defaults to showing the figure interactively) +] { + check-file $data --span (metadata $data).span + + let graphs = open --raw $data + | from 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)$"} + + let options = [ + # --y-label "time (in ms)" + ...($graphs.points | flatten | into-axis-options -x "filesize" -y "duration") + --no-legend + ...$COMMON_OPTIONS + (if $save != null { [ --save $save ] }) + ] + + gplt plot ($graphs | to json) ...($options | flatten | compact) +} diff --git a/benchmarks/.nushell/setup/plot.nu b/benchmarks/nu-lib/setup.nu similarity index 51% rename from benchmarks/.nushell/setup/plot.nu rename to benchmarks/nu-lib/setup.nu index 351ea18d..0cf90357 100644 --- a/benchmarks/.nushell/setup/plot.nu +++ b/benchmarks/nu-lib/setup.nu @@ -1,11 +1,61 @@ -use ../../../.nushell math * -use ../../../.nushell fs check-file -use ../../../.nushell plot [ into-axis-options, COMMON_OPTIONS, gplt ] +use ../../nu-utils log +use ../../nu-utils math * +use ../../nu-utils fs check-file +use ../../nu-utils plot [ into-axis-options, COMMON_OPTIONS, gplt ] -export def main [data: path, --save: path] { +use std formats * + +# run the "trusted setup" benchmarks +# +# - input: the list of polynomial degrees +# - output: the output path, as NDJSON +export def run [ + --output: path, # the output path (defaults to a random file in $nu.temp-path) + --curves: list<string>, # the curves to benchmark + --force, # does not ask for confirmation if the output file already exists, it will be overwritten + --nb-measurements: int = 10, # the number of measurements per benchmark run +]: list<int> -> path { + let input = $in + + if ($input | is-empty) or ($curves | is-empty) { + print "nothing to do" + return + } + + let new_file = $output == null + let output = $output | default (mktemp --tmpdir komodo_setup.XXXXXX) + let pretty_output = $"(ansi purple)($output)(ansi reset)" + if ($output | path exists) and not $new_file { + log warning $"($pretty_output) already exists" + if not $force { + let res = ["no", "yes"] | input list $"Do you want to overwrite ($pretty_output)?" + if $res == null or $res == "no" { + log info "aborting" + return + } + + } + } + + cargo run --release --package benchmarks --bin setup -- ...[ + --nb-measurements $nb_measurements + ...$input + --curves ...$curves + ] out> $output + + log info $"results saved to ($pretty_output)" + $output +} + +# plot the "trusted setup" benchmark results +export def plot [ + data: path, # where to load the data from + --save: path, # an optional path where to save the figure (defaults to showing the figure interactively) +] { check-file $data --span (metadata $data).span - let raw = open $data + let raw = open --raw $data + | from ndjson | ns-to-ms times | compute-stats times | insert degree { get label | parse "degree {d}" | into record | get d | into int } diff --git a/examples/cli.nu b/examples/cli.nu index 12b75025..e7765693 100755 --- a/examples/cli.nu +++ b/examples/cli.nu @@ -7,7 +7,7 @@ use ../komodo.nu [ "komodo reconstruct", "komodo ls", ] -use ../.nushell binary [ "bytes from_int" ] +use ../nu-utils binary [ "bytes from_int" ] use std assert diff --git a/komodo.nu b/komodo.nu index c23b7929..d1ca5d81 100644 --- a/komodo.nu +++ b/komodo.nu @@ -2,7 +2,7 @@ # # please run `komodo --help` or `komodo <tab>` to have a look at more information -use .nushell binary ["bytes from_int"] +use nu-utils binary ["bytes from_int"] const KOMODO_BINARY = "./target/release/komodo" const DEFAULT_LOG_LEVEL = "INFO" diff --git a/.nushell/binary.nu b/nu-utils/binary.nu similarity index 100% rename from .nushell/binary.nu rename to nu-utils/binary.nu diff --git a/.nushell/cargo.nu b/nu-utils/cargo.nu similarity index 100% rename from .nushell/cargo.nu rename to nu-utils/cargo.nu diff --git a/.nushell/color.nu b/nu-utils/color.nu similarity index 100% rename from .nushell/color.nu rename to nu-utils/color.nu diff --git a/.nushell/error.nu b/nu-utils/error.nu similarity index 100% rename from .nushell/error.nu rename to nu-utils/error.nu diff --git a/.nushell/formats.nu b/nu-utils/formats.nu similarity index 100% rename from .nushell/formats.nu rename to nu-utils/formats.nu diff --git a/.nushell/fs.nu b/nu-utils/fs.nu similarity index 100% rename from .nushell/fs.nu rename to nu-utils/fs.nu diff --git a/nu-utils/log.nu b/nu-utils/log.nu new file mode 100644 index 00000000..0a7ee150 --- /dev/null +++ b/nu-utils/log.nu @@ -0,0 +1,7 @@ +export def info [msg: string] { + print $"[(ansi green_bold)INFO(ansi reset)] ($msg)" +} + +export def warning [msg: string] { + print $"[(ansi yellow_bold)WARNING(ansi reset)] ($msg)" +} diff --git a/.nushell/math.nu b/nu-utils/math.nu similarity index 100% rename from .nushell/math.nu rename to nu-utils/math.nu diff --git a/.nushell/mod.nu b/nu-utils/mod.nu similarity index 90% rename from .nushell/mod.nu rename to nu-utils/mod.nu index c6e1c6a9..69f677bf 100644 --- a/.nushell/mod.nu +++ b/nu-utils/mod.nu @@ -7,3 +7,4 @@ export module fs.nu export module math.nu export module parse.nu export module plot.nu +export module log.nu diff --git a/.nushell/parse.nu b/nu-utils/parse.nu similarity index 100% rename from .nushell/parse.nu rename to nu-utils/parse.nu diff --git a/.nushell/plot.nu b/nu-utils/plot.nu similarity index 100% rename from .nushell/plot.nu rename to nu-utils/plot.nu diff --git a/tests/binary.nu b/tests/binary.nu index 21a5a736..def39bc4 100644 --- a/tests/binary.nu +++ b/tests/binary.nu @@ -1,4 +1,4 @@ -use ../.nushell binary [ "bytes from_int", "bytes to_int" ] +use ../nu-utils binary [ "bytes from_int", "bytes to_int" ] use std assert diff --git a/tests/cli.nu b/tests/cli.nu index fd149dff..269baf3c 100644 --- a/tests/cli.nu +++ b/tests/cli.nu @@ -7,7 +7,7 @@ use ../komodo.nu [ "komodo ls", "komodo clean", ] -use ../.nushell binary [ "bytes from_int" ] +use ../nu-utils binary [ "bytes from_int" ] use std assert diff --git a/tests/color.nu b/tests/color.nu index 27609447..1c1c119f 100644 --- a/tests/color.nu +++ b/tests/color.nu @@ -1,4 +1,4 @@ -use ../.nushell color [ +use ../nu-utils color [ "color from-floats", "color from-ints", "color from-string", -- GitLab