poulpy/poulpy-hal/src/layouts/vec_znx_dft.rs
poulpy-hal/src/layouts/vec_znx_dft.rsRaw
1use std::{
2 fmt,
3 hash::{DefaultHasher, Hasher},
4 marker::PhantomData,
5};
6
7use rand_distr::num_traits::Zero;
8
9use crate::{
10 alloc_aligned,
11 layouts::{
12 Backend, Data, DataMut, DataRef, DataView, DataViewMut, DigestU64, VecZnxBig, ZnxInfos, ZnxSliceSize, ZnxView,
13 ZnxViewMut, ZnxZero,
14 },
15 oep::VecZnxDftAllocBytesImpl,
16};
17
18#[repr(C)]
19#[derive(PartialEq, Eq)]
20pub struct VecZnxDft<D: Data, B: Backend> {
21 pub data: D,
22 pub n: usize,
23 pub cols: usize,
24 pub size: usize,
25 pub max_size: usize,
26 pub _phantom: PhantomData<B>,
27}
28
29impl<D: DataRef, B: Backend> DigestU64 for VecZnxDft<D, B> {
30 fn digest_u64(&self) -> u64 {
31 let mut h: DefaultHasher = DefaultHasher::new();
32 h.write(self.data.as_ref());
33 h.write_usize(self.n);
34 h.write_usize(self.cols);
35 h.write_usize(self.size);
36 h.write_usize(self.max_size);
37 h.finish()
38 }
39}
40
41impl<D: Data, B: Backend> ZnxSliceSize for VecZnxDft<D, B> {
42 fn sl(&self) -> usize {
43 B::layout_prep_word_count() * self.n() * self.cols()
44 }
45}
46
47impl<D: DataRef, B: Backend> ZnxView for VecZnxDft<D, B> {
48 type Scalar = B::ScalarPrep;
49}
50
51impl<D: Data, B: Backend> VecZnxDft<D, B> {
52 pub fn into_big(self) -> VecZnxBig<D, B> {
53 VecZnxBig::<D, B>::from_data(self.data, self.n, self.cols, self.size)
54 }
55}
56
57impl<D: Data, B: Backend> ZnxInfos for VecZnxDft<D, B> {
58 fn cols(&self) -> usize {
59 self.cols
60 }
61
62 fn rows(&self) -> usize {
63 1
64 }
65
66 fn n(&self) -> usize {
67 self.n
68 }
69
70 fn size(&self) -> usize {
71 self.size
72 }
73}
74
75impl<D: Data, B: Backend> DataView for VecZnxDft<D, B> {
76 type D = D;
77 fn data(&self) -> &Self::D {
78 &self.data
79 }
80}
81
82impl<D: Data, B: Backend> DataViewMut for VecZnxDft<D, B> {
83 fn data_mut(&mut self) -> &mut Self::D {
84 &mut self.data
85 }
86}
87
88impl<D: DataRef, B: Backend> VecZnxDft<D, B> {
89 pub fn max_size(&self) -> usize {
90 self.max_size
91 }
92}
93
94impl<D: DataMut, B: Backend> VecZnxDft<D, B> {
95 pub fn set_size(&mut self, size: usize) {
96 assert!(size <= self.max_size);
97 self.size = size
98 }
99}
100
101impl<D: DataMut, B: Backend> ZnxZero for VecZnxDft<D, B>
102where
103 Self: ZnxViewMut,
104 <Self as ZnxView>::Scalar: Zero + Copy,
105{
106 fn zero(&mut self) {
107 self.raw_mut().fill(<Self as ZnxView>::Scalar::zero())
108 }
109 fn zero_at(&mut self, i: usize, j: usize) {
110 self.at_mut(i, j).fill(<Self as ZnxView>::Scalar::zero());
111 }
112}
113
114impl<D: DataRef + From<Vec<u8>>, B: Backend> VecZnxDft<D, B>
115where
116 B: VecZnxDftAllocBytesImpl<B>,
117{
118 pub fn alloc(n: usize, cols: usize, size: usize) -> Self {
119 let data: Vec<u8> = alloc_aligned::<u8>(B::vec_znx_dft_bytes_of_impl(n, cols, size));
120 Self {
121 data: data.into(),
122 n,
123 cols,
124 size,
125 max_size: size,
126 _phantom: PhantomData,
127 }
128 }
129
130 pub fn from_bytes(n: usize, cols: usize, size: usize, bytes: impl Into<Vec<u8>>) -> Self {
131 let data: Vec<u8> = bytes.into();
132 assert!(data.len() == B::vec_znx_dft_bytes_of_impl(n, cols, size));
133 Self {
134 data: data.into(),
135 n,
136 cols,
137 size,
138 max_size: size,
139 _phantom: PhantomData,
140 }
141 }
142}
143
144pub type VecZnxDftOwned<B> = VecZnxDft<Vec<u8>, B>;
145
146impl<D: Data, B: Backend> VecZnxDft<D, B> {
147 pub fn from_data(data: D, n: usize, cols: usize, size: usize) -> Self {
148 Self {
149 data,
150 n,
151 cols,
152 size,
153 max_size: size,
154 _phantom: PhantomData,
155 }
156 }
157}
158
159pub trait VecZnxDftToRef<B: Backend> {
160 fn to_ref(&self) -> VecZnxDft<&[u8], B>;
161}
162
163impl<D: DataRef, B: Backend> VecZnxDftToRef<B> for VecZnxDft<D, B> {
164 fn to_ref(&self) -> VecZnxDft<&[u8], B> {
165 VecZnxDft {
166 data: self.data.as_ref(),
167 n: self.n,
168 cols: self.cols,
169 size: self.size,
170 max_size: self.max_size,
171 _phantom: std::marker::PhantomData,
172 }
173 }
174}
175
176pub trait VecZnxDftToMut<B: Backend> {
177 fn to_mut(&mut self) -> VecZnxDft<&mut [u8], B>;
178}
179
180impl<D: DataMut, B: Backend> VecZnxDftToMut<B> for VecZnxDft<D, B> {
181 fn to_mut(&mut self) -> VecZnxDft<&mut [u8], B> {
182 VecZnxDft {
183 data: self.data.as_mut(),
184 n: self.n,
185 cols: self.cols,
186 size: self.size,
187 max_size: self.max_size,
188 _phantom: std::marker::PhantomData,
189 }
190 }
191}
192
193impl<D: DataRef, B: Backend> fmt::Display for VecZnxDft<D, B> {
194 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 writeln!(
196 f,
197 "VecZnxDft(n={}, cols={}, size={})",
198 self.n, self.cols, self.size
199 )?;
200
201 for col in 0..self.cols {
202 writeln!(f, "Column {col}:")?;
203 for size in 0..self.size {
204 let coeffs = self.at(col, size);
205 write!(f, " Size {size}: [")?;
206
207 let max_show = 100;
208 let show_count = coeffs.len().min(max_show);
209
210 for (i, &coeff) in coeffs.iter().take(show_count).enumerate() {
211 if i > 0 {
212 write!(f, ", ")?;
213 }
214 write!(f, "{coeff}")?;
215 }
216
217 if coeffs.len() > max_show {
218 write!(f, ", ... ({} more)", coeffs.len() - max_show)?;
219 }
220
221 writeln!(f, "]")?;
222 }
223 }
224 Ok(())
225 }
226}