use std::hint::black_box; use criterion::{BenchmarkId, Criterion}; use crate::{ api::{ ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxAutomorphism, VecZnxAutomorphismInplace, VecZnxAutomorphismInplaceTmpBytes, }, layouts::{Backend, FillUniform, Module, ScratchOwned, VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos, ZnxView, ZnxViewMut}, reference::znx::{ZnxAutomorphism, ZnxCopy, ZnxZero}, source::Source, }; pub fn vec_znx_automorphism_inplace_tmp_bytes(n: usize) -> usize { n * size_of::() } pub fn vec_znx_automorphism(p: i64, res: &mut R, res_col: usize, a: &A, a_col: usize) where R: VecZnxToMut, A: VecZnxToRef, ZNXARI: ZnxAutomorphism + ZnxZero, { let a: VecZnx<&[u8]> = a.to_ref(); let mut res: VecZnx<&mut [u8]> = res.to_mut(); #[cfg(debug_assertions)] { use crate::layouts::ZnxInfos; assert_eq!(a.n(), res.n()); } let min_size: usize = res.size().min(a.size()); for j in 0..min_size { ZNXARI::znx_automorphism(p, res.at_mut(res_col, j), a.at(a_col, j)); } for j in min_size..res.size() { ZNXARI::znx_zero(res.at_mut(res_col, j)); } } pub fn vec_znx_automorphism_inplace(p: i64, res: &mut R, res_col: usize, tmp: &mut [i64]) where R: VecZnxToMut, ZNXARI: ZnxAutomorphism + ZnxCopy, { let mut res: VecZnx<&mut [u8]> = res.to_mut(); #[cfg(debug_assertions)] { assert_eq!(res.n(), tmp.len()); } for j in 0..res.size() { ZNXARI::znx_automorphism(p, tmp, res.at(res_col, j)); ZNXARI::znx_copy(res.at_mut(res_col, j), tmp); } } pub fn bench_vec_znx_automorphism(c: &mut Criterion, label: &str) where Module: VecZnxAutomorphism + ModuleNew, { let group_name: String = format!("vec_znx_automorphism::{label}"); let mut group = c.benchmark_group(group_name); fn runner(params: [usize; 3]) -> impl FnMut() where Module: VecZnxAutomorphism + ModuleNew, { let n: usize = 1 << params[0]; let cols: usize = params[1]; let size: usize = params[2]; let module: Module = Module::::new(n as u64); let mut source: Source = Source::new([0u8; 32]); let mut a: VecZnx> = VecZnx::alloc(n, cols, size); let mut res: VecZnx> = VecZnx::alloc(n, cols, size); // Fill a with random i64 a.fill_uniform(50, &mut source); res.fill_uniform(50, &mut source); move || { for i in 0..cols { module.vec_znx_automorphism(-7, &mut res, i, &a, i); } black_box(()); } } for params in [[10, 2, 2], [11, 2, 4], [12, 2, 8], [13, 2, 16], [14, 2, 32]] { let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x({}x{})", 1 << params[0], params[1], params[2],)); let mut runner = runner::(params); group.bench_with_input(id, &(), |b, _| b.iter(&mut runner)); } group.finish(); } pub fn bench_vec_znx_automorphism_inplace(c: &mut Criterion, label: &str) where Module: VecZnxAutomorphismInplace + VecZnxAutomorphismInplaceTmpBytes + ModuleNew, ScratchOwned: ScratchOwnedAlloc + ScratchOwnedBorrow, { let group_name: String = format!("vec_znx_automorphism_inplace::{label}"); let mut group = c.benchmark_group(group_name); fn runner(params: [usize; 3]) -> impl FnMut() where Module: VecZnxAutomorphismInplace + ModuleNew + VecZnxAutomorphismInplaceTmpBytes, ScratchOwned: ScratchOwnedAlloc + ScratchOwnedBorrow, { let n: usize = 1 << params[0]; let cols: usize = params[1]; let size: usize = params[2]; let module: Module = Module::::new(n as u64); let mut source: Source = Source::new([0u8; 32]); let mut res: VecZnx> = VecZnx::alloc(n, cols, size); let mut scratch = ScratchOwned::alloc(module.vec_znx_automorphism_inplace_tmp_bytes()); // Fill a with random i64 res.fill_uniform(50, &mut source); move || { for i in 0..cols { module.vec_znx_automorphism_inplace(-7, &mut res, i, scratch.borrow()); } black_box(()); } } for params in [[10, 2, 2], [11, 2, 4], [12, 2, 8], [13, 2, 16], [14, 2, 32]] { let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x({}x{})", 1 << params[0], params[1], params[2],)); let mut runner = runner::(params); group.bench_with_input(id, &(), |b, _| b.iter(&mut runner)); } group.finish(); }