arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/core/src/layouts/prepared/gglwe_tsk.rs
core/src/layouts/prepared/gglwe_tsk.rsRaw
  1use backend::hal::{
  2    api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
  3    layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat},
  4};
  5
  6use crate::layouts::{
  7    GGLWETensorKey, Infos,
  8    prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc},
  9};
 10
 11#[derive(PartialEq, Eq)]
 12pub struct GGLWETensorKeyPrepared<D: Data, B: Backend> {
 13    pub(crate) keys: Vec<GGLWESwitchingKeyPrepared<D, B>>,
 14}
 15
 16impl<B: Backend> GGLWETensorKeyPrepared<Vec<u8>, B> {
 17    pub fn alloc(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> Self
 18    where
 19        Module<B>: VmpPMatAlloc<B>,
 20    {
 21        let mut keys: Vec<GGLWESwitchingKeyPrepared<Vec<u8>, B>> = Vec::new();
 22        let pairs: usize = (((rank + 1) * rank) >> 1).max(1);
 23        (0..pairs).for_each(|_| {
 24            keys.push(GGLWESwitchingKeyPrepared::alloc(
 25                module, n, basek, k, rows, digits, 1, rank,
 26            ));
 27        });
 28        Self { keys }
 29    }
 30
 31    pub fn bytes_of(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> usize
 32    where
 33        Module<B>: VmpPMatAllocBytes,
 34    {
 35        let pairs: usize = (((rank + 1) * rank) >> 1).max(1);
 36        pairs * GGLWESwitchingKeyPrepared::bytes_of(module, n, basek, k, rows, digits, 1, rank)
 37    }
 38}
 39
 40impl<D: Data, B: Backend> Infos for GGLWETensorKeyPrepared<D, B> {
 41    type Inner = VmpPMat<D, B>;
 42
 43    fn inner(&self) -> &Self::Inner {
 44        self.keys[0].inner()
 45    }
 46
 47    fn basek(&self) -> usize {
 48        self.keys[0].basek()
 49    }
 50
 51    fn k(&self) -> usize {
 52        self.keys[0].k()
 53    }
 54}
 55
 56impl<D: Data, B: Backend> GGLWETensorKeyPrepared<D, B> {
 57    pub fn rank(&self) -> usize {
 58        self.keys[0].rank()
 59    }
 60
 61    pub fn rank_in(&self) -> usize {
 62        self.keys[0].rank_in()
 63    }
 64
 65    pub fn rank_out(&self) -> usize {
 66        self.keys[0].rank_out()
 67    }
 68
 69    pub fn digits(&self) -> usize {
 70        self.keys[0].digits()
 71    }
 72}
 73
 74impl<D: DataMut, B: Backend> GGLWETensorKeyPrepared<D, B> {
 75    // Returns a mutable reference to GLWESwitchingKey_{s}(s[i] * s[j])
 76    pub fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GGLWESwitchingKeyPrepared<D, B> {
 77        if i > j {
 78            std::mem::swap(&mut i, &mut j);
 79        };
 80        let rank: usize = self.rank();
 81        &mut self.keys[i * rank + j - (i * (i + 1) / 2)]
 82    }
 83}
 84
 85impl<D: DataRef, B: Backend> GGLWETensorKeyPrepared<D, B> {
 86    // Returns a reference to GLWESwitchingKey_{s}(s[i] * s[j])
 87    pub fn at(&self, mut i: usize, mut j: usize) -> &GGLWESwitchingKeyPrepared<D, B> {
 88        if i > j {
 89            std::mem::swap(&mut i, &mut j);
 90        };
 91        let rank: usize = self.rank();
 92        &self.keys[i * rank + j - (i * (i + 1) / 2)]
 93    }
 94}
 95
 96impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWETensorKey<DR>> for GGLWETensorKeyPrepared<D, B>
 97where
 98    Module<B>: VmpPrepare<B>,
 99{
100    fn prepare(&mut self, module: &Module<B>, other: &GGLWETensorKey<DR>, scratch: &mut Scratch<B>) {
101        #[cfg(debug_assertions)]
102        {
103            assert_eq!(self.keys.len(), other.keys.len());
104        }
105        self.keys
106            .iter_mut()
107            .zip(other.keys.iter())
108            .for_each(|(a, b)| {
109                a.prepare(module, b, scratch);
110            });
111    }
112}
113
114impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWETensorKeyPrepared<Vec<u8>, B>> for GGLWETensorKey<D>
115where
116    Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
117{
118    fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGLWETensorKeyPrepared<Vec<u8>, B> {
119        let mut tsk_prepared: GGLWETensorKeyPrepared<Vec<u8>, B> = GGLWETensorKeyPrepared::alloc(
120            module,
121            self.n(),
122            self.basek(),
123            self.k(),
124            self.rows(),
125            self.digits(),
126            self.rank(),
127        );
128        tsk_prepared.prepare(module, self, scratch);
129        tsk_prepared
130    }
131}