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, 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}