|
|
|
|
@@ -13,9 +13,9 @@ use tfhe::keycache::NamedParam;
|
|
|
|
|
use tfhe::named::Named;
|
|
|
|
|
use tfhe::prelude::*;
|
|
|
|
|
use tfhe::{
|
|
|
|
|
ClientKey, CompressedServerKey, FheBool, FheIntegerType, FheUint, FheUint10, FheUint12,
|
|
|
|
|
FheUint128, FheUint14, FheUint16, FheUint2, FheUint32, FheUint4, FheUint6, FheUint64, FheUint8,
|
|
|
|
|
FheUintId, IntegerId, KVStore,
|
|
|
|
|
ClientKey, CompressedServerKey, FheIntegerType, FheUint, FheUint10, FheUint12, FheUint128,
|
|
|
|
|
FheUint14, FheUint16, FheUint2, FheUint32, FheUint4, FheUint6, FheUint64, FheUint8, FheUintId,
|
|
|
|
|
IntegerId, KVStore,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
mod oprf;
|
|
|
|
|
@@ -30,75 +30,13 @@ impl<Id: FheUintId> BenchWait for FheUint<Id> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl BenchWait for FheBool {
|
|
|
|
|
fn wait_bench(&self) {
|
|
|
|
|
self.wait()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<T1: FheWait, T2> BenchWait for (T1, T2) {
|
|
|
|
|
fn wait_bench(&self) {
|
|
|
|
|
self.0.wait()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn bench_fhe_type_unary_op<FheType, F, R>(
|
|
|
|
|
c: &mut Criterion,
|
|
|
|
|
client_key: &ClientKey,
|
|
|
|
|
type_name: &str,
|
|
|
|
|
bit_size: usize,
|
|
|
|
|
display_name: &str,
|
|
|
|
|
func_name: &str,
|
|
|
|
|
func: F,
|
|
|
|
|
) where
|
|
|
|
|
F: Fn(&FheType) -> R,
|
|
|
|
|
R: BenchWait,
|
|
|
|
|
FheType: FheEncrypt<u128, ClientKey>,
|
|
|
|
|
FheType: FheWait,
|
|
|
|
|
{
|
|
|
|
|
let mut bench_group = c.benchmark_group(type_name);
|
|
|
|
|
let mut bench_prefix = "hlapi".to_string();
|
|
|
|
|
if cfg!(feature = "gpu") {
|
|
|
|
|
bench_prefix = format!("{}::cuda", bench_prefix);
|
|
|
|
|
} else if cfg!(feature = "hpu") {
|
|
|
|
|
bench_prefix = format!("{}::hpu", bench_prefix);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bench_prefix = format!("{}::ops", bench_prefix);
|
|
|
|
|
|
|
|
|
|
let mut rng = thread_rng();
|
|
|
|
|
|
|
|
|
|
let param = client_key.computation_parameters();
|
|
|
|
|
let param_name = param.name();
|
|
|
|
|
let bit_size = bit_size as u32;
|
|
|
|
|
|
|
|
|
|
let write_record = |bench_id: String, display_name| {
|
|
|
|
|
write_to_json::<u64, _>(
|
|
|
|
|
&bench_id,
|
|
|
|
|
param,
|
|
|
|
|
¶m_name,
|
|
|
|
|
display_name,
|
|
|
|
|
&OperatorType::Atomic,
|
|
|
|
|
bit_size,
|
|
|
|
|
vec![],
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let lhs = FheType::encrypt(rng.gen(), client_key);
|
|
|
|
|
|
|
|
|
|
let bench_id = format!("{bench_prefix}::{func_name}::{param_name}::{type_name}");
|
|
|
|
|
|
|
|
|
|
bench_group.bench_function(&bench_id, |b| {
|
|
|
|
|
b.iter(|| {
|
|
|
|
|
let res = func(&lhs);
|
|
|
|
|
res.wait_bench();
|
|
|
|
|
black_box(res)
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
write_record(bench_id, display_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn bench_fhe_type_binary_op<FheType, F, R>(
|
|
|
|
|
fn bench_fhe_type_op<FheType, F, R>(
|
|
|
|
|
c: &mut Criterion,
|
|
|
|
|
client_key: &ClientKey,
|
|
|
|
|
type_name: &str,
|
|
|
|
|
@@ -155,69 +93,11 @@ fn bench_fhe_type_binary_op<FheType, F, R>(
|
|
|
|
|
write_record(bench_id, display_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn bench_fhe_type_ternary_op<FheType, F, R>(
|
|
|
|
|
c: &mut Criterion,
|
|
|
|
|
client_key: &ClientKey,
|
|
|
|
|
type_name: &str,
|
|
|
|
|
bit_size: usize,
|
|
|
|
|
display_name: &str,
|
|
|
|
|
func_name: &str,
|
|
|
|
|
func: F,
|
|
|
|
|
) where
|
|
|
|
|
F: Fn(&FheBool, &FheType, &FheType) -> R,
|
|
|
|
|
R: BenchWait,
|
|
|
|
|
FheType: FheEncrypt<u128, ClientKey>,
|
|
|
|
|
FheType: FheWait,
|
|
|
|
|
{
|
|
|
|
|
let mut bench_group = c.benchmark_group(type_name);
|
|
|
|
|
let mut bench_prefix = "hlapi".to_string();
|
|
|
|
|
if cfg!(feature = "gpu") {
|
|
|
|
|
bench_prefix = format!("{}::cuda", bench_prefix);
|
|
|
|
|
} else if cfg!(feature = "hpu") {
|
|
|
|
|
bench_prefix = format!("{}::hpu", bench_prefix);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bench_prefix = format!("{}::ops", bench_prefix);
|
|
|
|
|
|
|
|
|
|
let mut rng = thread_rng();
|
|
|
|
|
|
|
|
|
|
let param = client_key.computation_parameters();
|
|
|
|
|
let param_name = param.name();
|
|
|
|
|
let bit_size = bit_size as u32;
|
|
|
|
|
|
|
|
|
|
let write_record = |bench_id: String, display_name| {
|
|
|
|
|
write_to_json::<u64, _>(
|
|
|
|
|
&bench_id,
|
|
|
|
|
param,
|
|
|
|
|
¶m_name,
|
|
|
|
|
display_name,
|
|
|
|
|
&OperatorType::Atomic,
|
|
|
|
|
bit_size,
|
|
|
|
|
vec![],
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let bool = FheBool::encrypt(rng.gen(), client_key);
|
|
|
|
|
let lhs = FheType::encrypt(rng.gen(), client_key);
|
|
|
|
|
let rhs = FheType::encrypt(rng.gen(), client_key);
|
|
|
|
|
|
|
|
|
|
let bench_id = format!("{bench_prefix}::{func_name}::{param_name}::{type_name}");
|
|
|
|
|
|
|
|
|
|
bench_group.bench_function(&bench_id, |b| {
|
|
|
|
|
b.iter(|| {
|
|
|
|
|
let res = func(&bool, &lhs, &rhs);
|
|
|
|
|
res.wait_bench();
|
|
|
|
|
black_box(res)
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
write_record(bench_id, display_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! bench_type_binary_op (
|
|
|
|
|
macro_rules! bench_type_op (
|
|
|
|
|
(type_name: $fhe_type:ident, display_name: $display_name:literal, operation: $op:ident) => {
|
|
|
|
|
::paste::paste! {
|
|
|
|
|
fn [<bench_ $fhe_type:snake _ $op>](c: &mut Criterion, cks: &ClientKey) {
|
|
|
|
|
bench_fhe_type_binary_op::<$fhe_type, _, _>(
|
|
|
|
|
bench_fhe_type_op::<$fhe_type, _, _>(
|
|
|
|
|
c,
|
|
|
|
|
cks,
|
|
|
|
|
stringify!($fhe_type),
|
|
|
|
|
@@ -231,77 +111,22 @@ macro_rules! bench_type_binary_op (
|
|
|
|
|
};
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
macro_rules! bench_type_unary_op (
|
|
|
|
|
(type_name: $fhe_type:ident, display_name: $display_name:literal, operation: $op:ident) => {
|
|
|
|
|
::paste::paste! {
|
|
|
|
|
fn [<bench_ $fhe_type:snake _ $op>](c: &mut Criterion, cks: &ClientKey) {
|
|
|
|
|
bench_fhe_type_unary_op::<$fhe_type, _, _>(
|
|
|
|
|
c,
|
|
|
|
|
cks,
|
|
|
|
|
stringify!($fhe_type),
|
|
|
|
|
$fhe_type::num_bits(),
|
|
|
|
|
$display_name,
|
|
|
|
|
stringify!($op),
|
|
|
|
|
|lhs| lhs.$op()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
macro_rules! bench_type_ternary_op (
|
|
|
|
|
(type_name: $fhe_type:ident, display_name: $display_name:literal, operation: $op:ident) => {
|
|
|
|
|
::paste::paste! {
|
|
|
|
|
fn [<bench_ $fhe_type:snake _ $op>](c: &mut Criterion, cks: &ClientKey) {
|
|
|
|
|
bench_fhe_type_ternary_op::<$fhe_type, _, _>(
|
|
|
|
|
c,
|
|
|
|
|
cks,
|
|
|
|
|
stringify!($fhe_type),
|
|
|
|
|
$fhe_type::num_bits(),
|
|
|
|
|
$display_name,
|
|
|
|
|
stringify!($op),
|
|
|
|
|
|cond, lhs, rhs| cond.$op(lhs, rhs)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
macro_rules! generate_typed_benches {
|
|
|
|
|
($fhe_type:ident) => {
|
|
|
|
|
// bench_type_binary_op!(type_name: $fhe_type, display_name: "sum", operation: sum);
|
|
|
|
|
// bench_type_unary_op!(type_name: $fhe_type, display_name: "bitnot", operation: bitnot);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "add", operation: add);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "bitand", operation: bitand);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "bitor", operation: bitor);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "bitxor", operation: bitxor);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "div", operation: div);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "div_rem", operation: div_rem);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "eq", operation: eq);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "ge", operation: ge);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "gt", operation: gt);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "le", operation: le);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "left_rotate", operation: rotate_left);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "left_shift", operation: shl);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "lt", operation: lt);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "max", operation: max);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "min", operation: min);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "mul", operation: mul);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "ne", operation: ne);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "overflowing_add", operation: overflowing_add);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "overflowing_sub", operation: overflowing_sub);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "rem", operation: rem);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "right_rotate", operation: rotate_right);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "right_shift", operation: shr);
|
|
|
|
|
bench_type_binary_op!(type_name: $fhe_type, display_name: "sub", operation: sub);
|
|
|
|
|
bench_type_ternary_op!(type_name: $fhe_type, display_name: "flip", operation: flip);
|
|
|
|
|
bench_type_ternary_op!(type_name: $fhe_type, display_name: "if_then_else", operation: if_then_else);
|
|
|
|
|
bench_type_unary_op!(type_name: $fhe_type, display_name: "leading_ones", operation: leading_ones);
|
|
|
|
|
bench_type_unary_op!(type_name: $fhe_type, display_name: "leading_zeros", operation: leading_zeros);
|
|
|
|
|
bench_type_unary_op!(type_name: $fhe_type, display_name: "neg", operation: neg);
|
|
|
|
|
bench_type_unary_op!(type_name: $fhe_type, display_name: "not", operation: not);
|
|
|
|
|
bench_type_unary_op!(type_name: $fhe_type, display_name: "trailing_ones", operation: trailing_ones);
|
|
|
|
|
bench_type_unary_op!(type_name: $fhe_type, display_name: "trailing_zeros", operation: trailing_zeros);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "add", operation: add);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "overflowing_add", operation: overflowing_add);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "sub", operation: sub);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "overflowing_sub", operation: overflowing_sub);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "mul", operation: mul);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "bitand", operation: bitand);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "bitor", operation: bitor);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "bitxor", operation: bitxor);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "left_shift", operation: shl);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "right_shift", operation: shr);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "left_rotate", operation: rotate_left);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "right_rotate", operation: rotate_right);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "min", operation: min);
|
|
|
|
|
bench_type_op!(type_name: $fhe_type, display_name: "max", operation: max);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -323,37 +148,19 @@ macro_rules! run_benches {
|
|
|
|
|
$(
|
|
|
|
|
::paste::paste! {
|
|
|
|
|
[<bench_ $fhe_type:snake _add>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _overflowing_add>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _sub>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _overflowing_sub>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _mul>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _bitand>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _bitor>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _bitxor>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _div>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _div_rem>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _eq>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _flip>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _ge>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _gt>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _if_then_else>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _le>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _leading_ones>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _leading_zeros>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _lt>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _max>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _min>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _mul>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _ne>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _neg>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _not>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _not>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _overflowing_add>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _overflowing_sub>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _rem>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _rotate_left>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _rotate_right>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _shl>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _shr>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _sub>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _trailing_ones>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _trailing_zeros>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _rotate_left>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _rotate_right>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _min>]($c, $cks);
|
|
|
|
|
[<bench_ $fhe_type:snake _max>]($c, $cks);
|
|
|
|
|
}
|
|
|
|
|
)+
|
|
|
|
|
};
|
|
|
|
|
|