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