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}