1use poulpy_hal::{
2 layouts::{
3 Backend, Data, FillUniform, HostDataMut, HostDataRef, MatZnx, MatZnxAtBackendMut, MatZnxAtBackendRef, MatZnxToBackendMut,
4 MatZnxToBackendRef, ReaderFrom, WriterTo,
5 },
6 source::Source,
7};
8use std::{
9 fmt,
10 ops::{Deref, DerefMut},
11};
12
13use crate::layouts::{Base2K, Degree, Dnum, Dsize, GLWE, GLWEInfos, GLWEViewMut, GLWEViewRef, LWEInfos, Rank, TorusPrecision};
14use poulpy_hal::layouts::ZnxWord;
15
16pub trait GGSWInfos
23where
24 Self: GLWEInfos,
25{
26 fn k_aux(&self) -> TorusPrecision;
30 fn dnum(&self) -> Dnum;
32 fn dsize(&self) -> Dsize;
34 fn ggsw_layout(&self) -> GGSWLayout {
36 GGSWLayout {
37 n: self.n(),
38 base2k: self.base2k(),
39 dnum: self.dnum(),
40 k_aux: self.k_aux(),
41 rank: self.rank(),
42 dsize: self.dsize(),
43 }
44 }
45}
46
47#[derive(PartialEq, Eq, Copy, Clone, Debug)]
49pub struct GGSWLayout {
50 pub n: Degree,
52 pub base2k: Base2K,
54 pub dnum: Dnum,
56 pub k_aux: TorusPrecision,
58 pub rank: Rank,
60 pub dsize: Dsize,
62}
63
64impl LWEInfos for GGSWLayout {
65 fn base2k(&self) -> Base2K {
66 self.base2k
67 }
68
69 fn n(&self) -> Degree {
70 self.n
71 }
72
73 fn max_size(&self) -> usize {
74 crate::layouts::key_size(self.base2k, self.dnum, self.dsize, self.k_aux)
75 }
76
77 fn k(&self) -> TorusPrecision {
78 crate::layouts::key_k(self.base2k, self.dnum, self.dsize, self.k_aux)
79 }
80}
81impl GLWEInfos for GGSWLayout {
82 fn rank(&self) -> Rank {
83 self.rank
84 }
85}
86
87impl GGSWInfos for GGSWLayout {
88 fn k_aux(&self) -> TorusPrecision {
89 self.k_aux
90 }
91
92 fn dnum(&self) -> Dnum {
93 self.dnum
94 }
95
96 fn dsize(&self) -> Dsize {
97 self.dsize
98 }
99}
100
101#[derive(PartialEq, Eq, Clone)]
109pub struct GGSW<D: Data, W: ZnxWord> {
110 pub(crate) data: MatZnx<D, W>,
111 pub(crate) k_aux: TorusPrecision,
112 pub(crate) base2k: Base2K,
113 pub(crate) dsize: Dsize,
114}
115
116pub struct GGSWBackendRef<'a, BE: Backend + 'a> {
117 inner: GGSW<BE::BufRef<'a>, BE::ZnxWord>,
118}
119
120impl<'a, BE: Backend + 'a> GGSWBackendRef<'a, BE> {
121 pub fn from_inner(inner: GGSW<BE::BufRef<'a>, BE::ZnxWord>) -> Self {
122 Self { inner }
123 }
124
125 pub fn into_inner(self) -> GGSW<BE::BufRef<'a>, BE::ZnxWord> {
126 self.inner
127 }
128
129 pub fn at_view(&self, row: usize, col: usize) -> GLWEViewRef<'_, BE> {
130 GLWEViewRef::from_inner(ggsw_at_backend_ref_from_ref::<BE>(&self.inner, row, col))
131 }
132}
133
134impl<'a, BE: Backend + 'a> Deref for GGSWBackendRef<'a, BE> {
135 type Target = GGSW<BE::BufRef<'a>, BE::ZnxWord>;
136
137 fn deref(&self) -> &Self::Target {
138 &self.inner
139 }
140}
141
142pub struct GGSWBackendMut<'a, BE: Backend + 'a> {
143 inner: GGSW<BE::BufMut<'a>, BE::ZnxWord>,
144}
145
146impl<'a, BE: Backend + 'a> GGSWBackendMut<'a, BE> {
147 pub fn from_inner(inner: GGSW<BE::BufMut<'a>, BE::ZnxWord>) -> Self {
148 Self { inner }
149 }
150
151 pub fn into_inner(self) -> GGSW<BE::BufMut<'a>, BE::ZnxWord> {
152 self.inner
153 }
154
155 pub fn at_view(&self, row: usize, col: usize) -> GLWEViewRef<'_, BE> {
156 GLWEViewRef::from_inner(ggsw_at_backend_ref_from_mut::<BE>(&self.inner, row, col))
157 }
158
159 pub fn at_view_mut(&mut self, row: usize, col: usize) -> GLWEViewMut<'_, BE> {
160 GLWEViewMut::from_inner(ggsw_at_backend_mut_from_mut::<BE>(&mut self.inner, row, col))
161 }
162}
163
164impl<'a, BE: Backend + 'a> Deref for GGSWBackendMut<'a, BE> {
165 type Target = GGSW<BE::BufMut<'a>, BE::ZnxWord>;
166
167 fn deref(&self) -> &Self::Target {
168 &self.inner
169 }
170}
171
172impl<'a, BE: Backend + 'a> DerefMut for GGSWBackendMut<'a, BE> {
173 fn deref_mut(&mut self) -> &mut Self::Target {
174 &mut self.inner
175 }
176}
177
178impl<'a, BE: Backend + 'a> LWEInfos for GGSWBackendRef<'a, BE> {
179 fn base2k(&self) -> Base2K {
180 self.inner.base2k()
181 }
182
183 fn n(&self) -> Degree {
184 self.inner.n()
185 }
186
187 fn max_size(&self) -> usize {
188 self.inner.max_size()
189 }
190
191 fn k(&self) -> TorusPrecision {
192 self.inner.k()
193 }
194}
195
196impl<'a, BE: Backend + 'a> GLWEInfos for GGSWBackendRef<'a, BE> {
197 fn rank(&self) -> Rank {
198 self.inner.rank()
199 }
200}
201
202impl<'a, BE: Backend + 'a> GGSWInfos for GGSWBackendRef<'a, BE> {
203 fn k_aux(&self) -> TorusPrecision {
204 self.inner.k_aux()
205 }
206
207 fn dnum(&self) -> Dnum {
208 self.inner.dnum()
209 }
210
211 fn dsize(&self) -> Dsize {
212 self.inner.dsize()
213 }
214}
215
216impl<'a, BE: Backend + 'a> LWEInfos for GGSWBackendMut<'a, BE> {
217 fn base2k(&self) -> Base2K {
218 self.inner.base2k()
219 }
220
221 fn n(&self) -> Degree {
222 self.inner.n()
223 }
224
225 fn max_size(&self) -> usize {
226 self.inner.max_size()
227 }
228
229 fn k(&self) -> TorusPrecision {
230 self.inner.k()
231 }
232}
233
234impl<'a, BE: Backend + 'a> GLWEInfos for GGSWBackendMut<'a, BE> {
235 fn rank(&self) -> Rank {
236 self.inner.rank()
237 }
238}
239
240impl<'a, BE: Backend + 'a> GGSWInfos for GGSWBackendMut<'a, BE> {
241 fn k_aux(&self) -> TorusPrecision {
242 self.inner.k_aux()
243 }
244
245 fn dnum(&self) -> Dnum {
246 self.inner.dnum()
247 }
248
249 fn dsize(&self) -> Dsize {
250 self.inner.dsize()
251 }
252}
253
254impl<'a, BE: Backend + 'a> GGSWToBackendRef<BE> for GGSWBackendRef<'a, BE> {
255 fn to_backend_ref(&self) -> GGSWBackendRef<'_, BE> {
256 GGSWBackendRef::from_inner(GGSW {
257 dsize: self.inner.dsize(),
258 base2k: self.inner.base2k(),
259 k_aux: self.inner.k_aux(),
260 data: poulpy_hal::layouts::mat_znx_backend_ref_from_ref::<BE>(&self.inner.data),
261 })
262 }
263}
264
265impl<'a, BE: Backend + 'a> GGSWToBackendRef<BE> for GGSWBackendMut<'a, BE> {
266 fn to_backend_ref(&self) -> GGSWBackendRef<'_, BE> {
267 GGSWBackendRef::from_inner(GGSW {
268 dsize: self.inner.dsize,
269 base2k: self.inner.base2k,
270 k_aux: self.inner.k_aux,
271 data: poulpy_hal::layouts::mat_znx_backend_ref_from_mut::<BE>(&self.inner.data),
272 })
273 }
274}
275
276impl<'a, BE: Backend + 'a> GGSWToBackendMut<BE> for GGSWBackendMut<'a, BE> {
277 fn to_backend_mut(&mut self) -> GGSWBackendMut<'_, BE> {
278 GGSWBackendMut::from_inner(GGSW {
279 dsize: self.inner.dsize,
280 base2k: self.inner.base2k,
281 k_aux: self.inner.k_aux,
282 data: poulpy_hal::layouts::mat_znx_backend_mut_from_mut::<BE>(&mut self.inner.data),
283 })
284 }
285}
286
287impl<'a, BE: Backend + 'a> GGSWAtViewRef<BE> for GGSWBackendRef<'a, BE> {
288 fn at_view(&self, row: usize, col: usize) -> GLWEViewRef<'_, BE> {
289 GGSWBackendRef::at_view(self, row, col)
290 }
291}
292
293impl<'a, BE: Backend + 'a> GGSWAtViewRef<BE> for GGSWBackendMut<'a, BE> {
294 fn at_view(&self, row: usize, col: usize) -> GLWEViewRef<'_, BE> {
295 GGSWBackendMut::at_view(self, row, col)
296 }
297}
298
299impl<'a, BE: Backend + 'a> GGSWAtViewRef<BE> for &GGSWBackendRef<'a, BE> {
300 fn at_view(&self, row: usize, col: usize) -> GLWEViewRef<'_, BE> {
301 GGSWBackendRef::at_view(self, row, col)
302 }
303}
304
305impl<D: Data, W: ZnxWord> LWEInfos for GGSW<D, W> {
306 fn n(&self) -> Degree {
307 Degree(self.data.n() as u32)
308 }
309
310 fn base2k(&self) -> Base2K {
311 self.base2k
312 }
313
314 fn max_size(&self) -> usize {
315 self.data.size()
316 }
317
318 fn k(&self) -> TorusPrecision {
319 crate::layouts::key_k(self.base2k, self.dnum(), self.dsize, self.k_aux)
320 }
321}
322
323impl<D: Data, W: ZnxWord> GLWEInfos for GGSW<D, W> {
324 fn rank(&self) -> Rank {
325 Rank(self.data.cols_out() as u32 - 1)
326 }
327}
328
329impl<D: Data, W: ZnxWord> GGSWInfos for GGSW<D, W> {
330 fn k_aux(&self) -> TorusPrecision {
331 self.k_aux
332 }
333
334 fn dsize(&self) -> Dsize {
335 self.dsize
336 }
337
338 fn dnum(&self) -> Dnum {
339 Dnum(self.data.rows() as u32)
340 }
341}
342
343impl<D: HostDataRef, W: ZnxWord> fmt::Debug for GGSW<D, W> {
344 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
345 write!(f, "{}", self.data)
346 }
347}
348
349impl<D: HostDataRef, W: ZnxWord> fmt::Display for GGSW<D, W> {
350 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
351 write!(
352 f,
353 "(GGSW: k: {} base2k: {} dsize: {}) {}",
354 self.k().0,
355 self.base2k().0,
356 self.dsize().0,
357 self.data
358 )
359 }
360}
361
362impl<D: HostDataMut, W: ZnxWord> FillUniform for GGSW<D, W> {
363 fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
364 self.data.fill_uniform(log_bound, source);
365 }
366}
367
368impl<D: HostDataRef, W: ZnxWord> GGSW<D, W> {
369 pub fn at(&self, row: usize, col: usize) -> GLWE<&[u8], W> {
370 let data = self.data.at(row, col);
371 GLWE {
372 base2k: self.base2k,
373 k: self.k(),
374 data,
375 }
376 }
377}
378
379pub trait GGSWAtBackendRef<BE: Backend> {
381 fn at_backend(&self, row: usize, col: usize) -> GLWE<BE::BufRef<'_>, BE::ZnxWord>;
382}
383
384impl<BE: Backend> GGSWAtBackendRef<BE> for GGSW<BE::OwnedBuf, BE::ZnxWord> {
385 fn at_backend(&self, row: usize, col: usize) -> GLWE<BE::BufRef<'_>, BE::ZnxWord> {
386 let data = <MatZnx<BE::OwnedBuf, BE::ZnxWord> as MatZnxAtBackendRef<BE>>::at_backend(&self.data, row, col);
387 GLWE {
388 base2k: self.base2k,
389 k: self.k(),
390 data,
391 }
392 }
393}
394
395pub(crate) fn ggsw_at_backend_ref_from_ref<'a, 'b, BE: Backend>(
396 ggsw: &'a GGSW<BE::BufRef<'b>, BE::ZnxWord>,
397 row: usize,
398 col: usize,
399) -> GLWE<BE::BufRef<'a>, BE::ZnxWord> {
400 let data = poulpy_hal::layouts::mat_znx_at_backend_ref_from_ref::<BE>(&ggsw.data, row, col);
401 GLWE {
402 base2k: ggsw.base2k,
403 k: ggsw.k(),
404 data,
405 }
406}
407
408pub trait GGSWAtViewRef<BE: Backend> {
409 fn at_view(&self, row: usize, col: usize) -> GLWEViewRef<'_, BE>;
410}
411
412impl<BE: Backend> GGSWAtViewRef<BE> for GGSW<BE::OwnedBuf, BE::ZnxWord> {
413 fn at_view(&self, row: usize, col: usize) -> GLWEViewRef<'_, BE> {
414 GLWEViewRef::from_inner(<GGSW<BE::OwnedBuf, BE::ZnxWord> as GGSWAtBackendRef<BE>>::at_backend(
415 self, row, col,
416 ))
417 }
418}
419
420pub(crate) fn ggsw_at_backend_ref_from_mut<'a, 'b, BE: Backend>(
421 ggsw: &'a GGSW<BE::BufMut<'b>, BE::ZnxWord>,
422 row: usize,
423 col: usize,
424) -> GLWE<BE::BufRef<'a>, BE::ZnxWord> {
425 let data = poulpy_hal::layouts::mat_znx_at_backend_ref_from_mut::<BE>(&ggsw.data, row, col);
426 GLWE {
427 base2k: ggsw.base2k,
428 k: ggsw.k(),
429 data,
430 }
431}
432
433impl<D: HostDataMut, W: ZnxWord> GGSW<D, W> {
434 pub fn at_mut(&mut self, row: usize, col: usize) -> GLWE<&mut [u8], W> {
435 let base2k = self.base2k;
436 let k = self.k();
437 let data = self.data.at_mut(row, col);
438 GLWE { base2k, k, data }
439 }
440}
441
442pub trait GGSWAtBackendMut<BE: Backend> {
444 fn at_backend_mut(&mut self, row: usize, col: usize) -> GLWE<BE::BufMut<'_>, BE::ZnxWord>;
445}
446
447impl<BE: Backend> GGSWAtBackendMut<BE> for GGSW<BE::OwnedBuf, BE::ZnxWord> {
448 fn at_backend_mut(&mut self, row: usize, col: usize) -> GLWE<BE::BufMut<'_>, BE::ZnxWord> {
449 let base2k = self.base2k;
450 let k = self.k();
451 let data = <MatZnx<BE::OwnedBuf, BE::ZnxWord> as MatZnxAtBackendMut<BE>>::at_backend_mut(&mut self.data, row, col);
452 GLWE { base2k, k, data }
453 }
454}
455
456pub(crate) fn ggsw_at_backend_mut_from_mut<'a, 'b, BE: Backend>(
457 ggsw: &'a mut GGSW<BE::BufMut<'b>, BE::ZnxWord>,
458 row: usize,
459 col: usize,
460) -> GLWE<BE::BufMut<'a>, BE::ZnxWord> {
461 let base2k = ggsw.base2k;
462 let k = ggsw.k();
463 let data = poulpy_hal::layouts::mat_znx_at_backend_mut_from_mut::<BE>(&mut ggsw.data, row, col);
464 GLWE { base2k, k, data }
465}
466
467pub trait GGSWAtViewMut<BE: Backend> {
468 fn at_view_mut(&mut self, row: usize, col: usize) -> GLWEViewMut<'_, BE>;
469}
470
471impl<BE: Backend> GGSWAtViewMut<BE> for GGSW<BE::OwnedBuf, BE::ZnxWord> {
472 fn at_view_mut(&mut self, row: usize, col: usize) -> GLWEViewMut<'_, BE> {
473 GLWEViewMut::from_inner(<GGSW<BE::OwnedBuf, BE::ZnxWord> as GGSWAtBackendMut<BE>>::at_backend_mut(
474 self, row, col,
475 ))
476 }
477}
478
479impl<'a, BE: Backend + 'a> GGSWAtViewMut<BE> for GGSWBackendMut<'a, BE> {
480 fn at_view_mut(&mut self, row: usize, col: usize) -> GLWEViewMut<'_, BE> {
481 GGSWBackendMut::at_view_mut(self, row, col)
482 }
483}
484
485impl<D: Data, W: ZnxWord> GGSW<D, W> {
486 pub fn reinterpret<To>(self) -> GGSW<To::OwnedBuf, To::ZnxWord>
488 where
489 To: Backend<OwnedBuf = D, ZnxWord = W>,
490 {
491 let (n, rows, cols_in, cols_out, size) = (
492 self.data.n(),
493 self.data.rows(),
494 self.data.cols_in(),
495 self.data.cols_out(),
496 self.data.size(),
497 );
498 GGSW {
499 data: MatZnx::from_data(self.data.into_data(), n, rows, cols_in, cols_out, size),
500 k_aux: self.k_aux,
501 base2k: self.base2k,
502 dsize: self.dsize,
503 }
504 }
505}
506
507#[expect(
508 dead_code,
509 reason = "host-owned constructors are kept for serialization and host-only staging"
510)]
511impl<W: ZnxWord> GGSW<Vec<u8>, W> {
512 pub(crate) fn alloc_from_infos<A>(infos: &A) -> Self
513 where
514 A: GGSWInfos,
515 {
516 Self::alloc(
517 infos.n(),
518 infos.base2k(),
519 infos.dnum(),
520 infos.dsize(),
521 infos.k_aux(),
522 infos.rank(),
523 )
524 }
525
526 pub(crate) fn alloc(n: Degree, base2k: Base2K, dnum: Dnum, dsize: Dsize, k_aux: TorusPrecision, rank: Rank) -> Self {
527 let size: usize = crate::layouts::key_size(base2k, dnum, dsize, k_aux);
528
529 GGSW {
530 data: MatZnx::from_data(
531 poulpy_hal::layouts::HostBytesBackend::alloc_bytes(MatZnx::<Vec<u8>, W>::bytes_of(
532 n.into(),
533 dnum.into(),
534 (rank + 1).into(),
535 (rank + 1).into(),
536 size,
537 )),
538 n.into(),
539 dnum.into(),
540 (rank + 1).into(),
541 (rank + 1).into(),
542 size,
543 ),
544 k_aux,
545 base2k,
546 dsize,
547 }
548 }
549
550 pub fn bytes_of_from_infos<A>(infos: &A) -> usize
551 where
552 A: GGSWInfos,
553 {
554 Self::bytes_of(
555 infos.n(),
556 infos.base2k(),
557 infos.dnum(),
558 infos.dsize(),
559 infos.k_aux(),
560 infos.rank(),
561 )
562 }
563
564 pub fn bytes_of(n: Degree, base2k: Base2K, dnum: Dnum, dsize: Dsize, k_aux: TorusPrecision, rank: Rank) -> usize {
565 let size: usize = crate::layouts::key_size(base2k, dnum, dsize, k_aux);
566
567 MatZnx::<Vec<u8>, W>::bytes_of(n.into(), dnum.into(), (rank + 1).into(), (rank + 1).into(), size)
568 }
569}
570
571use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
572
573impl<D: HostDataMut, W: ZnxWord> ReaderFrom for GGSW<D, W> {
574 fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
575 self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
576 self.dsize = Dsize(reader.read_u32::<LittleEndian>()?);
577 self.k_aux = TorusPrecision(reader.read_u32::<LittleEndian>()?);
578 self.data.read_from(reader)
579 }
580}
581
582impl<D: HostDataRef, W: ZnxWord> WriterTo for GGSW<D, W> {
583 fn write_to<Wr: std::io::Write>(&self, writer: &mut Wr) -> std::io::Result<()> {
584 writer.write_u32::<LittleEndian>(self.base2k.into())?;
585 writer.write_u32::<LittleEndian>(self.dsize.into())?;
586 writer.write_u32::<LittleEndian>(self.k_aux.into())?;
587 self.data.write_to(writer)
588 }
589}
590
591pub trait GGSWToBackendMut<BE: Backend>: GGSWToBackendRef<BE> {
592 fn to_backend_mut(&mut self) -> GGSWBackendMut<'_, BE>;
593}
594
595impl<BE: Backend, D: Data> GGSWToBackendMut<BE> for GGSW<D, BE::ZnxWord>
596where
597 MatZnx<D, BE::ZnxWord>: MatZnxToBackendRef<BE> + MatZnxToBackendMut<BE>,
598{
599 fn to_backend_mut(&mut self) -> GGSWBackendMut<'_, BE> {
600 GGSWBackendMut::from_inner(GGSW {
601 dsize: self.dsize,
602 base2k: self.base2k,
603 k_aux: self.k_aux,
604 data: self.data.to_backend_mut(),
605 })
606 }
607}
608
609impl<'b, BE: Backend + 'b> GGSWToBackendRef<BE> for &mut GGSW<BE::BufMut<'b>, BE::ZnxWord> {
610 fn to_backend_ref(&self) -> GGSWBackendRef<'_, BE> {
611 GGSWBackendRef::from_inner(GGSW {
612 dsize: self.dsize,
613 base2k: self.base2k,
614 k_aux: self.k_aux,
615 data: poulpy_hal::layouts::mat_znx_backend_ref_from_mut::<BE>(&self.data),
616 })
617 }
618}
619
620impl<'b, BE: Backend + 'b> GGSWToBackendMut<BE> for &mut GGSW<BE::BufMut<'b>, BE::ZnxWord> {
621 fn to_backend_mut(&mut self) -> GGSWBackendMut<'_, BE> {
622 ggsw_backend_mut_from_mut::<BE>(self)
623 }
624}
625
626pub fn ggsw_backend_mut_from_mut<'a, 'b, BE: Backend>(ggsw: &'a mut GGSW<BE::BufMut<'b>, BE::ZnxWord>) -> GGSWBackendMut<'a, BE> {
627 GGSWBackendMut::from_inner(GGSW {
628 dsize: ggsw.dsize,
629 base2k: ggsw.base2k,
630 k_aux: ggsw.k_aux,
631 data: poulpy_hal::layouts::mat_znx_backend_mut_from_mut::<BE>(&mut ggsw.data),
632 })
633}
634
635pub struct GGSWBackendRowViewMut<'a, BE: Backend + 'a> {
639 inner: GGSWBackendMut<'a, BE>,
640}
641
642impl<'a, BE: Backend + 'a> GGSWBackendRowViewMut<'a, BE> {
643 pub fn from_inner(inner: GGSWBackendMut<'a, BE>) -> Self {
644 Self { inner }
645 }
646}
647
648impl<'a, BE: Backend + 'a> LWEInfos for GGSWBackendRowViewMut<'a, BE> {
649 fn base2k(&self) -> Base2K {
650 self.inner.base2k()
651 }
652 fn n(&self) -> Degree {
653 self.inner.n()
654 }
655 fn max_size(&self) -> usize {
656 self.inner.max_size()
657 }
658 fn k(&self) -> TorusPrecision {
659 self.inner.k()
660 }
661}
662
663impl<'a, BE: Backend + 'a> GLWEInfos for GGSWBackendRowViewMut<'a, BE> {
664 fn rank(&self) -> Rank {
665 self.inner.rank()
666 }
667}
668
669impl<'a, BE: Backend + 'a> GGSWInfos for GGSWBackendRowViewMut<'a, BE> {
670 fn k_aux(&self) -> TorusPrecision {
671 self.inner.k_aux()
672 }
673 fn dnum(&self) -> Dnum {
674 self.inner.dnum()
675 }
676 fn dsize(&self) -> Dsize {
677 self.inner.dsize()
678 }
679}
680
681impl<'a, BE: Backend + 'a> GGSWToBackendRef<BE> for GGSWBackendRowViewMut<'a, BE> {
682 fn to_backend_ref(&self) -> GGSWBackendRef<'_, BE> {
683 self.inner.to_backend_ref()
684 }
685}
686
687impl<'a, BE: Backend + 'a> GGSWToBackendMut<BE> for GGSWBackendRowViewMut<'a, BE> {
688 fn to_backend_mut(&mut self) -> GGSWBackendMut<'_, BE> {
689 GGSWBackendMut::from_inner(GGSW {
690 dsize: self.inner.inner.dsize,
691 base2k: self.inner.inner.base2k,
692 k_aux: self.inner.inner.k_aux,
693 data: poulpy_hal::layouts::mat_znx_backend_mut_from_mut::<BE>(&mut self.inner.inner.data),
694 })
695 }
696}
697
698impl<'a, BE: Backend + 'a> GGSWAtViewRef<BE> for GGSWBackendRowViewMut<'a, BE> {
699 fn at_view(&self, row: usize, col: usize) -> GLWEViewRef<'_, BE> {
700 self.inner.at_view(row, col)
701 }
702}
703
704impl<'a, BE: Backend + 'a> GGSWAtViewMut<BE> for GGSWBackendRowViewMut<'a, BE> {
705 fn at_view_mut(&mut self, row: usize, col: usize) -> GLWEViewMut<'_, BE> {
706 self.inner.at_view_mut(row, col)
707 }
708}
709
710pub trait GGSWToBackendRef<BE: Backend> {
711 fn to_backend_ref(&self) -> GGSWBackendRef<'_, BE>;
712}
713
714impl<BE: Backend, D: Data> GGSWToBackendRef<BE> for GGSW<D, BE::ZnxWord>
715where
716 MatZnx<D, BE::ZnxWord>: MatZnxToBackendRef<BE>,
717{
718 fn to_backend_ref(&self) -> GGSWBackendRef<'_, BE> {
719 GGSWBackendRef::from_inner(GGSW {
720 dsize: self.dsize,
721 base2k: self.base2k,
722 k_aux: self.k_aux,
723 data: self.data.to_backend_ref(),
724 })
725 }
726}