pub(crate) mod test_add;
pub(crate) mod test_aes;
pub(crate) mod test_aes256;
pub(crate) mod test_bitwise_op;
pub(crate) mod test_cmux;
pub(crate) mod test_comparison;
pub(crate) mod test_div_mod;
pub(crate) mod test_ilog2;
pub(crate) mod test_kreyvium;
pub(crate) mod test_mul;
pub(crate) mod test_neg;
pub(crate) mod test_oprf;
pub(crate) mod test_rotate;
pub(crate) mod test_scalar_add;
pub(crate) mod test_scalar_bitwise_op;
pub(crate) mod test_scalar_comparison;
pub(crate) mod test_scalar_div_mod;
pub(crate) mod test_scalar_mul;
pub(crate) mod test_scalar_rotate;
pub(crate) mod test_scalar_shift;
pub(crate) mod test_scalar_sub;
pub(crate) mod test_shift;
pub(crate) mod test_sub;
pub(crate) mod test_trivium;
pub(crate) mod test_vector_comparisons;
pub(crate) mod test_vector_find;
use crate::core_crypto::gpu::CudaStreams;
use crate::integer::gpu::ciphertext::boolean_value::CudaBooleanBlock;
use crate::integer::gpu::ciphertext::CudaUnsignedRadixCiphertext;
use crate::integer::gpu::{CudaOprfServerKey, CudaServerKey};
use crate::integer::server_key::radix_parallel::tests_cases_unsigned::*;
pub use crate::integer::server_key::radix_parallel::MatchValues;
use crate::integer::{BooleanBlock, RadixCiphertext, RadixClientKey, ServerKey, U256};
use std::sync::Arc;
macro_rules! create_gpu_parameterized_test{
($name:ident { $($param:ident),* $(,)? }) => {
::paste::paste! {
$(
#[test]
fn [<test_gpu_ $name _ $param:lower>]() {
$name($param)
}
)*
}
};
($name:ident)=> {
create_gpu_parameterized_test!($name
{
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
TEST_PARAM_GPU_MULTI_BIT_GROUP_4_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
});
};
}
macro_rules! create_gpu_parameterized_stringified_test{
($name:ident { $($param:ident),* $(,)? }) => {
::paste::paste! {
$(
#[test]
fn [<test_gpu_ $name _ $param:lower>]() {
$name($param, stringify!($param))
}
)*
}
};
}
use crate::integer::gpu::server_key::radix::tests_signed::GpuMultiDeviceFunctionExecutor;
use tfhe_csprng::seeders::Seed;
pub(crate) use {create_gpu_parameterized_stringified_test, create_gpu_parameterized_test};
pub(crate) struct GpuContext {
pub(crate) streams: CudaStreams,
pub(crate) sks: CudaServerKey,
pub(crate) oprf_key: Option<CudaOprfServerKey>,
}
pub(crate) struct GpuFunctionExecutor<F> {
pub(crate) context: Option<GpuContext>,
pub(crate) func: F,
}
impl<F> GpuFunctionExecutor<F> {
pub(crate) fn new(func: F) -> Self {
Self {
context: None,
func,
}
}
}
impl<F> GpuFunctionExecutor<F> {
pub(crate) fn setup_from_keys(&mut self, cks: &RadixClientKey, _sks: &Arc<ServerKey>) {
let streams = CudaStreams::new_multi_gpu();
let sks = CudaServerKey::new(cks.as_ref(), &streams);
streams.synchronize();
let context = GpuContext {
streams,
sks,
oprf_key: None,
};
self.context = Some(context);
}
}
impl<'a, F>
FunctionExecutor<
(&'a RadixCiphertext, &'a RadixCiphertext, usize),
crate::Result<RadixCiphertext>,
> for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
usize,
&CudaStreams,
) -> crate::Result<CudaUnsignedRadixCiphertext>,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a RadixCiphertext, &'a RadixCiphertext, usize),
) -> crate::Result<RadixCiphertext> {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let gpu_result = (self.func)(
&context.sks,
&d_ctxt_1,
&d_ctxt_2,
input.2,
&context.streams,
)?;
Ok(gpu_result.to_radix_ciphertext(&context.streams))
}
}
impl<'a, F>
FunctionExecutor<
(&'a RadixCiphertext, &'a RadixCiphertext, u128, usize, usize),
RadixCiphertext,
> for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
u128,
usize,
usize,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a RadixCiphertext, &'a RadixCiphertext, u128, usize, usize),
) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let gpu_result = (self.func)(
&context.sks,
&d_ctxt_1,
&d_ctxt_2,
input.2,
input.3,
input.4,
&context.streams,
);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F>
FunctionExecutor<(&'a RadixCiphertext, &'a RadixCiphertext, u128, usize), RadixCiphertext>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
u128,
usize,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a RadixCiphertext, &'a RadixCiphertext, u128, usize),
) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let gpu_result = (self.func)(
&context.sks,
&d_ctxt_1,
&d_ctxt_2,
input.2,
input.3,
&context.streams,
);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, &'a RadixCiphertext), RadixCiphertext>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, &'a RadixCiphertext)) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let gpu_result = (self.func)(&context.sks, &d_ctxt_1, &d_ctxt_2, &context.streams);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a mut RadixCiphertext, &'a RadixCiphertext), ()>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&mut CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a mut RadixCiphertext, &'a RadixCiphertext)) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let mut d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
(self.func)(&context.sks, &mut d_ctxt_1, &d_ctxt_2, &context.streams);
*input.0 = d_ctxt_1.to_radix_ciphertext(&context.streams);
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, u64), RadixCiphertext> for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
u64,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, u64)) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let gpu_result = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<F> FunctionExecutor<(RadixCiphertext, u64), RadixCiphertext> for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
u64,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (RadixCiphertext, u64)) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(&input.0, &context.streams);
let gpu_result = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F> FunctionExecutor<&'a RadixCiphertext, RadixCiphertext> for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: &'a RadixCiphertext) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1 = CudaUnsignedRadixCiphertext::from_radix_ciphertext(input, &context.streams);
let gpu_result = (self.func)(&context.sks, &d_ctxt_1, &context.streams);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F> FunctionExecutor<&'a mut RadixCiphertext, ()> for GpuFunctionExecutor<F>
where
F: Fn(&CudaServerKey, &mut CudaUnsignedRadixCiphertext, &CudaStreams),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: &'a mut RadixCiphertext) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let mut d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input, &context.streams);
(self.func)(&context.sks, &mut d_ctxt_1, &context.streams);
*input = d_ctxt_1.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F> FunctionExecutor<&'a Vec<RadixCiphertext>, Option<RadixCiphertext>>
for GpuFunctionExecutor<F>
where
F: Fn(&CudaServerKey, Vec<CudaUnsignedRadixCiphertext>) -> Option<CudaUnsignedRadixCiphertext>,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: &'a Vec<RadixCiphertext>) -> Option<RadixCiphertext> {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: Vec<CudaUnsignedRadixCiphertext> = input
.iter()
.map(|ct| CudaUnsignedRadixCiphertext::from_radix_ciphertext(ct, &context.streams))
.collect();
let d_res = (self.func)(&context.sks, d_ctxt_1);
Some(d_res.unwrap().to_radix_ciphertext(&context.streams))
}
}
impl<'a, F>
FunctionExecutor<(&'a RadixCiphertext, &'a RadixCiphertext), (RadixCiphertext, BooleanBlock)>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaBooleanBlock),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a RadixCiphertext, &'a RadixCiphertext),
) -> (RadixCiphertext, BooleanBlock) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, &d_ctxt_2, &context.streams);
(
d_res.0.to_radix_ciphertext(&context.streams),
d_res.1.to_boolean_block(&context.streams),
)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, u64), (RadixCiphertext, BooleanBlock)>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
u64,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaBooleanBlock),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, u64)) -> (RadixCiphertext, BooleanBlock) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
(
d_res.0.to_radix_ciphertext(&context.streams),
d_res.1.to_boolean_block(&context.streams),
)
}
}
impl<'a, F> FunctionExecutor<&'a RadixCiphertext, (RadixCiphertext, BooleanBlock)>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaBooleanBlock),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: &'a RadixCiphertext) -> (RadixCiphertext, BooleanBlock) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, &context.streams);
(
d_res.0.to_radix_ciphertext(&context.streams),
d_res.1.to_boolean_block(&context.streams),
)
}
}
impl<'a, F>
FunctionExecutor<(&'a RadixCiphertext, &'a RadixCiphertext), (RadixCiphertext, RadixCiphertext)>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaUnsignedRadixCiphertext),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a RadixCiphertext, &'a RadixCiphertext),
) -> (RadixCiphertext, RadixCiphertext) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, &d_ctxt_2, &context.streams);
(
d_res.0.to_radix_ciphertext(&context.streams),
d_res.1.to_radix_ciphertext(&context.streams),
)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, u64), (RadixCiphertext, RadixCiphertext)>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
u64,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaUnsignedRadixCiphertext),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, u64)) -> (RadixCiphertext, RadixCiphertext) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
(
d_res.0.to_radix_ciphertext(&context.streams),
d_res.1.to_radix_ciphertext(&context.streams),
)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, &'a RadixCiphertext), BooleanBlock>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> CudaBooleanBlock,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, &'a RadixCiphertext)) -> BooleanBlock {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, &d_ctxt_2, &context.streams);
d_res.to_boolean_block(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, u64), BooleanBlock> for GpuFunctionExecutor<F>
where
F: Fn(&CudaServerKey, &CudaUnsignedRadixCiphertext, u64, &CudaStreams) -> CudaBooleanBlock,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, u64)) -> BooleanBlock {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
d_res.to_boolean_block(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, U256), BooleanBlock> for GpuFunctionExecutor<F>
where
F: Fn(&CudaServerKey, &CudaUnsignedRadixCiphertext, U256, &CudaStreams) -> CudaBooleanBlock,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, U256)) -> BooleanBlock {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
d_res.to_boolean_block(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, U256), RadixCiphertext>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
U256,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, U256)) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
d_res.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F>
FunctionExecutor<(&'a BooleanBlock, &'a RadixCiphertext, &'a RadixCiphertext), RadixCiphertext>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaBooleanBlock,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a BooleanBlock, &'a RadixCiphertext, &'a RadixCiphertext),
) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaBooleanBlock =
CudaBooleanBlock::from_boolean_block(input.0, &context.streams);
let d_ctxt_2: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let d_ctxt_3: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.2, &context.streams);
let d_res = (self.func)(
&context.sks,
&d_ctxt_1,
&d_ctxt_2,
&d_ctxt_3,
&context.streams,
);
d_res.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F>
FunctionExecutor<(&'a RadixCiphertext, &'a MatchValues<u64>), (RadixCiphertext, BooleanBlock)>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&MatchValues<u64>,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaBooleanBlock),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a RadixCiphertext, &'a MatchValues<u64>),
) -> (RadixCiphertext, BooleanBlock) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let (d_res, d_block) = (self.func)(&context.sks, &d_ctxt, input.1, &context.streams);
let res = d_res.to_radix_ciphertext(&context.streams);
let block = d_block.to_boolean_block(&context.streams);
(res, block)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, &'a MatchValues<u64>, u64), RadixCiphertext>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&MatchValues<u64>,
u64,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a RadixCiphertext, &'a MatchValues<u64>, u64),
) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt, input.1, input.2, &context.streams);
d_res.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, &'a [u64]), BooleanBlock>
for GpuFunctionExecutor<F>
where
F: Fn(&CudaServerKey, &CudaUnsignedRadixCiphertext, &[u64], &CudaStreams) -> CudaBooleanBlock,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, &'a [u64])) -> BooleanBlock {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_block = (self.func)(&context.sks, &d_ctxt, input.1, &context.streams);
d_block.to_boolean_block(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a [RadixCiphertext], &'a RadixCiphertext), BooleanBlock>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&[CudaUnsignedRadixCiphertext],
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> CudaBooleanBlock,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a [RadixCiphertext], &'a RadixCiphertext)) -> BooleanBlock {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let mut d_ctxs = Vec::<CudaUnsignedRadixCiphertext>::with_capacity(input.0.len());
for ctx in input.0 {
d_ctxs.push(CudaUnsignedRadixCiphertext::from_radix_ciphertext(
ctx,
&context.streams,
));
}
let d_ctxt2: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let d_block = (self.func)(&context.sks, &d_ctxs, &d_ctxt2, &context.streams);
d_block.to_boolean_block(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a [RadixCiphertext], u64), BooleanBlock> for GpuFunctionExecutor<F>
where
F: Fn(&CudaServerKey, &[CudaUnsignedRadixCiphertext], u64, &CudaStreams) -> CudaBooleanBlock,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a [RadixCiphertext], u64)) -> BooleanBlock {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let mut d_ctxs = Vec::<CudaUnsignedRadixCiphertext>::with_capacity(input.0.len());
for ctx in input.0 {
d_ctxs.push(CudaUnsignedRadixCiphertext::from_radix_ciphertext(
ctx,
&context.streams,
));
}
let d_block = (self.func)(&context.sks, &d_ctxs, input.1, &context.streams);
d_block.to_boolean_block(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, &'a [u64]), (RadixCiphertext, BooleanBlock)>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&[u64],
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaBooleanBlock),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a RadixCiphertext, &'a [u64]),
) -> (RadixCiphertext, BooleanBlock) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let (d_res, d_block) = (self.func)(&context.sks, &d_ctxt, input.1, &context.streams);
let res = d_res.to_radix_ciphertext(&context.streams);
let block = d_block.to_boolean_block(&context.streams);
(res, block)
}
}
impl<'a, F>
FunctionExecutor<(&'a [RadixCiphertext], &'a RadixCiphertext), (RadixCiphertext, BooleanBlock)>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&[CudaUnsignedRadixCiphertext],
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaBooleanBlock),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a [RadixCiphertext], &'a RadixCiphertext),
) -> (RadixCiphertext, BooleanBlock) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let mut d_ctxs = Vec::<CudaUnsignedRadixCiphertext>::with_capacity(input.0.len());
for ctx in input.0 {
d_ctxs.push(CudaUnsignedRadixCiphertext::from_radix_ciphertext(
ctx,
&context.streams,
));
}
let d_ctxt2: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let (d_res, d_block) = (self.func)(&context.sks, &d_ctxs, &d_ctxt2, &context.streams);
let res = d_res.to_radix_ciphertext(&context.streams);
let block = d_block.to_boolean_block(&context.streams);
(res, block)
}
}
impl<'a, F> FunctionExecutor<(&'a [RadixCiphertext], u64), (RadixCiphertext, BooleanBlock)>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&[CudaUnsignedRadixCiphertext],
u64,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaBooleanBlock),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a [RadixCiphertext], u64)) -> (RadixCiphertext, BooleanBlock) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let mut d_ctxs = Vec::<CudaUnsignedRadixCiphertext>::with_capacity(input.0.len());
for ctx in input.0 {
d_ctxs.push(CudaUnsignedRadixCiphertext::from_radix_ciphertext(
ctx,
&context.streams,
));
}
let (d_res, d_block) = (self.func)(&context.sks, &d_ctxs, input.1, &context.streams);
let res = d_res.to_radix_ciphertext(&context.streams);
let block = d_block.to_boolean_block(&context.streams);
(res, block)
}
}
impl<'a, F> FunctionExecutor<(&'a [RadixCiphertext], &'a [RadixCiphertext]), BooleanBlock>
for GpuFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&[CudaUnsignedRadixCiphertext],
&[CudaUnsignedRadixCiphertext],
&CudaStreams,
) -> CudaBooleanBlock,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a [RadixCiphertext], &'a [RadixCiphertext])) -> BooleanBlock {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let mut d_ctxs1 = Vec::<CudaUnsignedRadixCiphertext>::with_capacity(input.0.len());
for ctx in input.0 {
d_ctxs1.push(CudaUnsignedRadixCiphertext::from_radix_ciphertext(
ctx,
&context.streams,
));
}
let mut d_ctxs2 = Vec::<CudaUnsignedRadixCiphertext>::with_capacity(input.0.len());
for ctx in input.1 {
d_ctxs2.push(CudaUnsignedRadixCiphertext::from_radix_ciphertext(
ctx,
&context.streams,
));
}
let d_block = (self.func)(&context.sks, &d_ctxs1, &d_ctxs2, &context.streams);
d_block.to_boolean_block(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, &'a RadixCiphertext), RadixCiphertext>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, &'a RadixCiphertext)) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let gpu_result = (self.func)(&context.sks, &d_ctxt_1, &d_ctxt_2, &context.streams);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a mut RadixCiphertext, &'a RadixCiphertext), ()>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&mut CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a mut RadixCiphertext, &'a RadixCiphertext)) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let mut d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
(self.func)(&context.sks, &mut d_ctxt_1, &d_ctxt_2, &context.streams);
*input.0 = d_ctxt_1.to_radix_ciphertext(&context.streams);
}
}
impl<F> FunctionExecutor<(Seed, u64, u64, u64), RadixCiphertext>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(&CudaServerKey, Seed, u64, u64, u64, &CudaStreams) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (Seed, u64, u64, u64)) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let gpu_result = (self.func)(
&context.sks,
input.0,
input.1,
input.2,
input.3,
&context.streams,
);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<F> FunctionExecutor<(Seed, u64, u64), RadixCiphertext> for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(&CudaServerKey, Seed, u64, u64, &CudaStreams) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (Seed, u64, u64)) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let gpu_result = (self.func)(&context.sks, input.0, input.1, input.2, &context.streams);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<F> FunctionExecutor<(Seed, u64), RadixCiphertext> for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(&CudaServerKey, Seed, u64, &CudaStreams) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (Seed, u64)) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let gpu_result = (self.func)(&context.sks, input.0, input.1, &context.streams);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, u64), RadixCiphertext>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
u64,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, u64)) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let gpu_result = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<F> FunctionExecutor<(RadixCiphertext, u64), RadixCiphertext>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
u64,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (RadixCiphertext, u64)) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(&input.0, &context.streams);
let gpu_result = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F> FunctionExecutor<&'a RadixCiphertext, RadixCiphertext>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: &'a RadixCiphertext) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1 = CudaUnsignedRadixCiphertext::from_radix_ciphertext(input, &context.streams);
let gpu_result = (self.func)(&context.sks, &d_ctxt_1, &context.streams);
gpu_result.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F> FunctionExecutor<&'a mut RadixCiphertext, ()> for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(&CudaServerKey, &mut CudaUnsignedRadixCiphertext, &CudaStreams),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: &'a mut RadixCiphertext) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let mut d_ctxt_1 =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input, &context.streams);
(self.func)(&context.sks, &mut d_ctxt_1, &context.streams);
*input = d_ctxt_1.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F> FunctionExecutor<&'a Vec<RadixCiphertext>, Option<RadixCiphertext>>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(&CudaServerKey, Vec<CudaUnsignedRadixCiphertext>) -> Option<CudaUnsignedRadixCiphertext>,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: &'a Vec<RadixCiphertext>) -> Option<RadixCiphertext> {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: Vec<CudaUnsignedRadixCiphertext> = input
.iter()
.map(|ct| CudaUnsignedRadixCiphertext::from_radix_ciphertext(ct, &context.streams))
.collect();
let d_res = (self.func)(&context.sks, d_ctxt_1);
Some(d_res.unwrap().to_radix_ciphertext(&context.streams))
}
}
impl<'a, F>
FunctionExecutor<(&'a RadixCiphertext, &'a RadixCiphertext), (RadixCiphertext, BooleanBlock)>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaBooleanBlock),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a RadixCiphertext, &'a RadixCiphertext),
) -> (RadixCiphertext, BooleanBlock) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, &d_ctxt_2, &context.streams);
(
d_res.0.to_radix_ciphertext(&context.streams),
d_res.1.to_boolean_block(&context.streams),
)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, u64), (RadixCiphertext, BooleanBlock)>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
u64,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaBooleanBlock),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, u64)) -> (RadixCiphertext, BooleanBlock) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
(
d_res.0.to_radix_ciphertext(&context.streams),
d_res.1.to_boolean_block(&context.streams),
)
}
}
impl<'a, F> FunctionExecutor<&'a RadixCiphertext, (RadixCiphertext, BooleanBlock)>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaBooleanBlock),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: &'a RadixCiphertext) -> (RadixCiphertext, BooleanBlock) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, &context.streams);
(
d_res.0.to_radix_ciphertext(&context.streams),
d_res.1.to_boolean_block(&context.streams),
)
}
}
impl<'a, F>
FunctionExecutor<(&'a RadixCiphertext, &'a RadixCiphertext), (RadixCiphertext, RadixCiphertext)>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaUnsignedRadixCiphertext),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a RadixCiphertext, &'a RadixCiphertext),
) -> (RadixCiphertext, RadixCiphertext) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, &d_ctxt_2, &context.streams);
(
d_res.0.to_radix_ciphertext(&context.streams),
d_res.1.to_radix_ciphertext(&context.streams),
)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, u64), (RadixCiphertext, RadixCiphertext)>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
u64,
&CudaStreams,
) -> (CudaUnsignedRadixCiphertext, CudaUnsignedRadixCiphertext),
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, u64)) -> (RadixCiphertext, RadixCiphertext) {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
(
d_res.0.to_radix_ciphertext(&context.streams),
d_res.1.to_radix_ciphertext(&context.streams),
)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, &'a RadixCiphertext), BooleanBlock>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> CudaBooleanBlock,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, &'a RadixCiphertext)) -> BooleanBlock {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_ctxt_2: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, &d_ctxt_2, &context.streams);
d_res.to_boolean_block(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, u64), BooleanBlock>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(&CudaServerKey, &CudaUnsignedRadixCiphertext, u64, &CudaStreams) -> CudaBooleanBlock,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, u64)) -> BooleanBlock {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
d_res.to_boolean_block(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, U256), BooleanBlock>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(&CudaServerKey, &CudaUnsignedRadixCiphertext, U256, &CudaStreams) -> CudaBooleanBlock,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, U256)) -> BooleanBlock {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
d_res.to_boolean_block(&context.streams)
}
}
impl<'a, F> FunctionExecutor<(&'a RadixCiphertext, U256), RadixCiphertext>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaUnsignedRadixCiphertext,
U256,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(&mut self, input: (&'a RadixCiphertext, U256)) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.0, &context.streams);
let d_res = (self.func)(&context.sks, &d_ctxt_1, input.1, &context.streams);
d_res.to_radix_ciphertext(&context.streams)
}
}
impl<'a, F>
FunctionExecutor<(&'a BooleanBlock, &'a RadixCiphertext, &'a RadixCiphertext), RadixCiphertext>
for GpuMultiDeviceFunctionExecutor<F>
where
F: Fn(
&CudaServerKey,
&CudaBooleanBlock,
&CudaUnsignedRadixCiphertext,
&CudaUnsignedRadixCiphertext,
&CudaStreams,
) -> CudaUnsignedRadixCiphertext,
{
fn setup(&mut self, cks: &RadixClientKey, sks: Arc<ServerKey>) {
self.setup_from_keys(cks, &sks);
}
fn execute(
&mut self,
input: (&'a BooleanBlock, &'a RadixCiphertext, &'a RadixCiphertext),
) -> RadixCiphertext {
let context = self
.context
.as_ref()
.expect("setup was not properly called");
let d_ctxt_1: CudaBooleanBlock =
CudaBooleanBlock::from_boolean_block(input.0, &context.streams);
let d_ctxt_2: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.1, &context.streams);
let d_ctxt_3: CudaUnsignedRadixCiphertext =
CudaUnsignedRadixCiphertext::from_radix_ciphertext(input.2, &context.streams);
let d_res = (self.func)(
&context.sks,
&d_ctxt_1,
&d_ctxt_2,
&d_ctxt_3,
&context.streams,
);
d_res.to_radix_ciphertext(&context.streams)
}
}