arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-hal/src/reference/vec_znx/add.rs
poulpy-hal/src/reference/vec_znx/add.rsRaw
  1use std::hint::black_box;
  2
  3use criterion::{BenchmarkId, Criterion};
  4
  5use crate::{
  6    api::{ModuleNew, VecZnxAdd, VecZnxAddInplace},
  7    layouts::{Backend, FillUniform, Module, VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos, ZnxView, ZnxViewMut},
  8    reference::znx::{ZnxAdd, ZnxAddInplace, ZnxCopy, ZnxZero},
  9    source::Source,
 10};
 11
 12pub fn vec_znx_add<R, A, B, ZNXARI>(res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
 13where
 14    R: VecZnxToMut,
 15    A: VecZnxToRef,
 16    B: VecZnxToRef,
 17    ZNXARI: ZnxAdd + ZnxCopy + ZnxZero,
 18{
 19    let a: VecZnx<&[u8]> = a.to_ref();
 20    let b: VecZnx<&[u8]> = b.to_ref();
 21    let mut res: VecZnx<&mut [u8]> = res.to_mut();
 22
 23    #[cfg(debug_assertions)]
 24    {
 25        assert_eq!(a.n(), res.n());
 26        assert_eq!(b.n(), res.n());
 27    }
 28
 29    let res_size: usize = res.size();
 30    let a_size: usize = a.size();
 31    let b_size: usize = b.size();
 32
 33    if a_size <= b_size {
 34        let sum_size: usize = a_size.min(res_size);
 35        let cpy_size: usize = b_size.min(res_size);
 36
 37        for j in 0..sum_size {
 38            ZNXARI::znx_add(res.at_mut(res_col, j), a.at(a_col, j), b.at(b_col, j));
 39        }
 40
 41        for j in sum_size..cpy_size {
 42            ZNXARI::znx_copy(res.at_mut(res_col, j), b.at(b_col, j));
 43        }
 44
 45        for j in cpy_size..res_size {
 46            ZNXARI::znx_zero(res.at_mut(res_col, j));
 47        }
 48    } else {
 49        let sum_size: usize = b_size.min(res_size);
 50        let cpy_size: usize = a_size.min(res_size);
 51
 52        for j in 0..sum_size {
 53            ZNXARI::znx_add(res.at_mut(res_col, j), a.at(a_col, j), b.at(b_col, j));
 54        }
 55
 56        for j in sum_size..cpy_size {
 57            ZNXARI::znx_copy(res.at_mut(res_col, j), a.at(a_col, j));
 58        }
 59
 60        for j in cpy_size..res_size {
 61            ZNXARI::znx_zero(res.at_mut(res_col, j));
 62        }
 63    }
 64}
 65
 66pub fn vec_znx_add_inplace<R, A, ZNXARI>(res: &mut R, res_col: usize, a: &A, a_col: usize)
 67where
 68    R: VecZnxToMut,
 69    A: VecZnxToRef,
 70    ZNXARI: ZnxAddInplace,
 71{
 72    let a: VecZnx<&[u8]> = a.to_ref();
 73    let mut res: VecZnx<&mut [u8]> = res.to_mut();
 74
 75    #[cfg(debug_assertions)]
 76    {
 77        assert_eq!(a.n(), res.n());
 78    }
 79
 80    let res_size: usize = res.size();
 81    let a_size: usize = a.size();
 82
 83    let sum_size: usize = a_size.min(res_size);
 84
 85    for j in 0..sum_size {
 86        ZNXARI::znx_add_inplace(res.at_mut(res_col, j), a.at(a_col, j));
 87    }
 88}
 89
 90pub fn bench_vec_znx_add<B: Backend>(c: &mut Criterion, label: &str)
 91where
 92    Module<B>: VecZnxAdd + ModuleNew<B>,
 93{
 94    let group_name: String = format!("vec_znx_add::{label}");
 95
 96    let mut group = c.benchmark_group(group_name);
 97
 98    fn runner<B: Backend>(params: [usize; 3]) -> impl FnMut()
 99    where
100        Module<B>: VecZnxAdd + ModuleNew<B>,
101    {
102        let n: usize = 1 << params[0];
103        let cols: usize = params[1];
104        let size: usize = params[2];
105
106        let module: Module<B> = Module::<B>::new(n as u64);
107
108        let mut source: Source = Source::new([0u8; 32]);
109
110        let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
111        let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
112        let mut c: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
113
114        // Fill a with random i64
115        a.fill_uniform(50, &mut source);
116        b.fill_uniform(50, &mut source);
117
118        move || {
119            for i in 0..cols {
120                module.vec_znx_add(&mut c, i, &a, i, &b, i);
121            }
122            black_box(());
123        }
124    }
125
126    for params in [[10, 2, 2], [11, 2, 4], [12, 2, 8], [13, 2, 16], [14, 2, 32]] {
127        let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x({}x{})", 1 << params[0], params[1], params[2],));
128        let mut runner = runner::<B>(params);
129        group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
130    }
131
132    group.finish();
133}
134
135pub fn bench_vec_znx_add_inplace<B: Backend>(c: &mut Criterion, label: &str)
136where
137    Module<B>: VecZnxAddInplace + ModuleNew<B>,
138{
139    let group_name: String = format!("vec_znx_add_inplace::{label}");
140
141    let mut group = c.benchmark_group(group_name);
142
143    fn runner<B: Backend>(params: [usize; 3]) -> impl FnMut()
144    where
145        Module<B>: VecZnxAddInplace + ModuleNew<B>,
146    {
147        let n: usize = 1 << params[0];
148        let cols: usize = params[1];
149        let size: usize = params[2];
150
151        let module: Module<B> = Module::<B>::new(n as u64);
152
153        let mut source: Source = Source::new([0u8; 32]);
154
155        let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
156        let mut b: VecZnx<Vec<u8>> = VecZnx::alloc(n, cols, size);
157
158        // Fill a with random i64
159        a.fill_uniform(50, &mut source);
160        b.fill_uniform(50, &mut source);
161
162        move || {
163            for i in 0..cols {
164                module.vec_znx_add_inplace(&mut b, i, &a, i);
165            }
166            black_box(());
167        }
168    }
169
170    for params in [[10, 2, 2], [11, 2, 4], [12, 2, 8], [13, 2, 16], [14, 2, 32]] {
171        let id: BenchmarkId = BenchmarkId::from_parameter(format!("{}x({}x{})", 1 << params[0], params[1], params[2]));
172        let mut runner = runner::<B>(params);
173        group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
174    }
175
176    group.finish();
177}