From a36528a242dc12677e36581a91b85621f982112a Mon Sep 17 00:00:00 2001 From: batzor <32958247+batzor@users.noreply.github.com> Date: Thu, 29 Aug 2024 17:01:46 +0900 Subject: [PATCH] test(benchmark): add fri benchmark --- Cargo.Bazel.lock | 81 ++++++++++- Cargo.lock | 19 +++ Cargo.toml | 1 + WORKSPACE | 1 + benchmark/fri/BUILD.bazel | 63 +++++++++ benchmark/fri/README.md | 48 +++++++ benchmark/fri/fri_benchmark.cc | 159 ++++++++++++++++++++++ benchmark/fri/fri_benchmark_mac_m3.png | Bin 0 -> 17670 bytes benchmark/fri/fri_benchmark_ubuntu_i9.png | Bin 0 -> 16949 bytes benchmark/fri/fri_config.cc | 56 ++++++++ benchmark/fri/fri_config.h | 40 ++++++ benchmark/fri/fri_runner.h | 94 +++++++++++++ benchmark/fri/plonky3/BUILD.bazel | 13 ++ benchmark/fri/plonky3/Cargo.toml | 31 +++++ benchmark/fri/plonky3/src/lib.rs | 142 +++++++++++++++++++ 15 files changed, 747 insertions(+), 1 deletion(-) create mode 100644 benchmark/fri/BUILD.bazel create mode 100644 benchmark/fri/README.md create mode 100644 benchmark/fri/fri_benchmark.cc create mode 100644 benchmark/fri/fri_benchmark_mac_m3.png create mode 100644 benchmark/fri/fri_benchmark_ubuntu_i9.png create mode 100644 benchmark/fri/fri_config.cc create mode 100644 benchmark/fri/fri_config.h create mode 100644 benchmark/fri/fri_runner.h create mode 100644 benchmark/fri/plonky3/BUILD.bazel create mode 100644 benchmark/fri/plonky3/Cargo.toml create mode 100644 benchmark/fri/plonky3/src/lib.rs diff --git a/Cargo.Bazel.lock b/Cargo.Bazel.lock index 6eb764bf4..09737038c 100644 --- a/Cargo.Bazel.lock +++ b/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "493a31da6b3ac2a5605ba241c05d083f25487a1fdd2efcb09d582c8b3be8cba9", + "checksum": "9871a4efaf95d41779221d5e5a0d86242b4e5832107cd0c8e50ccc004fb34199", "crates": { "addchain 0.2.0": { "name": "addchain", @@ -12952,6 +12952,84 @@ }, "license": "MIT OR Apache-2.0" }, + "plonky3_fri_benchmark 0.0.1": { + "name": "plonky3_fri_benchmark", + "version": "0.0.1", + "repository": null, + "targets": [ + { + "Library": { + "crate_name": "plonky3_fri_benchmark", + "crate_root": "src/lib.rs", + "srcs": [ + "**/*.rs" + ] + } + } + ], + "library_target_name": "plonky3_fri_benchmark", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "deps": { + "common": [ + { + "id": "p3-baby-bear 0.1.3-succinct", + "target": "p3_baby_bear" + }, + { + "id": "p3-challenger 0.1.3-succinct", + "target": "p3_challenger" + }, + { + "id": "p3-commit 0.1.3-succinct", + "target": "p3_commit" + }, + { + "id": "p3-dft 0.1.3-succinct", + "target": "p3_dft" + }, + { + "id": "p3-field 0.1.3-succinct", + "target": "p3_field" + }, + { + "id": "p3-fri 0.1.3-succinct", + "target": "p3_fri" + }, + { + "id": "p3-matrix 0.1.3-succinct", + "target": "p3_matrix" + }, + { + "id": "p3-merkle-tree 0.1.3-succinct", + "target": "p3_merkle_tree" + }, + { + "id": "p3-poseidon2 0.1.3-succinct", + "target": "p3_poseidon2" + }, + { + "id": "p3-symmetric 0.1.3-succinct", + "target": "p3_symmetric" + }, + { + "id": "p3-util 0.1.3-succinct", + "target": "p3_util" + }, + { + "id": "zkhash 0.2.0", + "target": "zkhash" + } + ], + "selects": {} + }, + "edition": "2021", + "version": "0.0.1" + }, + "license": "MIT OR Apache-2.0" + }, "plonky3_poseidon2_benchmark 0.0.1": { "name": "plonky3_poseidon2_benchmark", "version": "0.0.1", @@ -21549,6 +21627,7 @@ "halo2_msm_benchmark 0.0.1": "benchmark/msm/halo2", "horizen_poseidon2_benchmark 0.0.1": "benchmark/poseidon2/horizen", "plonky3_batch_fft_benchmark 0.0.1": "benchmark/fft_batch/plonky3", + "plonky3_fri_benchmark 0.0.1": "benchmark/fri/plonky3", "plonky3_poseidon2_benchmark 0.0.1": "benchmark/poseidon2/plonky3", "tachyon_plonky3 0.0.1": "vendors/plonky3", "tachyon_rs 0.0.1": "tachyon/rs", diff --git a/Cargo.lock b/Cargo.lock index 3c2aa8214..2e86e81e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2509,6 +2509,25 @@ dependencies = [ "tachyon_rs", ] +[[package]] +name = "plonky3_fri_benchmark" +version = "0.0.1" +dependencies = [ + "p3-baby-bear", + "p3-challenger", + "p3-commit", + "p3-dft", + "p3-field", + "p3-fri", + "p3-matrix", + "p3-merkle-tree", + "p3-poseidon2", + "p3-symmetric", + "p3-util", + "tachyon_rs", + "zkhash 0.2.0 (git+https://github.com/HorizenLabs/poseidon2.git?rev=bb476b9)", +] + [[package]] name = "plonky3_poseidon2_benchmark" version = "0.0.1" diff --git a/Cargo.toml b/Cargo.toml index cd6e937b9..571e41dad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ members = [ "benchmark/fft/bellman", "benchmark/fft/halo2", "benchmark/fft_batch/plonky3", + "benchmark/fri/plonky3", "benchmark/poseidon/arkworks", "benchmark/poseidon2/horizen", "benchmark/poseidon2/plonky3", diff --git a/WORKSPACE b/WORKSPACE index dda3518e9..8aefd0dd6 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -58,6 +58,7 @@ crates_repository( "//benchmark/fft/bellman:Cargo.toml", "//benchmark/fft/halo2:Cargo.toml", "//benchmark/fft_batch/plonky3:Cargo.toml", + "//benchmark/fri/plonky3:Cargo.toml", "//benchmark/poseidon/arkworks:Cargo.toml", "//benchmark/poseidon2/horizen:Cargo.toml", "//benchmark/poseidon2/plonky3:Cargo.toml", diff --git a/benchmark/fri/BUILD.bazel b/benchmark/fri/BUILD.bazel new file mode 100644 index 000000000..f96aeda53 --- /dev/null +++ b/benchmark/fri/BUILD.bazel @@ -0,0 +1,63 @@ +load( + "//bazel:tachyon_cc.bzl", + "tachyon_cc_binary", + "tachyon_cc_library", +) + +tachyon_cc_library( + name = "fri_config", + testonly = True, + srcs = ["fri_config.cc"], + hdrs = ["fri_config.h"], + deps = [ + "//benchmark:config", + "//tachyon/base/console", + "//tachyon/base/containers:container_util", + ], +) + +tachyon_cc_library( + name = "fri_runner", + testonly = True, + hdrs = ["fri_runner.h"], + deps = [ + ":fri_config", + "//benchmark:simple_reporter", + "//tachyon/base/containers:container_util", + "//tachyon/base/time", + "//tachyon/c/math/matrix", + "//tachyon/crypto/hashes/sponge/poseidon2:poseidon2_horizen_external_matrix", + "//tachyon/math/matrix:matrix_types", + ], +) + +tachyon_cc_binary( + name = "fri_benchmark", + testonly = True, + srcs = ["fri_benchmark.cc"], + deps = [ + ":fri_config", + ":fri_runner", + "//benchmark:simple_reporter", + "//benchmark/fri/plonky3", + "//tachyon/base:profiler", + "//tachyon/c/math/finite_fields/baby_bear", + "//tachyon/crypto/challenger:duplex_challenger", + "//tachyon/crypto/commitments/fri:fri_config", + "//tachyon/crypto/commitments/fri:two_adic_fri", + "//tachyon/crypto/commitments/fri:two_adic_multiplicative_coset", + "//tachyon/crypto/commitments/merkle_tree/field_merkle_tree:extension_field_merkle_tree_mmcs", + "//tachyon/crypto/commitments/merkle_tree/field_merkle_tree:field_merkle_tree_mmcs", + "//tachyon/crypto/hashes/sponge:padding_free_sponge", + "//tachyon/crypto/hashes/sponge:truncated_permutation", + "//tachyon/crypto/hashes/sponge/poseidon2", + "//tachyon/crypto/hashes/sponge/poseidon2:poseidon2_horizen_external_matrix", + "//tachyon/math/finite_fields:packed_field_traits_forward", + "//tachyon/math/finite_fields/baby_bear:baby_bear4", + "//tachyon/math/finite_fields/baby_bear:packed_baby_bear4", + "//tachyon/math/finite_fields/baby_bear:poseidon2", + "//tachyon/math/matrix:matrix_types", + "//tachyon/math/polynomials/univariate:radix2_evaluation_domain", + "@com_google_absl//absl/strings", + ], +) diff --git a/benchmark/fri/README.md b/benchmark/fri/README.md new file mode 100644 index 000000000..bae5c423f --- /dev/null +++ b/benchmark/fri/README.md @@ -0,0 +1,48 @@ +# FRI Benchmark + +## CPU + +```bash +Run on 13th Gen Intel(R) Core(TM) i9-13900K (32 X 5500 MHz CPU s) +CPU Caches: + L1 Data 48 KiB (x16) + L1 Instruction 32 KiB (x16) + L2 Unified 2048 KiB (x16) + L3 Unified 36864 KiB (x1) + +Run on Apple M3 Pro (12 X 4050 MHz) +CPU Caches: + L1 Data 64 KiB (x12) + L1 Instruction 128 KiB (x12) + L2 Unified 4096 KiB (x12) +``` + +```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 +``` + +## 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 | + +![image](/benchmark/fri/fri_benchmark_ubuntu_i9.png) + +## On Mac M3 Pro + +WARNING: On Mac M3, high degree tests are not feasible due to memory constraints. + +| Exponent | Tachyon | Plonky3 | +| :------- | ------- | ------------ | +| 18 | 3.68509 | **1.39107** | +| 19 | 7.37079 | **2.76483** | +| 20 | 14.9081 | **5.62375** | +| 21 | 30.3153 | **11.8295** | +| 22 | 64.8022 | **25.4490** | + +![image](/benchmark/fri/fri_benchmark_mac_m3.png) diff --git a/benchmark/fri/fri_benchmark.cc b/benchmark/fri/fri_benchmark.cc new file mode 100644 index 000000000..7241f5125 --- /dev/null +++ b/benchmark/fri/fri_benchmark.cc @@ -0,0 +1,159 @@ +#include + +#include "absl/strings/substitute.h" + +// clang-format off +#include "benchmark/simple_reporter.h" +#include "benchmark/fri/fri_config.h" +#include "benchmark/fri/fri_runner.h" +// clang-format on +#include "tachyon/base/profiler.h" +#include "tachyon/c/math/finite_fields/baby_bear/baby_bear_type_traits.h" +#include "tachyon/crypto/challenger/duplex_challenger.h" +#include "tachyon/crypto/commitments/fri/fri_config.h" +#include "tachyon/crypto/commitments/fri/two_adic_fri.h" +#include "tachyon/crypto/commitments/fri/two_adic_multiplicative_coset.h" +#include "tachyon/crypto/commitments/merkle_tree/field_merkle_tree/extension_field_merkle_tree_mmcs.h" +#include "tachyon/crypto/commitments/merkle_tree/field_merkle_tree/field_merkle_tree_mmcs.h" +#include "tachyon/crypto/hashes/sponge/padding_free_sponge.h" +#include "tachyon/crypto/hashes/sponge/poseidon2/poseidon2.h" +#include "tachyon/crypto/hashes/sponge/poseidon2/poseidon2_horizen_external_matrix.h" +#include "tachyon/crypto/hashes/sponge/truncated_permutation.h" +#include "tachyon/math/finite_fields/baby_bear/baby_bear4.h" +#include "tachyon/math/finite_fields/baby_bear/packed_baby_bear4.h" +#include "tachyon/math/finite_fields/baby_bear/poseidon2.h" +#include "tachyon/math/matrix/matrix_types.h" +#include "tachyon/math/polynomials/univariate/radix2_evaluation_domain.h" + +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, + uint64_t* duration); + +template +void CheckResult(bool check_results, const Commitment& tachyon_result, + const Commitment& vendor_result) { + if (check_results) { + CHECK_EQ(tachyon_result, vendor_result) << "Results not matched"; + } +} + +void Run(const FRIConfig& config) { + constexpr size_t kRate = 8; + constexpr size_t kChunk = 8; + constexpr size_t kN = 2; + + using F = math::BabyBear; + using ExtF = math::BabyBear4; + using PackedF = math::PackedBabyBear; + using ExtPackedF = math::PackedBabyBear4; + using Poseidon2 = crypto::Poseidon2Sponge>>; + using PackedPoseidon2 = + crypto::Poseidon2Sponge>>; + using MyHasher = crypto::PaddingFreeSponge; + using MyPackedHasher = + crypto::PaddingFreeSponge; + using MyCompressor = crypto::TruncatedPermutation; + using MyPackedCompressor = + crypto::TruncatedPermutation; + using MMCS = + crypto::FieldMerkleTreeMMCS; + using ExtMMCS = + crypto::FieldMerkleTreeMMCS; + using ChallengeMMCS = crypto::ExtensionFieldMerkleTreeMMCS; + using Challenger = crypto::DuplexChallenger; + using MyPCS = crypto::TwoAdicFRI; + + PackedF::Init(); + ExtPackedF::Init(); + + crypto::Poseidon2Config poseidon2_config = + crypto::Poseidon2Config::CreateCustom( + 15, 7, 8, 13, math::GetPoseidon2BabyBearInternalShiftVector<15>()); + Poseidon2 sponge(poseidon2_config); + MyHasher hasher(sponge); + MyCompressor compressor(sponge); + + crypto::Poseidon2Config packed_config = + crypto::Poseidon2Config::CreateCustom( + 15, 7, 8, 13, math::GetPoseidon2BabyBearInternalShiftVector<15>()); + PackedPoseidon2 packed_sponge(packed_config); + MyPackedHasher packed_hasher(packed_sponge); + MyPackedCompressor packed_compressor(std::move(packed_sponge)); + MMCS mmcs(hasher, packed_hasher, compressor, packed_compressor); + + ChallengeMMCS challenge_mmcs( + ExtMMCS(std::move(hasher), std::move(packed_hasher), + std::move(compressor), std::move(packed_compressor))); + + crypto::FRIConfig fri_config{config.log_blowup(), 10, 8, + challenge_mmcs}; + MyPCS pcs = MyPCS(std::move(mmcs), std::move(fri_config)); + + SimpleReporter reporter; + std::string name; + name = absl::Substitute("FRI Benchmark (b: $0, l: $1)", config.batch_size(), + config.log_blowup()); + reporter.set_title(name); + reporter.set_x_label("Max Exponent"); + reporter.set_column_labels(base::Map( + config.exponents(), + [](uint32_t exponent) { return base::NumberToString(exponent); })); + + FRIRunner runner(reporter, config, pcs); + + std::vector degrees = config.GetDegrees(); + + reporter.AddVendor(Vendor::Tachyon()); + for (Vendor vendor : config.vendors()) { + reporter.AddVendor(vendor); + } + + for (size_t degree : degrees) { + math::RowMajorMatrix input = + math::RowMajorMatrix::Random(degree, config.batch_size()); + + F tachyon_commit = runner.Run(Vendor::Tachyon(), input); + for (Vendor vendor : config.vendors()) { + if (vendor.value() == Vendor::kPlonky3) { + F vendor_commit = + runner.RunExternal(vendor, run_fri_plonky3_baby_bear, input); + CheckResult(config.check_results(), tachyon_commit, vendor_commit); + } else { + NOTREACHED(); + } + } + } + + reporter.Show(); +} + +int RealMain(int argc, char** argv) { + base::FilePath tmp_file; + CHECK(base::GetTempDir(&tmp_file)); + tmp_file = tmp_file.Append("fri_benchmark.perfetto-trace"); + base::Profiler profiler({tmp_file}); + + profiler.Init(); + profiler.Start(); + + FRIConfig config; + if (!config.Parse(argc, argv)) { + return 1; + } + + Run(config); + return 0; +} + +} // namespace tachyon::benchmark + +int main(int argc, char** argv) { + return tachyon::benchmark::RealMain(argc, argv); +} diff --git a/benchmark/fri/fri_benchmark_mac_m3.png b/benchmark/fri/fri_benchmark_mac_m3.png new file mode 100644 index 0000000000000000000000000000000000000000..1065aaf2b23a8e431602b88ba98bffebb8e740d2 GIT binary patch literal 17670 zcmeIacT|=6wk7(388MUsf)Wg%k`X}=NhT1GAXy|BksvuKSuL?dK}CX+1z{5eL_l&- zBnYCCl`M!P0Z~9CzWKB2oO|na^&R*1A3fga(PxZPR>9t1Tw$&`=kkVzn&K*kjSLh; ztx`I2NRy)Iy(x;WYxz?AM7*}`6aLuicv#<2%f{5v<&^z7O7)bZ?FAdh3+AUcJD;<6 zFt@SZEwooiL}0U-qob{Zl(4YXzds;kV}D*)Z1It2ILHdyBgY*mYRxI~f4T%YnmI)s za!@+7U;ASCaQh|0z=`>Vg+A{K47;tD2MBx)aN`Trd=UC+-6b)lnxi~|ZwB8EWNIQN_Zq`rYB{ecsUAFvWeLCpHGt$J56@{bX1yH@mk}VQuZnr8%5GTCJ=l zQh&^N7&TjdPOAT2kXCb=)n^N?=DyGM{FV6A+wwPxj-rnGP|GRmr08OKs@JFN^sxg6 zuH;wm49>D_t~#CGpYc{Uf5hs-ho^@-Iy$C*_C;}6{r1~$d3}*?$}unPU!6`j>wbA7 zt|)49xOM2&jwpeNIcnqpwYch!B`aAfPp30YUz#4EarA86x;1<{Njov-gmv!Wl^cWv zp44>v+}Wn+&-9+wXrWUbEGT~d4ZBf}?ZcPF!l@%4&PO$R(=B4+xHQG-I40ih*OF*Sx#9b(?-sQIW;F=*z}la}%1= zOZBpyhIDzjxf9Im8k9|_eRISAaoPo5@iz}mkm_O zhet~Hw6m>^XwOV*LiY-0U-+PTTW&swdthp;$Mr|Mi}=~fwY{G|58hSe%pLJq!zv>0 z(&>@S&CAcPvhc%efp&MB;$UBtS5tCYk!yQvSypSV1FdL&+R_8x75dQW@K%P_)pat< zqEVS&FSVdMr_*b}C}N+BuC8uyd893Iqqv1+dC^4EiRlWt z`G@b{>+@{iZZS7Kfu9GyiP%TOEmSd^RKIFS)XF+lx^!Z=RZq|$Qv-MO`SpX?rj!$w z_3^4|3y~9pjVijyIyMDkKHF78KYcT}ta+Z=xjrBufKjO&AG^uEfs@nv<;$0nS?A84 zWu2d&SLiACi)d+neEiH2Q5Ioi!%utGaLHacB5Le0p+j@dZ@130YHeD+VnwcxjixI% z+t}FHh*0d2pFe*pSX*1Cd(H5(;SzsiVKIF_>`a?{;qRp+=|1)36swP2_sbOr19qKy z@%w=a)d;D^J7*DIWwp;-MvY7B>+4x1tixl6+j1Qg{5Fa+G)UQY$;T=O@s%fP(NdG& z#8~8quG+MRH8(d`&1&YysD!(_`>o51ma(u#-MMq}_v_a;NG_E>T*7-YntnMWqjs!< zpJV^KhwIu?5!o6VcldPpE+1O2W_xU&4g{~8ydU|4I z+$Nc(-997!BHc#r)|loGzV4`tQ*r8xa6!5BLy8nox16OWz(T++zKh z>FMrX@Fr3wnVDag$7*u=+lW`Kg{YbKk0klXO#BOj>^AI`py6%pz~a zTt*CecI>dMyt75Er^9Q(qwM9&%Fa#`Et*;*4wr`e?VoJ5X+~CsmmBBU?r+a?(n4U2 zw^*hn;?0Eau?p?*oUx+WmHMoz@2`zz-ncOdp)!bL2jdy+v1<7wHqvTS-1x_D+Z-3> zehdZa86Q(q^FMv&jMKMIujo5zUJLV2TZcnM&-u1wS<*I`xF5swZZL9bkK1IOvmY0t zgM1Tr{-U39BKu9cv9t5D4v!y3PJ<0fm=j!EA)~K`DpNx3~vp zMvFrp(VyA2ZCmfhk01MmSNLs`XzF@?HO9+ostYng$J-DZGM7Q7mt4o<(UB?a7={8JW8n0E1P`ezl z*P%SYAS-FCa@%c5t8IdUHBUZVP#Zqz!?=r^?cR1(`;DzhI{e#2MeEXMYa}{Z18yCQ zRbWmSemfI<_M)5Hre$k59W&>C6fcN#v!xZ!=fzsR_;Z4Trbe==L-5MLkV@6WTyI?tA5|wQh1_Wo4!9#)ZDl`PUD2 zD^&P%_~AY`qNI9U9=({06SUkpD_~MoAa8Q@#kjBr%I><~2WiV5YFJ&`*)eV?6KKs=#w?i|GS*k?w-PyvhEZ=R)t=VahZf2b9bpP)6xh8A}7Z+E}{aptGGA$bU&Y7B8lz7vrW!#I5 zjI?M@HM(5?C}8}y*KDbIF4EZ*q0CVo+7{}^Z=nZt~gzlb#^lH zxh4IK;^n!Q<>f4roFQk=olCTAP9+^S(|Onc1uOHNotLxup6|-L^R{f+lJ}#-jiVZk zE!NKw9Zc2P2n`ZPPDf>_1yRODm}_q>>_N$ z=Ef?xn7O#p5)u;VGulG5lXX+{Grr1SItT!9A4nnYoz?{}=K;sh*H&&A$Bp!tZ7^vV zsHde(akX`mCLa?U%TetyJ$|?BbS(lv+_7In+@`~D*=qJX-0he8BCc7NT4YHHn&d@} zzQtX~BYgG+ui=n-bmz{U1L_gRLIMJh-u zmiSfMu;$iz>8I%(TX-n+=6(0$1+<)<=w*d&KbqF7OFuNovUr78jmjc49`76T;%J(2 z;W(bXWmO=r0Wg=ebgJjTM4VzG6N^QAqU*%qx3RI>v7U;R<3<)MSFE_p-I!{0VuO&O zhJu2RMPpJgYe+~44M&qI&pim(;yT{{@b&AXDJI25l?I}_cdsmzUAuF1xwrh1wd>c% zB25N+Lrj{`VO?|*HRE1Bo2%gRI+8avE1~3Hp9UagA1XM@KiHT|3*y%sL=csQE)lSb z@|b*JT`;ELF;=!gEko{FL`+dAI!!X7(f8&}EqQrwWQDOxL&+?G2znp&(}I06khsn+J3Rek74=pJC0+=g8~3u_Eco>2n)6jJ1Z6^ z_kQ}6aQ*cbH(H<- z(`r=Yp36P(Im{;5(XPDKB8%Lovy`~&s~hWgq+a4mPfr(RJSbf7^}yw#p~9k}v>Y*& zsXh;zj)LQxB&-WkhgWe*>t~#Q+Z1L~bo}wM&7HQTs~A?T5)?C2s!Kmpk$Lvjx(a)= z8x|qMgkZrFQZ-e^)n`un4i(Le)C00bShQx_L>2w~ys2U$wysQNF~P!{zrG2RP{)JR zJ$m%$jYjRZiV{O~P2iB`a=%Sk7spN?K75#YujkC!uVXi-pTXc7=Z|Fc%>`tZFDspiFiwoTFduZp=%Uf__lm2b~?32C=(27qtObvPeV zyzm1!rWQ^2q1$Mo9ufnu@=1sLcU8QEm%G-xrmS1HE-)e@<$RQf?w&B!x6wgl31)I#Wq{%;e&M}{RePQe`hx3d;SbX69zEiw*@bY@X@!UFCk1*AbzjP5B%IqE z@WB-k#iMj}=_>mIf9scj{N@Vm#DqY_Bd@BiRzZ!>15)f67ON|(?_QYglOrXn$YUl6 zS!q!0StvWzwWx5sPDO2ZA%al{fJYoycF6Uu4G?o9s%MH({Lp!WA_ z62A2H`Lc*$y%dAECr?BW_=BOA^i@*yn>8-q;@GEaXJhh7B$?LtbdN)BUlx zNg)vy5ICwXJ@$L~ZLU$r;g&^fq@(ZLS*!X$^l)0ybdtS;gH!1$i3HLV`X63TO`gQv zXPMO=_}=%n8QH%jtR@~PDCgWH4@!c$xw-35N_M7wuQHzSAuji?mjUkG8}A$oJRf;U z0j<%0Eh`t7S6Moa*N9h`iK(L9b7ol0Bcvm7=H+^Iv(6$9Jc?A=pP$wP^$h1(hRJyq zX=-Y+R|6p1wbgpe3}^47KZy)&N;OK}b*7w@?Z9?xJ(^mC*qQQM^b#|-Sa%&THZ~^U zjXa`v?=(o?yDc+$zdlFhVIDwEvyqpbp{q~Nx87=w-K}1eeUw>t>jdUcOSG`I#a9?! zozCf*WuUr}@*D?Z@Hl9SpS2IE%l>>MJKevHL;B*AcZ#obN&$^0N*1jlI4O?vD4ok@ zie8>A3+2G6|J{DH3ES5tI)|)UpEYi~Egkc*^m=|i)AfXeo#eM^1>b!0Rp^wL(5!DW8o;NL9E_AauV|U- z=8)8%$%eU4!}#|f6XM`XtzAq-J3iP-8NV>^eCpS;2z0}JK8hZ9K$$7C+&rujBIM-4 zhDWM;)NcKeV_PGQKR)%~c(Bf)X2=oH8Y4^tI=V^`9`Q-#*W`=$8R?!d-bC$JR`$hc z&U3SDD<&+2sX0P|L?k+`W4)?`IcBFNO&%x(4VmUzKc}V=5KqcSj@S+^3}<&b;^#@Y zTLK>td)o)PcmEu0PD{g_RbxJjk@{S^zT?-f{Yshu=V*mIUS3{!D-%P_>H`A<{$uNR zsA+?)n3$g#<=?vX0BRB`eW;LHb#m(|Do0^)iRcAffv>M`9SN$QirYhA4w3+CQ3hhm zZf>xA8!59<&a;3_`yN16{uAhAw5h3!tGHwh^Ib-po}R1LF81`GSrvbMu@cu7h3k*Q z^l)O)vel?0w6p2@Vn8}PJUn~-)RmR%I9%EuqM%j-zo7$2ISmFP8wrM-8?RR%1k+J3 zb$vBQ9m$18J(B?t6PkF0@kbwMy2>G_ce2!*EYc7DaA6O|x@0^WhSjT`Gs(IAi!s$C zW0DxGSC`W%_MGEZBJ(7t*Q}k)#c z&r!0{@GAR*Pgo!G^eh4_{dAw%u+TNjd9))1QxZa4J0R2c;{hN`ZPZt%FSrZK=U0}H zR?WR?qu3GLQj>~sp>~}dGoJ3!*HrL90;?$v24G zyxVG48*{B^6!Se$u#|Bb%er+j_wTb70<8u->a7mpmypo&n3)XX9&XRqd-(97|JNN# zs-a@X8k2OgKtm{=ICSXuZL>-nOvaqexe%is_vr-A%g#@o@k5;kp`xX&9Y{}4KR%e8 zX7T-VO~8C7e`6~0uG;*=>GVqL?0vypo>QmD1}?c-%<=Ae6W>-*$n696uI^`<=+-jVkD+cpKsmem|mpQiSKodDftfCq;5<=#G1 zI5U#36Q|5vgC_s#)hmJpW7B|8q+G`n{5fR??=NY~IDZ=$tPw2MP{$66vR$P{7h;El zv=m&*@Mqr})9E>*iYt5f%&L`i0We`EZ{-#Wo>{jKX1>AXM@Wg9NSPC;j_(Kpm>xk!{@v1b*Dg&%DW zw^y@E+Sbf)?zwRP+qZAy?+&inn{`5f#RE|W79n&br)M=TVW@nQO~Z~T_irIZ{N!$L zf?>+PxpT#b4Es-Ixq3XxATDQh?SdoYDv-2(VCrH z6)UJJiBvj)Fox#bJM&sGVQf;IBgcF(9z=d$Q3x$HXi@j5WkRuH#RjNv6%ynM{_KftyG@x`vt1`FhC2#R;2fH$LxeR#{_^46 zq=MbbXdO0qa`G~sX*`nH>|OMJ{}1_cVf$QCL99JQ^%)}69rwgQy<)&PCI+c;LH#H4 zKz~p51^k}@(kX+3{5CPsc#CZ}sp5@~k7vB}L~pU3TkhQ}kKl@Up@Ra1^oS;X*{?O< zB@NdK=4;T*vhL9hWJeN4KdBbHD5kY*yYzwApNWc!hCiDCv2OnQ{w{R4!2RI0FuS1Tl;Y-YC|p~ZO8Yyj5L7UrXh}!O^Q92OagVZU8T$jc2lcH69)~P zn4*)ci@a_i_`S=u^g5TPKIZs3;o{jC08ui9Gpt$TvQZ0Ft1->QWVkiEdG_abOoBW$ zQF6tOMM#L8?Tbt7Poj{jRfDL|1T_DIUfa--V|Ru_##LMKHm6hO@P`aVB%DRvqgUd? z86Y_fGEDu7X1}TUvG1)*OhX~EsE_ySxYWl1{`&~xqHu8Xi*tUx(^XQx$%8{bU$=gJ zmQAOu2f(%K+(h%l`!lzhSvPQSq@V*^B22)2Tz_`qL(KE5%aTDZ;)pfkquHlQeaOjV z7iPcHukrCjD2bn|VgiwiTW+rPocwZJ=KJg2D0=ri=YO8J>MSxM*cs$g5~c=YhgB36 z{V7*~nnxvdMd<0oDy#xco`_3sd1e(B+bP26$0cWsbO?@$iXwT^RYIp1q!&-d!@jps z&4Sr&F@Oi8q~4(vD&>^4T|M%#*W8c^L0^R2CRyP&`NfWb zRWBeSLJ*bZ@nZp?Ct6W>I6H@|yFLa6!KPH2QV}tS&qrm@ zFmPER+~yx&Tw`EhAZW)499e$MQKo}H9%_-&i4d*S5PrhxUzbsoVFeG(I|RcAW}^g~ z<X_V5CKyOUI>(TCb_Er{dz`c%`ITYE3gfG^85svuevpe`f{aop0a1)`6>ah>E3z z7D384;*k%G*dxxIY+o^Usmskh!n@_&wd)wh)m!AYz=6JMZ9M@R^B9yFZr+_cE6od| zqcY;vErEPI=vy{V3)?y8_tc^V?JLScXt3bdgwMpgLr} zRc`Y#Uuxc#V}}N3?>;}gyxQAJJ(0 zriJ=?dbTAu4vr&}OB!>zsSf8>s}|4*TCMYQGaNRz6Yxx-Ohj}jhGFUk%;4waOL{rj z)o|`Z`4}BlB5r8Es_Xu)GmaP{3EiO!RG4|Lnx$}VvegxXACHl{XFF*4iSC=iNk9tz z6(zs_{(FMUXouIOg%D#8Xj*#_{Bym-4;{lXYG^*!YotTH?G2#bLzECa{`3&0==#4j zICMiTfL_O2m%hE);e#QU_UiZXac#i1pu2asC?#S35MZe`=@3%( zImJo_epEee4BGT*If!hYYMwP$oUg@jE*3OmWczC-^03<({MSrmyPE1{T60AxtZj00 z|I?Dw>11#qaq;c@_jaSzLOs2`Wv>ATg-(Z37jMvLJNDzC_d`{{4B=gU*iZcrL*ai& ztN$$o@OL%#|H!Z0QlakxG{BG*E{k!}e!TC~r=7C0#^M$YcZ!RPQI~=+y86~3oR3zV z+wDyRCNPm4QE1UkwGyVUSp`js3~z1_*2M?|cp5M3F`bhnhL39{etOEGlk}*otBZaZ zJVq#33CtUh2vrvl2w?{N7ZF1(I*SUEmC37G5>i8Pf|DXV_E`BQaVU*(@$t$5&uls| zOS%JG?knG8(QxF{sZ%XEc0J75Az@+3U%p(Rt-r32I~4^)+tbstIjaU)j51Q29v%^)x*V6hb7{8p(s)p?7Vn=tT+Jz+0InSzCGYOt z_2x%iU0okGGa7gQEyH=Jc}%JhJMTb4NU5wmLiA;b!T$5Ww7lZtI>(M38`+5)iay}* zikI*cNnk?Jv77O)Vy9j#2687l1n}KP0C6->okCY9lytORO?L>u2wV zRZzpxPqd+RS{KhbLoHB(<`M7+u&J`N^dJb)s+t;r@b+<__M8~<+UnC;eNN@%{}FKK z-wh*m*6=4KM)-gDpRlb$4Vw?OzbloV)vwyK3f3hzBH^Kh0Zv1nx=n1AI0acC* zuwa^KsSUn&FBU+eG2z%jKuljhKOI-synR)uVhQgIIVrrCr0fn?6@;R#1=nuVTfxF6 zsUR%)fovhIX+_C;7#eY+)LrYVqo$xZ639f@Q|%N3aYZ*M0iWMSr4iizX5XkbkTKi^ zP6QgyuS}y&LhI)R%L!WC@!SnW1+y`a-f%xO z=O*NMCQt*t2kJEj3SHFth?c8Yt{}s7`zJA@1%-tT>A!jNMyS>m^^=b;Tg_hy_T=Cv*9l9t`VW&cL>8YuH zu7xSZ8yiqGz3ZG*UFgoAKW~Xiu?4;k^F|!pTT}Ne^#$Y_d@|dVq`c+}0N`UW?j|0- z$ubSSz({j5u3lO9E}bnz1LDcxHh&es14Rb_Bvi)jnX&uW;SeTxr@RAn&Qh-d#H4=+ z@7;SGRgM6W)2C18%xu8x4d)Z3e0+Q?fNP}OCLg0&G-g@qDb*oSdWVLF0tlC@@zmFS zeIqT}L0RE1Sa$0%Nw>4L(l# z&G^t?0MRMM_`NtgWpjZF8h(#+pOU(=Y%m ziHHn*DMGv$K`EZ(N=g#&f=o-G6UiHlErc~hSxrr7qMMxho3H!oF0c9TTq%aRny`P^ zS=fL>#`X7U3gVeiaj}(bC6M!^YG#e>2OD_7JO>&a!!LHq99~*Nr~r&6{^vkj1JUal zUpkDe`uCxwm&{i2rzL`8yFT4hAM{$7iNdH92gg%Rk^&AD7`^p86$WO37>nSG z0pDBb2wY6a1h^gwF#`1^Z6pD8#W$QTkQ);il(Q!0EPS_QN$N(*!QMX8vRMcoFG5pJ z%njRk@n^ljZ#ATR8NER%ZiI9KxhI?615+k6-<|*ZZNXC8PnCCxWx=0I4(jvB_?B6m zC{P_YH$LtNUm73A8l4FoD>{&wjT+4#m4y=4bU2Qjo7orN2TM-A-;`#Oh8P50TAk>H zY8hw1j*loC-=+H+dt0`SJYrOB3rsSE5s|%F216m9;&oi$TiKb%#uq;>kpZ>+?d#5O z7k1&BRX4V385tW#B0|*(NtYn+d(;`TRxN13?j!?zqKp1;Bz=+X$1BE{dYQ@VLyOyK zyS@@~r%IM2J`h;2bx{{+4s;iOrMfk8vt128`ZgWFZ!|oa*eJN*dXl8bfws1_w4U8L%w!@$o4y z%>O9nn1esS7u^sz7;IY_ig+B27E;oTTPW!jzyuQ_p%yBp1R_GGw<<{G?2hUX;Sd^) zwo%M%bE(L9n%A5P5de!8=G_QoN=l#ZWBrHZnoKizw`|#u>}kQ2pZ??Szp>Tvl%{ow zU}l+2Ue@!s869}&fAof(%L;29eFZ)-3J`LTh!q(76PdLD^a{bO<&752Fv0JJx;Oyo z`5rg%L|9-PCbb*B&kdGti{(KK-K6yQFbCgdC|sFy=cxW^A;X+#fQO+kA2Ns*f)56v zne_LYRowrx+kXi~3P;awm84Rg$|_0%#~tR0DggNndOY!fsRRoggQY0bp-+t{6R0O@ zJ%4t7=dxk+J3a}CW&(|kVkVI1+S+=I-bj=Ji{;WzgWBmXzqBB<8H~tvNP_q+2Yq(( z@Wf388JoiR<@)j3hEz8XyseD9)08{;uK~5rmU|5E4)pnq(PdgMFkOZOFkTevYy9_$m~2?$zV=;Mnm+$BYsf7+N651%TNJICTC^cx}w#o5XoTf)-62a<|s$ z(=nh+gwS$fibF8@Zo<>2lrLireN$Qa4yG@s*(p27IYb18$COyvc$7kSo$-;DmS)o95Qs_@UQmS_P57$!O@>w8&iRFhTts1G+B)Om;UNxNUQNWl>_b1`6!yNtP{06= zn_}MdrxyB;^fl7rKUss zdnJ4Or}f{iELjPAl^`J}UE1ufKYjXC41Q@sm4fi1ar5%>DiOzEylPlOk%yaJAUg0# z2J76VBCv1FJpuMlT@$d6iZ+Sb=e+ z>`@TPgEg+<_{?D{sdNS0sBI=56G5QGXplQ4TdrQc3aI@Hs~;!L2&~tJJVDs$NDp>? zMZV~-VoI$l)quM_Sm1b!P0>#UbtvP*1@J-lYE0{&oGJ~xe?I{|x7s4h0?iS1u6y-Kys~wl11L!_0!o_j zJcPI01MJuZlTjv3#jWs#JM%vmOM_Mi`)tG%z!HUm6p_A^(3F&OvQP z6gA8IH=-7;e%B&^&R+`!{~Ip**ELY*nhu5K^Y3hXDd3{#ZST(}|6e~b%zk+LiG=BZ zy$$9;u*DJ6t4iOY`RU|4TY;ej_iF$N)b_AB4i(=MKwSjPYIpx$6S~jE`r#aLhnT*N zOaYwL3X`zW4dT;jNI4;a&Xp4*jc;h#y>g)3V2nd4XKFdm>SOvQ{1*WYOK`DfCj)^113!Zv`&H@M6%{Q<$IRFoxWPd%fqIJF#7|(&{kHk-cQB19 zX~LhR<%WO6riqZ`tEq7kzfX7G5A0F!*0_WKK4}Q$$WTlF z#Rj*)XwTts?QaQY5kbCvt##2!%sUu&AH(vsuZ0M8@XNq8W@IOWj3R9QU;J0|pWM>L zuhD0I;<{U~=zzwQ3U3qG1_R<008)w0a~dMrqTZ1sf4Ke_8TS2#vm7nsp|eF5B-+B6 zy&%d1#IRLCWH933A+~dfwfwtxYeC%4$G}A9qNB(kD)zz zC+5y=l*iF?SpJvWl;Jl%$>_(v|9L#7qckr6uSayjip7+2>3;+#70q~ZDdvs;!b$Ys z?1&vp+#~+Rk>SqIvG4ZAAOGY}@(GjoeroowzL^iLJdiT|f9?PLm+2b0NWb>$EWolY z^S|sk|LH!o;_16kvY3DSZHtMC34{!_6VEQ#xhUaknAIMv@PGTf-xz^@Tq_hmko9;-t*KK6Qh-k3vs~8=}p8 z2KNC(32mmlzejx6j9o#XA7jtL-0E}i zG~I@4Vd&ZhqO-U_4V&!1mQ-EG|_i8)Ft7#)<1ec*wxLltOI z$ioW`2R;=d`ajl9&aZy%)GZn8#a`-rxkrDOExSrEgL8TDyj+Z zjP7VhA&(KGBl%bS_TkXf)Kq0fMMYu?;B=g!`9Qis%Ira7I$QQ?Isa2-C3cTlCH;B& z>Rxy9;5f>f0GmFHY%vhYh=+%mtceT*3;V$lAtG!Z;N4C41Y@$4T{rP360(Tc1TaW0 zv1Y^@DKXJ9rH|&u2A1Jipv~c4tgwLYVUmpS`*y8If8LIff2sc&oL0btrRVLB#VB*p zFZkE5xq_JR9{L-0S}eaoA9fel$uEhp`+?FFG|Fp8T!8yZ4^183s%>&|a>Ub!-X8Df zTgGfOEE!Lu@x$~8f}g}up37(|)TA7mzF{rOVhT)cDS5XaBaNVYg6`ajh7OvWqsbJP&|}8x zgA$p7WgI1z%o@3WajIcTq+JAJz87RWd z21JPoRsj#{V{h*{0po)AyG#*_SoHu8Ho~`F&+ez)Yz9~#tcZXe%r6o#ycgr&!$UTa zJ`N9CeS(?s$y49!Y$c*yO($#`VTv0cN-M4sVN5xmp@7XVJu z{p;5|AfJlnCQrBoT|1rQ$Va^F0gp(vkdre3|Kq<4v$m$b{(X$D{lOdUoIhU5rl}0>-e4L8BNuX!SK() ziu1ZI*nz#m_oGF{E))+qt6`nEv0W{^zonaRGktUzA>D{RP2e!RaY~x7vyf4{aI(b` zb_{OR5BNW{!RmvJBJ)4Uz(laH$op$YjvRTXXW|h@Kokm<|Kxwtp;$!zEN9jUOowyp z><<03&+54d6Rgu{hY=keodM#iprD{l<6PMb-jfp5Z{O-co|l#mUvmxA2A*74(hHMQ z86U_Qk*sC}B|z8DS9uY|>htjT-xm{!m@Lc;Hl++TaQ%C_ZmETACky=!6LD2zZ#P4# zGy5@Franp2^XJLZ05KyWhQd>`$|ue&eYeDOVa^3M;dklo(E71%s0Fm6hsXe%ovc(QIQuis1Ns5qWs$_Dy!7v91xV6~pyzR2AmD%wwoG3@-psw@hUo}DbM*}$d! z0@X3}Sg!rK9yDQb9DAfF=9s*lf6wnL)~8A>9dW|Djaz6BI?FEW{yrru#D%4_i@^y^ zfA_~8Fh7*EqdX%$qIirZW+)3YG=g+547fh_c!y+xA| z!%%7(v4Zf?YzD3cCKi@>w1mBWs%mOYaL=V;;7-C=PIjKLOS(mI;l;I;#CVG6lx!iE zF8p!;wL$Ok^V8`&B_-bvtY>1vP6|3AoD>sSdfZp;h2`IW+u{CYAx2r_h5wZ-YrsVj z7!=g2Ujg?k04;F~W3jd2={XfFNA8;zu6a%NUY1PL$krcRBcpw??L)@-AdI*0_!7bR+t;t}@H>929Vroxn9%5}*d;ZHOh8yi_{8+k zN*?0++>Nq`S%@47Qa|=g_h4&K0j@4hG-}xOyIEaeuqM`L11!)0-cMkg$`Znc|2$&T z96F5aa8@&+sqt=9y=GcF!(SwE%V2SJ<38udWGfntiipzFpb5B@aQ~V=M%vM=lQAw0 z+*6mWMYB#usi0XM4cns%722-hD|RW6a2^4V;8Q&kK-PRnwdTFJDB&a{weu=K>>N z#%k;nijb9Jv~*TQfA(G2_4UL1V#U}diqF`WO{j-Uo;o6m+#fdE2dnilni@wB3|HdN z3va=RnOM0I3B;(RfQc|%7Hz|2qXcx7SeVGlvAJ>(#$@ugT)6;sVHHxq|`eWM5i@@eIuG z<(R%Ao~3)vx&Ar?v@CK6>~l*`bzSxM#IANjl1}w~Xm$0T02MP^y*5z2COp~k>Qs(z zNr^mmZq4AihO~t?k%V_}*^an>F$|N@50PWz|Dd>`L7OZ&2N1Cr&OH+hiS@*-Ohd;` znpv}aIdKbzx4?uS9&F+^EKWWQpGFgK6;NMK0~hiN3$@SF*_oMnpn!k~C0hrmxA(2{ zhxgE&$Un(usFQ`|FZVXoA(a3ac!-`#eh#-)KJjx(mE-R*zyV+%PliEa$uqlwac2dE zaviT_6!S__10>*%uSk52C1Vz;_`mE7uz|z^H)4a9To_uYS`X->9jK#348n(W z&P;y&ssaA@Cc6VtodYn*Io}9za10_`+Q(MrC~!qRHjr?X{G(@}fDes&E#xErbxsz_ zb&7oNvodUX6K6$ZLIAT(;}< z_z@AW7Lf#VXmw|2amj>T^ENQf0E*E>c7q}kMI5XvUnii!!C`&IzZaeO6)Y7J?T+^_ z5da#HMID;co(u1zvEa{??~l79n+8cRZeG5fo$ZqT%+9B$c%&VEu#?zE7Xd zHYRE*;_rPxr!7mRlmGdgakIDmbBip9Ei5g4m=Q@s0K2CLg`GfUqH3s};dJ}53pUiU zvC3fRGsIu_Ye#VoHch=Y8|>YYt=q19cke#LIBNlslkD7{%QC=%^+QY@CPU3>&Delr zZ%x4B<21w|vZ8?sqyrE@{4J8xigS>!;*r18R+~GPTh~1$CsC;F{8{~hU{!`JXG>#EdI<&&x;f+)k)8EGU m@IOs5fBV^=eE81=Dr(W4%%11b(P+?=(qXkjsRvG8`F{Y0^y7R0 literal 0 HcmV?d00001 diff --git a/benchmark/fri/fri_benchmark_ubuntu_i9.png b/benchmark/fri/fri_benchmark_ubuntu_i9.png new file mode 100644 index 0000000000000000000000000000000000000000..96f4ffb8ec1498bc83d6b59957a051ffe0248186 GIT binary patch literal 16949 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 C2 + +#include "tachyon/base/console/iostream.h" +#include "tachyon/base/containers/container_util.h" + +namespace tachyon::benchmark { + +FRIConfig::FRIConfig() { + parser_.AddFlag>>(&exponents_) + .set_short_name("-k") + .set_required() + .set_help( + "Specify the exponent 'k's where the degree of poly to test is 2ᵏ."); + parser_.AddFlag>(&batch_size_) + .set_short_name("-b") + .set_long_name("--batch_size") + .set_default_value(100) + .set_help("Specify the batch size. By default, 100."); + parser_.AddFlag>(&input_num_) + .set_short_name("-i") + .set_long_name("--input_num") + .set_default_value(4) + .set_help( + "Specify the number of inputs in a single round. By default, 4."); + parser_.AddFlag>(&log_blowup_) + .set_short_name("-l") + .set_long_name("--log_blowup") + .set_default_value(1) + .set_help("Specify the log blowup. By default, 1."); + parser_.AddFlag>>(&vendors_) + .set_long_name("--vendor") + .set_help("Vendors to be benchmarked with. (supported vendors: plonky3"); +} + +void FRIConfig::PostParse() { + base::ranges::sort(exponents_); // NOLINT(build/include_what_you_use) +} + +std::vector FRIConfig::GetDegrees() const { + return base::Map(exponents_, + [](uint32_t exponent) { return (size_t{1} << exponent); }); +} + +bool FRIConfig::Validate() const { + for (const Vendor vendor : vendors_) { + if (vendor.value() != Vendor::kPlonky3) { + tachyon_cerr << "Unsupported vendor " << vendor.ToString() << std::endl; + return false; + } + } + return true; +} + +} // namespace tachyon::benchmark diff --git a/benchmark/fri/fri_config.h b/benchmark/fri/fri_config.h new file mode 100644 index 000000000..b89b7a22e --- /dev/null +++ b/benchmark/fri/fri_config.h @@ -0,0 +1,40 @@ +#ifndef BENCHMARK_FRI_FRI_CONFIG_H_ +#define BENCHMARK_FRI_FRI_CONFIG_H_ + +#include + +#include + +// clang-format off +#include "benchmark/config.h" +// clang-format on + +namespace tachyon::benchmark { + +class FRIConfig : public Config { + public: + FRIConfig(); + FRIConfig(const FRIConfig& other) = delete; + FRIConfig& operator=(const FRIConfig& other) = delete; + + const std::vector& exponents() const { return exponents_; } + size_t batch_size() const { return batch_size_; } + size_t input_num() const { return input_num_; } + uint32_t log_blowup() const { return log_blowup_; } + + std::vector GetDegrees() const; + + private: + // Config methods + void PostParse() override; + bool Validate() const override; + + std::vector exponents_; + size_t batch_size_; + size_t input_num_; + uint32_t log_blowup_; +}; + +} // namespace tachyon::benchmark + +#endif // BENCHMARK_FRI_FRI_CONFIG_H_ diff --git a/benchmark/fri/fri_runner.h b/benchmark/fri/fri_runner.h new file mode 100644 index 000000000..dbe18177f --- /dev/null +++ b/benchmark/fri/fri_runner.h @@ -0,0 +1,94 @@ +#ifndef BENCHMARK_FRI_FRI_RUNNER_H_ +#define BENCHMARK_FRI_FRI_RUNNER_H_ + +#include +#include + +#include +#include +#include + +// clang-format off +#include "benchmark/fri/fri_config.h" +#include "benchmark/simple_reporter.h" +// clang-format on +#include "tachyon/base/time/time.h" +#include "tachyon/c/math/finite_fields/baby_bear/baby_bear_type_traits.h" +#include "tachyon/crypto/commitments/fri/two_adic_multiplicative_coset.h" +#include "tachyon/math/matrix/matrix_types.h" + +namespace tachyon::benchmark { + +template +class FRIRunner { + public: + using F = typename PCS::F; + using Domain = crypto::TwoAdicMultiplicativeCoset; + + typedef tachyon_baby_bear* (*ExternalFn)(const tachyon_baby_bear* data, + const size_t* degrees, + size_t num_of_degrees, + 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) {} + + F Run(Vendor vendor, const math::RowMajorMatrix& input) { + size_t max_degree = static_cast(input.rows()); + std::vector degrees = GetInputDegrees(max_degree); + + std::vector> inner_polys = + base::Map(degrees, [this, input](size_t degree) { + math::RowMajorMatrix ret = + Eigen::Map>( + &input.data()[0], degree, config_.batch_size()); + return ret; + }); + + std::vector inner_domains = + base::Map(degrees, [this](size_t degree) { + return this->pcs_.GetNaturalDomainForDegree(degree); + }); + + 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)); + reporter_.AddTime(vendor, base::TimeTicks::Now() - start); + return commit[1]; + } + + F RunExternal(Vendor vendor, ExternalFn fn, + const math::RowMajorMatrix& input) { + size_t max_degree = static_cast(input.rows()); + std::vector degrees = GetInputDegrees(max_degree); + + uint64_t duration_in_us = 0; + tachyon_baby_bear* data = + fn(c::base::c_cast(input.data()), °rees[0], degrees.size(), + 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 GetInputDegrees(size_t max_degree) { + std::vector 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); + } + return degrees; + } + + SimpleReporter& reporter_; + const FRIConfig& config_; + PCS& pcs_; +}; + +} // namespace tachyon::benchmark + +#endif // BENCHMARK_FRI_FRI_RUNNER_H_ diff --git a/benchmark/fri/plonky3/BUILD.bazel b/benchmark/fri/plonky3/BUILD.bazel new file mode 100644 index 000000000..0152e05a6 --- /dev/null +++ b/benchmark/fri/plonky3/BUILD.bazel @@ -0,0 +1,13 @@ +load("@crate_index//:defs.bzl", "aliases", "all_crate_deps") +load("//bazel:tachyon_rust.bzl", "tachyon_rust_static_library") + +tachyon_rust_static_library( + name = "plonky3", + srcs = glob(["src/**/*.rs"]), + aliases = aliases(), + proc_macro_deps = all_crate_deps(proc_macro = True), + visibility = ["//benchmark/fri:__pkg__"], + deps = all_crate_deps(normal = True) + [ + "//tachyon/rs:tachyon_rs", + ], +) diff --git a/benchmark/fri/plonky3/Cargo.toml b/benchmark/fri/plonky3/Cargo.toml new file mode 100644 index 000000000..994774f5c --- /dev/null +++ b/benchmark/fri/plonky3/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "plonky3_fri_benchmark" +version = "0.0.1" +authors = ["The Tachyon Authors "] +edition = "2021" +description = """ +Plonky3 FRI Benchmark +""" +license = "MIT OR Apache-2.0" +repository = "https://github.com/kroma-network/tachyon" +readme = "README.md" +categories = ["cryptography"] +keywords = ["tachyon", "benchmark", "plonky3"] +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +p3-baby-bear = "0.1.3-succinct" +p3-challenger = "0.1.3-succinct" +p3-commit = "0.1.3-succinct" +p3-dft = "0.1.3-succinct" +p3-field = "0.1.3-succinct" +p3-fri = "0.1.3-succinct" +p3-matrix = "0.1.3-succinct" +p3-merkle-tree = "0.1.3-succinct" +p3-poseidon2 = "0.1.3-succinct" +p3-symmetric = "0.1.3-succinct" +p3-util = "0.1.3-succinct" +tachyon_rs = { path = "../../../tachyon/rs" } +zkhash = { git = "https://github.com/HorizenLabs/poseidon2.git", rev = "bb476b9" } diff --git a/benchmark/fri/plonky3/src/lib.rs b/benchmark/fri/plonky3/src/lib.rs new file mode 100644 index 000000000..e78198f16 --- /dev/null +++ b/benchmark/fri/plonky3/src/lib.rs @@ -0,0 +1,142 @@ +use std::fmt::Debug; +use std::time::Instant; + +use p3_baby_bear::{BabyBear, DiffusionMatrixBabyBear}; +use p3_challenger::{CanObserve, DuplexChallenger, FieldChallenger}; +use p3_commit::{ExtensionMmcs, Pcs, PolynomialSpace}; +use p3_dft::Radix2DitParallel; +use p3_field::extension::BinomialExtensionField; +use p3_field::{AbstractField, ExtensionField, Field}; +use p3_fri::{FriConfig, TwoAdicFriPcs}; +use p3_matrix::dense::RowMajorMatrix; +use p3_merkle_tree::FieldMerkleTreeMmcs; +use p3_poseidon2::{Poseidon2, Poseidon2ExternalMatrixHL}; +use p3_symmetric::{PaddingFreeSponge, TruncatedPermutation}; +use p3_util::log2_strict_usize; + +use tachyon_rs::math::finite_fields::baby_bear::BabyBear as CppBabyBear; +use zkhash::ark_ff::PrimeField as ark_PrimeField; +use zkhash::poseidon2::poseidon2_instance_babybear::RC16 as BabyBearRC16; + +type Val = BabyBear; +type Challenge = BinomialExtensionField; + +type Perm = Poseidon2; +type MyHash = PaddingFreeSponge; +type MyCompress = TruncatedPermutation; + +type ValMmcs = + FieldMerkleTreeMmcs<::Packing, ::Packing, MyHash, MyCompress, 8>; +type ChallengeMmcs = ExtensionMmcs; + +type Dft = Radix2DitParallel; +type Challenger = DuplexChallenger; +type MyPcs = TwoAdicFriPcs; + +fn get_perm(rounds_f: usize, rounds_p: usize) -> Perm { + let mut round_constants: Vec<[BabyBear; 16]> = BabyBearRC16 + .iter() + .map(|vec| { + vec.iter() + .cloned() + .map(|ark_ff| BabyBear::from_canonical_u32(ark_ff.into_bigint().0[0] as u32)) + .collect::>() + .try_into() + .unwrap() + }) + .collect(); + let internal_start = rounds_f / 2; + let internal_end = (rounds_f / 2) + rounds_p; + let internal_round_constants = round_constants + .drain(internal_start..internal_end) + .map(|vec| vec[0]) + .collect::>(); + let external_round_constants = round_constants; + + Perm::new( + rounds_f, + external_round_constants, + Poseidon2ExternalMatrixHL, + rounds_p, + internal_round_constants, + DiffusionMatrixBabyBear, + ) +} + +fn get_pcs(log_blowup: usize, log_n: usize) -> (MyPcs, Challenger) { + let perm = get_perm(8, 13); + + let hash = MyHash::new(perm.clone()); + let compress = MyCompress::new(perm.clone()); + + let val_mmcs = ValMmcs::new(hash, compress); + let challenge_mmcs = ChallengeMmcs::new(val_mmcs.clone()); + + let fri_config = FriConfig { + log_blowup, + num_queries: 10, + proof_of_work_bits: 8, + mmcs: challenge_mmcs, + }; + + let pcs = MyPcs::new(log_n, Dft {}, val_mmcs, fri_config); + (pcs, Challenger::new(perm.clone())) +} + +fn do_test_fri( + (pcs, _challenger): &(P, Challenger), + degrees: Vec, + data: Vec>, + duration: *mut u64, +) -> *mut CppBabyBear +where + P: Pcs, + P::Domain: PolynomialSpace, + Val: Field, + Challenge: ExtensionField, + Challenger: Clone + CanObserve + FieldChallenger, +

>::Commitment: Debug, +{ + let domains: Vec<_> = degrees + .iter() + .map(|°ree| pcs.natural_domain_for_degree(degree)) + .collect(); + let domains_and_polys: Vec<(P::Domain, RowMajorMatrix)> = + domains.into_iter().zip(data.into_iter()).collect(); + + let start = Instant::now(); + let (commit, _data) = pcs.commit(domains_and_polys); + unsafe { + duration.write(start.elapsed().as_micros() as u64); + } + Box::into_raw(Box::new(commit)) 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, + 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> = degrees + .iter() + .map(|°ree| { + let size = degree * batch_size; + let values: Vec = + unsafe { std::slice::from_raw_parts(data as *mut BabyBear, size).to_vec() }; + RowMajorMatrix::::new(values, batch_size) + }) + .collect(); + do_test_fri(&(pcs, challenger), degrees, polys, duration) +}