diff --git a/tfhe/docs/guides/run_on_gpu.md b/tfhe/docs/guides/run_on_gpu.md index 3b8d12effd..8f041cb732 100644 --- a/tfhe/docs/guides/run_on_gpu.md +++ b/tfhe/docs/guides/run_on_gpu.md @@ -83,6 +83,13 @@ fn main() { } ``` +Beware that when the GPU feature is activated, when calling: +```rust +let config = ConfigBuilder::default().build(); +``` +the cryptographic parameters differ from the CPU ones, used when the GPU feature is not activated. +Indeed, TFHE-rs uses dedicated parameters for the GPU in order to achieve better performance. + ### Setting the keys The configuration of the key is different from the CPU. More precisely, if both client and server keys are still generated by the client (which is assumed to run on a CPU), the server key has then to be decompressed by the server to be converted into the right format. To do so, the server should run this function: `decompressed_to_gpu()`. @@ -128,50 +135,6 @@ Finally, the client decrypts the results using: let decrypted_result: u8 = result.decrypt(&client_key); ``` -### Improving performance - -**TFHE-rs** allows to leverage the high number of threads given by a GPU. To maximize the number of GPU threads, update your configuration accordingly: - -```Rust -let config = ConfigBuilder::with_custom_parameters(PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS).build(); -``` - -Here's the complete example: - -```rust -use tfhe::{ConfigBuilder, set_server_key, FheUint8, ClientKey, CompressedServerKey}; -use tfhe::prelude::*; -use tfhe::shortint::parameters::PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS; - -fn main() { - - let config = ConfigBuilder::with_custom_parameters(PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS).build(); - - let client_key= ClientKey::generate(config); - let compressed_server_key = CompressedServerKey::new(&client_key); - - let gpu_key = compressed_server_key.decompress_to_gpu(); - - let clear_a = 27u8; - let clear_b = 128u8; - - let a = FheUint8::encrypt(clear_a, &client_key); - let b = FheUint8::encrypt(clear_b, &client_key); - - //Server-side - - set_server_key(gpu_key); - let result = a + b; - - //Client-side - let decrypted_result: u8 = result.decrypt(&client_key); - - let clear_result = clear_a + clear_b; - - assert_eq!(decrypted_result, clear_result); -} -``` - ## List of available operations The GPU backend includes the following operations for both signed and unsigned encrypted integers: diff --git a/tfhe/src/high_level_api/config.rs b/tfhe/src/high_level_api/config.rs index a96e2a7946..1176a73797 100644 --- a/tfhe/src/high_level_api/config.rs +++ b/tfhe/src/high_level_api/config.rs @@ -24,6 +24,8 @@ impl Config { /// /// The configuration is needed to select parameters you wish to use for these types /// (whether it is the default parameters or some custom parameters). +/// The default parameters are specialized for GPU execution +/// in case the gpu feature is activated. #[derive(Clone)] pub struct ConfigBuilder { config: Config, @@ -43,6 +45,8 @@ impl ConfigBuilder { } /// Use default parameters with big encryption + /// The returned parameters are specialized for the GPU + /// in case the gpu feature is activated /// /// For more information see [crate::core_crypto::prelude::PBSOrder::KeyswitchBootstrap] pub fn default_with_big_encryption() -> Self { diff --git a/tfhe/src/high_level_api/keys/inner.rs b/tfhe/src/high_level_api/keys/inner.rs index 0057c5a8b1..3855f98666 100644 --- a/tfhe/src/high_level_api/keys/inner.rs +++ b/tfhe/src/high_level_api/keys/inner.rs @@ -43,8 +43,14 @@ impl IntegerConfig { } pub(in crate::high_level_api) fn default_big() -> Self { + #[cfg(not(feature = "gpu"))] + let params = crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS.into(); + #[cfg(feature = "gpu")] + let params = + crate::shortint::parameters::PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS + .into(); Self { - block_parameters: crate::shortint::parameters::PARAM_MESSAGE_2_CARRY_2_KS_PBS.into(), + block_parameters: params, dedicated_compact_public_key_parameters: None, compression_parameters: None, }