diff --git a/.github/workflows/aws_tfhe_gpu_tests.yml b/.github/workflows/aws_tfhe_gpu_tests.yml index 31d8486042..2bd165172b 100644 --- a/.github/workflows/aws_tfhe_gpu_tests.yml +++ b/.github/workflows/aws_tfhe_gpu_tests.yml @@ -112,6 +112,9 @@ jobs: run: | make test_c_api_gpu + - name: Run High Level API Tests + run: | + make test_high_level_api_gpu - name: Slack Notification if: ${{ always() }} diff --git a/Makefile b/Makefile index ffa8fde238..07e1247414 100644 --- a/Makefile +++ b/Makefile @@ -533,6 +533,11 @@ test_high_level_api: install_rs_build_toolchain --features=$(TARGET_ARCH_FEATURE),boolean,shortint,integer,internal-keycache -p $(TFHE_SPEC) \ -- high_level_api:: +test_high_level_api_gpu: install_rs_build_toolchain + RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) nextest run --cargo-profile $(CARGO_PROFILE) \ + --features=$(TARGET_ARCH_FEATURE),integer,internal-keycache,gpu -p $(TFHE_SPEC) \ + -E "test(/high_level_api::.*gpu.*/)" + .PHONY: test_user_doc # Run tests from the .md documentation test_user_doc: install_rs_build_toolchain RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) --doc \ diff --git a/tfhe/src/high_level_api/booleans/base.rs b/tfhe/src/high_level_api/booleans/base.rs index e719b63896..5c8f86bf68 100644 --- a/tfhe/src/high_level_api/booleans/base.rs +++ b/tfhe/src/high_level_api/booleans/base.rs @@ -325,15 +325,13 @@ impl FheEq for FheBool { InnerBoolean::Cpu(BooleanBlock::new_unchecked(inner)) } #[cfg(feature = "gpu")] - InternalServerKey::Cuda(_) => { - // with_thread_local_cuda_stream(|stream| { - // let inner = - // cuda_key - // .key - // .scalar_eq(&self.ciphertext.on_gpu(), u8::from(other), - // stream); InnerBoolean::Cuda(inner) - todo!() - } + InternalServerKey::Cuda(cuda_key) => with_thread_local_cuda_stream(|stream| { + let inner = + cuda_key + .key + .scalar_eq(&self.ciphertext.on_gpu(), u8::from(other), stream); + InnerBoolean::Cuda(inner) + }), }); Self::new(ciphertext) } @@ -366,15 +364,13 @@ impl FheEq for FheBool { InnerBoolean::Cpu(BooleanBlock::new_unchecked(inner)) } #[cfg(feature = "gpu")] - InternalServerKey::Cuda(_) => { - // with_thread_local_cuda_stream(|stream| { - // let inner = - // cuda_key - // .key - // .scalar_ne(&self.ciphertext.on_gpu(), u8::from(other), - // stream); InnerBoolean::Cuda(inner) - todo!() - } + InternalServerKey::Cuda(cuda_key) => with_thread_local_cuda_stream(|stream| { + let inner = + cuda_key + .key + .scalar_ne(&self.ciphertext.on_gpu(), u8::from(other), stream); + InnerBoolean::Cuda(inner) + }), }); Self::new(ciphertext) } diff --git a/tfhe/src/high_level_api/booleans/compact.rs b/tfhe/src/high_level_api/booleans/compact.rs index be77218cec..b0957302a2 100644 --- a/tfhe/src/high_level_api/booleans/compact.rs +++ b/tfhe/src/high_level_api/booleans/compact.rs @@ -48,7 +48,9 @@ impl CompactFheBool { assert_eq!(ct.blocks.len(), 1); let mut block = BooleanBlock::new_unchecked(ct.blocks.into_iter().next().unwrap()); block.0.degree = Degree::new(1); - FheBool::new(block) + let mut ciphertext = FheBool::new(block); + ciphertext.ciphertext.move_to_device_of_server_key_if_set(); + ciphertext } } @@ -131,7 +133,9 @@ impl CompactFheBoolList { assert_eq!(ct.blocks.len(), 1); let mut block = BooleanBlock::new_unchecked(ct.blocks.into_iter().next().unwrap()); block.0.degree = Degree::new(1); - FheBool::new(block) + let mut ciphertext = FheBool::new(block); + ciphertext.ciphertext.move_to_device_of_server_key_if_set(); + ciphertext }) .collect::>() } diff --git a/tfhe/src/high_level_api/booleans/compressed.rs b/tfhe/src/high_level_api/booleans/compressed.rs index baa2d00d12..20cde67f3b 100644 --- a/tfhe/src/high_level_api/booleans/compressed.rs +++ b/tfhe/src/high_level_api/booleans/compressed.rs @@ -43,9 +43,11 @@ impl CompressedFheBool { /// /// See [CompressedFheBool] example. pub fn decompress(&self) -> FheBool { - FheBool::new(BooleanBlock::new_unchecked( + let mut ciphertext = FheBool::new(BooleanBlock::new_unchecked( self.ciphertext.clone().decompress(), - )) + )); + ciphertext.ciphertext.move_to_device_of_server_key_if_set(); + ciphertext } } diff --git a/tfhe/src/high_level_api/booleans/tests.rs b/tfhe/src/high_level_api/booleans/tests.rs index 765fefa92c..feff3b8929 100644 --- a/tfhe/src/high_level_api/booleans/tests.rs +++ b/tfhe/src/high_level_api/booleans/tests.rs @@ -352,75 +352,6 @@ fn compact_bool_list_test_case(setup_fn: impl FnOnce() -> (ClientKey, Device)) { } } -#[cfg(feature = "gpu")] -mod gpu { - use super::*; - use crate::Device; - - fn setup_gpu_default() -> ClientKey { - let config = ConfigBuilder::default().build(); - let cks = ClientKey::generate(config); - let csks = crate::CompressedServerKey::new(&cks); - - let server_keys = csks.decompress_to_gpu(); - - set_server_key(server_keys); - cks - } - - #[test] - fn test_xor_truth_table_static_default() { - let keys = setup_gpu_default(); - - let ttrue = FheBool::encrypt(true, &keys); - let ffalse = FheBool::encrypt(false, &keys); - - assert_eq!(ttrue.current_device(), Device::CudaGpu); - assert_eq!(ffalse.current_device(), Device::CudaGpu); - - xor_truth_table(&ttrue, &ffalse, &keys); - } - - #[test] - fn test_and_truth_table_static_default() { - let keys = setup_gpu_default(); - - let ttrue = FheBool::encrypt(true, &keys); - let ffalse = FheBool::encrypt(false, &keys); - - assert_eq!(ttrue.current_device(), Device::CudaGpu); - assert_eq!(ffalse.current_device(), Device::CudaGpu); - - and_truth_table(&ttrue, &ffalse, &keys); - } - - #[test] - fn test_or_truth_table_static_default() { - let keys = setup_gpu_default(); - - let ttrue = FheBool::encrypt(true, &keys); - let ffalse = FheBool::encrypt(false, &keys); - - assert_eq!(ttrue.current_device(), Device::CudaGpu); - assert_eq!(ffalse.current_device(), Device::CudaGpu); - - or_truth_table(&ttrue, &ffalse, &keys); - } - - #[test] - fn test_not_truth_table_static_default() { - let keys = setup_gpu_default(); - - let ttrue = FheBool::encrypt(true, &keys); - let ffalse = FheBool::encrypt(false, &keys); - - assert_eq!(ttrue.current_device(), Device::CudaGpu); - assert_eq!(ffalse.current_device(), Device::CudaGpu); - - not_truth_table(&ttrue, &ffalse, &keys); - } -} - mod cpu { use super::*; use crate::Device; @@ -784,3 +715,320 @@ mod cpu { assert_eq!(clear, true); } } + +#[cfg(feature = "gpu")] +mod gpu { + use super::*; + + fn setup_gpu_default() -> ClientKey { + let config = ConfigBuilder::default().build(); + let cks = crate::ClientKey::generate(config); + let csks = crate::CompressedServerKey::new(&cks); + + let server_keys = csks.decompress_to_gpu(); + + set_server_key(server_keys); + cks + } + + #[test] + fn test_xor_truth_table_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt(true, &keys); + let ffalse = FheBool::encrypt(false, &keys); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + xor_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_scalar_xor_truth_table_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt(true, &keys); + let ffalse = FheBool::encrypt(false, &keys); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + scalar_xor_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_xor_truth_table_trivial_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt_trivial(true); + let ffalse = FheBool::encrypt_trivial(false); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + xor_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_scalar_xor_truth_table_trivial_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt_trivial(true); + let ffalse = FheBool::encrypt_trivial(false); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + scalar_xor_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_and_truth_table_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt(true, &keys); + let ffalse = FheBool::encrypt(false, &keys); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + and_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_scalar_and_truth_table_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt(true, &keys); + let ffalse = FheBool::encrypt(false, &keys); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + scalar_and_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_and_truth_table_trivial_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt_trivial(true); + let ffalse = FheBool::encrypt_trivial(false); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + and_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_scalar_and_truth_table_trivial_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt_trivial(true); + let ffalse = FheBool::encrypt_trivial(false); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + scalar_and_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_or_truth_table_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt(true, &keys); + let ffalse = FheBool::encrypt(false, &keys); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + or_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_scalar_or_truth_table_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt(true, &keys); + let ffalse = FheBool::encrypt(false, &keys); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + scalar_or_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_or_truth_table_trivial_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt_trivial(true); + let ffalse = FheBool::encrypt_trivial(false); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + or_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_scalar_or_truth_table_trivial_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt_trivial(true); + let ffalse = FheBool::encrypt_trivial(false); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + scalar_or_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_not_truth_table_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt(true, &keys); + let ffalse = FheBool::encrypt(false, &keys); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + not_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_not_truth_table_trivial_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt_trivial(true); + let ffalse = FheBool::encrypt_trivial(false); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + not_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_eq_truth_table_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt(true, &keys); + let ffalse = FheBool::encrypt(false, &keys); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + eq_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_scalar_eq_truth_table_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt(true, &keys); + let ffalse = FheBool::encrypt(false, &keys); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + scalar_eq_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_eq_truth_table_trivial_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt_trivial(true); + let ffalse = FheBool::encrypt_trivial(false); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + eq_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_scalar_eq_truth_table_trivial_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt_trivial(true); + let ffalse = FheBool::encrypt_trivial(false); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + scalar_eq_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_ne_truth_table_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt(true, &keys); + let ffalse = FheBool::encrypt(false, &keys); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + ne_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_scalar_ne_truth_table_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt(true, &keys); + let ffalse = FheBool::encrypt(false, &keys); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + scalar_ne_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_ne_truth_table_trivial_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt_trivial(true); + let ffalse = FheBool::encrypt_trivial(false); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + ne_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_scalar_ne_truth_table_trivial_default() { + let keys = setup_gpu_default(); + + let ttrue = FheBool::encrypt_trivial(true); + let ffalse = FheBool::encrypt_trivial(false); + + assert_eq!(ttrue.current_device(), Device::CudaGpu); + assert_eq!(ffalse.current_device(), Device::CudaGpu); + + scalar_ne_truth_table(&ttrue, &ffalse, &keys); + } + + #[test] + fn test_compressed_bool() { + compressed_bool_test_case(|| (setup_gpu_default(), Device::CudaGpu)); + } + + #[test] + fn test_compact_bool() { + compact_bool_test_case(|| (setup_gpu_default(), Device::CudaGpu)); + } + + #[test] + fn test_compact_bool_list() { + compact_bool_list_test_case(|| (setup_gpu_default(), Device::CudaGpu)); + } +}