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