poulpy/base2k/src/vec_znx_big_ops.rs
base2k/src/vec_znx_big_ops.rsRaw
1use crate::ffi::vec_znx;
2use crate::znx_base::{ZnxInfos, ZnxView, ZnxViewMut};
3use crate::{
4 Backend, FFT64, Module, Scratch, VecZnx, VecZnxBig, VecZnxBigOwned, VecZnxBigToMut, VecZnxBigToRef, VecZnxScratch,
5 VecZnxToMut, VecZnxToRef, ZnxSliceSize, bytes_of_vec_znx_big,
6};
7
8pub trait VecZnxBigAlloc<B: Backend> {
9 /// Allocates a vector Z[X]/(X^N+1) that stores not normalized values.
10 fn new_vec_znx_big(&self, cols: usize, size: usize) -> VecZnxBigOwned<B>;
11
12 /// Returns a new [VecZnxBig] with the provided bytes array as backing array.
13 ///
14 /// Behavior: takes ownership of the backing array.
15 ///
16 /// # Arguments
17 ///
18 /// * `cols`: the number of polynomials..
19 /// * `size`: the number of polynomials per column.
20 /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_big].
21 ///
22 /// # Panics
23 /// If `bytes.len()` < [Module::bytes_of_vec_znx_big].
24 fn new_vec_znx_big_from_bytes(&self, cols: usize, size: usize, bytes: Vec<u8>) -> VecZnxBigOwned<B>;
25
26 // /// Returns a new [VecZnxBig] with the provided bytes array as backing array.
27 // ///
28 // /// Behavior: the backing array is only borrowed.
29 // ///
30 // /// # Arguments
31 // ///
32 // /// * `cols`: the number of polynomials..
33 // /// * `size`: the number of polynomials per column.
34 // /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_big].
35 // ///
36 // /// # Panics
37 // /// If `bytes.len()` < [Module::bytes_of_vec_znx_big].
38 // fn new_vec_znx_big_from_bytes_borrow(&self, cols: usize, size: usize, tmp_bytes: &mut [u8]) -> VecZnxBig<B>;
39
40 /// Returns the minimum number of bytes necessary to allocate
41 /// a new [VecZnxBig] through [VecZnxBig::from_bytes].
42 fn bytes_of_vec_znx_big(&self, cols: usize, size: usize) -> usize;
43}
44
45pub trait VecZnxBigOps<BACKEND: Backend> {
46 /// Adds `a` to `b` and stores the result on `c`.
47 fn vec_znx_big_add<R, A, B>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
48 where
49 R: VecZnxBigToMut<BACKEND>,
50 A: VecZnxBigToRef<BACKEND>,
51 B: VecZnxBigToRef<BACKEND>;
52
53 /// Adds `a` to `b` and stores the result on `b`.
54 fn vec_znx_big_add_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
55 where
56 R: VecZnxBigToMut<BACKEND>,
57 A: VecZnxBigToRef<BACKEND>;
58
59 /// Adds `a` to `b` and stores the result on `c`.
60 fn vec_znx_big_add_small<R, A, B>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
61 where
62 R: VecZnxBigToMut<BACKEND>,
63 A: VecZnxBigToRef<BACKEND>,
64 B: VecZnxToRef;
65
66 /// Adds `a` to `b` and stores the result on `b`.
67 fn vec_znx_big_add_small_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
68 where
69 R: VecZnxBigToMut<BACKEND>,
70 A: VecZnxToRef;
71
72 /// Subtracts `a` to `b` and stores the result on `c`.
73 fn vec_znx_big_sub<R, A, B>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
74 where
75 R: VecZnxBigToMut<BACKEND>,
76 A: VecZnxBigToRef<BACKEND>,
77 B: VecZnxBigToRef<BACKEND>;
78
79 /// Subtracts `a` from `b` and stores the result on `b`.
80 fn vec_znx_big_sub_ab_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
81 where
82 R: VecZnxBigToMut<BACKEND>,
83 A: VecZnxBigToRef<BACKEND>;
84
85 /// Subtracts `b` from `a` and stores the result on `b`.
86 fn vec_znx_big_sub_ba_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
87 where
88 R: VecZnxBigToMut<BACKEND>,
89 A: VecZnxBigToRef<BACKEND>;
90
91 /// Subtracts `b` from `a` and stores the result on `c`.
92 fn vec_znx_big_sub_small_a<R, A, B>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
93 where
94 R: VecZnxBigToMut<BACKEND>,
95 A: VecZnxToRef,
96 B: VecZnxBigToRef<BACKEND>;
97
98 /// Subtracts `a` from `res` and stores the result on `res`.
99 fn vec_znx_big_sub_small_a_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
100 where
101 R: VecZnxBigToMut<BACKEND>,
102 A: VecZnxToRef;
103
104 /// Subtracts `b` from `a` and stores the result on `c`.
105 fn vec_znx_big_sub_small_b<R, A, B>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
106 where
107 R: VecZnxBigToMut<BACKEND>,
108 A: VecZnxBigToRef<BACKEND>,
109 B: VecZnxToRef;
110
111 /// Subtracts `res` from `a` and stores the result on `res`.
112 fn vec_znx_big_sub_small_b_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
113 where
114 R: VecZnxBigToMut<BACKEND>,
115 A: VecZnxToRef;
116
117 /// Negates `a` inplace.
118 fn vec_znx_big_negate_inplace<A>(&self, a: &mut A, a_col: usize)
119 where
120 A: VecZnxBigToMut<BACKEND>;
121
122 /// Normalizes `a` and stores the result on `b`.
123 ///
124 /// # Arguments
125 ///
126 /// * `log_base2k`: normalization basis.
127 /// * `tmp_bytes`: scratch space of size at least [VecZnxBigOps::vec_znx_big_normalize].
128 fn vec_znx_big_normalize<R, A>(
129 &self,
130 log_base2k: usize,
131 res: &mut R,
132 res_col: usize,
133 a: &A,
134 a_col: usize,
135 scratch: &mut Scratch,
136 ) where
137 R: VecZnxToMut,
138 A: VecZnxBigToRef<BACKEND>;
139
140 /// Applies the automorphism X^i -> X^ik on `a` and stores the result on `b`.
141 fn vec_znx_big_automorphism<R, A>(&self, k: i64, res: &mut R, res_col: usize, a: &A, a_col: usize)
142 where
143 R: VecZnxBigToMut<BACKEND>,
144 A: VecZnxBigToRef<BACKEND>;
145
146 /// Applies the automorphism X^i -> X^ik on `a` and stores the result on `a`.
147 fn vec_znx_big_automorphism_inplace<A>(&self, k: i64, a: &mut A, a_col: usize)
148 where
149 A: VecZnxBigToMut<BACKEND>;
150
151}
152
153pub trait VecZnxBigScratch {
154 /// Returns the minimum number of bytes to apply [VecZnxBigOps::vec_znx_big_normalize].
155 fn vec_znx_big_normalize_tmp_bytes(&self) -> usize;
156}
157
158impl<B: Backend> VecZnxBigAlloc<B> for Module<B> {
159 fn new_vec_znx_big(&self, cols: usize, size: usize) -> VecZnxBigOwned<B> {
160 VecZnxBig::new(self, cols, size)
161 }
162
163 fn new_vec_znx_big_from_bytes(&self, cols: usize, size: usize, bytes: Vec<u8>) -> VecZnxBigOwned<B> {
164 VecZnxBig::new_from_bytes(self, cols, size, bytes)
165 }
166
167 fn bytes_of_vec_znx_big(&self, cols: usize, size: usize) -> usize {
168 bytes_of_vec_znx_big(self, cols, size)
169 }
170}
171
172impl VecZnxBigOps<FFT64> for Module<FFT64> {
173
174 fn vec_znx_big_add<R, A, B>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
175 where
176 R: VecZnxBigToMut<FFT64>,
177 A: VecZnxBigToRef<FFT64>,
178 B: VecZnxBigToRef<FFT64>,
179 {
180 let a: VecZnxBig<&[u8], FFT64> = a.to_ref();
181 let b: VecZnxBig<&[u8], FFT64> = b.to_ref();
182 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
183
184 #[cfg(debug_assertions)]
185 {
186 assert_eq!(a.n(), self.n());
187 assert_eq!(b.n(), self.n());
188 assert_eq!(res.n(), self.n());
189 assert_ne!(a.as_ptr(), b.as_ptr());
190 }
191 unsafe {
192 vec_znx::vec_znx_add(
193 self.ptr,
194 res.at_mut_ptr(res_col, 0),
195 res.size() as u64,
196 res.sl() as u64,
197 a.at_ptr(a_col, 0),
198 a.size() as u64,
199 a.sl() as u64,
200 b.at_ptr(b_col, 0),
201 b.size() as u64,
202 b.sl() as u64,
203 )
204 }
205 }
206
207 fn vec_znx_big_add_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
208 where
209 R: VecZnxBigToMut<FFT64>,
210 A: VecZnxBigToRef<FFT64>,
211 {
212 let a: VecZnxBig<&[u8], FFT64> = a.to_ref();
213 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
214
215 #[cfg(debug_assertions)]
216 {
217 assert_eq!(a.n(), self.n());
218 assert_eq!(res.n(), self.n());
219 }
220 unsafe {
221 vec_znx::vec_znx_add(
222 self.ptr,
223 res.at_mut_ptr(res_col, 0),
224 res.size() as u64,
225 res.sl() as u64,
226 a.at_ptr(a_col, 0),
227 a.size() as u64,
228 a.sl() as u64,
229 res.at_ptr(res_col, 0),
230 res.size() as u64,
231 res.sl() as u64,
232 )
233 }
234 }
235
236 fn vec_znx_big_sub<R, A, B>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
237 where
238 R: VecZnxBigToMut<FFT64>,
239 A: VecZnxBigToRef<FFT64>,
240 B: VecZnxBigToRef<FFT64>,
241 {
242 let a: VecZnxBig<&[u8], FFT64> = a.to_ref();
243 let b: VecZnxBig<&[u8], FFT64> = b.to_ref();
244 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
245
246 #[cfg(debug_assertions)]
247 {
248 assert_eq!(a.n(), self.n());
249 assert_eq!(b.n(), self.n());
250 assert_eq!(res.n(), self.n());
251 assert_ne!(a.as_ptr(), b.as_ptr());
252 }
253 unsafe {
254 vec_znx::vec_znx_sub(
255 self.ptr,
256 res.at_mut_ptr(res_col, 0),
257 res.size() as u64,
258 res.sl() as u64,
259 a.at_ptr(a_col, 0),
260 a.size() as u64,
261 a.sl() as u64,
262 b.at_ptr(b_col, 0),
263 b.size() as u64,
264 b.sl() as u64,
265 )
266 }
267 }
268
269 fn vec_znx_big_sub_ab_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
270 where
271 R: VecZnxBigToMut<FFT64>,
272 A: VecZnxBigToRef<FFT64>,
273 {
274 let a: VecZnxBig<&[u8], FFT64> = a.to_ref();
275 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
276
277 #[cfg(debug_assertions)]
278 {
279 assert_eq!(a.n(), self.n());
280 assert_eq!(res.n(), self.n());
281 }
282 unsafe {
283 vec_znx::vec_znx_sub(
284 self.ptr,
285 res.at_mut_ptr(res_col, 0),
286 res.size() as u64,
287 res.sl() as u64,
288 res.at_ptr(res_col, 0),
289 res.size() as u64,
290 res.sl() as u64,
291 a.at_ptr(a_col, 0),
292 a.size() as u64,
293 a.sl() as u64,
294 )
295 }
296 }
297
298 fn vec_znx_big_sub_ba_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
299 where
300 R: VecZnxBigToMut<FFT64>,
301 A: VecZnxBigToRef<FFT64>,
302 {
303 let a: VecZnxBig<&[u8], FFT64> = a.to_ref();
304 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
305
306 #[cfg(debug_assertions)]
307 {
308 assert_eq!(a.n(), self.n());
309 assert_eq!(res.n(), self.n());
310 }
311 unsafe {
312 vec_znx::vec_znx_sub(
313 self.ptr,
314 res.at_mut_ptr(res_col, 0),
315 res.size() as u64,
316 res.sl() as u64,
317 a.at_ptr(a_col, 0),
318 a.size() as u64,
319 a.sl() as u64,
320 res.at_ptr(res_col, 0),
321 res.size() as u64,
322 res.sl() as u64,
323 )
324 }
325 }
326
327 fn vec_znx_big_sub_small_b<R, A, B>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
328 where
329 R: VecZnxBigToMut<FFT64>,
330 A: VecZnxBigToRef<FFT64>,
331 B: VecZnxToRef,
332 {
333 let a: VecZnxBig<&[u8], FFT64> = a.to_ref();
334 let b: VecZnx<&[u8]> = b.to_ref();
335 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
336
337 #[cfg(debug_assertions)]
338 {
339 assert_eq!(a.n(), self.n());
340 assert_eq!(b.n(), self.n());
341 assert_eq!(res.n(), self.n());
342 assert_ne!(a.as_ptr(), b.as_ptr());
343 }
344 unsafe {
345 vec_znx::vec_znx_sub(
346 self.ptr,
347 res.at_mut_ptr(res_col, 0),
348 res.size() as u64,
349 res.sl() as u64,
350 a.at_ptr(a_col, 0),
351 a.size() as u64,
352 a.sl() as u64,
353 b.at_ptr(b_col, 0),
354 b.size() as u64,
355 b.sl() as u64,
356 )
357 }
358 }
359
360 fn vec_znx_big_sub_small_b_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
361 where
362 R: VecZnxBigToMut<FFT64>,
363 A: VecZnxToRef,
364 {
365 let a: VecZnx<&[u8]> = a.to_ref();
366 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
367
368 #[cfg(debug_assertions)]
369 {
370 assert_eq!(a.n(), self.n());
371 assert_eq!(res.n(), self.n());
372 }
373 unsafe {
374 vec_znx::vec_znx_sub(
375 self.ptr,
376 res.at_mut_ptr(res_col, 0),
377 res.size() as u64,
378 res.sl() as u64,
379 a.at_ptr(a_col, 0),
380 a.size() as u64,
381 a.sl() as u64,
382 res.at_ptr(res_col, 0),
383 res.size() as u64,
384 res.sl() as u64,
385 )
386 }
387 }
388
389 fn vec_znx_big_sub_small_a<R, A, B>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
390 where
391 R: VecZnxBigToMut<FFT64>,
392 A: VecZnxToRef,
393 B: VecZnxBigToRef<FFT64>,
394 {
395 let a: VecZnx<&[u8]> = a.to_ref();
396 let b: VecZnxBig<&[u8], FFT64> = b.to_ref();
397 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
398
399 #[cfg(debug_assertions)]
400 {
401 assert_eq!(a.n(), self.n());
402 assert_eq!(b.n(), self.n());
403 assert_eq!(res.n(), self.n());
404 assert_ne!(a.as_ptr(), b.as_ptr());
405 }
406 unsafe {
407 vec_znx::vec_znx_sub(
408 self.ptr,
409 res.at_mut_ptr(res_col, 0),
410 res.size() as u64,
411 res.sl() as u64,
412 a.at_ptr(a_col, 0),
413 a.size() as u64,
414 a.sl() as u64,
415 b.at_ptr(b_col, 0),
416 b.size() as u64,
417 b.sl() as u64,
418 )
419 }
420 }
421
422 fn vec_znx_big_sub_small_a_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
423 where
424 R: VecZnxBigToMut<FFT64>,
425 A: VecZnxToRef,
426 {
427 let a: VecZnx<&[u8]> = a.to_ref();
428 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
429
430 #[cfg(debug_assertions)]
431 {
432 assert_eq!(a.n(), self.n());
433 assert_eq!(res.n(), self.n());
434 }
435 unsafe {
436 vec_znx::vec_znx_sub(
437 self.ptr,
438 res.at_mut_ptr(res_col, 0),
439 res.size() as u64,
440 res.sl() as u64,
441 res.at_ptr(res_col, 0),
442 res.size() as 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 fn vec_znx_big_add_small<R, A, B>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize, b: &B, b_col: usize)
452 where
453 R: VecZnxBigToMut<FFT64>,
454 A: VecZnxBigToRef<FFT64>,
455 B: VecZnxToRef,
456 {
457 let a: VecZnxBig<&[u8], FFT64> = a.to_ref();
458 let b: VecZnx<&[u8]> = b.to_ref();
459 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
460
461 #[cfg(debug_assertions)]
462 {
463 assert_eq!(a.n(), self.n());
464 assert_eq!(b.n(), self.n());
465 assert_eq!(res.n(), self.n());
466 assert_ne!(a.as_ptr(), b.as_ptr());
467 }
468 unsafe {
469 vec_znx::vec_znx_add(
470 self.ptr,
471 res.at_mut_ptr(res_col, 0),
472 res.size() as u64,
473 res.sl() as u64,
474 a.at_ptr(a_col, 0),
475 a.size() as u64,
476 a.sl() as u64,
477 b.at_ptr(b_col, 0),
478 b.size() as u64,
479 b.sl() as u64,
480 )
481 }
482 }
483
484 fn vec_znx_big_add_small_inplace<R, A>(&self, res: &mut R, res_col: usize, a: &A, a_col: usize)
485 where
486 R: VecZnxBigToMut<FFT64>,
487 A: VecZnxToRef,
488 {
489 let a: VecZnx<&[u8]> = a.to_ref();
490 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
491
492 #[cfg(debug_assertions)]
493 {
494 assert_eq!(a.n(), self.n());
495 assert_eq!(res.n(), self.n());
496 }
497 unsafe {
498 vec_znx::vec_znx_add(
499 self.ptr,
500 res.at_mut_ptr(res_col, 0),
501 res.size() as u64,
502 res.sl() as u64,
503 res.at_ptr(res_col, 0),
504 res.size() as u64,
505 res.sl() as u64,
506 a.at_ptr(a_col, 0),
507 a.size() as u64,
508 a.sl() as u64,
509 )
510 }
511 }
512
513 fn vec_znx_big_negate_inplace<A>(&self, a: &mut A, res_col: usize)
514 where
515 A: VecZnxBigToMut<FFT64>,
516 {
517 let mut a: VecZnxBig<&mut [u8], FFT64> = a.to_mut();
518 #[cfg(debug_assertions)]
519 {
520 assert_eq!(a.n(), self.n());
521 }
522 unsafe {
523 vec_znx::vec_znx_negate(
524 self.ptr,
525 a.at_mut_ptr(res_col, 0),
526 a.size() as u64,
527 a.sl() as u64,
528 a.at_ptr(res_col, 0),
529 a.size() as u64,
530 a.sl() as u64,
531 )
532 }
533 }
534
535 fn vec_znx_big_normalize<R, A>(
536 &self,
537 log_base2k: usize,
538 res: &mut R,
539 res_col: usize,
540 a: &A,
541 a_col: usize,
542 scratch: &mut Scratch,
543 ) where
544 R: VecZnxToMut,
545 A: VecZnxBigToRef<FFT64>,
546 {
547 let a: VecZnxBig<&[u8], FFT64> = a.to_ref();
548 let mut res: VecZnx<&mut [u8]> = res.to_mut();
549
550 #[cfg(debug_assertions)]
551 {
552 assert_eq!(a.n(), self.n());
553 assert_eq!(res.n(), self.n());
554 //(Jay)Note: This is calling VezZnxOps::vec_znx_normalize_tmp_bytes and not VecZnxBigOps::vec_znx_big_normalize_tmp_bytes.
555 // In the FFT backend the tmp sizes are same but will be different in the NTT backend
556 // assert!(tmp_bytes.len() >= <Self as VecZnxOps<&mut [u8], & [u8]>>::vec_znx_normalize_tmp_bytes(&self));
557 // assert_alignement(tmp_bytes.as_ptr());
558 }
559
560 let (tmp_bytes, _) = scratch.tmp_slice(<Self as VecZnxBigScratch>::vec_znx_big_normalize_tmp_bytes(
561 &self,
562 ));
563 unsafe {
564 vec_znx::vec_znx_normalize_base2k(
565 self.ptr,
566 log_base2k as u64,
567 res.at_mut_ptr(res_col, 0),
568 res.size() as u64,
569 res.sl() as u64,
570 a.at_ptr(a_col, 0),
571 a.size() as u64,
572 a.sl() as u64,
573 tmp_bytes.as_mut_ptr(),
574 );
575 }
576 }
577
578 fn vec_znx_big_automorphism<R, A>(&self, k: i64, res: &mut R, res_col: usize, a: &A, a_col: usize)
579 where
580 R: VecZnxBigToMut<FFT64>,
581 A: VecZnxBigToRef<FFT64>,
582 {
583 let a: VecZnxBig<&[u8], FFT64> = a.to_ref();
584 let mut res: VecZnxBig<&mut [u8], FFT64> = res.to_mut();
585
586 #[cfg(debug_assertions)]
587 {
588 assert_eq!(a.n(), self.n());
589 assert_eq!(res.n(), self.n());
590 }
591 unsafe {
592 vec_znx::vec_znx_automorphism(
593 self.ptr,
594 k,
595 res.at_mut_ptr(res_col, 0),
596 res.size() as u64,
597 res.sl() as u64,
598 a.at_ptr(a_col, 0),
599 a.size() as u64,
600 a.sl() as u64,
601 )
602 }
603 }
604
605 fn vec_znx_big_automorphism_inplace<A>(&self, k: i64, a: &mut A, a_col: usize)
606 where
607 A: VecZnxBigToMut<FFT64>,
608 {
609 let mut a: VecZnxBig<&mut [u8], FFT64> = a.to_mut();
610
611 #[cfg(debug_assertions)]
612 {
613 assert_eq!(a.n(), self.n());
614 }
615 unsafe {
616 vec_znx::vec_znx_automorphism(
617 self.ptr,
618 k,
619 a.at_mut_ptr(a_col, 0),
620 a.size() as u64,
621 a.sl() as u64,
622 a.at_ptr(a_col, 0),
623 a.size() as u64,
624 a.sl() as u64,
625 )
626 }
627 }
628}
629
630impl<B: Backend> VecZnxBigScratch for Module<B> {
631 fn vec_znx_big_normalize_tmp_bytes(&self) -> usize {
632 <Self as VecZnxScratch>::vec_znx_normalize_tmp_bytes(self)
633 }
634}