arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-hal/src/layouts/vec_znx_big.rs
poulpy-hal/src/layouts/vec_znx_big.rsRaw
  1use std::{
  2    hash::{DefaultHasher, Hasher},
  3    marker::PhantomData,
  4};
  5
  6use rand_distr::num_traits::Zero;
  7use std::fmt;
  8
  9use crate::{
 10    alloc_aligned,
 11    layouts::{
 12        Backend, Data, DataMut, DataRef, DataView, DataViewMut, DigestU64, ZnxInfos, ZnxSliceSize, ZnxView, ZnxViewMut, ZnxZero,
 13    },
 14    oep::VecZnxBigAllocBytesImpl,
 15};
 16
 17#[repr(C)]
 18#[derive(PartialEq, Eq, Hash)]
 19pub struct VecZnxBig<D: Data, B: Backend> {
 20    pub data: D,
 21    pub n: usize,
 22    pub cols: usize,
 23    pub size: usize,
 24    pub max_size: usize,
 25    pub _phantom: PhantomData<B>,
 26}
 27
 28impl<D: DataRef, B: Backend> DigestU64 for VecZnxBig<D, B> {
 29    fn digest_u64(&self) -> u64 {
 30        let mut h: DefaultHasher = DefaultHasher::new();
 31        h.write(self.data.as_ref());
 32        h.write_usize(self.n);
 33        h.write_usize(self.cols);
 34        h.write_usize(self.size);
 35        h.write_usize(self.max_size);
 36        h.finish()
 37    }
 38}
 39
 40impl<D: Data, B: Backend> ZnxSliceSize for VecZnxBig<D, B> {
 41    fn sl(&self) -> usize {
 42        B::layout_big_word_count() * self.n() * self.cols()
 43    }
 44}
 45
 46impl<D: DataRef, B: Backend> ZnxView for VecZnxBig<D, B> {
 47    type Scalar = B::ScalarBig;
 48}
 49
 50impl<D: Data, B: Backend> ZnxInfos for VecZnxBig<D, B> {
 51    fn cols(&self) -> usize {
 52        self.cols
 53    }
 54
 55    fn rows(&self) -> usize {
 56        1
 57    }
 58
 59    fn n(&self) -> usize {
 60        self.n
 61    }
 62
 63    fn size(&self) -> usize {
 64        self.size
 65    }
 66}
 67
 68impl<D: Data, B: Backend> DataView for VecZnxBig<D, B> {
 69    type D = D;
 70    fn data(&self) -> &Self::D {
 71        &self.data
 72    }
 73}
 74
 75impl<D: Data, B: Backend> DataViewMut for VecZnxBig<D, B> {
 76    fn data_mut(&mut self) -> &mut Self::D {
 77        &mut self.data
 78    }
 79}
 80
 81impl<D: DataMut, B: Backend> ZnxZero for VecZnxBig<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> VecZnxBig<D, B>
 95where
 96    B: VecZnxBigAllocBytesImpl,
 97{
 98    pub fn alloc(n: usize, cols: usize, size: usize) -> Self {
 99        let data = alloc_aligned::<u8>(B::vec_znx_big_bytes_of_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_bytes_of_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
124impl<D: Data, B: Backend> VecZnxBig<D, B> {
125    pub fn from_data(data: D, n: usize, cols: usize, size: usize) -> Self {
126        Self {
127            data,
128            n,
129            cols,
130            size,
131            max_size: size,
132            _phantom: PhantomData,
133        }
134    }
135}
136
137pub type VecZnxBigOwned<B> = VecZnxBig<Vec<u8>, B>;
138
139pub trait VecZnxBigToRef<B: Backend> {
140    fn to_ref(&self) -> VecZnxBig<&[u8], B>;
141}
142
143impl<D: DataRef, B: Backend> VecZnxBigToRef<B> for VecZnxBig<D, B> {
144    fn to_ref(&self) -> VecZnxBig<&[u8], B> {
145        VecZnxBig {
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 VecZnxBigToMut<B: Backend> {
157    fn to_mut(&mut self) -> VecZnxBig<&mut [u8], B>;
158}
159
160impl<D: DataMut, B: Backend> VecZnxBigToMut<B> for VecZnxBig<D, B> {
161    fn to_mut(&mut self) -> VecZnxBig<&mut [u8], B> {
162        VecZnxBig {
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 VecZnxBig<D, B> {
174    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175        writeln!(f, "VecZnxBig(n={}, cols={}, size={})", self.n, self.cols, self.size)?;
176
177        for col in 0..self.cols {
178            writeln!(f, "Column {col}:")?;
179            for size in 0..self.size {
180                let coeffs = self.at(col, size);
181                write!(f, "  Size {size}: [")?;
182
183                let max_show = 100;
184                let show_count = coeffs.len().min(max_show);
185
186                for (i, &coeff) in coeffs.iter().take(show_count).enumerate() {
187                    if i > 0 {
188                        write!(f, ", ")?;
189                    }
190                    write!(f, "{coeff}")?;
191                }
192
193                if coeffs.len() > max_show {
194                    write!(f, ", ... ({} more)", coeffs.len() - max_show)?;
195                }
196
197                writeln!(f, "]")?;
198            }
199        }
200        Ok(())
201    }
202}