arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/base2k/src/vector_matrix_product.rs
base2k/src/vector_matrix_product.rsRaw
  1use crate::ffi::vmp::{
  2    delete_vmp_pmat, new_vmp_pmat, vmp_apply_dft, vmp_apply_dft_tmp_bytes, vmp_apply_dft_to_dft,
  3    vmp_apply_dft_to_dft_tmp_bytes, vmp_pmat_t, vmp_prepare_contiguous,
  4    vmp_prepare_contiguous_tmp_bytes,
  5};
  6use crate::{Module, VecZnx, VecZnxDft};
  7
  8pub struct VmpPMat {
  9    pub data: *mut vmp_pmat_t,
 10    pub rows: usize,
 11    pub cols: usize,
 12    pub n: usize,
 13}
 14
 15impl VmpPMat {
 16    pub fn data(&self) -> *mut vmp_pmat_t {
 17        self.data
 18    }
 19
 20    pub fn rows(&self) -> usize {
 21        self.rows
 22    }
 23
 24    pub fn cols(&self) -> usize {
 25        self.cols
 26    }
 27
 28    pub fn n(&self) -> usize {
 29        self.n
 30    }
 31
 32    pub fn as_f64(&self) -> &[f64] {
 33        let ptr: *const f64 = self.data as *const f64;
 34        let len: usize = (self.rows() * self.cols() * self.n() * 8) / std::mem::size_of::<f64>();
 35        unsafe { &std::slice::from_raw_parts(ptr, len) }
 36    }
 37
 38    pub fn get_addr(&self, row: usize, col: usize, blk: usize) -> &[f64] {
 39        let nrows: usize = self.rows();
 40        let ncols: usize = self.cols();
 41        if col == (ncols - 1) && (ncols & 1 == 1) {
 42            &self.as_f64()[blk * nrows * ncols * 8 + col * nrows * 8 + row * 8..]
 43        } else {
 44            &self.as_f64()[blk * nrows * ncols * 8
 45                + (col / 2) * (2 * nrows) * 8
 46                + row * 2 * 8
 47                + (col % 2) * 8..]
 48        }
 49    }
 50
 51    pub fn at(&self, row: usize, col: usize) -> Vec<f64> {
 52        //assert!(row <= self.rows && col <= self.cols);
 53
 54        let mut res: Vec<f64> = vec![f64::default(); self.n];
 55
 56        if self.n < 8 {
 57            res.copy_from_slice(
 58                &self.as_f64()[(row + col * self.rows()) * self.n()
 59                    ..(row + col * self.rows()) * (self.n() + 1)],
 60            );
 61        } else {
 62            (0..self.n >> 3).for_each(|blk| {
 63                res[blk * 8..(blk + 1) * 8].copy_from_slice(&self.get_addr(row, col, blk)[..8]);
 64            });
 65        }
 66
 67        res
 68    }
 69
 70    pub fn at_mut(&self, row: usize, col: usize) -> &mut [f64] {
 71        assert!(row <= self.rows && col <= self.cols);
 72        let idx: usize = col * (self.n / 2 * self.rows) + row * (self.n >> 1);
 73        let ptr: *mut f64 = self.data as *mut f64;
 74        let len: usize = (self.rows() * self.cols() * self.n() * 8) / std::mem::size_of::<f64>();
 75        unsafe { &mut std::slice::from_raw_parts_mut(ptr, len)[idx..idx + self.n] }
 76    }
 77
 78    pub fn delete(self) {
 79        unsafe { delete_vmp_pmat(self.data) };
 80        drop(self);
 81    }
 82}
 83
 84impl Module {
 85    pub fn new_vmp_pmat(&self, rows: usize, cols: usize) -> VmpPMat {
 86        unsafe {
 87            VmpPMat {
 88                data: new_vmp_pmat(self.0, rows as u64, cols as u64),
 89                rows,
 90                cols,
 91                n: self.n(),
 92            }
 93        }
 94    }
 95
 96    pub fn vmp_prepare_contiguous_tmp_bytes(&self, rows: usize, cols: usize) -> usize {
 97        unsafe { vmp_prepare_contiguous_tmp_bytes(self.0, rows as u64, cols as u64) as usize }
 98    }
 99
100    pub fn vmp_prepare_contiguous(&self, b: &mut VmpPMat, a: &[i64], buf: &mut [u8]) {
101        unsafe {
102            vmp_prepare_contiguous(
103                self.0,
104                b.data(),
105                a.as_ptr(),
106                b.rows() as u64,
107                b.cols() as u64,
108                buf.as_mut_ptr(),
109            );
110        }
111    }
112
113    pub fn vmp_apply_dft_tmp_bytes(
114        &self,
115        c_limbs: usize,
116        a_limbs: usize,
117        rows: usize,
118        cols: usize,
119    ) -> usize {
120        unsafe {
121            vmp_apply_dft_tmp_bytes(
122                self.0,
123                c_limbs as u64,
124                a_limbs as u64,
125                rows as u64,
126                cols as u64,
127            ) as usize
128        }
129    }
130
131    pub fn vmp_apply_dft(&self, c: &mut VecZnxDft, a: &VecZnx, b: &VmpPMat, buf: &mut [u8]) {
132        unsafe {
133            vmp_apply_dft(
134                self.0,
135                c.0,
136                c.limbs() as u64,
137                a.as_ptr(),
138                a.limbs() as u64,
139                a.n() as u64,
140                b.data(),
141                b.rows() as u64,
142                b.cols() as u64,
143                buf.as_mut_ptr(),
144            )
145        }
146    }
147
148    pub fn vmp_apply_dft_to_dft_tmp_bytes(
149        &self,
150        c_limbs: usize,
151        a_limbs: usize,
152        rows: usize,
153        cols: usize,
154    ) -> usize {
155        unsafe {
156            vmp_apply_dft_to_dft_tmp_bytes(
157                self.0,
158                c_limbs as u64,
159                a_limbs as u64,
160                rows as u64,
161                cols as u64,
162            ) as usize
163        }
164    }
165
166    pub fn vmp_apply_dft_to_dft(
167        &self,
168        c: &mut VecZnxDft,
169        a: &VecZnxDft,
170        b: &VmpPMat,
171        buf: &mut [u8],
172    ) {
173        unsafe {
174            vmp_apply_dft_to_dft(
175                self.0,
176                c.0,
177                c.limbs() as u64,
178                a.0,
179                a.limbs() as u64,
180                b.data(),
181                b.rows() as u64,
182                b.cols() as u64,
183                buf.as_mut_ptr(),
184            )
185        }
186    }
187
188    pub fn vmp_apply_dft_to_dft_inplace(&self, b: &mut VecZnxDft, a: &VmpPMat, buf: &mut [u8]) {
189        unsafe {
190            vmp_apply_dft_to_dft(
191                self.0,
192                b.0,
193                b.limbs() as u64,
194                b.0,
195                b.limbs() as u64,
196                a.data(),
197                a.rows() as u64,
198                a.cols() as u64,
199                buf.as_mut_ptr(),
200            )
201        }
202    }
203}
204
205pub struct Matrix3D<T> {
206    pub data: Vec<T>,
207    pub rows: usize,
208    pub cols: usize,
209    pub n: usize,
210}
211
212impl<T: Default + Clone> Matrix3D<T> {
213    pub fn new(rows: usize, cols: usize, n: usize) -> Self {
214        let size = rows * cols * n;
215        Self {
216            data: vec![T::default(); size],
217            rows,
218            cols,
219            n,
220        }
221    }
222
223    pub fn at(&self, row: usize, col: usize) -> &[T] {
224        assert!(row <= self.rows && col <= self.cols);
225        let idx: usize = col * (self.n * self.rows) + row * self.n;
226        &self.data[idx..idx + self.n]
227    }
228
229    pub fn at_mut(&mut self, row: usize, col: usize) -> &mut [T] {
230        assert!(row <= self.rows && col <= self.cols);
231        let idx: usize = col * (self.n * self.rows) + row * self.n;
232        &mut self.data[idx..idx + self.n]
233    }
234}