arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-hal/src/api/convolution.rs
poulpy-hal/src/api/convolution.rsRaw
  1use crate::layouts::{
  2    Backend, CnvPVecL, CnvPVecLToMut, CnvPVecLToRef, CnvPVecR, CnvPVecRToMut, CnvPVecRToRef, Scratch, VecZnxBigToMut,
  3    VecZnxDftToMut, VecZnxToRef, ZnxInfos, ZnxViewMut,
  4};
  5
  6pub trait CnvPVecAlloc<BE: Backend> {
  7    fn cnv_pvec_left_alloc(&self, cols: usize, size: usize) -> CnvPVecL<Vec<u8>, BE>;
  8    fn cnv_pvec_right_alloc(&self, cols: usize, size: usize) -> CnvPVecR<Vec<u8>, BE>;
  9}
 10
 11pub trait CnvPVecBytesOf {
 12    fn bytes_of_cnv_pvec_left(&self, cols: usize, size: usize) -> usize;
 13    fn bytes_of_cnv_pvec_right(&self, cols: usize, size: usize) -> usize;
 14}
 15
 16pub trait Convolution<BE: Backend> {
 17    fn cnv_prepare_left_tmp_bytes(&self, res_size: usize, a_size: usize) -> usize;
 18    fn cnv_prepare_left<R, A>(&self, res: &mut R, a: &A, scratch: &mut Scratch<BE>)
 19    where
 20        R: CnvPVecLToMut<BE> + ZnxInfos + ZnxViewMut<Scalar = BE::ScalarPrep>,
 21        A: VecZnxToRef + ZnxInfos;
 22
 23    fn cnv_prepare_right_tmp_bytes(&self, res_size: usize, a_size: usize) -> usize;
 24    fn cnv_prepare_right<R, A>(&self, res: &mut R, a: &A, scratch: &mut Scratch<BE>)
 25    where
 26        R: CnvPVecRToMut<BE> + ZnxInfos + ZnxViewMut<Scalar = BE::ScalarPrep>,
 27        A: VecZnxToRef + ZnxInfos;
 28
 29    fn cnv_apply_dft_tmp_bytes(&self, res_size: usize, res_offset: usize, a_size: usize, b_size: usize) -> usize;
 30
 31    fn cnv_by_const_apply_tmp_bytes(&self, res_size: usize, res_offset: usize, a_size: usize, b_size: usize) -> usize;
 32
 33    /// Evaluates a bivariate convolution over Z[X, Y] (x) Z[Y] mod (X^N + 1) where Y = 2^-K over the
 34    /// selected columns and stores the result on the selected column, scaled by 2^{res_offset * Base2K}
 35    ///
 36    /// Behavior is identical to [Convolution::cnv_apply_dft] with `b` treated as a constant polynomial
 37    /// in the X variable, for example:
 38    ///```text
 39    ///       1    X   X^2  X^3
 40    /// a = 1 [a00, a10, a20, a30] = (a00 + a01 * 2^-K) + (a10 + a11 * 2^-K) * X ...
 41    ///     Y [a01, a11, a21, a31]
 42    ///
 43    /// b = 1 [b0] = (b00 + b01 * 2^-K)
 44    ///     Y [b0]
 45    /// ```
 46    /// This method is intended to be used for multiplications by constants that are greater than the base2k.
 47    #[allow(clippy::too_many_arguments)]
 48    fn cnv_by_const_apply<R, A>(
 49        &self,
 50        res: &mut R,
 51        res_offset: usize,
 52        res_col: usize,
 53        a: &A,
 54        a_col: usize,
 55        b: &[i64],
 56        scratch: &mut Scratch<BE>,
 57    ) where
 58        R: VecZnxBigToMut<BE>,
 59        A: VecZnxToRef;
 60
 61    #[allow(clippy::too_many_arguments)]
 62    /// Evaluates a bivariate convolution over Z[X, Y] (x) Z[X, Y] mod (X^N + 1) where Y = 2^-K over the
 63    /// selected columns and stores the result on the selected column, scaled by 2^{res_offset * Base2K}
 64    ///
 65    /// # Example
 66    ///```text
 67    ///       1    X   X^2  X^3
 68    /// a = 1 [a00, a10, a20, a30] = (a00 + a01 * 2^-K) + (a10 + a11 * 2^-K) * X ...
 69    ///     Y [a01, a11, a21, a31]
 70    ///
 71    /// b = 1 [b00, b10, b20, b30] = (b00 + b01 * 2^-K) + (b10 + b11 * 2^-K) * X ...
 72    ///     Y [b01, b11, b21, b31]
 73    ///
 74    /// If res_offset = 0:
 75    ///
 76    ///            1    X   X^2  X^3
 77    /// res = 1  [r00, r10, r20, r30] = (r00 + r01 * 2^-K + r02 * 2^-2K + r03 * 2^-3K) + ... * X + ...
 78    ///       Y  [r01, r11, r21, r31]
 79    ///       Y^2[r02, r12, r22, r32]
 80    ///       Y^3[r03, r13, r23, r33]
 81    ///
 82    /// If res_offset = 1:
 83    ///
 84    ///            1    X   X^2  X^3
 85    /// res = 1  [r01, r11, r21, r31]  = (r01 + r02 * 2^-K + r03 * 2^-2K) + ... * X + ...
 86    ///       Y  [r02, r12, r22, r32]
 87    ///       Y^2[r03, r13, r23, r33]
 88    ///       Y^3[  0,   0,   0 ,  0]
 89    /// ```
 90    /// If res.size() < a.size() + b.size() + k, result is truncated accordingly in the Y dimension.
 91    fn cnv_apply_dft<R, A, B>(
 92        &self,
 93        res: &mut R,
 94        res_offset: usize,
 95        res_col: usize,
 96        a: &A,
 97        a_col: usize,
 98        b: &B,
 99        b_col: usize,
100        scratch: &mut Scratch<BE>,
101    ) where
102        R: VecZnxDftToMut<BE>,
103        A: CnvPVecLToRef<BE>,
104        B: CnvPVecRToRef<BE>;
105
106    fn cnv_pairwise_apply_dft_tmp_bytes(&self, res_size: usize, res_offset: usize, a_size: usize, b_size: usize) -> usize;
107
108    #[allow(clippy::too_many_arguments)]
109    /// Evaluates the bivariate pair-wise convolution res = (a[i] + a[j]) * (b[i] + b[j]).
110    /// If i == j then calls [Convolution::cnv_apply_dft], i.e. res = a[i] * b[i].
111    /// See [Convolution::cnv_apply_dft] for information about the bivariate convolution.
112    fn cnv_pairwise_apply_dft<R, A, B>(
113        &self,
114        res: &mut R,
115        res_offset: usize,
116        res_col: usize,
117        a: &A,
118        b: &B,
119        i: usize,
120        j: usize,
121        scratch: &mut Scratch<BE>,
122    ) where
123        R: VecZnxDftToMut<BE>,
124        A: CnvPVecLToRef<BE>,
125        B: CnvPVecRToRef<BE>;
126}