poulpy/poulpy-backend/src/cpu_spqlios/fft64/vec_znx.rs
poulpy-backend/src/cpu_spqlios/fft64/vec_znx.rsRaw
1use poulpy_hal::{
2 api::{
3 TakeSlice, VecZnxLshTmpBytes, VecZnxMergeRingsTmpBytes, VecZnxNormalizeTmpBytes, VecZnxRshTmpBytes,
4 VecZnxSplitRingTmpBytes,
5 },
6 layouts::{
7 Module, ScalarZnx, ScalarZnxToRef, Scratch, VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos, ZnxSliceSize, ZnxView, ZnxViewMut,
8 },
9 oep::{
10 TakeSliceImpl, VecZnxAddImpl, VecZnxAddInplaceImpl, VecZnxAddNormalImpl, VecZnxAddScalarImpl, VecZnxAddScalarInplaceImpl,
11 VecZnxAutomorphismImpl, VecZnxAutomorphismInplaceImpl, VecZnxAutomorphismInplaceTmpBytesImpl, VecZnxCopyImpl,
12 VecZnxFillNormalImpl, VecZnxFillUniformImpl, VecZnxLshImpl, VecZnxLshInplaceImpl, VecZnxLshTmpBytesImpl,
13 VecZnxMergeRingsImpl, VecZnxMergeRingsTmpBytesImpl, VecZnxMulXpMinusOneImpl, VecZnxMulXpMinusOneInplaceImpl,
14 VecZnxMulXpMinusOneInplaceTmpBytesImpl, VecZnxNegateImpl, VecZnxNegateInplaceImpl, VecZnxNormalizeImpl,
15 VecZnxNormalizeInplaceImpl, VecZnxNormalizeTmpBytesImpl, VecZnxRotateImpl, VecZnxRotateInplaceImpl,
16 VecZnxRotateInplaceTmpBytesImpl, VecZnxRshImpl, VecZnxRshInplaceImpl, VecZnxRshTmpBytesImpl, VecZnxSplitRingImpl,
17 VecZnxSplitRingTmpBytesImpl, VecZnxSubImpl, VecZnxSubInplaceImpl, VecZnxSubNegateInplaceImpl, VecZnxSubScalarImpl,
18 VecZnxSubScalarInplaceImpl, VecZnxSwitchRingImpl, VecZnxZeroImpl,
19 },
20 reference::{
21 vec_znx::{
22 vec_znx_add_normal_ref, vec_znx_automorphism_inplace_tmp_bytes, vec_znx_copy, vec_znx_fill_normal_ref,
23 vec_znx_fill_uniform_ref, vec_znx_lsh, vec_znx_lsh_inplace, vec_znx_lsh_tmp_bytes, vec_znx_merge_rings,
24 vec_znx_merge_rings_tmp_bytes, vec_znx_mul_xp_minus_one_inplace_tmp_bytes, vec_znx_normalize_tmp_bytes,
25 vec_znx_rotate_inplace_tmp_bytes, vec_znx_rsh, vec_znx_rsh_inplace, vec_znx_rsh_tmp_bytes, vec_znx_split_ring,
26 vec_znx_split_ring_tmp_bytes, vec_znx_switch_ring, vec_znx_zero,
27 },
28 znx::{znx_copy_ref, znx_zero_ref},
29 },
30 source::Source,
31};
32
33use crate::cpu_spqlios::{
34 FFT64Spqlios,
35 ffi::{module::module_info_t, vec_znx, znx},
36};
37
38unsafe impl VecZnxZeroImpl<Self> for FFT64Spqlios {
39 fn vec_znx_zero_impl<R>(_module: &Module<Self>, res: &mut R, res_col: usize)
40 where
41 R: VecZnxToMut,
42 {
43 vec_znx_zero::<_, FFT64Spqlios>(res, res_col);
44 }
45}
46
47unsafe impl VecZnxNormalizeTmpBytesImpl<Self> for FFT64Spqlios {
48 fn vec_znx_normalize_tmp_bytes_impl(module: &Module<Self>) -> usize {
49 vec_znx_normalize_tmp_bytes(module.n())
50 }
51}
52
53unsafe impl VecZnxNormalizeImpl<Self> for FFT64Spqlios
54where
55 Self: TakeSliceImpl<Self> + VecZnxNormalizeTmpBytesImpl<Self>,
56{
57 fn vec_znx_normalize_impl<R, A>(
58 module: &Module<Self>,
59 res_basek: usize,
60 res: &mut R,
61 res_col: usize,
62 a_basek: usize,
63 a: &A,
64 a_col: usize,
65 scratch: &mut Scratch<Self>,
66 ) where
67 R: VecZnxToMut,
68 A: VecZnxToRef,
69 {
70 let a: VecZnx<&[u8]> = a.to_ref();
71 let mut res: VecZnx<&mut [u8]> = res.to_mut();
72
73 #[cfg(debug_assertions)]
74 {
75 assert_eq!(res.n(), a.n());
76 assert_eq!(
77 res_basek, a_basek,
78 "res_basek != a_basek -> base2k conversion is not supported"
79 )
80 }
81
82 let (tmp_bytes, _) = scratch.take_slice(module.vec_znx_normalize_tmp_bytes());
83
84 unsafe {
85 vec_znx::vec_znx_normalize_base2k(
86 module.ptr() as *const module_info_t,
87 res_basek as u64,
88 res.at_mut_ptr(res_col, 0),
89 res.size() as u64,
90 res.sl() as u64,
91 a.at_ptr(a_col, 0),
92 a.size() as u64,
93 a.sl() as u64,
94 tmp_bytes.as_mut_ptr(),
95 );
96 }
97 }
98}
99
100unsafe impl VecZnxNormalizeInplaceImpl<Self> for FFT64Spqlios
101where
102 Self: TakeSliceImpl<Self> + VecZnxNormalizeTmpBytesImpl<Self>,
103{
104 fn vec_znx_normalize_inplace_impl<A>(
105 module: &Module<Self>,
106 base2k: usize,
107 a: &mut A,
108 a_col: usize,
109 scratch: &mut Scratch<Self>,
110 ) where
111 A: VecZnxToMut,
112 {
113 let mut a: VecZnx<&mut [u8]> = a.to_mut();
114
115 let (tmp_bytes, _) = scratch.take_slice(module.vec_znx_normalize_tmp_bytes());
116
117 unsafe {
118 vec_znx::vec_znx_normalize_base2k(
119 module.ptr() as *const module_info_t,
120 base2k as u64,
121 a.at_mut_ptr(a_col, 0),
122 a.size() as u64,
123 a.sl() as u64,
124 a.at_ptr(a_col, 0),
125 a.size() as u64,
126 a.sl() as u64,
127 tmp_bytes.as_mut_ptr(),
128 );
129 }
130 }
131}
132
133unsafe impl VecZnxAddImpl<Self> for FFT64Spqlios {
134 fn vec_znx_add_impl<R, A, C>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &C, b_col: usize)
135 where
136 R: VecZnxToMut,
137 A: VecZnxToRef,
138 C: VecZnxToRef,
139 {
140 let a: VecZnx<&[u8]> = a.to_ref();
141 let b: VecZnx<&[u8]> = b.to_ref();
142 let mut res: VecZnx<&mut [u8]> = res.to_mut();
143
144 #[cfg(debug_assertions)]
145 {
146 assert_eq!(a.n(), res.n());
147 assert_eq!(b.n(), res.n());
148 assert_ne!(a.as_ptr(), b.as_ptr());
149 }
150 unsafe {
151 vec_znx::vec_znx_add(
152 module.ptr() as *const module_info_t,
153 res.at_mut_ptr(res_col, 0),
154 res.size() as u64,
155 res.sl() as u64,
156 a.at_ptr(a_col, 0),
157 a.size() as u64,
158 a.sl() as u64,
159 b.at_ptr(b_col, 0),
160 b.size() as u64,
161 b.sl() as u64,
162 )
163 }
164 }
165}
166
167unsafe impl VecZnxAddInplaceImpl<Self> for FFT64Spqlios {
168 fn vec_znx_add_inplace_impl<R, A>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
169 where
170 R: VecZnxToMut,
171 A: VecZnxToRef,
172 {
173 let a: VecZnx<&[u8]> = a.to_ref();
174 let mut res: VecZnx<&mut [u8]> = res.to_mut();
175
176 #[cfg(debug_assertions)]
177 {
178 assert_eq!(a.n(), res.n());
179 }
180 unsafe {
181 vec_znx::vec_znx_add(
182 module.ptr() as *const module_info_t,
183 res.at_mut_ptr(res_col, 0),
184 res.size() as u64,
185 res.sl() as u64,
186 a.at_ptr(a_col, 0),
187 a.size() as u64,
188 a.sl() as u64,
189 res.at_ptr(res_col, 0),
190 res.size() as u64,
191 res.sl() as u64,
192 )
193 }
194 }
195}
196
197unsafe impl VecZnxAddScalarInplaceImpl<Self> for FFT64Spqlios {
198 fn vec_znx_add_scalar_inplace_impl<R, A>(
199 module: &Module<Self>,
200 res: &mut R,
201 res_col: usize,
202 res_limb: usize,
203 a: &A,
204 a_col: usize,
205 ) where
206 R: VecZnxToMut,
207 A: ScalarZnxToRef,
208 {
209 let mut res: VecZnx<&mut [u8]> = res.to_mut();
210 let a: ScalarZnx<&[u8]> = a.to_ref();
211
212 #[cfg(debug_assertions)]
213 {
214 assert_eq!(a.n(), res.n());
215 }
216
217 unsafe {
218 vec_znx::vec_znx_add(
219 module.ptr() as *const module_info_t,
220 res.at_mut_ptr(res_col, res_limb),
221 1_u64,
222 res.sl() as u64,
223 a.at_ptr(a_col, 0),
224 a.size() as u64,
225 a.sl() as u64,
226 res.at_ptr(res_col, res_limb),
227 1_u64,
228 res.sl() as u64,
229 )
230 }
231 }
232}
233
234unsafe impl VecZnxAddScalarImpl<Self> for FFT64Spqlios {
235 fn vec_znx_add_scalar_impl<R, A, B>(
236 module: &Module<Self>,
237 res: &mut R,
238 res_col: usize,
239 a: &A,
240 a_col: usize,
241 b: &B,
242 b_col: usize,
243 b_limb: usize,
244 ) where
245 R: VecZnxToMut,
246 A: ScalarZnxToRef,
247 B: VecZnxToRef,
248 {
249 let mut res: VecZnx<&mut [u8]> = res.to_mut();
250 let a: ScalarZnx<&[u8]> = a.to_ref();
251 let b: VecZnx<&[u8]> = b.to_ref();
252
253 #[cfg(debug_assertions)]
254 {
255 assert_eq!(a.n(), res.n());
256 }
257
258 let min_size: usize = b.size().min(res.size());
259
260 unsafe {
261 vec_znx::vec_znx_add(
262 module.ptr() as *const module_info_t,
263 res.at_mut_ptr(res_col, b_limb),
264 1_u64,
265 res.sl() as u64,
266 a.at_ptr(a_col, 0),
267 a.size() as u64,
268 a.sl() as u64,
269 b.at_ptr(b_col, b_limb),
270 1_u64,
271 b.sl() as u64,
272 );
273
274 for j in 0..min_size {
275 if j != b_limb {
276 znx_copy_ref(res.at_mut(res_col, j), b.at(b_col, j));
277 }
278 }
279
280 for j in min_size..res.size() {
281 znx_zero_ref(res.at_mut(res_col, j));
282 }
283 }
284 }
285}
286
287unsafe impl VecZnxSubImpl<Self> for FFT64Spqlios {
288 fn vec_znx_sub_impl<R, A, C>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &C, b_col: usize)
289 where
290 R: VecZnxToMut,
291 A: VecZnxToRef,
292 C: VecZnxToRef,
293 {
294 let a: VecZnx<&[u8]> = a.to_ref();
295 let b: VecZnx<&[u8]> = b.to_ref();
296 let mut res: VecZnx<&mut [u8]> = res.to_mut();
297
298 #[cfg(debug_assertions)]
299 {
300 assert_eq!(a.n(), res.n());
301 assert_eq!(b.n(), res.n());
302 assert_ne!(a.as_ptr(), b.as_ptr());
303 }
304 unsafe {
305 vec_znx::vec_znx_sub(
306 module.ptr() as *const module_info_t,
307 res.at_mut_ptr(res_col, 0),
308 res.size() as u64,
309 res.sl() as u64,
310 a.at_ptr(a_col, 0),
311 a.size() as u64,
312 a.sl() as u64,
313 b.at_ptr(b_col, 0),
314 b.size() as u64,
315 b.sl() as u64,
316 )
317 }
318 }
319}
320
321unsafe impl VecZnxSubInplaceImpl<Self> for FFT64Spqlios {
322 fn vec_znx_sub_inplace_impl<R, A>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
323 where
324 R: VecZnxToMut,
325 A: VecZnxToRef,
326 {
327 let a: VecZnx<&[u8]> = a.to_ref();
328 let mut res: VecZnx<&mut [u8]> = res.to_mut();
329 #[cfg(debug_assertions)]
330 {
331 assert_eq!(a.n(), res.n());
332 }
333 unsafe {
334 vec_znx::vec_znx_sub(
335 module.ptr() as *const module_info_t,
336 res.at_mut_ptr(res_col, 0),
337 res.size() as u64,
338 res.sl() as u64,
339 res.at_ptr(res_col, 0),
340 res.size() as u64,
341 res.sl() as u64,
342 a.at_ptr(a_col, 0),
343 a.size() as u64,
344 a.sl() as u64,
345 )
346 }
347 }
348}
349
350unsafe impl VecZnxSubNegateInplaceImpl<Self> for FFT64Spqlios {
351 fn vec_znx_sub_negate_inplace_impl<R, A>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
352 where
353 R: VecZnxToMut,
354 A: VecZnxToRef,
355 {
356 let a: VecZnx<&[u8]> = a.to_ref();
357 let mut res: VecZnx<&mut [u8]> = res.to_mut();
358 #[cfg(debug_assertions)]
359 {
360 assert_eq!(a.n(), res.n());
361 }
362 unsafe {
363 vec_znx::vec_znx_sub(
364 module.ptr() as *const module_info_t,
365 res.at_mut_ptr(res_col, 0),
366 res.size() as u64,
367 res.sl() as u64,
368 a.at_ptr(a_col, 0),
369 a.size() as u64,
370 a.sl() as u64,
371 res.at_ptr(res_col, 0),
372 res.size() as u64,
373 res.sl() as u64,
374 )
375 }
376 }
377}
378
379unsafe impl VecZnxSubScalarImpl<Self> for FFT64Spqlios {
380 fn vec_znx_sub_scalar_impl<R, A, B>(
381 module: &Module<Self>,
382 res: &mut R,
383 res_col: usize,
384 a: &A,
385 a_col: usize,
386 b: &B,
387 b_col: usize,
388 b_limb: usize,
389 ) where
390 R: VecZnxToMut,
391 A: ScalarZnxToRef,
392 B: VecZnxToRef,
393 {
394 let mut res: VecZnx<&mut [u8]> = res.to_mut();
395 let a: ScalarZnx<&[u8]> = a.to_ref();
396 let b: VecZnx<&[u8]> = b.to_ref();
397
398 #[cfg(debug_assertions)]
399 {
400 assert_eq!(a.n(), res.n());
401 }
402
403 let min_size: usize = b.size().min(res.size());
404
405 unsafe {
406 vec_znx::vec_znx_sub(
407 module.ptr() as *const module_info_t,
408 res.at_mut_ptr(res_col, b_limb),
409 1_u64,
410 res.sl() as u64,
411 b.at_ptr(b_col, b_limb),
412 1_u64,
413 b.sl() as u64,
414 a.at_ptr(a_col, 0),
415 a.size() as u64,
416 a.sl() as u64,
417 );
418
419 for j in 0..min_size {
420 if j != b_limb {
421 res.at_mut(res_col, j).copy_from_slice(b.at(b_col, j))
422 }
423 }
424
425 for j in min_size..res.size() {
426 znx_zero_ref(res.at_mut(res_col, j));
427 }
428 }
429 }
430}
431
432unsafe impl VecZnxSubScalarInplaceImpl<Self> for FFT64Spqlios {
433 fn vec_znx_sub_scalar_inplace_impl<R, A>(
434 module: &Module<Self>,
435 res: &mut R,
436 res_col: usize,
437 res_limb: usize,
438 a: &A,
439 a_col: usize,
440 ) where
441 R: VecZnxToMut,
442 A: ScalarZnxToRef,
443 {
444 let mut res: VecZnx<&mut [u8]> = res.to_mut();
445 let a: ScalarZnx<&[u8]> = a.to_ref();
446
447 #[cfg(debug_assertions)]
448 {
449 assert_eq!(a.n(), res.n());
450 }
451
452 unsafe {
453 vec_znx::vec_znx_sub(
454 module.ptr() as *const module_info_t,
455 res.at_mut_ptr(res_col, res_limb),
456 1_u64,
457 res.sl() as u64,
458 res.at_ptr(res_col, res_limb),
459 1_u64,
460 res.sl() as u64,
461 a.at_ptr(a_col, 0),
462 a.size() as u64,
463 a.sl() as u64,
464 )
465 }
466 }
467}
468
469unsafe impl VecZnxNegateImpl<Self> for FFT64Spqlios {
470 fn vec_znx_negate_impl<R, A>(module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
471 where
472 R: VecZnxToMut,
473 A: VecZnxToRef,
474 {
475 let a: VecZnx<&[u8]> = a.to_ref();
476 let mut res: VecZnx<&mut [u8]> = res.to_mut();
477 #[cfg(debug_assertions)]
478 {
479 assert_eq!(a.n(), res.n());
480 }
481 unsafe {
482 vec_znx::vec_znx_negate(
483 module.ptr() as *const module_info_t,
484 res.at_mut_ptr(res_col, 0),
485 res.size() as u64,
486 res.sl() as u64,
487 a.at_ptr(a_col, 0),
488 a.size() as u64,
489 a.sl() as u64,
490 )
491 }
492 }
493}
494
495unsafe impl VecZnxNegateInplaceImpl<Self> for FFT64Spqlios {
496 fn vec_znx_negate_inplace_impl<A>(module: &Module<Self>, a: &mut A, a_col: usize)
497 where
498 A: VecZnxToMut,
499 {
500 let mut a: VecZnx<&mut [u8]> = a.to_mut();
501 unsafe {
502 vec_znx::vec_znx_negate(
503 module.ptr() as *const module_info_t,
504 a.at_mut_ptr(a_col, 0),
505 a.size() as u64,
506 a.sl() as u64,
507 a.at_ptr(a_col, 0),
508 a.size() as u64,
509 a.sl() as u64,
510 )
511 }
512 }
513}
514
515unsafe impl VecZnxLshTmpBytesImpl<Self> for FFT64Spqlios {
516 fn vec_znx_lsh_tmp_bytes_impl(module: &Module<Self>) -> usize {
517 vec_znx_lsh_tmp_bytes(module.n())
518 }
519}
520
521unsafe impl VecZnxRshTmpBytesImpl<Self> for FFT64Spqlios {
522 fn vec_znx_rsh_tmp_bytes_impl(module: &Module<Self>) -> usize {
523 vec_znx_rsh_tmp_bytes(module.n())
524 }
525}
526
527unsafe impl VecZnxLshImpl<Self> for FFT64Spqlios
528where
529 Module<Self>: VecZnxNormalizeTmpBytes,
530 Scratch<Self>: TakeSlice,
531{
532 fn vec_znx_lsh_impl<R, A>(
533 module: &Module<Self>,
534 base2k: usize,
535 k: usize,
536 res: &mut R,
537 res_col: usize,
538 a: &A,
539 a_col: usize,
540 scratch: &mut Scratch<Self>,
541 ) where
542 R: VecZnxToMut,
543 A: VecZnxToRef,
544 {
545 let (carry, _) = scratch.take_slice(module.vec_znx_lsh_tmp_bytes() / size_of::<i64>());
546 vec_znx_lsh::<_, _, FFT64Spqlios>(base2k, k, res, res_col, a, a_col, carry)
547 }
548}
549
550unsafe impl VecZnxLshInplaceImpl<Self> for FFT64Spqlios
551where
552 Module<Self>: VecZnxNormalizeTmpBytes,
553 Scratch<Self>: TakeSlice,
554{
555 fn vec_znx_lsh_inplace_impl<A>(
556 module: &Module<Self>,
557 base2k: usize,
558 k: usize,
559 a: &mut A,
560 a_col: usize,
561 scratch: &mut Scratch<Self>,
562 ) where
563 A: VecZnxToMut,
564 {
565 let (carry, _) = scratch.take_slice(module.vec_znx_lsh_tmp_bytes() / size_of::<i64>());
566 vec_znx_lsh_inplace::<_, FFT64Spqlios>(base2k, k, a, a_col, carry)
567 }
568}
569
570unsafe impl VecZnxRshImpl<Self> for FFT64Spqlios
571where
572 Module<Self>: VecZnxNormalizeTmpBytes,
573 Scratch<Self>: TakeSlice,
574{
575 fn vec_znx_rsh_impl<R, A>(
576 module: &Module<Self>,
577 base2k: usize,
578 k: usize,
579 res: &mut R,
580 res_col: usize,
581 a: &A,
582 a_col: usize,
583 scratch: &mut Scratch<Self>,
584 ) where
585 R: VecZnxToMut,
586 A: VecZnxToRef,
587 {
588 let (carry, _) = scratch.take_slice(module.vec_znx_rsh_tmp_bytes() / size_of::<i64>());
589 vec_znx_rsh::<_, _, FFT64Spqlios>(base2k, k, res, res_col, a, a_col, carry)
590 }
591}
592
593unsafe impl VecZnxRshInplaceImpl<Self> for FFT64Spqlios
594where
595 Module<Self>: VecZnxNormalizeTmpBytes,
596 Scratch<Self>: TakeSlice,
597{
598 fn vec_znx_rsh_inplace_impl<A>(
599 module: &Module<Self>,
600 base2k: usize,
601 k: usize,
602 a: &mut A,
603 a_col: usize,
604 scratch: &mut Scratch<Self>,
605 ) where
606 A: VecZnxToMut,
607 {
608 let (carry, _) = scratch.take_slice(module.vec_znx_rsh_tmp_bytes() / size_of::<i64>());
609 vec_znx_rsh_inplace::<_, FFT64Spqlios>(base2k, k, a, a_col, carry)
610 }
611}
612
613unsafe impl VecZnxRotateImpl<Self> for FFT64Spqlios {
614 fn vec_znx_rotate_impl<R, A>(_module: &Module<Self>, k: i64, res: &mut R, res_col: usize, a: &A, a_col: usize)
615 where
616 R: VecZnxToMut,
617 A: VecZnxToRef,
618 {
619 let a: VecZnx<&[u8]> = a.to_ref();
620 let mut res: VecZnx<&mut [u8]> = res.to_mut();
621 #[cfg(debug_assertions)]
622 {
623 assert_eq!(res.n(), a.n());
624 }
625 unsafe {
626 let min_size = res.size().min(a.size());
627 (0..min_size).for_each(|j| {
628 znx::znx_rotate_i64(
629 a.n() as u64,
630 k,
631 res.at_mut_ptr(res_col, j),
632 a.at_ptr(a_col, j),
633 );
634 });
635
636 (min_size..res.size()).for_each(|j| {
637 znx_zero_ref(res.at_mut(res_col, j));
638 })
639 }
640 }
641}
642
643unsafe impl VecZnxRotateInplaceTmpBytesImpl<Self> for FFT64Spqlios
644where
645 Scratch<Self>: TakeSlice,
646{
647 fn vec_znx_rotate_inplace_tmp_bytes_impl(module: &Module<Self>) -> usize {
648 vec_znx_rotate_inplace_tmp_bytes(module.n())
649 }
650}
651
652unsafe impl VecZnxRotateInplaceImpl<Self> for FFT64Spqlios
653where
654 Scratch<Self>: TakeSlice,
655{
656 fn vec_znx_rotate_inplace_impl<A>(_module: &Module<Self>, k: i64, a: &mut A, a_col: usize, _scratch: &mut Scratch<Self>)
657 where
658 A: VecZnxToMut,
659 {
660 let mut a: VecZnx<&mut [u8]> = a.to_mut();
661 unsafe {
662 (0..a.size()).for_each(|j| {
663 znx::znx_rotate_inplace_i64(a.n() as u64, k, a.at_mut_ptr(a_col, j));
664 });
665 }
666 }
667}
668
669unsafe impl VecZnxAutomorphismImpl<Self> for FFT64Spqlios {
670 fn vec_znx_automorphism_impl<R, A>(module: &Module<Self>, k: i64, res: &mut R, res_col: usize, a: &A, a_col: usize)
671 where
672 R: VecZnxToMut,
673 A: VecZnxToRef,
674 {
675 let a: VecZnx<&[u8]> = a.to_ref();
676 let mut res: VecZnx<&mut [u8]> = res.to_mut();
677 #[cfg(debug_assertions)]
678 {
679 assert_eq!(a.n(), res.n());
680 }
681 unsafe {
682 vec_znx::vec_znx_automorphism(
683 module.ptr() as *const module_info_t,
684 k,
685 res.at_mut_ptr(res_col, 0),
686 res.size() as u64,
687 res.sl() as u64,
688 a.at_ptr(a_col, 0),
689 a.size() as u64,
690 a.sl() as u64,
691 )
692 }
693 }
694}
695
696unsafe impl VecZnxAutomorphismInplaceTmpBytesImpl<Self> for FFT64Spqlios {
697 fn vec_znx_automorphism_inplace_tmp_bytes_impl(module: &Module<Self>) -> usize {
698 vec_znx_automorphism_inplace_tmp_bytes(module.n())
699 }
700}
701
702unsafe impl VecZnxAutomorphismInplaceImpl<Self> for FFT64Spqlios {
703 fn vec_znx_automorphism_inplace_impl<A>(module: &Module<Self>, k: i64, a: &mut A, a_col: usize, _scratch: &mut Scratch<Self>)
704 where
705 A: VecZnxToMut,
706 {
707 let mut a: VecZnx<&mut [u8]> = a.to_mut();
708 #[cfg(debug_assertions)]
709 {
710 assert!(k & 1 != 0, "invalid galois element: must be odd but is {k}");
711 }
712 unsafe {
713 vec_znx::vec_znx_automorphism(
714 module.ptr() as *const module_info_t,
715 k,
716 a.at_mut_ptr(a_col, 0),
717 a.size() as u64,
718 a.sl() as u64,
719 a.at_ptr(a_col, 0),
720 a.size() as u64,
721 a.sl() as u64,
722 )
723 }
724 }
725}
726
727unsafe impl VecZnxMulXpMinusOneImpl<Self> for FFT64Spqlios {
728 fn vec_znx_mul_xp_minus_one_impl<R, A>(module: &Module<Self>, p: i64, res: &mut R, res_col: usize, a: &A, a_col: usize)
729 where
730 R: VecZnxToMut,
731 A: VecZnxToRef,
732 {
733 let a: VecZnx<&[u8]> = a.to_ref();
734 let mut res: VecZnx<&mut [u8]> = res.to_mut();
735 #[cfg(debug_assertions)]
736 {
737 assert_eq!(a.n(), res.n());
738 assert_eq!(res.n(), res.n());
739 }
740 unsafe {
741 vec_znx::vec_znx_mul_xp_minus_one(
742 module.ptr() as *const module_info_t,
743 p,
744 res.at_mut_ptr(res_col, 0),
745 res.size() as u64,
746 res.sl() as u64,
747 a.at_ptr(a_col, 0),
748 a.size() as u64,
749 a.sl() as u64,
750 )
751 }
752 }
753}
754
755unsafe impl VecZnxMulXpMinusOneInplaceTmpBytesImpl<Self> for FFT64Spqlios {
756 fn vec_znx_mul_xp_minus_one_inplace_tmp_bytes_impl(module: &Module<Self>) -> usize {
757 vec_znx_mul_xp_minus_one_inplace_tmp_bytes(module.n())
758 }
759}
760
761unsafe impl VecZnxMulXpMinusOneInplaceImpl<Self> for FFT64Spqlios {
762 fn vec_znx_mul_xp_minus_one_inplace_impl<R>(
763 module: &Module<Self>,
764 p: i64,
765 res: &mut R,
766 res_col: usize,
767 _scratch: &mut Scratch<Self>,
768 ) where
769 R: VecZnxToMut,
770 {
771 let mut res: VecZnx<&mut [u8]> = res.to_mut();
772 #[cfg(debug_assertions)]
773 {
774 assert_eq!(res.n(), res.n());
775 }
776 unsafe {
777 vec_znx::vec_znx_mul_xp_minus_one(
778 module.ptr() as *const module_info_t,
779 p,
780 res.at_mut_ptr(res_col, 0),
781 res.size() as u64,
782 res.sl() as u64,
783 res.at_ptr(res_col, 0),
784 res.size() as u64,
785 res.sl() as u64,
786 )
787 }
788 }
789}
790
791unsafe impl VecZnxSplitRingTmpBytesImpl<Self> for FFT64Spqlios {
792 fn vec_znx_split_ring_tmp_bytes_impl(module: &Module<Self>) -> usize {
793 vec_znx_split_ring_tmp_bytes(module.n())
794 }
795}
796
797unsafe impl VecZnxSplitRingImpl<Self> for FFT64Spqlios
798where
799 Module<Self>: VecZnxSplitRingTmpBytes,
800 Scratch<Self>: TakeSlice,
801{
802 fn vec_znx_split_ring_impl<R, A>(
803 module: &Module<Self>,
804 res: &mut [R],
805 res_col: usize,
806 a: &A,
807 a_col: usize,
808 scratch: &mut Scratch<Self>,
809 ) where
810 R: VecZnxToMut,
811 A: VecZnxToRef,
812 {
813 let (tmp, _) = scratch.take_slice(module.vec_znx_split_ring_tmp_bytes() / size_of::<i64>());
814 vec_znx_split_ring::<_, _, FFT64Spqlios>(res, res_col, a, a_col, tmp);
815 }
816}
817
818unsafe impl VecZnxMergeRingsTmpBytesImpl<Self> for FFT64Spqlios {
819 fn vec_znx_merge_rings_tmp_bytes_impl(module: &Module<Self>) -> usize {
820 vec_znx_merge_rings_tmp_bytes(module.n())
821 }
822}
823
824unsafe impl VecZnxMergeRingsImpl<Self> for FFT64Spqlios
825where
826 Module<Self>: VecZnxMergeRingsTmpBytes,
827{
828 fn vec_znx_merge_rings_impl<R, A>(
829 module: &Module<Self>,
830 res: &mut R,
831 res_col: usize,
832 a: &[A],
833 a_col: usize,
834 scratch: &mut Scratch<Self>,
835 ) where
836 R: VecZnxToMut,
837 A: VecZnxToRef,
838 {
839 let (tmp, _) = scratch.take_slice(module.vec_znx_merge_rings_tmp_bytes() / size_of::<i64>());
840 vec_znx_merge_rings::<_, _, FFT64Spqlios>(res, res_col, a, a_col, tmp);
841 }
842}
843
844unsafe impl VecZnxSwitchRingImpl<Self> for FFT64Spqlios
845where
846 Self: VecZnxCopyImpl<Self>,
847{
848 fn vec_znx_switch_ring_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
849 where
850 R: VecZnxToMut,
851 A: VecZnxToRef,
852 {
853 vec_znx_switch_ring::<_, _, FFT64Spqlios>(res, res_col, a, a_col);
854 }
855}
856
857unsafe impl VecZnxCopyImpl<Self> for FFT64Spqlios {
858 fn vec_znx_copy_impl<R, A>(_module: &Module<Self>, res: &mut R, res_col: usize, a: &A, a_col: usize)
859 where
860 R: VecZnxToMut,
861 A: VecZnxToRef,
862 {
863 vec_znx_copy::<_, _, FFT64Spqlios>(res, res_col, a, a_col)
864 }
865}
866
867unsafe impl VecZnxFillUniformImpl<Self> for FFT64Spqlios {
868 fn vec_znx_fill_uniform_impl<R>(_module: &Module<Self>, base2k: usize, res: &mut R, res_col: usize, source: &mut Source)
869 where
870 R: VecZnxToMut,
871 {
872 vec_znx_fill_uniform_ref(base2k, res, res_col, source)
873 }
874}
875
876unsafe impl VecZnxFillNormalImpl<Self> for FFT64Spqlios {
877 fn vec_znx_fill_normal_impl<R>(
878 _module: &Module<Self>,
879 base2k: usize,
880 res: &mut R,
881 res_col: usize,
882 k: usize,
883 source: &mut Source,
884 sigma: f64,
885 bound: f64,
886 ) where
887 R: VecZnxToMut,
888 {
889 vec_znx_fill_normal_ref(base2k, res, res_col, k, sigma, bound, source);
890 }
891}
892
893unsafe impl VecZnxAddNormalImpl<Self> for FFT64Spqlios {
894 fn vec_znx_add_normal_impl<R>(
895 _module: &Module<Self>,
896 base2k: usize,
897 res: &mut R,
898 res_col: usize,
899 k: usize,
900 source: &mut Source,
901 sigma: f64,
902 bound: f64,
903 ) where
904 R: VecZnxToMut,
905 {
906 vec_znx_add_normal_ref(base2k, res, res_col, k, sigma, bound, source);
907 }
908}