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, 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(module: &Module<FFT64>, 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 VmpPMatPrepareImpl<FFT64> for FFT64 {
56 fn vmp_prepare_impl<R, A>(module: &Module<FFT64>, res: &mut R, a: &A, scratch: &mut Scratch<FFT64>)
57 where
58 R: VmpPMatToMut<FFT64>,
59 A: MatZnxToRef,
60 {
61 let mut res: VmpPMat<&mut [u8], FFT64> = 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<FFT64> for FFT64 {
113 fn vmp_apply_dft_to_dft_tmp_bytes_impl(
114 module: &Module<FFT64>,
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<FFT64> for FFT64 {
135 fn vmp_apply_dft_to_dft_impl<R, A, C>(module: &Module<FFT64>, res: &mut R, a: &A, b: &C, scratch: &mut Scratch<FFT64>)
136 where
137 R: VecZnxDftToMut<FFT64>,
138 A: VecZnxDftToRef<FFT64>,
139 C: VmpPMatToRef<FFT64>,
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<FFT64> for FFT64 {
190 fn vmp_apply_dft_to_dft_add_tmp_bytes_impl(
191 module: &Module<FFT64>,
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<FFT64> for FFT64 {
212 fn vmp_apply_dft_to_dft_add_impl<R, A, C>(
213 module: &Module<FFT64>,
214 res: &mut R,
215 a: &A,
216 b: &C,
217 scale: usize,
218 scratch: &mut Scratch<FFT64>,
219 ) where
220 R: VecZnxDftToMut<FFT64>,
221 A: VecZnxDftToRef<FFT64>,
222 C: VmpPMatToRef<FFT64>,
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}