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