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