poulpy/base2k/src/vec_znx_big.rs
base2k/src/vec_znx_big.rsRaw
1use crate::ffi::vec_znx_big;
2use crate::ffi::vec_znx_dft;
3use crate::{is_aligned, Infos, Module, VecZnxApi, VecZnxDft};
4
5pub struct VecZnxBig(pub *mut vec_znx_big::vec_znx_bigcoeff_t, pub usize);
6
7impl VecZnxBig {
8 /// Returns a new [VecZnxBig] with the provided data as backing array.
9 /// User must ensure that data is properly alligned and that
10 /// the size of data is at least equal to [Module::bytes_of_vec_znx_big].
11 pub fn from_bytes(cols: usize, data: &mut [u8]) -> VecZnxBig {
12 debug_assert!(is_aligned(data.as_ptr()));
13 VecZnxBig(
14 data.as_mut_ptr() as *mut vec_znx_big::vec_znx_bigcoeff_t,
15 cols,
16 )
17 }
18
19 pub fn as_vec_znx_dft(&mut self) -> VecZnxDft {
20 VecZnxDft(self.0 as *mut vec_znx_dft::vec_znx_dft_t, self.1)
21 }
22 pub fn cols(&self) -> usize {
23 self.1
24 }
25}
26
27pub trait VecZnxBigOps {
28 /// Allocates a vector Z[X]/(X^N+1) that stores not normalized values.
29 fn new_vec_znx_big(&self, cols: usize) -> VecZnxBig;
30
31 /// Returns a new [VecZnxBig] with the provided bytes array as backing array.
32 ///
33 /// # Arguments
34 ///
35 /// * `cols`: the number of cols of the [VecZnxBig].
36 /// * `bytes`: a byte array of size at least [Module::bytes_of_vec_znx_big].
37 ///
38 /// # Panics
39 /// If `bytes.len()` < [Module::bytes_of_vec_znx_big].
40 fn new_vec_znx_big_from_bytes(&self, cols: usize, bytes: &mut [u8]) -> VecZnxBig;
41
42 /// Returns the minimum number of bytes necessary to allocate
43 /// a new [VecZnxBig] through [VecZnxBig::from_bytes].
44 fn bytes_of_vec_znx_big(&self, cols: usize) -> usize;
45
46 /// b <- b - a
47 fn vec_znx_big_sub_small_a_inplace<T: VecZnxApi + Infos>(&self, b: &mut VecZnxBig, a: &T);
48
49 /// c <- b - a
50 fn vec_znx_big_sub_small_a<T: VecZnxApi + Infos>(
51 &self,
52 c: &mut VecZnxBig,
53 a: &T,
54 b: &VecZnxBig,
55 );
56
57 /// c <- b + a
58 fn vec_znx_big_add_small<T: VecZnxApi + Infos>(&self, c: &mut VecZnxBig, a: &T, b: &VecZnxBig);
59
60 /// b <- b + a
61 fn vec_znx_big_add_small_inplace<T: VecZnxApi + Infos>(&self, b: &mut VecZnxBig, a: &T);
62
63 fn vec_znx_big_normalize_tmp_bytes(&self) -> usize;
64
65 /// b <- normalize(a)
66 fn vec_znx_big_normalize<T: VecZnxApi + Infos>(
67 &self,
68 log_base2k: usize,
69 b: &mut T,
70 a: &VecZnxBig,
71 tmp_bytes: &mut [u8],
72 );
73
74 fn vec_znx_big_range_normalize_base2k_tmp_bytes(&self) -> usize;
75
76 fn vec_znx_big_range_normalize_base2k<T: VecZnxApi + Infos>(
77 &self,
78 log_base2k: usize,
79 res: &mut T,
80 a: &VecZnxBig,
81 a_range_begin: usize,
82 a_range_xend: usize,
83 a_range_step: usize,
84 tmp_bytes: &mut [u8],
85 );
86
87 fn vec_znx_big_automorphism(&self, gal_el: i64, b: &mut VecZnxBig, a: &VecZnxBig);
88
89 fn vec_znx_big_automorphism_inplace(&self, gal_el: i64, a: &mut VecZnxBig);
90}
91
92impl VecZnxBigOps for Module {
93 fn new_vec_znx_big(&self, cols: usize) -> VecZnxBig {
94 unsafe { VecZnxBig(vec_znx_big::new_vec_znx_big(self.0, cols as u64), cols) }
95 }
96
97 fn new_vec_znx_big_from_bytes(&self, cols: usize, bytes: &mut [u8]) -> VecZnxBig {
98 debug_assert!(
99 bytes.len() >= <Module as VecZnxBigOps>::bytes_of_vec_znx_big(self, cols),
100 "invalid bytes: bytes.len()={} < bytes_of_vec_znx_dft={}",
101 bytes.len(),
102 <Module as VecZnxBigOps>::bytes_of_vec_znx_big(self, cols)
103 );
104 debug_assert!(is_aligned(bytes.as_ptr()));
105 VecZnxBig::from_bytes(cols, bytes)
106 }
107
108 fn bytes_of_vec_znx_big(&self, cols: usize) -> usize {
109 unsafe { vec_znx_big::bytes_of_vec_znx_big(self.0, cols as u64) as usize }
110 }
111
112 fn vec_znx_big_sub_small_a_inplace<T: VecZnxApi + Infos>(&self, b: &mut VecZnxBig, a: &T) {
113 unsafe {
114 vec_znx_big::vec_znx_big_sub_small_a(
115 self.0,
116 b.0,
117 b.cols() as u64,
118 a.as_ptr(),
119 a.cols() as u64,
120 a.n() as u64,
121 b.0,
122 b.cols() as u64,
123 )
124 }
125 }
126
127 fn vec_znx_big_sub_small_a<T: VecZnxApi + Infos>(
128 &self,
129 c: &mut VecZnxBig,
130 a: &T,
131 b: &VecZnxBig,
132 ) {
133 unsafe {
134 vec_znx_big::vec_znx_big_sub_small_a(
135 self.0,
136 c.0,
137 c.cols() as u64,
138 a.as_ptr(),
139 a.cols() as u64,
140 a.n() as u64,
141 b.0,
142 b.cols() as u64,
143 )
144 }
145 }
146
147 fn vec_znx_big_add_small<T: VecZnxApi + Infos>(&self, c: &mut VecZnxBig, a: &T, b: &VecZnxBig) {
148 unsafe {
149 vec_znx_big::vec_znx_big_add_small(
150 self.0,
151 c.0,
152 c.cols() as u64,
153 b.0,
154 b.cols() as u64,
155 a.as_ptr(),
156 a.cols() as u64,
157 a.n() as u64,
158 )
159 }
160 }
161
162 fn vec_znx_big_add_small_inplace<T: VecZnxApi + Infos>(&self, b: &mut VecZnxBig, a: &T) {
163 unsafe {
164 vec_znx_big::vec_znx_big_add_small(
165 self.0,
166 b.0,
167 b.cols() as u64,
168 b.0,
169 b.cols() as u64,
170 a.as_ptr(),
171 a.cols() as u64,
172 a.n() as u64,
173 )
174 }
175 }
176
177 fn vec_znx_big_normalize_tmp_bytes(&self) -> usize {
178 unsafe { vec_znx_big::vec_znx_big_normalize_base2k_tmp_bytes(self.0) as usize }
179 }
180
181 fn vec_znx_big_normalize<T: VecZnxApi + Infos>(
182 &self,
183 log_base2k: usize,
184 b: &mut T,
185 a: &VecZnxBig,
186 tmp_bytes: &mut [u8],
187 ) {
188 assert!(
189 tmp_bytes.len() >= <Module as VecZnxBigOps>::vec_znx_big_normalize_tmp_bytes(self),
190 "invalid tmp_bytes: tmp_bytes.len()={} <= self.vec_znx_big_normalize_tmp_bytes()={}",
191 tmp_bytes.len(),
192 <Module as VecZnxBigOps>::vec_znx_big_normalize_tmp_bytes(self)
193 );
194 debug_assert!(is_aligned(tmp_bytes.as_ptr()));
195 unsafe {
196 vec_znx_big::vec_znx_big_normalize_base2k(
197 self.0,
198 log_base2k as u64,
199 b.as_mut_ptr(),
200 b.cols() as u64,
201 b.n() as u64,
202 a.0,
203 a.cols() as u64,
204 tmp_bytes.as_mut_ptr(),
205 )
206 }
207 }
208
209 fn vec_znx_big_range_normalize_base2k_tmp_bytes(&self) -> usize {
210 unsafe { vec_znx_big::vec_znx_big_range_normalize_base2k_tmp_bytes(self.0) as usize }
211 }
212
213 fn vec_znx_big_range_normalize_base2k<T: VecZnxApi + Infos>(
214 &self,
215 log_base2k: usize,
216 res: &mut T,
217 a: &VecZnxBig,
218 a_range_begin: usize,
219 a_range_xend: usize,
220 a_range_step: usize,
221 tmp_bytes: &mut [u8],
222 ) {
223 assert!(
224 tmp_bytes.len() >= <Module as VecZnxBigOps>::vec_znx_big_range_normalize_base2k_tmp_bytes(self),
225 "invalid tmp_bytes: tmp_bytes.len()={} <= self.vec_znx_big_range_normalize_base2k_tmp_bytes()={}",
226 tmp_bytes.len(),
227 <Module as VecZnxBigOps>::vec_znx_big_range_normalize_base2k_tmp_bytes(self)
228 );
229 debug_assert!(is_aligned(tmp_bytes.as_ptr()));
230 unsafe {
231 vec_znx_big::vec_znx_big_range_normalize_base2k(
232 self.0,
233 log_base2k as u64,
234 res.as_mut_ptr(),
235 res.cols() as u64,
236 res.n() as u64,
237 a.0,
238 a_range_begin as u64,
239 a_range_xend as u64,
240 a_range_step as u64,
241 tmp_bytes.as_mut_ptr(),
242 );
243 }
244 }
245
246 fn vec_znx_big_automorphism(&self, gal_el: i64, b: &mut VecZnxBig, a: &VecZnxBig) {
247 unsafe {
248 vec_znx_big::vec_znx_big_automorphism(
249 self.0,
250 gal_el,
251 b.0,
252 b.cols() as u64,
253 a.0,
254 a.cols() as u64,
255 );
256 }
257 }
258
259 fn vec_znx_big_automorphism_inplace(&self, gal_el: i64, a: &mut VecZnxBig) {
260 unsafe {
261 vec_znx_big::vec_znx_big_automorphism(
262 self.0,
263 gal_el,
264 a.0,
265 a.cols() as u64,
266 a.0,
267 a.cols() as u64,
268 );
269 }
270 }
271}