arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-schemes/benches/circuit_bootstrapping.rs
poulpy-schemes/benches/circuit_bootstrapping.rsRaw
  1use std::hint::black_box;
  2
  3use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
  4use poulpy_backend::{FFT64Avx, FFT64Ref, FFT64Spqlios};
  5use poulpy_core::layouts::{
  6    Digits, GGLWEAutomorphismKeyLayout, GGLWETensorKeyLayout, GGSWCiphertext, GGSWCiphertextLayout, GLWESecret, LWECiphertext,
  7    LWECiphertextLayout, LWESecret, prepared::PrepareAlloc,
  8};
  9use poulpy_hal::{
 10    api::{
 11        ModuleNew, ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc,
 12        SvpPPolAllocBytes, SvpPrepare, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism,
 13        VecZnxAutomorphismInplace, VecZnxBigAddInplace, VecZnxBigAddSmallInplace, VecZnxBigAlloc, VecZnxBigAllocBytes,
 14        VecZnxBigAutomorphismInplace, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes, VecZnxBigSubSmallNegateInplace, VecZnxCopy,
 15        VecZnxDftAddInplace, VecZnxDftAlloc, VecZnxDftAllocBytes, VecZnxDftApply, VecZnxDftCopy, VecZnxFillUniform,
 16        VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA, VecZnxNegateInplace, VecZnxNormalize, VecZnxNormalizeInplace,
 17        VecZnxNormalizeTmpBytes, VecZnxRotate, VecZnxRotateInplace, VecZnxRotateInplaceTmpBytes, VecZnxRshInplace, VecZnxSub,
 18        VecZnxSubInplace, VecZnxSwitchRing, VmpApplyDftToDft, VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes, VmpPMatAlloc,
 19        VmpPrepare, ZnAddNormal, ZnFillUniform, ZnNormalizeInplace,
 20    },
 21    layouts::{Backend, Module, ScratchOwned},
 22    oep::{
 23        ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeMatZnxImpl, TakeScalarZnxImpl, TakeSvpPPolImpl,
 24        TakeVecZnxBigImpl, TakeVecZnxDftImpl, TakeVecZnxDftSliceImpl, TakeVecZnxImpl, TakeVecZnxSliceImpl,
 25    },
 26    source::Source,
 27};
 28use poulpy_schemes::tfhe::{
 29    blind_rotation::{
 30        BlincRotationExecute, BlindRotationAlgo, BlindRotationKey, BlindRotationKeyAlloc, BlindRotationKeyEncryptSk,
 31        BlindRotationKeyInfos, BlindRotationKeyLayout, BlindRotationKeyPrepared, CGGI,
 32    },
 33    circuit_bootstrapping::{
 34        CircuitBootstrappingKey, CircuitBootstrappingKeyEncryptSk, CircuitBootstrappingKeyLayout,
 35        CircuitBootstrappingKeyPrepared, CirtuitBootstrappingExecute,
 36    },
 37};
 38
 39pub fn benc_circuit_bootstrapping<B: Backend, BRA: BlindRotationAlgo>(c: &mut Criterion, label: &str)
 40where
 41    Module<B>: ModuleNew<B>
 42        + VecZnxFillUniform
 43        + VecZnxAddNormal
 44        + VecZnxNormalizeInplace<B>
 45        + VecZnxDftAllocBytes
 46        + VecZnxBigNormalize<B>
 47        + VecZnxDftApply<B>
 48        + SvpApplyDftToDftInplace<B>
 49        + VecZnxIdftApplyConsume<B>
 50        + VecZnxNormalizeTmpBytes
 51        + VecZnxSubInplace
 52        + VecZnxAddInplace
 53        + VecZnxNormalize<B>
 54        + VecZnxSub
 55        + VecZnxAddScalarInplace
 56        + VecZnxAutomorphism
 57        + VecZnxSwitchRing
 58        + VecZnxBigAllocBytes
 59        + VecZnxIdftApplyTmpA<B>
 60        + SvpApplyDftToDft<B>
 61        + VecZnxBigAddInplace<B>
 62        + VecZnxBigAddSmallInplace<B>
 63        + VecZnxBigAlloc<B>
 64        + VecZnxDftAlloc<B>
 65        + VecZnxBigNormalizeTmpBytes
 66        + VmpPMatAlloc<B>
 67        + VmpPrepare<B>
 68        + SvpPrepare<B>
 69        + SvpPPolAlloc<B>
 70        + VmpApplyDftToDftTmpBytes
 71        + VmpApplyDftToDft<B>
 72        + VmpApplyDftToDftAdd<B>
 73        + SvpPPolAllocBytes
 74        + VecZnxRotateInplace<B>
 75        + VecZnxBigAutomorphismInplace<B>
 76        + VecZnxRshInplace<B>
 77        + VecZnxDftCopy<B>
 78        + VecZnxNegateInplace
 79        + VecZnxCopy
 80        + VecZnxAutomorphismInplace<B>
 81        + VecZnxBigSubSmallNegateInplace<B>
 82        + VecZnxRotateInplaceTmpBytes
 83        + VecZnxBigAllocBytes
 84        + VecZnxDftAddInplace<B>
 85        + VecZnxRotate
 86        + ZnFillUniform
 87        + ZnAddNormal
 88        + ZnNormalizeInplace<B>,
 89    ScratchOwned<B>: ScratchOwnedAlloc<B> + ScratchOwnedBorrow<B>,
 90    B: Backend
 91        + ScratchOwnedAllocImpl<B>
 92        + ScratchOwnedBorrowImpl<B>
 93        + TakeVecZnxDftImpl<B>
 94        + ScratchAvailableImpl<B>
 95        + TakeVecZnxImpl<B>
 96        + TakeScalarZnxImpl<B>
 97        + TakeSvpPPolImpl<B>
 98        + TakeVecZnxBigImpl<B>
 99        + TakeVecZnxDftSliceImpl<B>
100        + TakeMatZnxImpl<B>
101        + TakeVecZnxSliceImpl<B>,
102    BlindRotationKey<Vec<u8>, BRA>: PrepareAlloc<B, BlindRotationKeyPrepared<Vec<u8>, BRA, B>>,
103    BlindRotationKeyPrepared<Vec<u8>, BRA, B>: BlincRotationExecute<B>,
104    BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk<B>,
105{
106    let group_name: String = format!("circuit_bootstrapping::{label}");
107
108    let mut group = c.benchmark_group(group_name);
109
110    struct Params {
111        name: String,
112        extension_factor: usize,
113        k_pt: usize,
114        block_size: usize,
115        lwe_infos: LWECiphertextLayout,
116        ggsw_infos: GGSWCiphertextLayout,
117        cbt_infos: CircuitBootstrappingKeyLayout,
118    }
119
120    fn runner<B: Backend, BRA: BlindRotationAlgo>(params: &Params) -> impl FnMut()
121    where
122        Module<B>: ModuleNew<B>
123            + VecZnxFillUniform
124            + VecZnxAddNormal
125            + VecZnxNormalizeInplace<B>
126            + VecZnxDftAllocBytes
127            + VecZnxBigNormalize<B>
128            + VecZnxDftApply<B>
129            + SvpApplyDftToDftInplace<B>
130            + VecZnxIdftApplyConsume<B>
131            + VecZnxNormalizeTmpBytes
132            + VecZnxSubInplace
133            + VecZnxAddInplace
134            + VecZnxNormalize<B>
135            + VecZnxSub
136            + VecZnxAddScalarInplace
137            + VecZnxAutomorphism
138            + VecZnxSwitchRing
139            + VecZnxBigAllocBytes
140            + VecZnxIdftApplyTmpA<B>
141            + SvpApplyDftToDft<B>
142            + VecZnxBigAddInplace<B>
143            + VecZnxBigAddSmallInplace<B>
144            + VecZnxBigAlloc<B>
145            + VecZnxDftAlloc<B>
146            + VecZnxBigNormalizeTmpBytes
147            + VmpPMatAlloc<B>
148            + VmpPrepare<B>
149            + SvpPrepare<B>
150            + SvpPPolAlloc<B>
151            + VmpApplyDftToDftTmpBytes
152            + VmpApplyDftToDft<B>
153            + VmpApplyDftToDftAdd<B>
154            + SvpPPolAllocBytes
155            + VecZnxRotateInplace<B>
156            + VecZnxBigAutomorphismInplace<B>
157            + VecZnxRshInplace<B>
158            + VecZnxDftCopy<B>
159            + VecZnxNegateInplace
160            + VecZnxCopy
161            + VecZnxAutomorphismInplace<B>
162            + VecZnxBigSubSmallNegateInplace<B>
163            + VecZnxRotateInplaceTmpBytes
164            + VecZnxBigAllocBytes
165            + VecZnxDftAddInplace<B>
166            + VecZnxRotate
167            + ZnFillUniform
168            + ZnAddNormal
169            + ZnNormalizeInplace<B>,
170        B: Backend
171            + ScratchOwnedAllocImpl<B>
172            + ScratchOwnedBorrowImpl<B>
173            + TakeVecZnxDftImpl<B>
174            + ScratchAvailableImpl<B>
175            + TakeVecZnxImpl<B>
176            + TakeScalarZnxImpl<B>
177            + TakeSvpPPolImpl<B>
178            + TakeVecZnxBigImpl<B>
179            + TakeVecZnxDftSliceImpl<B>
180            + TakeMatZnxImpl<B>
181            + TakeVecZnxSliceImpl<B>,
182        BlindRotationKey<Vec<u8>, BRA>: PrepareAlloc<B, BlindRotationKeyPrepared<Vec<u8>, BRA, B>>,
183        BlindRotationKeyPrepared<Vec<u8>, BRA, B>: BlincRotationExecute<B>,
184        BlindRotationKey<Vec<u8>, BRA>: BlindRotationKeyAlloc + BlindRotationKeyEncryptSk<B>,
185    {
186        // Scratch space (4MB)
187        let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(1 << 22);
188
189        let n_glwe: poulpy_core::layouts::Degree = params.cbt_infos.layout_brk.n_glwe();
190        let n_lwe: poulpy_core::layouts::Degree = params.cbt_infos.layout_brk.n_lwe();
191        let rank: poulpy_core::layouts::Rank = params.cbt_infos.layout_brk.rank;
192
193        let module: Module<B> = Module::<B>::new(n_glwe.as_u32() as u64);
194
195        let mut source_xs: Source = Source::new([1u8; 32]);
196        let mut source_xa: Source = Source::new([1u8; 32]);
197        let mut source_xe: Source = Source::new([1u8; 32]);
198
199        let mut sk_lwe: LWESecret<Vec<u8>> = LWESecret::alloc(n_lwe);
200        sk_lwe.fill_binary_block(params.block_size, &mut source_xs);
201        sk_lwe.fill_zero();
202
203        let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc_with(n_glwe, rank);
204        sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
205
206        let ct_lwe: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(&params.lwe_infos);
207
208        // Circuit bootstrapping evaluation key
209        let cbt_key: CircuitBootstrappingKey<Vec<u8>, BRA> = CircuitBootstrappingKey::encrypt_sk(
210            &module,
211            &sk_lwe,
212            &sk_glwe,
213            &params.cbt_infos,
214            &mut source_xa,
215            &mut source_xe,
216            scratch.borrow(),
217        );
218
219        let mut res: GGSWCiphertext<Vec<u8>> = GGSWCiphertext::alloc(&params.ggsw_infos);
220        let cbt_prepared: CircuitBootstrappingKeyPrepared<Vec<u8>, BRA, B> = cbt_key.prepare_alloc(&module, scratch.borrow());
221
222        move || {
223            cbt_prepared.execute_to_constant(
224                &module,
225                &mut res,
226                &ct_lwe,
227                params.k_pt,
228                params.extension_factor,
229                scratch.borrow(),
230            );
231            black_box(());
232        }
233    }
234
235    for params in [Params {
236        name: String::from("1-bit"),
237        extension_factor: 1,
238        k_pt: 1,
239        lwe_infos: LWECiphertextLayout {
240            n: 574_u32.into(),
241            k: 13_u32.into(),
242            base2k: 13_u32.into(),
243        },
244        block_size: 7,
245        ggsw_infos: GGSWCiphertextLayout {
246            n: 1024_u32.into(),
247            base2k: 13_u32.into(),
248            k: 26_u32.into(),
249            rows: 2_u32.into(),
250            digits: 1_u32.into(),
251            rank: 2_u32.into(),
252        },
253        cbt_infos: CircuitBootstrappingKeyLayout {
254            layout_brk: BlindRotationKeyLayout {
255                n_glwe: 1024_u32.into(),
256                n_lwe: 574_u32.into(),
257                base2k: 13_u32.into(),
258                k: 52_u32.into(),
259                rows: 3_u32.into(),
260                rank: 2_u32.into(),
261            },
262            layout_atk: GGLWEAutomorphismKeyLayout {
263                n: 1024_u32.into(),
264                base2k: 13_u32.into(),
265                k: 52_u32.into(),
266                rows: 3_u32.into(),
267                digits: Digits(1),
268                rank: 2_u32.into(),
269            },
270            layout_tsk: GGLWETensorKeyLayout {
271                n: 1024_u32.into(),
272                base2k: 13_u32.into(),
273                k: 52_u32.into(),
274                rows: 3_u32.into(),
275                digits: Digits(1),
276                rank: 2_u32.into(),
277            },
278        },
279    }] {
280        let id: BenchmarkId = BenchmarkId::from_parameter(params.name.clone());
281        let mut runner = runner::<B, BRA>(&params);
282        group.bench_with_input(id, &(), |b, _| b.iter(&mut runner));
283    }
284
285    group.finish();
286}
287
288fn bench_circuit_bootstrapping_cpu_ref_fft64(c: &mut Criterion) {
289    benc_circuit_bootstrapping::<FFT64Ref, CGGI>(c, "fft64_ref");
290}
291
292fn bench_circuit_bootstrapping_cpu_avx_fft64(c: &mut Criterion) {
293    benc_circuit_bootstrapping::<FFT64Avx, CGGI>(c, "fft64_avx");
294}
295
296fn bench_circuit_bootstrapping_cpu_spqlios_fft64(c: &mut Criterion) {
297    benc_circuit_bootstrapping::<FFT64Spqlios, CGGI>(c, "fft64_spqlios");
298}
299
300criterion_group!(
301    benches,
302    bench_circuit_bootstrapping_cpu_ref_fft64,
303    bench_circuit_bootstrapping_cpu_avx_fft64,
304    bench_circuit_bootstrapping_cpu_spqlios_fft64,
305);
306
307criterion_main!(benches);