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