poulpy/poulpy-backend/src/cpu_spqlios/fft64/vec_znx_dft.rs
poulpy-backend/src/cpu_spqlios/fft64/vec_znx_dft.rsRaw
1use poulpy_hal::{
2 api::{TakeSlice, VecZnxIDFTTmpBytes},
3 layouts::{
4 Backend, Data, Module, Scratch, VecZnx, VecZnxBig, VecZnxBigToMut, VecZnxDft, VecZnxDftOwned, VecZnxDftToMut,
5 VecZnxDftToRef, VecZnxToRef, ZnxInfos, ZnxSliceSize, ZnxView, ZnxViewMut, ZnxZero,
6 },
7 oep::{
8 DFTImpl, IDFTConsumeImpl, IDFTImpl, IDFTTmpAImpl, VecZnxDftAddImpl, VecZnxDftAddInplaceImpl, VecZnxDftAllocBytesImpl,
9 VecZnxDftAllocImpl, VecZnxDftCopyImpl, VecZnxDftFromBytesImpl, VecZnxDftSubABInplaceImpl, VecZnxDftSubBAInplaceImpl,
10 VecZnxDftSubImpl, VecZnxDftZeroImpl, VecZnxIDFTTmpBytesImpl,
11 },
12};
13
14use crate::cpu_spqlios::{
15 FFT64,
16 ffi::{vec_znx_big, vec_znx_dft},
17};
18
19unsafe impl VecZnxDftFromBytesImpl<Self> for FFT64 {
20 fn vec_znx_dft_from_bytes_impl(n: usize, cols: usize, size: usize, bytes: Vec<u8>) -> VecZnxDftOwned<Self> {
21 VecZnxDft::<Vec<u8>, FFT64>::from_bytes(n, cols, size, bytes)
22 }
23}
24
25unsafe impl VecZnxDftAllocBytesImpl<Self> for FFT64 {
26 fn vec_znx_dft_alloc_bytes_impl(n: usize, cols: usize, size: usize) -> usize {
27 FFT64::layout_prep_word_count() * n * cols * size * size_of::<<FFT64 as Backend>::ScalarPrep>()
28 }
29}
30
31unsafe impl VecZnxDftAllocImpl<Self> for FFT64 {
32 fn vec_znx_dft_alloc_impl(n: usize, cols: usize, size: usize) -> VecZnxDftOwned<Self> {
33 VecZnxDftOwned::alloc(n, cols, size)
34 }
35}
36
37unsafe impl VecZnxIDFTTmpBytesImpl<Self> for FFT64 {
38 fn vec_znx_idft_tmp_bytes_impl(module: &Module<Self>) -> usize {
39 unsafe { vec_znx_dft::vec_znx_idft_tmp_bytes(module.ptr()) as usize }
40 }
41}
42
43unsafe impl IDFTImpl<Self> for FFT64 {
44 fn idft_impl<R, A>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize, scratch: &mut Scratch<Self>)
45 where
46 R: VecZnxBigToMut<Self>,
47 A: VecZnxDftToRef<Self>,
48 {
49 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
50 let a: VecZnxDft<&[u8], FFT64> = a.to_ref();
51
52 #[cfg(debug_assertions)]
53 {
54 assert_eq!(res.n(), a.n())
55 }
56
57 let (tmp_bytes, _) = scratch.take_slice(module.vec_znx_idft_tmp_bytes());
58
59 let min_size: usize = res.size().min(a.size());
60
61 unsafe {
62 (0..min_size).for_each(|j| {
63 vec_znx_dft::vec_znx_idft(
64 module.ptr(),
65 res.at_mut_ptr(res_col, j) as *mut vec_znx_big::vec_znx_big_t,
66 1_u64,
67 a.at_ptr(a_col, j) as *const vec_znx_dft::vec_znx_dft_t,
68 1_u64,
69 tmp_bytes.as_mut_ptr(),
70 )
71 });
72 (min_size..res.size()).for_each(|j| {
73 res.zero_at(res_col, j);
74 });
75 }
76 }
77}
78
79unsafe impl IDFTTmpAImpl<Self> for FFT64 {
80 fn idft_tmp_a_impl<R, A>(module: &Module<Self>, res: &mut R, res_col: usize, a: &mut A, a_col: usize)
81 where
82 R: VecZnxBigToMut<Self>,
83 A: VecZnxDftToMut<Self>,
84 {
85 let mut res_mut: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
86 let mut a_mut: VecZnxDft<&mut [u8], FFT64> = a.to_mut();
87
88 let min_size: usize = res_mut.size().min(a_mut.size());
89
90 unsafe {
91 (0..min_size).for_each(|j| {
92 vec_znx_dft::vec_znx_idft_tmp_a(
93 module.ptr(),
94 res_mut.at_mut_ptr(res_col, j) as *mut vec_znx_big::vec_znx_big_t,
95 1_u64,
96 a_mut.at_mut_ptr(a_col, j) as *mut vec_znx_dft::vec_znx_dft_t,
97 1_u64,
98 )
99 });
100 (min_size..res_mut.size()).for_each(|j| {
101 res_mut.zero_at(res_col, j);
102 })
103 }
104 }
105}
106
107unsafe impl IDFTConsumeImpl<Self> for FFT64 {
108 fn idft_consume_impl<D: Data>(module: &Module<Self>, mut a: VecZnxDft<D, FFT64>) -> VecZnxBig<D, FFT64>
109 where
110 VecZnxDft<D, FFT64>: VecZnxDftToMut<Self>,
111 {
112 let mut a_mut: VecZnxDft<&mut [u8], FFT64> = a.to_mut();
113
114 unsafe {
115 // Rev col and rows because ZnxDft.sl() >= ZnxBig.sl()
116 (0..a_mut.size()).for_each(|j| {
117 (0..a_mut.cols()).for_each(|i| {
118 vec_znx_dft::vec_znx_idft_tmp_a(
119 module.ptr(),
120 a_mut.at_mut_ptr(i, j) as *mut vec_znx_big::vec_znx_big_t,
121 1_u64,
122 a_mut.at_mut_ptr(i, j) as *mut vec_znx_dft::vec_znx_dft_t,
123 1_u64,
124 )
125 });
126 });
127 }
128
129 a.into_big()
130 }
131}
132
133unsafe impl DFTImpl<Self> for FFT64 {
134 fn dft_impl<R, A>(module: &Module<Self>, step: usize, offset: usize, res: &mut R, res_col: usize, a: &A, a_col: usize)
135 where
136 R: VecZnxDftToMut<Self>,
137 A: VecZnxToRef,
138 {
139 let mut res_mut: VecZnxDft<&mut [u8], FFT64> = res.to_mut();
140 let a_ref: VecZnx<&[u8]> = a.to_ref();
141 let steps: usize = a_ref.size().div_ceil(step);
142 let min_steps: usize = res_mut.size().min(steps);
143 unsafe {
144 (0..min_steps).for_each(|j| {
145 let limb: usize = offset + j * step;
146 if limb < a_ref.size() {
147 vec_znx_dft::vec_znx_dft(
148 module.ptr(),
149 res_mut.at_mut_ptr(res_col, j) as *mut vec_znx_dft::vec_znx_dft_t,
150 1_u64,
151 a_ref.at_ptr(a_col, limb),
152 1_u64,
153 a_ref.sl() as u64,
154 )
155 }
156 });
157 (min_steps..res_mut.size()).for_each(|j| {
158 res_mut.zero_at(res_col, j);
159 });
160 }
161 }
162}
163
164unsafe impl VecZnxDftAddImpl<Self> for FFT64 {
165 fn vec_znx_dft_add_impl<R, A, D>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &D, b_col: usize)
166 where
167 R: VecZnxDftToMut<Self>,
168 A: VecZnxDftToRef<Self>,
169 D: VecZnxDftToRef<Self>,
170 {
171 let mut res_mut: VecZnxDft<&mut [u8], FFT64> = res.to_mut();
172 let a_ref: VecZnxDft<&[u8], FFT64> = a.to_ref();
173 let b_ref: VecZnxDft<&[u8], FFT64> = b.to_ref();
174
175 let min_size: usize = res_mut.size().min(a_ref.size()).min(b_ref.size());
176
177 unsafe {
178 (0..min_size).for_each(|j| {
179 vec_znx_dft::vec_dft_add(
180 module.ptr(),
181 res_mut.at_mut_ptr(res_col, j) as *mut vec_znx_dft::vec_znx_dft_t,
182 1,
183 a_ref.at_ptr(a_col, j) as *const vec_znx_dft::vec_znx_dft_t,
184 1,
185 b_ref.at_ptr(b_col, j) as *const vec_znx_dft::vec_znx_dft_t,
186 1,
187 );
188 });
189 }
190 (min_size..res_mut.size()).for_each(|j| {
191 res_mut.zero_at(res_col, j);
192 })
193 }
194}
195
196unsafe impl VecZnxDftAddInplaceImpl<Self> for FFT64 {
197 fn vec_znx_dft_add_inplace_impl<R, A>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
198 where
199 R: VecZnxDftToMut<Self>,
200 A: VecZnxDftToRef<Self>,
201 {
202 let mut res_mut: VecZnxDft<&mut [u8], FFT64> = res.to_mut();
203 let a_ref: VecZnxDft<&[u8], FFT64> = a.to_ref();
204
205 let min_size: usize = res_mut.size().min(a_ref.size());
206
207 unsafe {
208 (0..min_size).for_each(|j| {
209 vec_znx_dft::vec_dft_add(
210 module.ptr(),
211 res_mut.at_mut_ptr(res_col, j) as *mut vec_znx_dft::vec_znx_dft_t,
212 1,
213 res_mut.at_ptr(res_col, j) as *const vec_znx_dft::vec_znx_dft_t,
214 1,
215 a_ref.at_ptr(a_col, j) as *const vec_znx_dft::vec_znx_dft_t,
216 1,
217 );
218 });
219 }
220 }
221}
222
223unsafe impl VecZnxDftSubImpl<Self> for FFT64 {
224 fn vec_znx_dft_sub_impl<R, A, D>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &D, b_col: usize)
225 where
226 R: VecZnxDftToMut<Self>,
227 A: VecZnxDftToRef<Self>,
228 D: VecZnxDftToRef<Self>,
229 {
230 let mut res_mut: VecZnxDft<&mut [u8], FFT64> = res.to_mut();
231 let a_ref: VecZnxDft<&[u8], FFT64> = a.to_ref();
232 let b_ref: VecZnxDft<&[u8], FFT64> = b.to_ref();
233
234 let min_size: usize = res_mut.size().min(a_ref.size()).min(b_ref.size());
235
236 unsafe {
237 (0..min_size).for_each(|j| {
238 vec_znx_dft::vec_dft_sub(
239 module.ptr(),
240 res_mut.at_mut_ptr(res_col, j) as *mut vec_znx_dft::vec_znx_dft_t,
241 1,
242 a_ref.at_ptr(a_col, j) as *const vec_znx_dft::vec_znx_dft_t,
243 1,
244 b_ref.at_ptr(b_col, j) as *const vec_znx_dft::vec_znx_dft_t,
245 1,
246 );
247 });
248 }
249 (min_size..res_mut.size()).for_each(|j| {
250 res_mut.zero_at(res_col, j);
251 })
252 }
253}
254
255unsafe impl VecZnxDftSubABInplaceImpl<Self> for FFT64 {
256 fn vec_znx_dft_sub_ab_inplace_impl<R, A>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
257 where
258 R: VecZnxDftToMut<Self>,
259 A: VecZnxDftToRef<Self>,
260 {
261 let mut res_mut: VecZnxDft<&mut [u8], FFT64> = res.to_mut();
262 let a_ref: VecZnxDft<&[u8], FFT64> = a.to_ref();
263
264 let min_size: usize = res_mut.size().min(a_ref.size());
265
266 unsafe {
267 (0..min_size).for_each(|j| {
268 vec_znx_dft::vec_dft_sub(
269 module.ptr(),
270 res_mut.at_mut_ptr(res_col, j) as *mut vec_znx_dft::vec_znx_dft_t,
271 1,
272 res_mut.at_ptr(res_col, j) as *const vec_znx_dft::vec_znx_dft_t,
273 1,
274 a_ref.at_ptr(a_col, j) as *const vec_znx_dft::vec_znx_dft_t,
275 1,
276 );
277 });
278 }
279 }
280}
281
282unsafe impl VecZnxDftSubBAInplaceImpl<Self> for FFT64 {
283 fn vec_znx_dft_sub_ba_inplace_impl<R, A>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
284 where
285 R: VecZnxDftToMut<Self>,
286 A: VecZnxDftToRef<Self>,
287 {
288 let mut res_mut: VecZnxDft<&mut [u8], FFT64> = res.to_mut();
289 let a_ref: VecZnxDft<&[u8], FFT64> = a.to_ref();
290
291 let min_size: usize = res_mut.size().min(a_ref.size());
292
293 unsafe {
294 (0..min_size).for_each(|j| {
295 vec_znx_dft::vec_dft_sub(
296 module.ptr(),
297 res_mut.at_mut_ptr(res_col, j) as *mut vec_znx_dft::vec_znx_dft_t,
298 1,
299 a_ref.at_ptr(a_col, j) as *const vec_znx_dft::vec_znx_dft_t,
300 1,
301 res_mut.at_ptr(res_col, j) as *const vec_znx_dft::vec_znx_dft_t,
302 1,
303 );
304 });
305 }
306 }
307}
308
309unsafe impl VecZnxDftCopyImpl<Self> for FFT64 {
310 fn vec_znx_dft_copy_impl<R, A>(
311 _module: &Module<Self>,
312 step: usize,
313 offset: usize,
314 res: &mut R,
315 res_col: usize,
316 a: &A,
317 a_col: usize,
318 ) where
319 R: VecZnxDftToMut<Self>,
320 A: VecZnxDftToRef<Self>,
321 {
322 let mut res_mut: VecZnxDft<&mut [u8], FFT64> = res.to_mut();
323 let a_ref: VecZnxDft<&[u8], FFT64> = a.to_ref();
324
325 let steps: usize = a_ref.size().div_ceil(step);
326 let min_steps: usize = res_mut.size().min(steps);
327
328 (0..min_steps).for_each(|j| {
329 let limb: usize = offset + j * step;
330 if limb < a_ref.size() {
331 res_mut
332 .at_mut(res_col, j)
333 .copy_from_slice(a_ref.at(a_col, limb));
334 }
335 });
336 (min_steps..res_mut.size()).for_each(|j| {
337 res_mut.zero_at(res_col, j);
338 })
339 }
340}
341
342unsafe impl VecZnxDftZeroImpl<Self> for FFT64 {
343 fn vec_znx_dft_zero_impl<R>(_module: &Module<Self>, res: &mut R)
344 where
345 R: VecZnxDftToMut<Self>,
346 {
347 res.to_mut().data.fill(0);
348 }
349}