arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-hal/src/api/scratch.rs
poulpy-hal/src/api/scratch.rsRaw
  1use crate::{
  2    api::{CnvPVecBytesOf, ModuleN, SvpPPolBytesOf, VecZnxBigBytesOf, VecZnxDftBytesOf, VmpPMatBytesOf},
  3    layouts::{Backend, CnvPVecL, CnvPVecR, MatZnx, ScalarZnx, Scratch, SvpPPol, VecZnx, VecZnxBig, VecZnxDft, VmpPMat},
  4};
  5
  6/// Allocates a new [crate::layouts::ScratchOwned] of `size` aligned bytes.
  7pub trait ScratchOwnedAlloc<B: Backend> {
  8    fn alloc(size: usize) -> Self;
  9}
 10
 11/// Borrows a slice of bytes into a [Scratch].
 12pub trait ScratchOwnedBorrow<B: Backend> {
 13    fn borrow(&mut self) -> &mut Scratch<B>;
 14}
 15
 16/// Wrap an array of mutable borrowed bytes into a [Scratch].
 17pub trait ScratchFromBytes<B: Backend> {
 18    fn from_bytes(data: &mut [u8]) -> &mut Scratch<B>;
 19}
 20
 21/// Returns how many bytes left can be taken from the scratch.
 22pub trait ScratchAvailable {
 23    fn available(&self) -> usize;
 24}
 25
 26/// Takes a slice of bytes from a [Scratch] and return a new [Scratch] minus the taken array of bytes.
 27pub trait TakeSlice {
 28    fn take_slice<T>(&mut self, len: usize) -> (&mut [T], &mut Self);
 29}
 30
 31impl<BE: Backend> Scratch<BE>
 32where
 33    Self: TakeSlice + ScratchAvailable + ScratchFromBytes<BE>,
 34{
 35    pub fn split_at_mut(&mut self, len: usize) -> (&mut Scratch<BE>, &mut Self) {
 36        let (take_slice, rem_slice) = self.take_slice(len);
 37        (Self::from_bytes(take_slice), rem_slice)
 38    }
 39
 40    pub fn split_mut(&mut self, n: usize, len: usize) -> (Vec<&mut Scratch<BE>>, &mut Self) {
 41        assert!(self.available() >= n * len);
 42        let mut scratches: Vec<&mut Scratch<BE>> = Vec::with_capacity(n);
 43        let mut scratch: &mut Scratch<BE> = self;
 44        for _ in 0..n {
 45            let (tmp, scratch_new) = scratch.split_at_mut(len);
 46            scratch = scratch_new;
 47            scratches.push(tmp);
 48        }
 49        (scratches, scratch)
 50    }
 51}
 52
 53impl<B: Backend> ScratchTakeBasic for Scratch<B> where Self: TakeSlice + ScratchFromBytes<B> {}
 54
 55pub trait ScratchTakeBasic
 56where
 57    Self: TakeSlice,
 58{
 59    fn take_cnv_pvec_left<M, B: Backend>(&mut self, module: &M, cols: usize, size: usize) -> (CnvPVecL<&mut [u8], B>, &mut Self)
 60    where
 61        M: ModuleN + CnvPVecBytesOf,
 62    {
 63        let (take_slice, rem_slice) = self.take_slice(module.bytes_of_cnv_pvec_left(cols, size));
 64        (CnvPVecL::from_data(take_slice, module.n(), cols, size), rem_slice)
 65    }
 66
 67    fn take_cnv_pvec_right<M, B: Backend>(&mut self, module: &M, cols: usize, size: usize) -> (CnvPVecR<&mut [u8], B>, &mut Self)
 68    where
 69        M: ModuleN + CnvPVecBytesOf,
 70    {
 71        let (take_slice, rem_slice) = self.take_slice(module.bytes_of_cnv_pvec_right(cols, size));
 72        (CnvPVecR::from_data(take_slice, module.n(), cols, size), rem_slice)
 73    }
 74
 75    fn take_scalar_znx(&mut self, n: usize, cols: usize) -> (ScalarZnx<&mut [u8]>, &mut Self) {
 76        let (take_slice, rem_slice) = self.take_slice(ScalarZnx::bytes_of(n, cols));
 77        (ScalarZnx::from_data(take_slice, n, cols), rem_slice)
 78    }
 79
 80    fn take_svp_ppol<M, B: Backend>(&mut self, module: &M, cols: usize) -> (SvpPPol<&mut [u8], B>, &mut Self)
 81    where
 82        M: SvpPPolBytesOf + ModuleN,
 83    {
 84        let (take_slice, rem_slice) = self.take_slice(module.bytes_of_svp_ppol(cols));
 85        (SvpPPol::from_data(take_slice, module.n(), cols), rem_slice)
 86    }
 87
 88    fn take_vec_znx(&mut self, n: usize, cols: usize, size: usize) -> (VecZnx<&mut [u8]>, &mut Self) {
 89        let (take_slice, rem_slice) = self.take_slice(VecZnx::bytes_of(n, cols, size));
 90        (VecZnx::from_data(take_slice, n, cols, size), rem_slice)
 91    }
 92
 93    fn take_vec_znx_big<M, B: Backend>(&mut self, module: &M, cols: usize, size: usize) -> (VecZnxBig<&mut [u8], B>, &mut Self)
 94    where
 95        M: VecZnxBigBytesOf + ModuleN,
 96    {
 97        let (take_slice, rem_slice) = self.take_slice(module.bytes_of_vec_znx_big(cols, size));
 98        (VecZnxBig::from_data(take_slice, module.n(), cols, size), rem_slice)
 99    }
100
101    fn take_vec_znx_dft<M, B: Backend>(&mut self, module: &M, cols: usize, size: usize) -> (VecZnxDft<&mut [u8], B>, &mut Self)
102    where
103        M: VecZnxDftBytesOf + ModuleN,
104    {
105        let (take_slice, rem_slice) = self.take_slice(module.bytes_of_vec_znx_dft(cols, size));
106
107        (VecZnxDft::from_data(take_slice, module.n(), cols, size), rem_slice)
108    }
109
110    fn take_vec_znx_dft_slice<M, B: Backend>(
111        &mut self,
112        module: &M,
113        len: usize,
114        cols: usize,
115        size: usize,
116    ) -> (Vec<VecZnxDft<&mut [u8], B>>, &mut Self)
117    where
118        M: VecZnxDftBytesOf + ModuleN,
119    {
120        let mut scratch: &mut Self = self;
121        let mut slice: Vec<VecZnxDft<&mut [u8], B>> = Vec::with_capacity(len);
122        for _ in 0..len {
123            let (znx, new_scratch) = scratch.take_vec_znx_dft(module, cols, size);
124            scratch = new_scratch;
125            slice.push(znx);
126        }
127        (slice, scratch)
128    }
129
130    fn take_vec_znx_slice(&mut self, len: usize, n: usize, cols: usize, size: usize) -> (Vec<VecZnx<&mut [u8]>>, &mut Self) {
131        let mut scratch: &mut Self = self;
132        let mut slice: Vec<VecZnx<&mut [u8]>> = Vec::with_capacity(len);
133        for _ in 0..len {
134            let (znx, new_scratch) = scratch.take_vec_znx(n, cols, size);
135            scratch = new_scratch;
136            slice.push(znx);
137        }
138        (slice, scratch)
139    }
140
141    fn take_vmp_pmat<M, B: Backend>(
142        &mut self,
143        module: &M,
144        rows: usize,
145        cols_in: usize,
146        cols_out: usize,
147        size: usize,
148    ) -> (VmpPMat<&mut [u8], B>, &mut Self)
149    where
150        M: VmpPMatBytesOf + ModuleN,
151    {
152        let (take_slice, rem_slice) = self.take_slice(module.bytes_of_vmp_pmat(rows, cols_in, cols_out, size));
153        (
154            VmpPMat::from_data(take_slice, module.n(), rows, cols_in, cols_out, size),
155            rem_slice,
156        )
157    }
158
159    fn take_mat_znx(
160        &mut self,
161        n: usize,
162        rows: usize,
163        cols_in: usize,
164        cols_out: usize,
165        size: usize,
166    ) -> (MatZnx<&mut [u8]>, &mut Self) {
167        let (take_slice, rem_slice) = self.take_slice(MatZnx::bytes_of(n, rows, cols_in, cols_out, size));
168        (MatZnx::from_data(take_slice, n, rows, cols_in, cols_out, size), rem_slice)
169    }
170}