arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-hal/src/tests/vmp_pmat/vmp_apply.rs
poulpy-hal/src/tests/vmp_pmat/vmp_apply.rsRaw
  1use crate::{
  2    api::{
  3        ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxBigAlloc, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes,
  4        VecZnxDftAlloc, VecZnxDftFromVecZnx, VecZnxDftToVecZnxBigTmpA, VmpApply, VmpApplyTmpBytes, VmpPMatAlloc, VmpPrepare,
  5    },
  6    layouts::{MatZnx, Module, ScratchOwned, VecZnx, VecZnxBig, VecZnxDft, VmpPMat, ZnxInfos, ZnxViewMut},
  7    oep::{
  8        ModuleNewImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, VecZnxBigAllocImpl, VecZnxBigNormalizeImpl,
  9        VecZnxBigNormalizeTmpBytesImpl, VecZnxDftAllocImpl, VecZnxDftFromVecZnxImpl, VecZnxDftToVecZnxBigTmpAImpl, VmpApplyImpl,
 10        VmpApplyTmpBytesImpl, VmpPMatAllocImpl, VmpPMatPrepareImpl,
 11    },
 12};
 13
 14use crate::layouts::Backend;
 15
 16pub fn test_vmp_apply<B>()
 17where
 18    B: Backend
 19        + ModuleNewImpl<B>
 20        + VmpApplyTmpBytesImpl<B>
 21        + VecZnxBigNormalizeTmpBytesImpl<B>
 22        + VmpPMatAllocImpl<B>
 23        + VecZnxDftAllocImpl<B>
 24        + VecZnxBigAllocImpl<B>
 25        + VmpPMatPrepareImpl<B>
 26        + VecZnxDftFromVecZnxImpl<B>
 27        + VmpApplyImpl<B>
 28        + VecZnxDftToVecZnxBigTmpAImpl<B>
 29        + ScratchOwnedAllocImpl<B>
 30        + ScratchOwnedBorrowImpl<B>
 31        + VecZnxBigNormalizeImpl<B>,
 32{
 33    let log_n: i32 = 5;
 34    let n: usize = 1 << log_n;
 35
 36    let module: Module<B> = Module::<B>::new(n as u64);
 37    let basek: usize = 15;
 38    let a_size: usize = 5;
 39    let mat_size: usize = 6;
 40    let res_size: usize = a_size;
 41
 42    [1, 2].iter().for_each(|cols_in| {
 43        [1, 2].iter().for_each(|cols_out| {
 44            let a_cols: usize = *cols_in;
 45            let res_cols: usize = *cols_out;
 46
 47            let mat_rows: usize = a_size;
 48            let mat_cols_in: usize = a_cols;
 49            let mat_cols_out: usize = res_cols;
 50
 51            let mut scratch = ScratchOwned::alloc(
 52                module.vmp_apply_tmp_bytes(
 53                    res_size,
 54                    a_size,
 55                    mat_rows,
 56                    mat_cols_in,
 57                    mat_cols_out,
 58                    mat_size,
 59                ) | module.vec_znx_big_normalize_tmp_bytes(),
 60            );
 61
 62            let mut a: VecZnx<Vec<u8>> = VecZnx::alloc(n, a_cols, a_size);
 63
 64            (0..a_cols).for_each(|i| {
 65                a.at_mut(i, a_size - 1)[i + 1] = 1;
 66            });
 67
 68            let mut vmp: VmpPMat<Vec<u8>, B> = module.vmp_pmat_alloc(mat_rows, mat_cols_in, mat_cols_out, mat_size);
 69
 70            let mut c_dft: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(mat_cols_out, mat_size);
 71            let mut c_big: VecZnxBig<Vec<u8>, B> = module.vec_znx_big_alloc(mat_cols_out, mat_size);
 72
 73            let mut mat: MatZnx<Vec<u8>> = MatZnx::alloc(n, mat_rows, mat_cols_in, mat_cols_out, mat_size);
 74
 75            // Construts a [VecZnxMatDft] that performs cyclic rotations on each submatrix.
 76            (0..a.size()).for_each(|row_i| {
 77                (0..mat_cols_in).for_each(|col_in_i| {
 78                    (0..mat_cols_out).for_each(|col_out_i| {
 79                        let idx = 1 + col_in_i * mat_cols_out + col_out_i;
 80                        mat.at_mut(row_i, col_in_i).at_mut(col_out_i, row_i)[idx] = 1_i64; // X^{idx}
 81                    });
 82                });
 83            });
 84
 85            module.vmp_prepare(&mut vmp, &mat, scratch.borrow());
 86
 87            let mut a_dft: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(a_cols, a_size);
 88            (0..a_cols).for_each(|i| {
 89                module.vec_znx_dft_from_vec_znx(1, 0, &mut a_dft, i, &a, i);
 90            });
 91
 92            module.vmp_apply(&mut c_dft, &a_dft, &vmp, scratch.borrow());
 93
 94            let mut res_have_vi64: Vec<i64> = vec![i64::default(); n];
 95
 96            let mut res_have: VecZnx<Vec<u8>> = VecZnx::alloc(n, res_cols, res_size);
 97            (0..mat_cols_out).for_each(|i| {
 98                module.vec_znx_dft_to_vec_znx_big_tmp_a(&mut c_big, i, &mut c_dft, i);
 99                module.vec_znx_big_normalize(basek, &mut res_have, i, &c_big, i, scratch.borrow());
100            });
101
102            (0..mat_cols_out).for_each(|col_i| {
103                let mut res_want_vi64: Vec<i64> = vec![i64::default(); n];
104                (0..a_cols).for_each(|i| {
105                    res_want_vi64[(i + 1) + (1 + i * mat_cols_out + col_i)] = 1;
106                });
107                res_have.decode_vec_i64(basek, col_i, basek * a_size, &mut res_have_vi64);
108                assert_eq!(res_have_vi64, res_want_vi64);
109            });
110        });
111    });
112}