arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-cpu-ref/src/convolution.rs
poulpy-cpu-ref/src/convolution.rsRaw
  1use poulpy_hal::{
  2    api::{Convolution, ModuleN, ScratchTakeBasic, TakeSlice, VecZnxDftApply, VecZnxDftBytesOf},
  3    layouts::{
  4        Backend, CnvPVecL, CnvPVecLToMut, CnvPVecLToRef, CnvPVecR, CnvPVecRToMut, CnvPVecRToRef, Module, Scratch, VecZnx,
  5        VecZnxBig, VecZnxBigToMut, VecZnxDft, VecZnxDftToMut, VecZnxToRef, ZnxInfos,
  6    },
  7    oep::{CnvPVecBytesOfImpl, CnvPVecLAllocImpl, ConvolutionImpl},
  8    reference::fft64::convolution::{
  9        convolution_apply_dft, convolution_apply_dft_tmp_bytes, convolution_by_const_apply, convolution_by_const_apply_tmp_bytes,
 10        convolution_pairwise_apply_dft, convolution_pairwise_apply_dft_tmp_bytes, convolution_prepare_left,
 11        convolution_prepare_right,
 12    },
 13};
 14
 15use crate::{FFT64Ref, module::FFT64ModuleHandle};
 16
 17unsafe impl CnvPVecLAllocImpl<Self> for FFT64Ref {
 18    fn cnv_pvec_left_alloc_impl(n: usize, cols: usize, size: usize) -> CnvPVecL<Vec<u8>, Self> {
 19        CnvPVecL::alloc(n, cols, size)
 20    }
 21
 22    fn cnv_pvec_right_alloc_impl(n: usize, cols: usize, size: usize) -> CnvPVecR<Vec<u8>, Self> {
 23        CnvPVecR::alloc(n, cols, size)
 24    }
 25}
 26
 27unsafe impl CnvPVecBytesOfImpl for FFT64Ref {
 28    fn bytes_of_cnv_pvec_left_impl(n: usize, cols: usize, size: usize) -> usize {
 29        Self::layout_prep_word_count() * n * cols * size * size_of::<<FFT64Ref as Backend>::ScalarPrep>()
 30    }
 31
 32    fn bytes_of_cnv_pvec_right_impl(n: usize, cols: usize, size: usize) -> usize {
 33        Self::layout_prep_word_count() * n * cols * size * size_of::<<FFT64Ref as Backend>::ScalarPrep>()
 34    }
 35}
 36
 37unsafe impl ConvolutionImpl<Self> for FFT64Ref
 38where
 39    Module<Self>: ModuleN + VecZnxDftBytesOf + VecZnxDftApply<Self>,
 40{
 41    fn cnv_prepare_left_tmp_bytes_impl(module: &Module<Self>, res_size: usize, a_size: usize) -> usize {
 42        module.bytes_of_vec_znx_dft(1, res_size.min(a_size))
 43    }
 44
 45    fn cnv_prepare_left_impl<R, A>(module: &Module<Self>, res: &mut R, a: &A, scratch: &mut Scratch<Self>)
 46    where
 47        R: CnvPVecLToMut<Self>,
 48        A: VecZnxToRef,
 49    {
 50        let res: &mut CnvPVecL<&mut [u8], FFT64Ref> = &mut res.to_mut();
 51        let a: &VecZnx<&[u8]> = &a.to_ref();
 52        let (mut tmp, _) = scratch.take_vec_znx_dft(module, 1, res.size().min(a.size()));
 53        convolution_prepare_left(module.get_fft_table(), res, a, &mut tmp);
 54    }
 55
 56    fn cnv_prepare_right_tmp_bytes_impl(module: &Module<Self>, res_size: usize, a_size: usize) -> usize {
 57        module.bytes_of_vec_znx_dft(1, res_size.min(a_size))
 58    }
 59
 60    fn cnv_prepare_right_impl<R, A>(module: &Module<Self>, res: &mut R, a: &A, scratch: &mut Scratch<Self>)
 61    where
 62        R: CnvPVecRToMut<Self>,
 63        A: VecZnxToRef,
 64    {
 65        let res: &mut CnvPVecR<&mut [u8], FFT64Ref> = &mut res.to_mut();
 66        let a: &VecZnx<&[u8]> = &a.to_ref();
 67        let (mut tmp, _) = scratch.take_vec_znx_dft(module, 1, res.size().min(a.size()));
 68        convolution_prepare_right(module.get_fft_table(), res, a, &mut tmp);
 69    }
 70
 71    fn cnv_apply_dft_tmp_bytes_impl(
 72        _module: &Module<Self>,
 73        res_size: usize,
 74        _res_offset: usize,
 75        a_size: usize,
 76        b_size: usize,
 77    ) -> usize {
 78        convolution_apply_dft_tmp_bytes(res_size, a_size, b_size)
 79    }
 80
 81    fn cnv_by_const_apply_tmp_bytes_impl(
 82        _module: &Module<Self>,
 83        res_size: usize,
 84        _res_offset: usize,
 85        a_size: usize,
 86        b_size: usize,
 87    ) -> usize {
 88        convolution_by_const_apply_tmp_bytes(res_size, a_size, b_size)
 89    }
 90
 91    fn cnv_by_const_apply_impl<R, A>(
 92        module: &Module<Self>,
 93        res: &mut R,
 94        res_offset: usize,
 95        res_col: usize,
 96        a: &A,
 97        a_col: usize,
 98        b: &[i64],
 99        scratch: &mut Scratch<Self>,
100    ) where
101        R: VecZnxBigToMut<Self>,
102        A: VecZnxToRef,
103    {
104        let res: &mut VecZnxBig<&mut [u8], Self> = &mut res.to_mut();
105        let a: &VecZnx<&[u8]> = &a.to_ref();
106        let (tmp, _) =
107            scratch.take_slice(module.cnv_by_const_apply_tmp_bytes(res.size(), res_offset, a.size(), b.len()) / size_of::<i64>());
108        convolution_by_const_apply(res, res_offset, res_col, a, a_col, b, tmp);
109    }
110
111    fn cnv_apply_dft_impl<R, A, B>(
112        module: &Module<Self>,
113        res: &mut R,
114        res_offset: usize,
115        res_col: usize,
116        a: &A,
117        a_col: usize,
118        b: &B,
119        b_col: usize,
120        scratch: &mut Scratch<Self>,
121    ) where
122        R: VecZnxDftToMut<Self>,
123        A: CnvPVecLToRef<Self>,
124        B: CnvPVecRToRef<Self>,
125    {
126        let res: &mut VecZnxDft<&mut [u8], FFT64Ref> = &mut res.to_mut();
127        let a: &CnvPVecL<&[u8], FFT64Ref> = &a.to_ref();
128        let b: &CnvPVecR<&[u8], FFT64Ref> = &b.to_ref();
129        let (tmp, _) =
130            scratch.take_slice(module.cnv_apply_dft_tmp_bytes(res.size(), res_offset, a.size(), b.size()) / size_of::<f64>());
131        convolution_apply_dft(res, res_offset, res_col, a, a_col, b, b_col, tmp);
132    }
133
134    fn cnv_pairwise_apply_dft_tmp_bytes(
135        _module: &Module<Self>,
136        res_size: usize,
137        _res_offset: usize,
138        a_size: usize,
139        b_size: usize,
140    ) -> usize {
141        convolution_pairwise_apply_dft_tmp_bytes(res_size, a_size, b_size)
142    }
143
144    fn cnv_pairwise_apply_dft_impl<R, A, B>(
145        module: &Module<Self>,
146        res: &mut R,
147        res_offset: usize,
148        res_col: usize,
149        a: &A,
150        b: &B,
151        col_0: usize,
152        col_1: usize,
153        scratch: &mut Scratch<Self>,
154    ) where
155        R: VecZnxDftToMut<Self>,
156        A: CnvPVecLToRef<Self>,
157        B: CnvPVecRToRef<Self>,
158    {
159        let res: &mut VecZnxDft<&mut [u8], FFT64Ref> = &mut res.to_mut();
160        let a: &CnvPVecL<&[u8], FFT64Ref> = &a.to_ref();
161        let b: &CnvPVecR<&[u8], FFT64Ref> = &b.to_ref();
162        let (tmp, _) = scratch
163            .take_slice(module.cnv_pairwise_apply_dft_tmp_bytes(res.size(), res_offset, a.size(), b.size()) / size_of::<f64>());
164        convolution_pairwise_apply_dft(res, res_offset, res_col, a, b, col_0, col_1, tmp);
165    }
166}