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