poulpy/poulpy-core/src/layouts/glwe_tensor.rs
poulpy-core/src/layouts/glwe_tensor.rsRaw
1use poulpy_hal::{
2 layouts::{Data, DataMut, DataRef, FillUniform, VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos},
3 source::Source,
4};
5
6use crate::layouts::{Base2K, Degree, GLWE, GLWEInfos, GLWEToMut, GLWEToRef, LWEInfos, Rank, SetGLWEInfos, TorusPrecision};
7use std::fmt;
8
9#[derive(PartialEq, Eq, Clone)]
10pub struct GLWETensor<D: Data> {
11 pub(crate) data: VecZnx<D>,
12 pub(crate) base2k: Base2K,
13 pub(crate) rank: Rank,
14 pub(crate) k: TorusPrecision,
15}
16
17impl<D: DataMut> SetGLWEInfos for GLWETensor<D> {
18 fn set_base2k(&mut self, base2k: Base2K) {
19 self.base2k = base2k
20 }
21
22 fn set_k(&mut self, k: TorusPrecision) {
23 self.k = k
24 }
25}
26
27impl<D: DataRef> GLWETensor<D> {
28 pub fn data(&self) -> &VecZnx<D> {
29 &self.data
30 }
31}
32
33impl<D: DataMut> GLWETensor<D> {
34 pub fn data_mut(&mut self) -> &mut VecZnx<D> {
35 &mut self.data
36 }
37}
38
39impl<D: Data> LWEInfos for GLWETensor<D> {
40 fn base2k(&self) -> Base2K {
41 self.base2k
42 }
43
44 fn k(&self) -> TorusPrecision {
45 self.k
46 }
47
48 fn n(&self) -> Degree {
49 Degree(self.data.n() as u32)
50 }
51
52 fn size(&self) -> usize {
53 self.data.size()
54 }
55}
56
57impl<D: Data> GLWEInfos for GLWETensor<D> {
58 ///NOTE: self.rank() != self.to_ref().rank() if self is of type [GLWETensor]
59 fn rank(&self) -> Rank {
60 self.rank
61 }
62}
63
64impl<D: DataRef> fmt::Debug for GLWETensor<D> {
65 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66 write!(f, "{self}")
67 }
68}
69
70impl<D: DataRef> fmt::Display for GLWETensor<D> {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 write!(f, "GLWETensor: base2k={} k={}: {}", self.base2k().0, self.k().0, self.data)
73 }
74}
75
76impl<D: DataMut> FillUniform for GLWETensor<D> {
77 fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
78 self.data.fill_uniform(log_bound, source);
79 }
80}
81
82impl GLWETensor<Vec<u8>> {
83 pub fn alloc_from_infos<A>(infos: &A) -> Self
84 where
85 A: GLWEInfos,
86 {
87 Self::alloc(infos.n(), infos.base2k(), infos.k(), infos.rank())
88 }
89
90 pub fn alloc(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self {
91 let cols: usize = rank.as_usize() + 1;
92 let pairs: usize = (((cols + 1) * cols) >> 1).max(1);
93 GLWETensor {
94 data: VecZnx::alloc(n.into(), pairs, k.0.div_ceil(base2k.0) as usize),
95 base2k,
96 k,
97 rank,
98 }
99 }
100
101 pub fn bytes_of_from_infos<A>(infos: &A) -> usize
102 where
103 A: GLWEInfos,
104 {
105 Self::bytes_of(infos.n(), infos.base2k(), infos.k(), infos.rank())
106 }
107
108 pub fn bytes_of(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
109 let cols: usize = rank.as_usize() + 1;
110 let pairs: usize = (((cols + 1) * cols) >> 1).max(1);
111 VecZnx::bytes_of(n.into(), pairs, k.0.div_ceil(base2k.0) as usize)
112 }
113}
114
115impl<D: DataRef> GLWEToRef for GLWETensor<D> {
116 fn to_ref(&self) -> GLWE<&[u8]> {
117 GLWE {
118 k: self.k,
119 base2k: self.base2k,
120 data: self.data.to_ref(),
121 }
122 }
123}
124
125impl<D: DataMut> GLWEToMut for GLWETensor<D> {
126 fn to_mut(&mut self) -> GLWE<&mut [u8]> {
127 GLWE {
128 k: self.k,
129 base2k: self.base2k,
130 data: self.data.to_mut(),
131 }
132 }
133}