arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-backend/src/hal/layouts/svp_ppol.rs
poulpy-backend/src/hal/layouts/svp_ppol.rsRaw
  1use std::marker::PhantomData;
  2
  3use crate::{
  4    alloc_aligned,
  5    hal::{
  6        api::{DataView, DataViewMut, ZnxInfos},
  7        layouts::{Backend, Data, DataMut, DataRef, ReaderFrom, WriterTo},
  8    },
  9};
 10
 11#[derive(PartialEq, Eq)]
 12pub struct SvpPPol<D: Data, B: Backend> {
 13    data: D,
 14    n: usize,
 15    cols: usize,
 16    _phantom: PhantomData<B>,
 17}
 18
 19impl<D: Data, B: Backend> ZnxInfos for SvpPPol<D, B> {
 20    fn cols(&self) -> usize {
 21        self.cols
 22    }
 23
 24    fn rows(&self) -> usize {
 25        1
 26    }
 27
 28    fn n(&self) -> usize {
 29        self.n
 30    }
 31
 32    fn size(&self) -> usize {
 33        1
 34    }
 35}
 36
 37impl<D: Data, B: Backend> DataView for SvpPPol<D, B> {
 38    type D = D;
 39    fn data(&self) -> &Self::D {
 40        &self.data
 41    }
 42}
 43
 44impl<D: Data, B: Backend> DataViewMut for SvpPPol<D, B> {
 45    fn data_mut(&mut self) -> &mut Self::D {
 46        &mut self.data
 47    }
 48}
 49
 50pub trait SvpPPolBytesOf {
 51    fn bytes_of(n: usize, cols: usize) -> usize;
 52}
 53
 54impl<D: Data + From<Vec<u8>>, B: Backend> SvpPPol<D, B>
 55where
 56    SvpPPol<D, B>: SvpPPolBytesOf,
 57{
 58    pub(crate) fn alloc(n: usize, cols: usize) -> Self {
 59        let data: Vec<u8> = alloc_aligned::<u8>(Self::bytes_of(n, cols));
 60        Self {
 61            data: data.into(),
 62            n,
 63            cols,
 64            _phantom: PhantomData,
 65        }
 66    }
 67
 68    pub(crate) fn from_bytes(n: usize, cols: usize, bytes: impl Into<Vec<u8>>) -> Self {
 69        let data: Vec<u8> = bytes.into();
 70        assert!(data.len() == Self::bytes_of(n, cols));
 71        Self {
 72            data: data.into(),
 73            n,
 74            cols,
 75            _phantom: PhantomData,
 76        }
 77    }
 78}
 79
 80pub type SvpPPolOwned<B> = SvpPPol<Vec<u8>, B>;
 81
 82pub trait SvpPPolToRef<B: Backend> {
 83    fn to_ref(&self) -> SvpPPol<&[u8], B>;
 84}
 85
 86impl<D: DataRef, B: Backend> SvpPPolToRef<B> for SvpPPol<D, B> {
 87    fn to_ref(&self) -> SvpPPol<&[u8], B> {
 88        SvpPPol {
 89            data: self.data.as_ref(),
 90            n: self.n,
 91            cols: self.cols,
 92            _phantom: PhantomData,
 93        }
 94    }
 95}
 96
 97pub trait SvpPPolToMut<B: Backend> {
 98    fn to_mut(&mut self) -> SvpPPol<&mut [u8], B>;
 99}
100
101impl<D: DataMut, B: Backend> SvpPPolToMut<B> for SvpPPol<D, B> {
102    fn to_mut(&mut self) -> SvpPPol<&mut [u8], B> {
103        SvpPPol {
104            data: self.data.as_mut(),
105            n: self.n,
106            cols: self.cols,
107            _phantom: PhantomData,
108        }
109    }
110}
111
112impl<D: Data, B: Backend> SvpPPol<D, B> {
113    pub(crate) fn from_data(data: D, n: usize, cols: usize) -> Self {
114        Self {
115            data,
116            n,
117            cols,
118            _phantom: PhantomData,
119        }
120    }
121}
122
123use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
124
125impl<D: DataMut, B: Backend> ReaderFrom for SvpPPol<D, B> {
126    fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
127        self.n = reader.read_u64::<LittleEndian>()? as usize;
128        self.cols = reader.read_u64::<LittleEndian>()? as usize;
129        let len: usize = reader.read_u64::<LittleEndian>()? as usize;
130        let buf: &mut [u8] = self.data.as_mut();
131        if buf.len() != len {
132            return Err(std::io::Error::new(
133                std::io::ErrorKind::UnexpectedEof,
134                format!("self.data.len()={} != read len={}", buf.len(), len),
135            ));
136        }
137        reader.read_exact(&mut buf[..len])?;
138        Ok(())
139    }
140}
141
142impl<D: DataRef, B: Backend> WriterTo for SvpPPol<D, B> {
143    fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
144        writer.write_u64::<LittleEndian>(self.n as u64)?;
145        writer.write_u64::<LittleEndian>(self.cols as u64)?;
146        let buf: &[u8] = self.data.as_ref();
147        writer.write_u64::<LittleEndian>(buf.len() as u64)?;
148        writer.write_all(buf)?;
149        Ok(())
150    }
151}