From 3b9535ac2fe1f2abe680bac647345664c2110936 Mon Sep 17 00:00:00 2001 From: "Mayeul@Zama" Date: Mon, 3 Oct 2022 17:52:04 +0200 Subject: [PATCH] feat(cpp_interface): add Options struct --- .../src/concrete-optimizer.rs | 68 +++++++------------ .../src/cpp/concrete-optimizer.cpp | 34 +++++++--- .../src/cpp/concrete-optimizer.hpp | 18 ++++- concrete-optimizer-cpp/tests/src/main.cpp | 15 ++-- 4 files changed, 73 insertions(+), 62 deletions(-) diff --git a/concrete-optimizer-cpp/src/concrete-optimizer.rs b/concrete-optimizer-cpp/src/concrete-optimizer.rs index 440ee901c..477dcefd0 100644 --- a/concrete-optimizer-cpp/src/concrete-optimizer.rs +++ b/concrete-optimizer-cpp/src/concrete-optimizer.rs @@ -21,15 +21,10 @@ fn no_dag_solution() -> ffi::DagSolution { } } -fn optimize_bootstrap( - precision: u64, - security_level: u64, - noise_factor: f64, - maximum_acceptable_error_probability: f64, -) -> ffi::Solution { +fn optimize_bootstrap(precision: u64, noise_factor: f64, options: ffi::Options) -> ffi::Solution { let config = Config { - security_level, - maximum_acceptable_error_probability, + security_level: options.security_level, + maximum_acceptable_error_probability: options.maximum_acceptable_error_probability, ciphertext_modulus_log: 64, complexity_model: &CpuComplexity::default(), }; @@ -44,7 +39,7 @@ fn optimize_bootstrap( config, noise_factor, &search_space, - &decomposition::cache(security_level), + &decomposition::cache(options.security_level), ); result .best_solution @@ -203,14 +198,10 @@ impl OperationDag { .into() } - fn optimize_v0( - &self, - security_level: u64, - maximum_acceptable_error_probability: f64, - ) -> ffi::Solution { + fn optimize_v0(&self, options: ffi::Options) -> ffi::Solution { let config = Config { - security_level, - maximum_acceptable_error_probability, + security_level: options.security_level, + maximum_acceptable_error_probability: options.maximum_acceptable_error_probability, ciphertext_modulus_log: 64, complexity_model: &CpuComplexity::default(), }; @@ -221,34 +212,29 @@ impl OperationDag { &self.0, config, &search_space, - &decomposition::cache(security_level), + &decomposition::cache(options.security_level), ); result .best_solution .map_or_else(no_solution, |solution| solution.into()) } - fn optimize( - &self, - security_level: u64, - maximum_acceptable_error_probability: f64, - default_log_norm2_woppbs: f64, - ) -> ffi::DagSolution { + fn optimize(&self, options: ffi::Options) -> ffi::DagSolution { let config = Config { - security_level, - maximum_acceptable_error_probability, + security_level: options.security_level, + maximum_acceptable_error_probability: options.maximum_acceptable_error_probability, ciphertext_modulus_log: 64, complexity_model: &CpuComplexity::default(), }; let search_space = SearchSpace::default(); - let cache = decomposition::cache(security_level); + let cache = decomposition::cache(options.security_level); let result = concrete_optimizer::optimization::dag::solo_key::optimize_generic::optimize( &self.0, config, &search_space, - default_log_norm2_woppbs, + options.default_log_norm2_woppbs, &cache, ); result.map_or_else(no_dag_solution, |solution| solution.into()) @@ -286,12 +272,7 @@ mod ffi { extern "Rust" { #[namespace = "concrete_optimizer::v0"] - fn optimize_bootstrap( - precision: u64, - security_level: u64, - noise_factor: f64, - maximum_acceptable_error_probability: f64, - ) -> Solution; + fn optimize_bootstrap(precision: u64, noise_factor: f64, options: Options) -> Solution; #[namespace = "concrete_optimizer::utils"] fn convert_to_dag_solution(solution: &Solution) -> DagSolution; @@ -330,18 +311,9 @@ mod ffi { comment: &str, ) -> OperatorIndex; - fn optimize_v0( - self: &OperationDag, - security_level: u64, - maximum_acceptable_error_probability: f64, - ) -> Solution; + fn optimize_v0(self: &OperationDag, options: Options) -> Solution; - fn optimize( - self: &OperationDag, - security_level: u64, - maximum_acceptable_error_probability: f64, - default_log_norm2_woppbs: f64, - ) -> DagSolution; + fn optimize(self: &OperationDag, options: Options) -> DagSolution; fn dump(self: &OperationDag) -> String; @@ -393,4 +365,12 @@ mod ffi { pub cb_decomposition_base_log: u64, pub crt_decomposition: Vec, } + + #[namespace = "concrete_optimizer"] + #[derive(Debug, Clone, Copy, Default)] + pub struct Options { + pub security_level: u64, + pub maximum_acceptable_error_probability: f64, + pub default_log_norm2_woppbs: f64, + } } diff --git a/concrete-optimizer-cpp/src/cpp/concrete-optimizer.cpp b/concrete-optimizer-cpp/src/cpp/concrete-optimizer.cpp index e77f215f9..67987f2c6 100644 --- a/concrete-optimizer-cpp/src/cpp/concrete-optimizer.cpp +++ b/concrete-optimizer-cpp/src/cpp/concrete-optimizer.cpp @@ -941,6 +941,7 @@ union MaybeUninit { namespace concrete_optimizer { struct OperationDag; struct Weights; + struct Options; namespace dag { struct OperatorIndex; struct DagSolution; @@ -958,8 +959,8 @@ struct OperationDag final : public ::rust::Opaque { ::concrete_optimizer::dag::OperatorIndex add_lut(::concrete_optimizer::dag::OperatorIndex input, ::rust::Slice table, ::std::uint8_t out_precision) noexcept; ::concrete_optimizer::dag::OperatorIndex add_dot(::rust::Slice inputs, ::rust::Box<::concrete_optimizer::Weights> weights) noexcept; ::concrete_optimizer::dag::OperatorIndex add_levelled_op(::rust::Slice inputs, double lwe_dim_cost_factor, double fixed_cost, double manp, ::rust::Slice out_shape, ::rust::Str comment) noexcept; - ::concrete_optimizer::v0::Solution optimize_v0(::std::uint64_t security_level, double maximum_acceptable_error_probability) const noexcept; - ::concrete_optimizer::dag::DagSolution optimize(::std::uint64_t security_level, double maximum_acceptable_error_probability, double default_log_norm2_woppbs) const noexcept; + ::concrete_optimizer::v0::Solution optimize_v0(::concrete_optimizer::Options options) const noexcept; + ::concrete_optimizer::dag::DagSolution optimize(::concrete_optimizer::Options options) const noexcept; ::rust::String dump() const noexcept; ~OperationDag() = delete; @@ -1044,9 +1045,20 @@ struct DagSolution final { #endif // CXXBRIDGE1_STRUCT_concrete_optimizer$dag$DagSolution } // namespace dag +#ifndef CXXBRIDGE1_STRUCT_concrete_optimizer$Options +#define CXXBRIDGE1_STRUCT_concrete_optimizer$Options +struct Options final { + ::std::uint64_t security_level; + double maximum_acceptable_error_probability; + double default_log_norm2_woppbs; + + using IsRelocatable = ::std::true_type; +}; +#endif // CXXBRIDGE1_STRUCT_concrete_optimizer$Options + namespace v0 { extern "C" { -::concrete_optimizer::v0::Solution concrete_optimizer$v0$cxxbridge1$optimize_bootstrap(::std::uint64_t precision, ::std::uint64_t security_level, double noise_factor, double maximum_acceptable_error_probability) noexcept; +::concrete_optimizer::v0::Solution concrete_optimizer$v0$cxxbridge1$optimize_bootstrap(::std::uint64_t precision, double noise_factor, ::concrete_optimizer::Options options) noexcept; } // extern "C" } // namespace v0 @@ -1076,9 +1088,9 @@ extern "C" { ::concrete_optimizer::dag::OperatorIndex concrete_optimizer$cxxbridge1$OperationDag$add_levelled_op(::concrete_optimizer::OperationDag &self, ::rust::Slice inputs, double lwe_dim_cost_factor, double fixed_cost, double manp, ::rust::Slice out_shape, ::rust::Str comment) noexcept; -::concrete_optimizer::v0::Solution concrete_optimizer$cxxbridge1$OperationDag$optimize_v0(const ::concrete_optimizer::OperationDag &self, ::std::uint64_t security_level, double maximum_acceptable_error_probability) noexcept; +::concrete_optimizer::v0::Solution concrete_optimizer$cxxbridge1$OperationDag$optimize_v0(const ::concrete_optimizer::OperationDag &self, ::concrete_optimizer::Options options) noexcept; -void concrete_optimizer$cxxbridge1$OperationDag$optimize(const ::concrete_optimizer::OperationDag &self, ::std::uint64_t security_level, double maximum_acceptable_error_probability, double default_log_norm2_woppbs, ::concrete_optimizer::dag::DagSolution *return$) noexcept; +void concrete_optimizer$cxxbridge1$OperationDag$optimize(const ::concrete_optimizer::OperationDag &self, ::concrete_optimizer::Options options, ::concrete_optimizer::dag::DagSolution *return$) noexcept; void concrete_optimizer$cxxbridge1$OperationDag$dump(const ::concrete_optimizer::OperationDag &self, ::rust::String *return$) noexcept; ::std::size_t concrete_optimizer$cxxbridge1$Weights$operator$sizeof() noexcept; @@ -1092,8 +1104,8 @@ extern "C" { } // namespace weights namespace v0 { -::concrete_optimizer::v0::Solution optimize_bootstrap(::std::uint64_t precision, ::std::uint64_t security_level, double noise_factor, double maximum_acceptable_error_probability) noexcept { - return concrete_optimizer$v0$cxxbridge1$optimize_bootstrap(precision, security_level, noise_factor, maximum_acceptable_error_probability); +::concrete_optimizer::v0::Solution optimize_bootstrap(::std::uint64_t precision, double noise_factor, ::concrete_optimizer::Options options) noexcept { + return concrete_optimizer$v0$cxxbridge1$optimize_bootstrap(precision, noise_factor, options); } } // namespace v0 @@ -1135,13 +1147,13 @@ namespace dag { return concrete_optimizer$cxxbridge1$OperationDag$add_levelled_op(*this, inputs, lwe_dim_cost_factor, fixed_cost, manp, out_shape, comment); } -::concrete_optimizer::v0::Solution OperationDag::optimize_v0(::std::uint64_t security_level, double maximum_acceptable_error_probability) const noexcept { - return concrete_optimizer$cxxbridge1$OperationDag$optimize_v0(*this, security_level, maximum_acceptable_error_probability); +::concrete_optimizer::v0::Solution OperationDag::optimize_v0(::concrete_optimizer::Options options) const noexcept { + return concrete_optimizer$cxxbridge1$OperationDag$optimize_v0(*this, options); } -::concrete_optimizer::dag::DagSolution OperationDag::optimize(::std::uint64_t security_level, double maximum_acceptable_error_probability, double default_log_norm2_woppbs) const noexcept { +::concrete_optimizer::dag::DagSolution OperationDag::optimize(::concrete_optimizer::Options options) const noexcept { ::rust::MaybeUninit<::concrete_optimizer::dag::DagSolution> return$; - concrete_optimizer$cxxbridge1$OperationDag$optimize(*this, security_level, maximum_acceptable_error_probability, default_log_norm2_woppbs, &return$.value); + concrete_optimizer$cxxbridge1$OperationDag$optimize(*this, options, &return$.value); return ::std::move(return$.value); } diff --git a/concrete-optimizer-cpp/src/cpp/concrete-optimizer.hpp b/concrete-optimizer-cpp/src/cpp/concrete-optimizer.hpp index 478ff12cd..1d83a26fa 100644 --- a/concrete-optimizer-cpp/src/cpp/concrete-optimizer.hpp +++ b/concrete-optimizer-cpp/src/cpp/concrete-optimizer.hpp @@ -922,6 +922,7 @@ std::size_t align_of() { namespace concrete_optimizer { struct OperationDag; struct Weights; + struct Options; namespace dag { struct OperatorIndex; struct DagSolution; @@ -939,8 +940,8 @@ struct OperationDag final : public ::rust::Opaque { ::concrete_optimizer::dag::OperatorIndex add_lut(::concrete_optimizer::dag::OperatorIndex input, ::rust::Slice table, ::std::uint8_t out_precision) noexcept; ::concrete_optimizer::dag::OperatorIndex add_dot(::rust::Slice inputs, ::rust::Box<::concrete_optimizer::Weights> weights) noexcept; ::concrete_optimizer::dag::OperatorIndex add_levelled_op(::rust::Slice inputs, double lwe_dim_cost_factor, double fixed_cost, double manp, ::rust::Slice out_shape, ::rust::Str comment) noexcept; - ::concrete_optimizer::v0::Solution optimize_v0(::std::uint64_t security_level, double maximum_acceptable_error_probability) const noexcept; - ::concrete_optimizer::dag::DagSolution optimize(::std::uint64_t security_level, double maximum_acceptable_error_probability, double default_log_norm2_woppbs) const noexcept; + ::concrete_optimizer::v0::Solution optimize_v0(::concrete_optimizer::Options options) const noexcept; + ::concrete_optimizer::dag::DagSolution optimize(::concrete_optimizer::Options options) const noexcept; ::rust::String dump() const noexcept; ~OperationDag() = delete; @@ -1025,8 +1026,19 @@ struct DagSolution final { #endif // CXXBRIDGE1_STRUCT_concrete_optimizer$dag$DagSolution } // namespace dag +#ifndef CXXBRIDGE1_STRUCT_concrete_optimizer$Options +#define CXXBRIDGE1_STRUCT_concrete_optimizer$Options +struct Options final { + ::std::uint64_t security_level; + double maximum_acceptable_error_probability; + double default_log_norm2_woppbs; + + using IsRelocatable = ::std::true_type; +}; +#endif // CXXBRIDGE1_STRUCT_concrete_optimizer$Options + namespace v0 { -::concrete_optimizer::v0::Solution optimize_bootstrap(::std::uint64_t precision, ::std::uint64_t security_level, double noise_factor, double maximum_acceptable_error_probability) noexcept; +::concrete_optimizer::v0::Solution optimize_bootstrap(::std::uint64_t precision, double noise_factor, ::concrete_optimizer::Options options) noexcept; } // namespace v0 namespace utils { diff --git a/concrete-optimizer-cpp/tests/src/main.cpp b/concrete-optimizer-cpp/tests/src/main.cpp index b2d1ef971..d5b5eae84 100644 --- a/concrete-optimizer-cpp/tests/src/main.cpp +++ b/concrete-optimizer-cpp/tests/src/main.cpp @@ -17,10 +17,17 @@ const double PRECISION_16B = 16; const double WOP_FALLBACK_LOG_NORM = 8; const double NOISE_DEVIATION_COEFF = 1.0; +concrete_optimizer::Options default_options() { + concrete_optimizer::Options options; + options.security_level = SECURITY_128B; + options.maximum_acceptable_error_probability = P_ERROR; + return options; +} + void test_v0() { concrete_optimizer::v0::Solution solution = concrete_optimizer::v0::optimize_bootstrap( - PRECISION_1B, SECURITY_128B, NOISE_DEVIATION_COEFF, P_ERROR); + PRECISION_1B, NOISE_DEVIATION_COEFF, default_options()); assert(solution.glwe_polynomial_size == 1024); } @@ -43,7 +50,7 @@ void test_dag_no_lut() { concrete_optimizer::dag::OperatorIndex node2 = dag->add_dot(slice(inputs), std::move(weights)); - auto solution = dag->optimize_v0(SECURITY_128B, P_ERROR); + auto solution = dag->optimize_v0(default_options()); assert(solution.glwe_polynomial_size == 1024); } @@ -59,7 +66,7 @@ void test_dag_lut() { concrete_optimizer::dag::OperatorIndex node2 = dag->add_lut(input, slice(table), PRECISION_8B); - auto solution = dag->optimize(SECURITY_128B, P_ERROR, WOP_FALLBACK_LOG_NORM); + auto solution = dag->optimize(default_options()); assert(solution.glwe_dimension == 1); assert(solution.glwe_polynomial_size == 8192); assert(!solution.use_wop_pbs); @@ -77,7 +84,7 @@ void test_dag_lut_wop() { concrete_optimizer::dag::OperatorIndex node2 = dag->add_lut(input, slice(table), PRECISION_16B); - auto solution = dag->optimize(SECURITY_128B, P_ERROR, WOP_FALLBACK_LOG_NORM); + auto solution = dag->optimize(default_options()); assert(solution.glwe_dimension == 2); assert(solution.glwe_polynomial_size == 1024); assert(solution.use_wop_pbs);