poulpy/poulpy-backend/src/cpu_spqlios/fft64/vmp_pmat.rs
poulpy-backend/src/cpu_spqlios/fft64/vmp_pmat.rsRaw
1use poulpy_hal::{
2 api::{TakeSlice, VmpApplyTmpBytes, VmpPrepareTmpBytes, ZnxInfos, ZnxView, ZnxViewMut},
3 layouts::{
4 Backend, MatZnx, MatZnxToRef, Module, Scratch, VecZnxDft, VecZnxDftToMut, VecZnxDftToRef, VmpPMat, VmpPMatOwned,
5 VmpPMatToMut, VmpPMatToRef,
6 },
7 oep::{
8 VmpApplyAddImpl, VmpApplyAddTmpBytesImpl, VmpApplyImpl, VmpApplyTmpBytesImpl, VmpPMatAllocBytesImpl, VmpPMatAllocImpl,
9 VmpPMatFromBytesImpl, VmpPMatPrepareImpl, VmpPrepareTmpBytesImpl,
10 },
11};
12
13use crate::cpu_spqlios::{
14 FFT64,
15 ffi::{vec_znx_dft::vec_znx_dft_t, vmp},
16};
17
18unsafe impl VmpPMatAllocBytesImpl<FFT64> for FFT64 {
19 fn vmp_pmat_alloc_bytes_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> usize {
20 FFT64::layout_prep_word_count() * n * rows * cols_in * cols_out * size * size_of::<f64>()
21 }
22}
23
24unsafe impl VmpPMatFromBytesImpl<FFT64> for FFT64 {
25 fn vmp_pmat_from_bytes_impl(
26 n: usize,
27 rows: usize,
28 cols_in: usize,
29 cols_out: usize,
30 size: usize,
31 bytes: Vec<u8>,
32 ) -> VmpPMatOwned<FFT64> {
33 VmpPMatOwned::from_bytes(n, rows, cols_in, cols_out, size, bytes)
34 }
35}
36
37unsafe impl VmpPMatAllocImpl<FFT64> for FFT64 {
38 fn vmp_pmat_alloc_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> VmpPMatOwned<FFT64> {
39 VmpPMatOwned::alloc(n, rows, cols_in, cols_out, size)
40 }
41}
42
43unsafe impl VmpPrepareTmpBytesImpl<FFT64> for FFT64 {
44 fn vmp_prepare_tmp_bytes_impl(module: &Module<FFT64>, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> usize {
45 unsafe {
46 vmp::vmp_prepare_tmp_bytes(
47 module.ptr(),
48 (rows * cols_in) as u64,
49 (cols_out * size) as u64,
50 ) as usize
51 }
52 }
53}
54
55unsafe impl VmpPMatPrepareImpl<FFT64> for FFT64 {
56 fn vmp_prepare_impl<R, A>(module: &Module<FFT64>, res: &mut R, a: &A, scratch: &mut Scratch<FFT64>)
57 where
58 R: VmpPMatToMut<FFT64>,
59 A: MatZnxToRef,
60 {
61 let mut res: VmpPMat<&mut [u8], FFT64> = res.to_mut();
62 let a: MatZnx<&[u8]> = a.to_ref();
63
64 #[cfg(debug_assertions)]
65 {
66 assert_eq!(a.n(), res.n());
67 assert_eq!(
68 res.cols_in(),
69 a.cols_in(),
70 "res.cols_in: {} != a.cols_in: {}",
71 res.cols_in(),
72 a.cols_in()
73 );
74 assert_eq!(
75 res.rows(),
76 a.rows(),
77 "res.rows: {} != a.rows: {}",
78 res.rows(),
79 a.rows()
80 );
81 assert_eq!(
82 res.cols_out(),
83 a.cols_out(),
84 "res.cols_out: {} != a.cols_out: {}",
85 res.cols_out(),
86 a.cols_out()
87 );
88 assert_eq!(
89 res.size(),
90 a.size(),
91 "res.size: {} != a.size: {}",
92 res.size(),
93 a.size()
94 );
95 }
96
97 let (tmp_bytes, _) = scratch.take_slice(module.vmp_prepare_tmp_bytes(a.rows(), a.cols_in(), a.cols_out(), a.size()));
98
99 unsafe {
100 vmp::vmp_prepare_contiguous(
101 module.ptr(),
102 res.as_mut_ptr() as *mut vmp::vmp_pmat_t,
103 a.as_ptr(),
104 (a.rows() * a.cols_in()) as u64,
105 (a.size() * a.cols_out()) as u64,
106 tmp_bytes.as_mut_ptr(),
107 );
108 }
109 }
110}
111
112unsafe impl VmpApplyTmpBytesImpl<FFT64> for FFT64 {
113 fn vmp_apply_tmp_bytes_impl(
114 module: &Module<FFT64>,
115 res_size: usize,
116 a_size: usize,
117 b_rows: usize,
118 b_cols_in: usize,
119 b_cols_out: usize,
120 b_size: usize,
121 ) -> usize {
122 unsafe {
123 vmp::vmp_apply_dft_to_dft_tmp_bytes(
124 module.ptr(),
125 (res_size * b_cols_out) as u64,
126 (a_size * b_cols_in) as u64,
127 (b_rows * b_cols_in) as u64,
128 (b_size * b_cols_out) as u64,
129 ) as usize
130 }
131 }
132}
133
134unsafe impl VmpApplyImpl<FFT64> for FFT64 {
135 fn vmp_apply_impl<R, A, C>(module: &Module<FFT64>, res: &mut R, a: &A, b: &C, scratch: &mut Scratch<FFT64>)
136 where
137 R: VecZnxDftToMut<FFT64>,
138 A: VecZnxDftToRef<FFT64>,
139 C: VmpPMatToRef<FFT64>,
140 {
141 let mut res: VecZnxDft<&mut [u8], _> = res.to_mut();
142 let a: VecZnxDft<&[u8], _> = a.to_ref();
143 let b: VmpPMat<&[u8], _> = b.to_ref();
144
145 #[cfg(debug_assertions)]
146 {
147 assert_eq!(b.n(), res.n());
148 assert_eq!(a.n(), res.n());
149 assert_eq!(
150 res.cols(),
151 b.cols_out(),
152 "res.cols(): {} != b.cols_out: {}",
153 res.cols(),
154 b.cols_out()
155 );
156 assert_eq!(
157 a.cols(),
158 b.cols_in(),
159 "a.cols(): {} != b.cols_in: {}",
160 a.cols(),
161 b.cols_in()
162 );
163 }
164
165 let (tmp_bytes, _) = scratch.take_slice(module.vmp_apply_tmp_bytes(
166 res.size(),
167 a.size(),
168 b.rows(),
169 b.cols_in(),
170 b.cols_out(),
171 b.size(),
172 ));
173 unsafe {
174 vmp::vmp_apply_dft_to_dft(
175 module.ptr(),
176 res.as_mut_ptr() as *mut vec_znx_dft_t,
177 (res.size() * res.cols()) as u64,
178 a.as_ptr() as *const vec_znx_dft_t,
179 (a.size() * a.cols()) as u64,
180 b.as_ptr() as *const vmp::vmp_pmat_t,
181 (b.rows() * b.cols_in()) as u64,
182 (b.size() * b.cols_out()) as u64,
183 tmp_bytes.as_mut_ptr(),
184 )
185 }
186 }
187}
188
189unsafe impl VmpApplyAddTmpBytesImpl<FFT64> for FFT64 {
190 fn vmp_apply_add_tmp_bytes_impl(
191 module: &Module<FFT64>,
192 res_size: usize,
193 a_size: usize,
194 b_rows: usize,
195 b_cols_in: usize,
196 b_cols_out: usize,
197 b_size: usize,
198 ) -> usize {
199 unsafe {
200 vmp::vmp_apply_dft_to_dft_tmp_bytes(
201 module.ptr(),
202 (res_size * b_cols_out) as u64,
203 (a_size * b_cols_in) as u64,
204 (b_rows * b_cols_in) as u64,
205 (b_size * b_cols_out) as u64,
206 ) as usize
207 }
208 }
209}
210
211unsafe impl VmpApplyAddImpl<FFT64> for FFT64 {
212 fn vmp_apply_add_impl<R, A, C>(module: &Module<FFT64>, res: &mut R, a: &A, b: &C, scale: usize, scratch: &mut Scratch<FFT64>)
213 where
214 R: VecZnxDftToMut<FFT64>,
215 A: VecZnxDftToRef<FFT64>,
216 C: VmpPMatToRef<FFT64>,
217 {
218 let mut res: VecZnxDft<&mut [u8], _> = res.to_mut();
219 let a: VecZnxDft<&[u8], _> = a.to_ref();
220 let b: VmpPMat<&[u8], _> = b.to_ref();
221
222 #[cfg(debug_assertions)]
223 {
224 assert_eq!(b.n(), res.n());
225 assert_eq!(a.n(), res.n());
226 assert_eq!(
227 res.cols(),
228 b.cols_out(),
229 "res.cols(): {} != b.cols_out: {}",
230 res.cols(),
231 b.cols_out()
232 );
233 assert_eq!(
234 a.cols(),
235 b.cols_in(),
236 "a.cols(): {} != b.cols_in: {}",
237 a.cols(),
238 b.cols_in()
239 );
240 }
241
242 let (tmp_bytes, _) = scratch.take_slice(module.vmp_apply_tmp_bytes(
243 res.size(),
244 a.size(),
245 b.rows(),
246 b.cols_in(),
247 b.cols_out(),
248 b.size(),
249 ));
250 unsafe {
251 vmp::vmp_apply_dft_to_dft_add(
252 module.ptr(),
253 res.as_mut_ptr() as *mut vec_znx_dft_t,
254 (res.size() * res.cols()) as u64,
255 a.as_ptr() as *const vec_znx_dft_t,
256 (a.size() * a.cols()) as u64,
257 b.as_ptr() as *const vmp::vmp_pmat_t,
258 (b.rows() * b.cols_in()) as u64,
259 (b.size() * b.cols_out()) as u64,
260 (scale * b.cols_out()) as u64,
261 tmp_bytes.as_mut_ptr(),
262 )
263 }
264 }
265}