poulpy/backend/src/hal/layouts/vec_znx.rs
backend/src/hal/layouts/vec_znx.rsRaw
1use std::fmt;
2
3use crate::{
4 alloc_aligned,
5 hal::{
6 api::{DataView, DataViewMut, ZnxInfos, ZnxSliceSize, ZnxView, ZnxViewMut, ZnxZero},
7 layouts::{Data, DataMut, DataRef, ReaderFrom, WriterTo},
8 },
9};
10
11#[derive(PartialEq, Eq)]
12pub struct VecZnx<D: Data> {
13 pub(crate) data: D,
14 pub(crate) n: usize,
15 pub(crate) cols: usize,
16 pub(crate) size: usize,
17 pub(crate) max_size: usize,
18}
19
20impl<D: DataRef> fmt::Debug for VecZnx<D> {
21 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 write!(f, "{}", self)
23 }
24}
25
26impl<D: Data> ZnxInfos for VecZnx<D> {
27 fn cols(&self) -> usize {
28 self.cols
29 }
30
31 fn rows(&self) -> usize {
32 1
33 }
34
35 fn n(&self) -> usize {
36 self.n
37 }
38
39 fn size(&self) -> usize {
40 self.size
41 }
42}
43
44impl<D: Data> ZnxSliceSize for VecZnx<D> {
45 fn sl(&self) -> usize {
46 self.n() * self.cols()
47 }
48}
49
50impl<D: Data> DataView for VecZnx<D> {
51 type D = D;
52 fn data(&self) -> &Self::D {
53 &self.data
54 }
55}
56
57impl<D: Data> DataViewMut for VecZnx<D> {
58 fn data_mut(&mut self) -> &mut Self::D {
59 &mut self.data
60 }
61}
62
63impl<D: DataRef> ZnxView for VecZnx<D> {
64 type Scalar = i64;
65}
66
67impl VecZnx<Vec<u8>> {
68 pub fn rsh_scratch_space(n: usize) -> usize {
69 n * std::mem::size_of::<i64>()
70 }
71}
72
73impl<D: DataMut> ZnxZero for VecZnx<D> {
74 fn zero(&mut self) {
75 self.raw_mut().fill(0)
76 }
77 fn zero_at(&mut self, i: usize, j: usize) {
78 self.at_mut(i, j).fill(0);
79 }
80}
81
82impl<D: DataRef> VecZnx<D> {
83 pub fn alloc_bytes<Scalar: Sized>(n: usize, cols: usize, size: usize) -> usize {
84 n * cols * size * size_of::<Scalar>()
85 }
86}
87
88impl<D: DataRef + From<Vec<u8>>> VecZnx<D> {
89 pub fn new<Scalar: Sized>(n: usize, cols: usize, size: usize) -> Self {
90 let data: Vec<u8> = alloc_aligned::<u8>(Self::alloc_bytes::<Scalar>(n, cols, size));
91 Self {
92 data: data.into(),
93 n,
94 cols,
95 size,
96 max_size: size,
97 }
98 }
99
100 pub fn from_bytes<Scalar: Sized>(n: usize, cols: usize, size: usize, bytes: impl Into<Vec<u8>>) -> Self {
101 let data: Vec<u8> = bytes.into();
102 assert!(data.len() == Self::alloc_bytes::<Scalar>(n, cols, size));
103 Self {
104 data: data.into(),
105 n,
106 cols,
107 size,
108 max_size: size,
109 }
110 }
111}
112
113impl<D: Data> VecZnx<D> {
114 pub fn from_data(data: D, n: usize, cols: usize, size: usize) -> Self {
115 Self {
116 data,
117 n,
118 cols,
119 size,
120 max_size: size,
121 }
122 }
123}
124
125impl<D: DataRef> fmt::Display for VecZnx<D> {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 writeln!(
128 f,
129 "VecZnx(n={}, cols={}, size={})",
130 self.n, self.cols, self.size
131 )?;
132
133 for col in 0..self.cols {
134 writeln!(f, "Column {}:", col)?;
135 for size in 0..self.size {
136 let coeffs = self.at(col, size);
137 write!(f, " Size {}: [", size)?;
138
139 let max_show = 100;
140 let show_count = coeffs.len().min(max_show);
141
142 for (i, &coeff) in coeffs.iter().take(show_count).enumerate() {
143 if i > 0 {
144 write!(f, ", ")?;
145 }
146 write!(f, "{}", coeff)?;
147 }
148
149 if coeffs.len() > max_show {
150 write!(f, ", ... ({} more)", coeffs.len() - max_show)?;
151 }
152
153 writeln!(f, "]")?;
154 }
155 }
156 Ok(())
157 }
158}
159
160pub type VecZnxOwned = VecZnx<Vec<u8>>;
161pub type VecZnxMut<'a> = VecZnx<&'a mut [u8]>;
162pub type VecZnxRef<'a> = VecZnx<&'a [u8]>;
163
164pub trait VecZnxToRef {
165 fn to_ref(&self) -> VecZnx<&[u8]>;
166}
167
168impl<D: DataRef> VecZnxToRef for VecZnx<D> {
169 fn to_ref(&self) -> VecZnx<&[u8]> {
170 VecZnx {
171 data: self.data.as_ref(),
172 n: self.n,
173 cols: self.cols,
174 size: self.size,
175 max_size: self.max_size,
176 }
177 }
178}
179
180pub trait VecZnxToMut {
181 fn to_mut(&mut self) -> VecZnx<&mut [u8]>;
182}
183
184impl<D: DataMut> VecZnxToMut for VecZnx<D> {
185 fn to_mut(&mut self) -> VecZnx<&mut [u8]> {
186 VecZnx {
187 data: self.data.as_mut(),
188 n: self.n,
189 cols: self.cols,
190 size: self.size,
191 max_size: self.max_size,
192 }
193 }
194}
195
196impl<D: DataRef> VecZnx<D> {
197 pub fn clone(&self) -> VecZnx<Vec<u8>> {
198 let self_ref: VecZnx<&[u8]> = self.to_ref();
199 VecZnx {
200 data: self_ref.data.to_vec(),
201 n: self_ref.n,
202 cols: self_ref.cols,
203 size: self_ref.size,
204 max_size: self_ref.max_size,
205 }
206 }
207}
208
209use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
210
211impl<D: DataMut> ReaderFrom for VecZnx<D> {
212 fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
213 self.n = reader.read_u64::<LittleEndian>()? as usize;
214 self.cols = reader.read_u64::<LittleEndian>()? as usize;
215 self.size = reader.read_u64::<LittleEndian>()? as usize;
216 self.max_size = reader.read_u64::<LittleEndian>()? as usize;
217 let len: usize = reader.read_u64::<LittleEndian>()? as usize;
218 let buf: &mut [u8] = self.data.as_mut();
219 if buf.len() != len {
220 return Err(std::io::Error::new(
221 std::io::ErrorKind::UnexpectedEof,
222 format!("self.data.len()={} != read len={}", buf.len(), len),
223 ));
224 }
225 reader.read_exact(&mut buf[..len])?;
226 Ok(())
227 }
228}
229
230impl<D: DataRef> WriterTo for VecZnx<D> {
231 fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
232 writer.write_u64::<LittleEndian>(self.n as u64)?;
233 writer.write_u64::<LittleEndian>(self.cols as u64)?;
234 writer.write_u64::<LittleEndian>(self.size as u64)?;
235 writer.write_u64::<LittleEndian>(self.max_size as u64)?;
236 let buf: &[u8] = self.data.as_ref();
237 writer.write_u64::<LittleEndian>(buf.len() as u64)?;
238 writer.write_all(buf)?;
239 Ok(())
240 }
241}