Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion tfhe/src/high_level_api/array/cpu/booleans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::high_level_api::array::{ArrayBackend, BackendDataContainer, BackendDa
use crate::high_level_api::global_state;
use crate::integer::BooleanBlock;
use crate::prelude::{FheDecrypt, FheTryEncrypt};
use crate::{ClientKey, FheId};
use crate::{ClientKey, FheBool, FheId, Tag};
use rayon::prelude::*;
use std::ops::RangeBounds;

Expand Down Expand Up @@ -36,6 +36,28 @@ impl ArrayBackend for CpuFheBoolArrayBackend {
type Owned = Vec<BooleanBlock>;
}

impl From<Vec<FheBool>> for CpuFheBoolArray {
fn from(value: Vec<FheBool>) -> Self {
let vec = value
.into_iter()
.map(|b| BooleanBlock::new_unchecked(b.into_raw_parts()))
.collect::<Vec<_>>();

let shape = vec![vec.len()];
Self::new(vec, shape)
}
}

impl From<CpuFheBoolArray> for Vec<FheBool> {
fn from(value: CpuFheBoolArray) -> Self {
value
.into_container()
.into_iter()
.map(|boolean_block| FheBool::new(boolean_block, Tag::default()))
.collect()
}
}

impl BackendDataContainer for &[BooleanBlock] {
type Backend = CpuFheBoolArrayBackend;

Expand Down
44 changes: 43 additions & 1 deletion tfhe/src/high_level_api/array/cpu/integers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::integer::server_key::radix_parallel::scalar_div_mod::SignedReciprocab
use crate::integer::server_key::{Reciprocable, ScalarMultiplier};
use crate::integer::{IntegerRadixCiphertext, RadixCiphertext, SignedRadixCiphertext};
use crate::prelude::{FheDecrypt, FheTryEncrypt};
use crate::{ClientKey, Error};
use crate::{ClientKey, Error, FheInt, FheUint, Tag};
use rayon::prelude::*;
use std::marker::PhantomData;
use std::ops::RangeBounds;
Expand Down Expand Up @@ -54,6 +54,48 @@ where
type Owned = Vec<T>;
}

impl<Id: FheUintId> From<Vec<FheUint<Id>>> for CpuFheUintArray<Id> {
fn from(value: Vec<FheUint<Id>>) -> Self {
let vec: Vec<_> = value
.into_iter()
.map(|uint| uint.into_raw_parts().0)
.collect();
let shape = vec![vec.len()];
Self::new(vec, shape)
}
}

impl<Id: FheUintId> From<CpuFheUintArray<Id>> for Vec<FheUint<Id>> {
fn from(value: CpuFheUintArray<Id>) -> Self {
value
.into_container()
.into_iter()
.map(|radix| FheUint::new(radix, Tag::default()))
.collect()
}
}

impl<Id: FheIntId> From<Vec<FheInt<Id>>> for CpuFheIntArray<Id> {
fn from(value: Vec<FheInt<Id>>) -> Self {
let vec: Vec<_> = value
.into_iter()
.map(|uint| uint.into_raw_parts().0)
.collect();
let shape = vec![vec.len()];
Self::new(vec, shape)
}
}

impl<Id: FheIntId> From<CpuFheIntArray<Id>> for Vec<FheInt<Id>> {
fn from(value: CpuFheIntArray<Id>) -> Self {
value
.into_container()
.into_iter()
.map(|radix| FheInt::new(radix, Tag::default()))
.collect()
}
}

#[inline]
#[track_caller]
fn par_map_sks_op_on_pair_of_elements<'a, T, F>(
Expand Down
39 changes: 38 additions & 1 deletion tfhe/src/high_level_api/array/dynamic/booleans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use super::super::{FheBackendArray, FheBackendArraySlice, FheBackendArraySliceMu
use crate::array::traits::TensorSlice;
use crate::integer::BooleanBlock;
use crate::prelude::{FheDecrypt, FheTryEncrypt};
use crate::{ClientKey, Device};
use crate::{ClientKey, CpuFheBoolArray, Device, FheBool};
use std::borrow::{Borrow, Cow};
use std::ops::RangeBounds;

Expand All @@ -33,6 +33,43 @@ impl ArrayBackend for DynFheBoolArrayBackend {
type Owned = InnerBoolArray;
}

impl TryFrom<Vec<FheBool>> for FheBoolArray {
type Error = crate::Error;

fn try_from(values: Vec<FheBool>) -> Result<Self, Self::Error> {
if values.is_empty() {
return Ok(Self::new(InnerBoolArray::Cpu(vec![]), vec![0]));
}

let shape = vec![values.len()];
let device_of_first = values[0].current_device();
let inner = match device_of_first {
Device::Cpu => {
let new_values = values
.into_iter()
.map(|value| value.ciphertext.into_cpu())
.collect::<Vec<_>>();

InnerBoolArray::Cpu(new_values)
}
#[cfg(feature = "gpu")]
Device::CudaGpu => return Err(crate::error!("Array do not support GPU")),
#[cfg(feature = "hpu")]
Device::Hpu => return Err(crate::error!("Array do not support HPU")),
};

Ok(Self::new(inner, shape))
}
}

impl From<CpuFheBoolArray> for FheBoolArray {
fn from(cpu_array: CpuFheBoolArray) -> Self {
let CpuFheBoolArray { elems, dims, _id } = cpu_array;

Self::new(InnerBoolArray::Cpu(elems), dims)
}
}

impl BitwiseArrayBackend for DynFheBoolArrayBackend {
fn bitand<'a>(
lhs: TensorSlice<'_, Self::Slice<'a>>,
Expand Down
27 changes: 26 additions & 1 deletion tfhe/src/high_level_api/array/gpu/booleans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::high_level_api::array::{ArrayBackend, BackendDataContainer, BackendDa
use crate::high_level_api::global_state;
use crate::integer::gpu::ciphertext::boolean_value::CudaBooleanBlock;
use crate::prelude::{FheDecrypt, FheTryEncrypt};
use crate::{ClientKey, FheBoolId};
use crate::{ClientKey, FheBool, FheBoolId, Tag};
use rayon::prelude::*;
use std::ops::RangeBounds;

Expand Down Expand Up @@ -72,6 +72,31 @@ impl From<Vec<CudaBooleanBlock>> for GpuBooleanOwned {
}
}

impl From<Vec<FheBool>> for GpuFheBoolArray {
fn from(value: Vec<FheBool>) -> Self {
let container = with_cuda_internal_keys(|cuda_keys| {
value
.into_iter()
.map(|val| val.ciphertext.into_gpu(&cuda_keys.streams))
.collect::<Vec<_>>()
});

let shape = vec![container.len()];
Self::new(container, shape)
}
}

impl From<GpuFheBoolArray> for Vec<FheBool> {
fn from(value: GpuFheBoolArray) -> Self {
value
.into_container()
.0
.into_iter()
.map(|cuda_bool_block| FheBool::new(cuda_bool_block, Tag::default()))
.collect()
}
}

impl BackendDataContainer for GpuBooleanSlice<'_> {
type Backend = GpuFheBoolArrayBackend;

Expand Down
50 changes: 49 additions & 1 deletion tfhe/src/high_level_api/array/gpu/integers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::integer::gpu::ciphertext::{
use crate::integer::server_key::radix_parallel::scalar_div_mod::SignedReciprocable;
use crate::integer::server_key::{Reciprocable, ScalarMultiplier};
use crate::prelude::{CastInto, FheDecrypt, FheTryEncrypt};
use crate::{ClientKey, Error};
use crate::{ClientKey, Error, FheInt, FheUint, Tag};
use rayon::prelude::*;
use std::marker::PhantomData;
use std::ops::RangeBounds;
Expand Down Expand Up @@ -60,6 +60,54 @@ where
}
}

impl<Id: FheUintId> From<Vec<FheUint<Id>>> for GpuFheUintArray<Id> {
fn from(value: Vec<FheUint<Id>>) -> Self {
let container = with_cuda_internal_keys(|cuda_keys| {
value
.into_iter()
.map(|elem| elem.ciphertext.into_gpu(&cuda_keys.streams))
.collect::<Vec<_>>()
});
let shape = vec![container.len()];
Self::new(container, shape)
}
}

impl<Id: FheUintId> From<GpuFheUintArray<Id>> for Vec<FheUint<Id>> {
fn from(value: GpuFheUintArray<Id>) -> Self {
value
.into_container()
.0
.into_iter()
.map(|elem| FheUint::new(elem, Tag::default()))
.collect()
}
}

impl<Id: FheIntId> From<Vec<FheInt<Id>>> for GpuFheIntArray<Id> {
fn from(value: Vec<FheInt<Id>>) -> Self {
let container = with_cuda_internal_keys(|cuda_keys| {
value
.into_iter()
.map(|elem| elem.ciphertext.into_gpu(&cuda_keys.streams))
.collect::<Vec<_>>()
});
let shape = vec![container.len()];
Self::new(container, shape)
}
}

impl<Id: FheIntId> From<GpuFheIntArray<Id>> for Vec<FheInt<Id>> {
fn from(value: GpuFheIntArray<Id>) -> Self {
value
.into_container()
.0
.into_iter()
.map(|elem| FheInt::new(elem, Tag::default()))
.collect()
}
}

impl<T> ArrayBackend for GpuIntegerArrayBackend<T>
where
T: CudaIntegerRadixCiphertext,
Expand Down
Loading
Loading