diff --git a/concrete-optimizer/src/optimization/dag/solo_key/optimize_generic.rs b/concrete-optimizer/src/optimization/dag/solo_key/optimize_generic.rs index 4e5dcd830..7b4653125 100644 --- a/concrete-optimizer/src/optimization/dag/solo_key/optimize_generic.rs +++ b/concrete-optimizer/src/optimization/dag/solo_key/optimize_generic.rs @@ -1,3 +1,5 @@ +use std::ops::RangeInclusive; + use concrete_commons::numeric::UnsignedInteger; use crate::dag::operator::{Operator, Precision}; @@ -11,6 +13,7 @@ use crate::optimization::wop_atomic_pattern::Solution as WopSolution; const MINIMAL_WOP_PRECISION: Precision = 9; const MAXIMAL_WOP_PRECISION: Precision = 16; +const WOP_PRECISIONS: RangeInclusive = MINIMAL_WOP_PRECISION..=MAXIMAL_WOP_PRECISION; pub enum Solution { WpSolution(WpSolution), @@ -52,7 +55,26 @@ pub fn optimize( default_log_norm2_woppbs: f64, ) -> Option { let max_precision = max_precision(dag); - if max_precision < MINIMAL_WOP_PRECISION { + let nb_luts = analyze::lut_count_from_dag(dag); + let has_luts = nb_luts != 0; + if has_luts && WOP_PRECISIONS.contains(&max_precision) { + let nb_luts = analyze::lut_count_from_dag(dag); + let fallback_16b_precision = 16; + let default_log_norm = default_log_norm2_woppbs; + let worst_log_norm = analyze::worst_log_norm(dag); + let log_norm = default_log_norm.min(worst_log_norm); + let opt_sol = wop_optimize::( + fallback_16b_precision, + security_level, + log_norm, + maximum_acceptable_error_probability, + glwe_log_polynomial_sizes, + glwe_dimensions, + internal_lwe_dimensions, + ) + .best_solution; + opt_sol.map(|sol| Solution::WopSolution(updated_global_p_error(nb_luts, sol))) + } else { let opt_sol = optimize::optimize::( dag, security_level, @@ -63,23 +85,5 @@ pub fn optimize( ) .best_solution; opt_sol.map(Solution::WpSolution) - } else if max_precision > MAXIMAL_WOP_PRECISION { - None - } else { - let default_log_norm = default_log_norm2_woppbs; - let worst_log_norm = analyze::worst_log_norm(dag); - let nb_luts = analyze::lut_count_from_dag(dag); - let log_norm = default_log_norm.min(worst_log_norm); - let opt_sol = wop_optimize::( - max_precision as u64, - security_level, - log_norm, - maximum_acceptable_error_probability, - glwe_log_polynomial_sizes, - glwe_dimensions, - internal_lwe_dimensions, - ) - .best_solution; - opt_sol.map(|sol| Solution::WopSolution(updated_global_p_error(nb_luts, sol))) } }