arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-backend/src/cpu_spqlios/fft64/vmp_pmat.rs
poulpy-backend/src/cpu_spqlios/fft64/vmp_pmat.rsRaw
  1use poulpy_hal::{
  2    api::{TakeSlice, VmpApplyTmpBytes, VmpPrepareTmpBytes, ZnxInfos, ZnxView, ZnxViewMut},
  3    layouts::{
  4        Backend, MatZnx, MatZnxToRef, Module, Scratch, VecZnxDft, VecZnxDftToMut, VecZnxDftToRef, VmpPMat, VmpPMatOwned,
  5        VmpPMatToMut, VmpPMatToRef,
  6    },
  7    oep::{
  8        VmpApplyAddImpl, VmpApplyAddTmpBytesImpl, VmpApplyImpl, VmpApplyTmpBytesImpl, VmpPMatAllocBytesImpl, VmpPMatAllocImpl,
  9        VmpPMatFromBytesImpl, VmpPMatPrepareImpl, VmpPrepareTmpBytesImpl,
 10    },
 11};
 12
 13use crate::cpu_spqlios::{
 14    FFT64,
 15    ffi::{vec_znx_dft::vec_znx_dft_t, vmp},
 16};
 17
 18unsafe impl VmpPMatAllocBytesImpl<FFT64> for FFT64 {
 19    fn vmp_pmat_alloc_bytes_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> usize {
 20        FFT64::layout_prep_word_count() * n * rows * cols_in * cols_out * size * size_of::<f64>()
 21    }
 22}
 23
 24unsafe impl VmpPMatFromBytesImpl<FFT64> for FFT64 {
 25    fn vmp_pmat_from_bytes_impl(
 26        n: usize,
 27        rows: usize,
 28        cols_in: usize,
 29        cols_out: usize,
 30        size: usize,
 31        bytes: Vec<u8>,
 32    ) -> VmpPMatOwned<FFT64> {
 33        VmpPMatOwned::from_bytes(n, rows, cols_in, cols_out, size, bytes)
 34    }
 35}
 36
 37unsafe impl VmpPMatAllocImpl<FFT64> for FFT64 {
 38    fn vmp_pmat_alloc_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> VmpPMatOwned<FFT64> {
 39        VmpPMatOwned::alloc(n, rows, cols_in, cols_out, size)
 40    }
 41}
 42
 43unsafe impl VmpPrepareTmpBytesImpl<FFT64> for FFT64 {
 44    fn vmp_prepare_tmp_bytes_impl(
 45        module: &Module<FFT64>,
 46        n: usize,
 47        rows: usize,
 48        cols_in: usize,
 49        cols_out: usize,
 50        size: usize,
 51    ) -> usize {
 52        unsafe {
 53            vmp::vmp_prepare_tmp_bytes(
 54                module.ptr(),
 55                n as u64,
 56                (rows * cols_in) as u64,
 57                (cols_out * size) as u64,
 58            ) as usize
 59        }
 60    }
 61}
 62
 63unsafe impl VmpPMatPrepareImpl<FFT64> for FFT64 {
 64    fn vmp_prepare_impl<R, A>(module: &Module<FFT64>, res: &mut R, a: &A, scratch: &mut Scratch<FFT64>)
 65    where
 66        R: VmpPMatToMut<FFT64>,
 67        A: MatZnxToRef,
 68    {
 69        let mut res: VmpPMat<&mut [u8], FFT64> = res.to_mut();
 70        let a: MatZnx<&[u8]> = a.to_ref();
 71
 72        #[cfg(debug_assertions)]
 73        {
 74            assert_eq!(a.n(), res.n());
 75            assert_eq!(
 76                res.cols_in(),
 77                a.cols_in(),
 78                "res.cols_in: {} != a.cols_in: {}",
 79                res.cols_in(),
 80                a.cols_in()
 81            );
 82            assert_eq!(
 83                res.rows(),
 84                a.rows(),
 85                "res.rows: {} != a.rows: {}",
 86                res.rows(),
 87                a.rows()
 88            );
 89            assert_eq!(
 90                res.cols_out(),
 91                a.cols_out(),
 92                "res.cols_out: {} != a.cols_out: {}",
 93                res.cols_out(),
 94                a.cols_out()
 95            );
 96            assert_eq!(
 97                res.size(),
 98                a.size(),
 99                "res.size: {} != a.size: {}",
100                res.size(),
101                a.size()
102            );
103        }
104
105        let (tmp_bytes, _) =
106            scratch.take_slice(module.vmp_prepare_tmp_bytes(res.n(), a.rows(), a.cols_in(), a.cols_out(), a.size()));
107
108        unsafe {
109            vmp::vmp_prepare_contiguous(
110                module.ptr(),
111                res.as_mut_ptr() as *mut vmp::vmp_pmat_t,
112                a.as_ptr(),
113                (a.rows() * a.cols_in()) as u64,
114                (a.size() * a.cols_out()) as u64,
115                tmp_bytes.as_mut_ptr(),
116            );
117        }
118    }
119}
120
121unsafe impl VmpApplyTmpBytesImpl<FFT64> for FFT64 {
122    fn vmp_apply_tmp_bytes_impl(
123        module: &Module<FFT64>,
124        n: usize,
125        res_size: usize,
126        a_size: usize,
127        b_rows: usize,
128        b_cols_in: usize,
129        b_cols_out: usize,
130        b_size: usize,
131    ) -> usize {
132        unsafe {
133            vmp::vmp_apply_dft_to_dft_tmp_bytes(
134                module.ptr(),
135                n as u64,
136                (res_size * b_cols_out) as u64,
137                (a_size * b_cols_in) as u64,
138                (b_rows * b_cols_in) as u64,
139                (b_size * b_cols_out) as u64,
140            ) as usize
141        }
142    }
143}
144
145unsafe impl VmpApplyImpl<FFT64> for FFT64 {
146    fn vmp_apply_impl<R, A, C>(module: &Module<FFT64>, res: &mut R, a: &A, b: &C, scratch: &mut Scratch<FFT64>)
147    where
148        R: VecZnxDftToMut<FFT64>,
149        A: VecZnxDftToRef<FFT64>,
150        C: VmpPMatToRef<FFT64>,
151    {
152        let mut res: VecZnxDft<&mut [u8], _> = res.to_mut();
153        let a: VecZnxDft<&[u8], _> = a.to_ref();
154        let b: VmpPMat<&[u8], _> = b.to_ref();
155
156        #[cfg(debug_assertions)]
157        {
158            assert_eq!(b.n(), res.n());
159            assert_eq!(a.n(), res.n());
160            assert_eq!(
161                res.cols(),
162                b.cols_out(),
163                "res.cols(): {} != b.cols_out: {}",
164                res.cols(),
165                b.cols_out()
166            );
167            assert_eq!(
168                a.cols(),
169                b.cols_in(),
170                "a.cols(): {} != b.cols_in: {}",
171                a.cols(),
172                b.cols_in()
173            );
174        }
175
176        let (tmp_bytes, _) = scratch.take_slice(module.vmp_apply_tmp_bytes(
177            res.n(),
178            res.size(),
179            a.size(),
180            b.rows(),
181            b.cols_in(),
182            b.cols_out(),
183            b.size(),
184        ));
185        unsafe {
186            vmp::vmp_apply_dft_to_dft(
187                module.ptr(),
188                res.as_mut_ptr() as *mut vec_znx_dft_t,
189                (res.size() * res.cols()) as u64,
190                a.as_ptr() as *const vec_znx_dft_t,
191                (a.size() * a.cols()) as u64,
192                b.as_ptr() as *const vmp::vmp_pmat_t,
193                (b.rows() * b.cols_in()) as u64,
194                (b.size() * b.cols_out()) as u64,
195                tmp_bytes.as_mut_ptr(),
196            )
197        }
198    }
199}
200
201unsafe impl VmpApplyAddTmpBytesImpl<FFT64> for FFT64 {
202    fn vmp_apply_add_tmp_bytes_impl(
203        module: &Module<FFT64>,
204        n: usize,
205        res_size: usize,
206        a_size: usize,
207        b_rows: usize,
208        b_cols_in: usize,
209        b_cols_out: usize,
210        b_size: usize,
211    ) -> usize {
212        unsafe {
213            vmp::vmp_apply_dft_to_dft_tmp_bytes(
214                module.ptr(),
215                n as u64,
216                (res_size * b_cols_out) as u64,
217                (a_size * b_cols_in) as u64,
218                (b_rows * b_cols_in) as u64,
219                (b_size * b_cols_out) as u64,
220            ) as usize
221        }
222    }
223}
224
225unsafe impl VmpApplyAddImpl<FFT64> for FFT64 {
226    fn vmp_apply_add_impl<R, A, C>(module: &Module<FFT64>, res: &mut R, a: &A, b: &C, scale: usize, scratch: &mut Scratch<FFT64>)
227    where
228        R: VecZnxDftToMut<FFT64>,
229        A: VecZnxDftToRef<FFT64>,
230        C: VmpPMatToRef<FFT64>,
231    {
232        let mut res: VecZnxDft<&mut [u8], _> = res.to_mut();
233        let a: VecZnxDft<&[u8], _> = a.to_ref();
234        let b: VmpPMat<&[u8], _> = b.to_ref();
235
236        #[cfg(debug_assertions)]
237        {
238            assert_eq!(b.n(), res.n());
239            assert_eq!(a.n(), res.n());
240            assert_eq!(
241                res.cols(),
242                b.cols_out(),
243                "res.cols(): {} != b.cols_out: {}",
244                res.cols(),
245                b.cols_out()
246            );
247            assert_eq!(
248                a.cols(),
249                b.cols_in(),
250                "a.cols(): {} != b.cols_in: {}",
251                a.cols(),
252                b.cols_in()
253            );
254        }
255
256        let (tmp_bytes, _) = scratch.take_slice(module.vmp_apply_tmp_bytes(
257            res.n(),
258            res.size(),
259            a.size(),
260            b.rows(),
261            b.cols_in(),
262            b.cols_out(),
263            b.size(),
264        ));
265        unsafe {
266            vmp::vmp_apply_dft_to_dft_add(
267                module.ptr(),
268                res.as_mut_ptr() as *mut vec_znx_dft_t,
269                (res.size() * res.cols()) as u64,
270                a.as_ptr() as *const vec_znx_dft_t,
271                (a.size() * a.cols()) as u64,
272                b.as_ptr() as *const vmp::vmp_pmat_t,
273                (b.rows() * b.cols_in()) as u64,
274                (b.size() * b.cols_out()) as u64,
275                (scale * b.cols_out()) as u64,
276                tmp_bytes.as_mut_ptr(),
277            )
278        }
279    }
280}