use crate::{ api::{SvpPPolBytesOf, VecZnxBigBytesOf, VecZnxDftBytesOf, VmpPMatBytesOf}, layouts::{Backend, MatZnx, Module, ScalarZnx, Scratch, SvpPPol, VecZnx, VecZnxBig, VecZnxDft, VmpPMat}, }; /// Allocates a new [crate::layouts::ScratchOwned] of `size` aligned bytes. pub trait ScratchOwnedAlloc { fn alloc(size: usize) -> Self; } /// Borrows a slice of bytes into a [Scratch]. pub trait ScratchOwnedBorrow { fn borrow(&mut self) -> &mut Scratch; } /// Wrap an array of mutable borrowed bytes into a [Scratch]. pub trait ScratchFromBytes { fn from_bytes(data: &mut [u8]) -> &mut Scratch; } /// Returns how many bytes left can be taken from the scratch. pub trait ScratchAvailable { fn available(&self) -> usize; } /// Takes a slice of bytes from a [Scratch] and return a new [Scratch] minus the taken array of bytes. pub trait TakeSlice { fn take_slice(&mut self, len: usize) -> (&mut [T], &mut Self); } pub trait ScratchTakeBasic where Self: TakeSlice, { fn take_scalar_znx(&mut self, module: &Module, cols: usize) -> (ScalarZnx<&mut [u8]>, &mut Self) { let (take_slice, rem_slice) = self.take_slice(ScalarZnx::bytes_of(module.n(), cols)); ( ScalarZnx::from_data(take_slice, module.n(), cols), rem_slice, ) } fn take_svp_ppol(&mut self, module: &Module, cols: usize) -> (SvpPPol<&mut [u8], B>, &mut Self) where Module: SvpPPolBytesOf, { let (take_slice, rem_slice) = self.take_slice(module.bytes_of_svp_ppol(cols)); (SvpPPol::from_data(take_slice, module.n(), cols), rem_slice) } fn take_vec_znx(&mut self, module: &Module, cols: usize, size: usize) -> (VecZnx<&mut [u8]>, &mut Self) { let (take_slice, rem_slice) = self.take_slice(VecZnx::bytes_of(module.n(), cols, size)); ( VecZnx::from_data(take_slice, module.n(), cols, size), rem_slice, ) } fn take_vec_znx_big(&mut self, module: &Module, cols: usize, size: usize) -> (VecZnxBig<&mut [u8], B>, &mut Self) where Module: VecZnxBigBytesOf, { let (take_slice, rem_slice) = self.take_slice(module.bytes_of_vec_znx_big(cols, size)); ( VecZnxBig::from_data(take_slice, module.n(), cols, size), rem_slice, ) } fn take_vec_znx_dft(&mut self, module: &Module, cols: usize, size: usize) -> (VecZnxDft<&mut [u8], B>, &mut Self) where Module: VecZnxDftBytesOf, { let (take_slice, rem_slice) = self.take_slice(module.bytes_of_vec_znx_dft(cols, size)); ( VecZnxDft::from_data(take_slice, module.n(), cols, size), rem_slice, ) } fn take_vec_znx_dft_slice( &mut self, module: &Module, len: usize, cols: usize, size: usize, ) -> (Vec>, &mut Self) where Module: VecZnxDftBytesOf, { let mut scratch: &mut Self = self; let mut slice: Vec> = Vec::with_capacity(len); for _ in 0..len { let (znx, new_scratch) = scratch.take_vec_znx_dft(module, cols, size); scratch = new_scratch; slice.push(znx); } (slice, scratch) } fn take_vec_znx_slice( &mut self, module: &Module, len: usize, cols: usize, size: usize, ) -> (Vec>, &mut Self) { let mut scratch: &mut Self = self; let mut slice: Vec> = Vec::with_capacity(len); for _ in 0..len { let (znx, new_scratch) = scratch.take_vec_znx(module, cols, size); scratch = new_scratch; slice.push(znx); } (slice, scratch) } fn take_vmp_pmat( &mut self, module: &Module, rows: usize, cols_in: usize, cols_out: usize, size: usize, ) -> (VmpPMat<&mut [u8], B>, &mut Self) where Module: VmpPMatBytesOf, { let (take_slice, rem_slice) = self.take_slice(module.bytes_of_vmp_pmat(rows, cols_in, cols_out, size)); ( VmpPMat::from_data(take_slice, module.n(), rows, cols_in, cols_out, size), rem_slice, ) } fn take_mat_znx( &mut self, module: &Module, rows: usize, cols_in: usize, cols_out: usize, size: usize, ) -> (MatZnx<&mut [u8]>, &mut Self) { let (take_slice, rem_slice) = self.take_slice(MatZnx::bytes_of(module.n(), rows, cols_in, cols_out, size)); ( MatZnx::from_data(take_slice, module.n(), rows, cols_in, cols_out, size), rem_slice, ) } }