arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/base2k/src/vec_znx_dft_ops.rs
base2k/src/vec_znx_dft_ops.rsRaw
  1use crate::ffi::{vec_znx_big, vec_znx_dft};
  2use crate::vec_znx_dft::bytes_of_vec_znx_dft;
  3use crate::znx_base::ZnxInfos;
  4use crate::{Backend, VecZnxDftOwned};
  5use crate::{FFT64, Module, VecZnx, VecZnxBig, VecZnxDft, ZnxView, ZnxViewMut, ZnxZero, assert_alignement};
  6use std::cmp::min;
  7
  8pub trait VecZnxDftAlloc<B> {
  9    /// Allocates a vector Z[X]/(X^N+1) that stores normalized in the DFT space.
 10    fn new_vec_znx_dft(&self, cols: usize, size: usize) -> VecZnxDftOwned<B>;
 11
 12    /// Returns a new [VecZnxDft] with the provided bytes array as backing array.
 13    ///
 14    /// Behavior: takes ownership of the backing array.
 15    ///
 16    /// # Arguments
 17    ///
 18    /// * `cols`: the number of cols of the [VecZnxDft].
 19    /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_dft].
 20    ///
 21    /// # Panics
 22    /// If `bytes.len()` < [Module::bytes_of_vec_znx_dft].
 23    fn new_vec_znx_dft_from_bytes(&self, cols: usize, size: usize, bytes: Vec<u8>) -> VecZnxDftOwned<B>;
 24
 25    /// Returns a new [VecZnxDft] with the provided bytes array as backing array.
 26    ///
 27    /// # Arguments
 28    ///
 29    /// * `cols`: the number of cols of the [VecZnxDft].
 30    /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_dft].
 31    ///
 32    /// # Panics
 33    /// If `bytes.len()` < [Module::bytes_of_vec_znx_dft].
 34    fn bytes_of_vec_znx_dft(&self, cols: usize, size: usize) -> usize;
 35}
 36
 37pub trait VecZnxDftOps<DataMut, Data, B> {
 38    /// Returns the minimum number of bytes necessary to allocate
 39    /// a new [VecZnxDft] through [VecZnxDft::from_bytes].
 40    fn vec_znx_idft_tmp_bytes(&self) -> usize;
 41
 42    /// b <- IDFT(a), uses a as scratch space.
 43    fn vec_znx_idft_tmp_a(&self, res: &mut VecZnxBig<DataMut, B>, res_col: usize, a: &mut VecZnxDft<DataMut, B>, a_cols: usize);
 44
 45    fn vec_znx_idft(
 46        &self,
 47        res: &mut VecZnxBig<DataMut, B>,
 48        res_col: usize,
 49        a: &VecZnxDft<Data, B>,
 50        a_col: usize,
 51        tmp_bytes: &mut [u8],
 52    );
 53
 54    fn vec_znx_dft(&self, res: &mut VecZnxDft<DataMut, B>, res_col: usize, a: &VecZnx<Data>, a_col: usize);
 55}
 56
 57impl<B: Backend> VecZnxDftAlloc<B> for Module<B> {
 58    fn new_vec_znx_dft(&self, cols: usize, size: usize) -> VecZnxDftOwned<B> {
 59        VecZnxDftOwned::new(&self, cols, size)
 60    }
 61
 62    fn new_vec_znx_dft_from_bytes(&self, cols: usize, size: usize, bytes: Vec<u8>) -> VecZnxDftOwned<B> {
 63        VecZnxDftOwned::new_from_bytes(self, cols, size, bytes)
 64    }
 65
 66    // fn new_vec_znx_dft_from_bytes_borrow(&self, cols: usize, size: usize, bytes: &mut [u8]) -> VecZnxDft<FFT64> {
 67    //     VecZnxDft::from_bytes_borrow(self, 1, cols, size, bytes)
 68    // }
 69
 70    fn bytes_of_vec_znx_dft(&self, cols: usize, size: usize) -> usize {
 71        bytes_of_vec_znx_dft(self, cols, size)
 72    }
 73}
 74
 75impl<DataMut, Data> VecZnxDftOps<DataMut, Data, FFT64> for Module<FFT64>
 76where
 77    DataMut: AsMut<[u8]> + AsRef<[u8]>,
 78    Data: AsRef<[u8]>,
 79{
 80    fn vec_znx_idft_tmp_a(
 81        &self,
 82        res: &mut VecZnxBig<DataMut, FFT64>,
 83        res_col: usize,
 84        a: &mut VecZnxDft<DataMut, FFT64>,
 85        a_col: usize,
 86    ) {
 87        let min_size: usize = min(res.size(), a.size());
 88
 89        unsafe {
 90            (0..min_size).for_each(|j| {
 91                vec_znx_dft::vec_znx_idft_tmp_a(
 92                    self.ptr,
 93                    res.at_mut_ptr(res_col, j) as *mut vec_znx_big::vec_znx_big_t,
 94                    1 as u64,
 95                    a.at_mut_ptr(a_col, j) as *mut vec_znx_dft::vec_znx_dft_t,
 96                    1 as u64,
 97                )
 98            });
 99            (min_size..res.size()).for_each(|j| {
100                res.zero_at(res_col, j);
101            })
102        }
103    }
104
105    fn vec_znx_idft_tmp_bytes(&self) -> usize {
106        unsafe { vec_znx_dft::vec_znx_idft_tmp_bytes(self.ptr) as usize }
107    }
108
109    /// b <- DFT(a)
110    ///
111    /// # Panics
112    /// If b.cols < a_cols
113    fn vec_znx_dft(&self, res: &mut VecZnxDft<DataMut, FFT64>, res_col: usize, a: &VecZnx<Data>, a_col: usize) {
114        let min_size: usize = min(res.size(), a.size());
115
116        unsafe {
117            (0..min_size).for_each(|j| {
118                vec_znx_dft::vec_znx_dft(
119                    self.ptr,
120                    res.at_mut_ptr(res_col, j) as *mut vec_znx_dft::vec_znx_dft_t,
121                    1 as u64,
122                    a.at_ptr(a_col, j),
123                    1 as u64,
124                    a.sl() as u64,
125                )
126            });
127            (min_size..res.size()).for_each(|j| {
128                res.zero_at(res_col, j);
129            });
130        }
131    }
132
133    // b <- IDFT(a), scratch space size obtained with [vec_znx_idft_tmp_bytes].
134    fn vec_znx_idft(
135        &self,
136        res: &mut VecZnxBig<DataMut, FFT64>,
137        res_col: usize,
138        a: &VecZnxDft<Data, FFT64>,
139        a_col: usize,
140        tmp_bytes: &mut [u8],
141    ) {
142        #[cfg(debug_assertions)]
143        {
144            assert!(
145                tmp_bytes.len() >= <Self as VecZnxDftOps<DataMut, DataMut, FFT64>>::vec_znx_idft_tmp_bytes(self),
146                "invalid tmp_bytes: tmp_bytes.len()={} < self.vec_znx_idft_tmp_bytes()={}",
147                tmp_bytes.len(),
148                <Self as VecZnxDftOps<DataMut, DataMut, FFT64>>::vec_znx_idft_tmp_bytes(self)
149            );
150            assert_alignement(tmp_bytes.as_ptr())
151        }
152
153        let min_size: usize = min(res.size(), a.size());
154
155        unsafe {
156            (0..min_size).for_each(|j| {
157                vec_znx_dft::vec_znx_idft(
158                    self.ptr,
159                    res.at_mut_ptr(res_col, j) as *mut vec_znx_big::vec_znx_big_t,
160                    1 as u64,
161                    a.at_ptr(a_col, j) as *const vec_znx_dft::vec_znx_dft_t,
162                    1 as u64,
163                    tmp_bytes.as_mut_ptr(),
164                )
165            });
166            (min_size..res.size()).for_each(|j| {
167                res.zero_at(res_col, j);
168            });
169        }
170    }
171}