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