mirror of
https://github.com/zama-ai/tfhe-rs.git
synced 2026-01-10 15:18:33 -05:00
chore(bench): benchmark oprf function against all available precisions
This commit is contained in:
committed by
Arthur Meyre
parent
d8241942a6
commit
74cafd0e9d
@@ -4,17 +4,14 @@ mod oprf;
|
||||
#[path = "../utilities.rs"]
|
||||
mod utilities;
|
||||
|
||||
use crate::utilities::{write_to_json, EnvConfig, OperatorType};
|
||||
use crate::utilities::{write_to_json, EnvConfig, OperatorType, ParamsAndNumBlocksIter};
|
||||
use criterion::{criterion_group, Criterion};
|
||||
use itertools::iproduct;
|
||||
use rand::prelude::*;
|
||||
use std::env;
|
||||
use std::vec::IntoIter;
|
||||
use tfhe::integer::keycache::KEY_CACHE;
|
||||
use tfhe::integer::prelude::*;
|
||||
use tfhe::integer::{IntegerKeyKind, RadixCiphertext, RadixClientKey, ServerKey, U256};
|
||||
use tfhe::keycache::NamedParam;
|
||||
use tfhe::shortint::parameters::*;
|
||||
|
||||
/// The type used to hold scalar values
|
||||
/// It must be as big as the largest bit size tested
|
||||
@@ -27,57 +24,6 @@ fn gen_random_u256(rng: &mut ThreadRng) -> U256 {
|
||||
tfhe::integer::U256::from((clearlow, clearhigh))
|
||||
}
|
||||
|
||||
/// An iterator that yields a succession of combinations
|
||||
/// of parameters and a num_block to achieve a certain bit_size ciphertext
|
||||
/// in radix decomposition
|
||||
struct ParamsAndNumBlocksIter {
|
||||
params_and_bit_sizes:
|
||||
itertools::Product<IntoIter<tfhe::shortint::PBSParameters>, IntoIter<usize>>,
|
||||
}
|
||||
|
||||
impl Default for ParamsAndNumBlocksIter {
|
||||
fn default() -> Self {
|
||||
let env_config = EnvConfig::new();
|
||||
|
||||
if env_config.is_multi_bit {
|
||||
#[cfg(feature = "gpu")]
|
||||
let params = vec![PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS.into()];
|
||||
#[cfg(not(feature = "gpu"))]
|
||||
let params = vec![PARAM_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_2_KS_PBS.into()];
|
||||
|
||||
let params_and_bit_sizes = iproduct!(params, env_config.bit_sizes());
|
||||
Self {
|
||||
params_and_bit_sizes,
|
||||
}
|
||||
} else {
|
||||
// FIXME One set of parameter is tested since we want to benchmark only quickest
|
||||
// operations.
|
||||
let params = vec![
|
||||
PARAM_MESSAGE_2_CARRY_2_KS_PBS.into(),
|
||||
// PARAM_MESSAGE_3_CARRY_3_KS_PBS.into(),
|
||||
// PARAM_MESSAGE_4_CARRY_4_KS_PBS.into(),
|
||||
];
|
||||
|
||||
let params_and_bit_sizes = iproduct!(params, env_config.bit_sizes());
|
||||
Self {
|
||||
params_and_bit_sizes,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for ParamsAndNumBlocksIter {
|
||||
type Item = (tfhe::shortint::PBSParameters, usize, usize);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let (param, bit_size) = self.params_and_bit_sizes.next()?;
|
||||
let num_block =
|
||||
(bit_size as f64 / (param.message_modulus().0 as f64).log(2.0)).ceil() as usize;
|
||||
|
||||
Some((param, num_block, bit_size))
|
||||
}
|
||||
}
|
||||
|
||||
/// Base function to bench a server key function that is a binary operation, input ciphertexts will
|
||||
/// contain non zero carries
|
||||
fn bench_server_key_binary_function_dirty_inputs<F>(
|
||||
|
||||
@@ -1,42 +1,9 @@
|
||||
use crate::utilities::{write_to_json, OperatorType};
|
||||
use crate::utilities::{write_to_json, OperatorType, ParamsAndNumBlocksIter};
|
||||
use concrete_csprng::seeders::Seed;
|
||||
use criterion::{black_box, Criterion};
|
||||
use itertools::iproduct;
|
||||
use std::vec::IntoIter;
|
||||
use tfhe::integer::keycache::KEY_CACHE;
|
||||
use tfhe::integer::IntegerKeyKind;
|
||||
use tfhe::keycache::NamedParam;
|
||||
use tfhe::shortint::parameters::*;
|
||||
|
||||
/// An iterator that yields a succession of combinations
|
||||
/// of parameters and a num_block to achieve a certain bit_size ciphertext
|
||||
/// in radix decomposition
|
||||
struct ParamsAndNumBlocksIter {
|
||||
params_and_bit_sizes: itertools::Product<IntoIter<PBSParameters>, IntoIter<u64>>,
|
||||
}
|
||||
|
||||
impl Default for ParamsAndNumBlocksIter {
|
||||
fn default() -> Self {
|
||||
let params = vec![PARAM_MESSAGE_2_CARRY_2_KS_PBS.into()];
|
||||
let bit_sizes = vec![64];
|
||||
let params_and_bit_sizes = iproduct!(params, bit_sizes);
|
||||
Self {
|
||||
params_and_bit_sizes,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for ParamsAndNumBlocksIter {
|
||||
type Item = (PBSParameters, u64, u64);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let (param, bit_size) = self.params_and_bit_sizes.next()?;
|
||||
let num_block =
|
||||
(bit_size as f64 / (param.message_modulus().0 as f64).log(2.0)).ceil() as u64;
|
||||
|
||||
Some((param, num_block, bit_size))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unsigned_oprf(c: &mut Criterion) {
|
||||
let bench_name = "integer::unsigned_oprf";
|
||||
@@ -44,7 +11,7 @@ pub fn unsigned_oprf(c: &mut Criterion) {
|
||||
let mut bench_group = c.benchmark_group(bench_name);
|
||||
bench_group
|
||||
.sample_size(15)
|
||||
.measurement_time(std::time::Duration::from_secs(60));
|
||||
.measurement_time(std::time::Duration::from_secs(30));
|
||||
|
||||
for (param, num_block, bit_size) in ParamsAndNumBlocksIter::default() {
|
||||
let (_, sk) = KEY_CACHE.get_from_params(param, IntegerKeyKind::Radix);
|
||||
@@ -54,8 +21,8 @@ pub fn unsigned_oprf(c: &mut Criterion) {
|
||||
b.iter(|| {
|
||||
_ = black_box(sk.par_generate_oblivious_pseudo_random_unsigned_integer(
|
||||
Seed(0),
|
||||
bit_size,
|
||||
num_block,
|
||||
bit_size as u64,
|
||||
num_block as u64,
|
||||
));
|
||||
})
|
||||
});
|
||||
@@ -67,7 +34,7 @@ pub fn unsigned_oprf(c: &mut Criterion) {
|
||||
"oprf",
|
||||
&OperatorType::Atomic,
|
||||
bit_size as u32,
|
||||
vec![param.message_modulus().0.ilog2(); num_block as usize],
|
||||
vec![param.message_modulus().0.ilog2(); num_block],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
#[path = "../utilities.rs"]
|
||||
mod utilities;
|
||||
|
||||
use crate::utilities::{write_to_json, EnvConfig, OperatorType};
|
||||
use crate::utilities::{write_to_json, EnvConfig, OperatorType, ParamsAndNumBlocksIter};
|
||||
use criterion::{criterion_group, Criterion};
|
||||
use itertools::iproduct;
|
||||
use rand::prelude::*;
|
||||
use std::env;
|
||||
use std::vec::IntoIter;
|
||||
use tfhe::integer::keycache::KEY_CACHE;
|
||||
use tfhe::integer::prelude::*;
|
||||
use tfhe::integer::{IntegerKeyKind, RadixCiphertext, ServerKey, SignedRadixCiphertext, I256};
|
||||
use tfhe::keycache::NamedParam;
|
||||
#[cfg(feature = "gpu")]
|
||||
use tfhe::shortint::parameters::PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS;
|
||||
use tfhe::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS;
|
||||
#[cfg(not(feature = "gpu"))]
|
||||
use tfhe::shortint::parameters::PARAM_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_2_KS_PBS;
|
||||
|
||||
fn gen_random_i256(rng: &mut ThreadRng) -> I256 {
|
||||
let clearlow = rng.gen::<u128>();
|
||||
@@ -24,57 +17,6 @@ fn gen_random_i256(rng: &mut ThreadRng) -> I256 {
|
||||
tfhe::integer::I256::from((clearlow, clearhigh))
|
||||
}
|
||||
|
||||
/// An iterator that yields a succession of combinations
|
||||
/// of parameters and a num_block to achieve a certain bit_size ciphertext
|
||||
/// in radix decomposition
|
||||
struct ParamsAndNumBlocksIter {
|
||||
params_and_bit_sizes:
|
||||
itertools::Product<IntoIter<tfhe::shortint::PBSParameters>, IntoIter<usize>>,
|
||||
}
|
||||
|
||||
impl Default for ParamsAndNumBlocksIter {
|
||||
fn default() -> Self {
|
||||
let env_config = EnvConfig::new();
|
||||
|
||||
if env_config.is_multi_bit {
|
||||
#[cfg(feature = "gpu")]
|
||||
let params = vec![PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS.into()];
|
||||
#[cfg(not(feature = "gpu"))]
|
||||
let params = vec![PARAM_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_2_KS_PBS.into()];
|
||||
|
||||
let params_and_bit_sizes = iproduct!(params, env_config.bit_sizes());
|
||||
Self {
|
||||
params_and_bit_sizes,
|
||||
}
|
||||
} else {
|
||||
// FIXME One set of parameter is tested since we want to benchmark only quickest
|
||||
// operations.
|
||||
let params = vec![
|
||||
PARAM_MESSAGE_2_CARRY_2_KS_PBS.into(),
|
||||
// PARAM_MESSAGE_3_CARRY_3_KS_PBS.into(),
|
||||
// PARAM_MESSAGE_4_CARRY_4_KS_PBS.into(),
|
||||
];
|
||||
|
||||
let params_and_bit_sizes = iproduct!(params, env_config.bit_sizes());
|
||||
Self {
|
||||
params_and_bit_sizes,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for ParamsAndNumBlocksIter {
|
||||
type Item = (tfhe::shortint::PBSParameters, usize, usize);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let (param, bit_size) = self.params_and_bit_sizes.next()?;
|
||||
let num_block =
|
||||
(bit_size as f64 / param.message_modulus().0.ilog2() as f64).ceil() as usize;
|
||||
|
||||
Some((param, num_block, bit_size))
|
||||
}
|
||||
}
|
||||
|
||||
/// Base function to bench a server key function that is a binary operation, input ciphertext will
|
||||
/// contain only zero carries
|
||||
fn bench_server_key_signed_binary_function_clean_inputs<F>(
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
use itertools::iproduct;
|
||||
use serde::Serialize;
|
||||
use std::path::PathBuf;
|
||||
use std::vec::IntoIter;
|
||||
use std::{env, fs};
|
||||
#[cfg(feature = "boolean")]
|
||||
use tfhe::boolean::parameters::BooleanParameters;
|
||||
use tfhe::core_crypto::prelude::*;
|
||||
#[cfg(all(feature = "shortint", feature = "gpu"))]
|
||||
use tfhe::shortint::parameters::PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS;
|
||||
#[cfg(all(feature = "shortint", not(feature = "gpu")))]
|
||||
use tfhe::shortint::parameters::PARAM_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_2_KS_PBS;
|
||||
#[cfg(feature = "shortint")]
|
||||
use tfhe::shortint::parameters::ShortintKeySwitchingParameters;
|
||||
use tfhe::shortint::parameters::{ShortintKeySwitchingParameters, PARAM_MESSAGE_2_CARRY_2_KS_PBS};
|
||||
#[cfg(feature = "shortint")]
|
||||
use tfhe::shortint::PBSParameters;
|
||||
|
||||
@@ -268,6 +274,53 @@ impl EnvConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator that yields a succession of combinations
|
||||
/// of parameters and a num_block to achieve a certain bit_size ciphertext
|
||||
/// in radix decomposition
|
||||
pub struct ParamsAndNumBlocksIter {
|
||||
params_and_bit_sizes:
|
||||
itertools::Product<IntoIter<tfhe::shortint::PBSParameters>, IntoIter<usize>>,
|
||||
}
|
||||
|
||||
impl Default for ParamsAndNumBlocksIter {
|
||||
fn default() -> Self {
|
||||
let env_config = EnvConfig::new();
|
||||
|
||||
if env_config.is_multi_bit {
|
||||
#[cfg(feature = "gpu")]
|
||||
let params = vec![PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS.into()];
|
||||
#[cfg(not(feature = "gpu"))]
|
||||
let params = vec![PARAM_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_2_KS_PBS.into()];
|
||||
|
||||
let params_and_bit_sizes = iproduct!(params, env_config.bit_sizes());
|
||||
Self {
|
||||
params_and_bit_sizes,
|
||||
}
|
||||
} else {
|
||||
// FIXME One set of parameter is tested since we want to benchmark only quickest
|
||||
// operations.
|
||||
let params = vec![PARAM_MESSAGE_2_CARRY_2_KS_PBS.into()];
|
||||
|
||||
let params_and_bit_sizes = iproduct!(params, env_config.bit_sizes());
|
||||
Self {
|
||||
params_and_bit_sizes,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Iterator for ParamsAndNumBlocksIter {
|
||||
type Item = (tfhe::shortint::PBSParameters, usize, usize);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let (param, bit_size) = self.params_and_bit_sizes.next()?;
|
||||
let num_block =
|
||||
(bit_size as f64 / (param.message_modulus().0 as f64).log(2.0)).ceil() as usize;
|
||||
|
||||
Some((param, num_block, bit_size))
|
||||
}
|
||||
}
|
||||
|
||||
// Empty main to please clippy.
|
||||
#[allow(dead_code)]
|
||||
pub fn main() {}
|
||||
|
||||
Reference in New Issue
Block a user