diff --git a/compiler/concrete-optimizer b/compiler/concrete-optimizer index b446d3124..9c4fc43ae 160000 --- a/compiler/concrete-optimizer +++ b/compiler/concrete-optimizer @@ -1 +1 @@ -Subproject commit b446d3124d89e0e5783df947770ecec19e7a6582 +Subproject commit 9c4fc43ae9267206b9551060f04bb60d6fdd780f diff --git a/compiler/include/concretelang/Support/V0Parameters.h b/compiler/include/concretelang/Support/V0Parameters.h index 865411574..fcbce79ac 100644 --- a/compiler/include/concretelang/Support/V0Parameters.h +++ b/compiler/include/concretelang/Support/V0Parameters.h @@ -17,18 +17,22 @@ namespace concretelang { namespace optimizer { constexpr double P_ERROR_4_SIGMA = 1.0 - 0.999936657516; constexpr uint DEFAULT_SECURITY = 128; +constexpr uint DEFAULT_FALLBACK_LOG_NORM_WOPPBS = 8; struct Config { double p_error; bool display; bool strategy_v0; std::uint64_t security; + double fallback_log_norm_woppbs; }; constexpr Config DEFAULT_CONFIG = {P_ERROR_4_SIGMA, false, false, - DEFAULT_SECURITY}; + DEFAULT_SECURITY, + DEFAULT_FALLBACK_LOG_NORM_WOPPBS}; using Dag = rust::Box; using Solution = concrete_optimizer::v0::Solution; +using DagSolution = concrete_optimizer::dag::DagSolution; /* Contains any circuit description usable by the concrete-optimizer */ struct Description { diff --git a/compiler/lib/Dialect/FHE/Analysis/ConcreteOptimizer.cpp b/compiler/lib/Dialect/FHE/Analysis/ConcreteOptimizer.cpp index 727aa70c5..98c638e32 100644 --- a/compiler/lib/Dialect/FHE/Analysis/ConcreteOptimizer.cpp +++ b/compiler/lib/Dialect/FHE/Analysis/ConcreteOptimizer.cpp @@ -295,11 +295,6 @@ struct DagPass : ConcreteOptimizerBase { mlir::func::FuncOp func = getOperation(); auto name = std::string(func.getName()); DEBUG("ConcreteOptimizer Dag: " << name); - if (config.strategy_v0) { - // we avoid building the dag since it's not used in this case - // so strategy_v0 can be used to avoid dag creation issues - dags.insert(optimizer::FunctionsDag::value_type(name, llvm::None)); - } auto dag = FunctionToDag(func, config).build(); if (dag) { dags.insert( diff --git a/compiler/lib/Support/V0Parameters.cpp b/compiler/lib/Support/V0Parameters.cpp index 92bf183ab..90c4fecd9 100644 --- a/compiler/lib/Support/V0Parameters.cpp +++ b/compiler/lib/Support/V0Parameters.cpp @@ -22,23 +22,26 @@ namespace mlir { namespace concretelang { -optimizer::Solution getV0Parameter(V0FHEConstraint constraint, - optimizer::Config config) { +optimizer::DagSolution getV0Parameter(V0FHEConstraint constraint, + optimizer::Config config) { // the norm2 0 is equivalent to a maximum noise_factor of 2.0 // norm2 = 0 ==> 1.0 =< noise_factor < 2.0 // norm2 = k ==> 2^norm2 =< noise_factor < 2.0^norm2 + 1 double noise_factor = std::exp2(constraint.norm2 + 1); - return concrete_optimizer::v0::optimize_bootstrap( + auto solution = concrete_optimizer::v0::optimize_bootstrap( constraint.p, config.security, noise_factor, config.p_error); + return concrete_optimizer::utils::convert_to_dag_solution(solution); } -optimizer::Solution getV1Parameter(optimizer::Dag &dag, - optimizer::Config config) { - return dag->optimize_v0(config.security, config.p_error); +optimizer::DagSolution getV1Parameter(optimizer::Dag &dag, + optimizer::Config config) { + return dag->optimize(config.security, config.p_error, + config.fallback_log_norm_woppbs); } static void display(V0FHEConstraint constraint, - optimizer::Config optimizerConfig, optimizer::Solution sol, + optimizer::Config optimizerConfig, + optimizer::DagSolution sol, std::chrono::milliseconds duration) { if (!optimizerConfig.display && !mlir::concretelang::isVerbose()) { return; @@ -46,17 +49,17 @@ static void display(V0FHEConstraint constraint, auto o = llvm::outs; o() << "--- Circuit\n" << " " << constraint.p << " bits integers\n" - << constraint.norm2 << " manp (maxi log2 norm2)\n" - + << " " << constraint.norm2 << " manp (maxi log2 norm2)\n" + << " " << duration.count() << "ms to solve\n" << "--- Optimizer config\n" << " " << optimizerConfig.p_error << " error per pbs call\n" - - << "--- For each Pbs call\n" + << "--- Complexity for each Pbs call\n" << " " << (long)sol.complexity / (1000 * 1000) << " Millions Operations\n" + << "--- Correctness for each Pbs call\n" << " 1/" << int(1.0 / sol.p_error) << " errors (" << sol.p_error << ")\n" - << "--- Parameters resolution\n" + << " " << sol.glwe_dimension << "x glwe_dimension\n" << " 2**" << (size_t)std::log2l(sol.glwe_polynomial_size) << " polynomial (" << sol.glwe_polynomial_size << ")\n" << " " << sol.internal_ks_output_lwe_dimension << " lwe dimension \n" @@ -64,25 +67,23 @@ static void display(V0FHEConstraint constraint, << sol.ks_decomposition_base_log << "\n" << " blindrota l,b=" << sol.br_decomposition_level_count << "," << sol.br_decomposition_base_log << "\n" - << " " << sol.noise_max << " variance max\n" - << " " << duration.count() << "ms to solve\n" - << "---\n"; + << " wopPbs : " << (sol.use_wop_pbs ? "true" : "false") << "\n"; + if (sol.use_wop_pbs) { + o() << " |cb_decomp l,b=" << sol.cb_decomposition_level_count << "," + << sol.cb_decomposition_base_log << "\n"; + } + o() << "---\n"; } llvm::Optional getParameter(optimizer::Description &descr, optimizer::Config config) { namespace chrono = std::chrono; auto start = chrono::high_resolution_clock::now(); - auto sol = (!descr.dag || config.strategy_v0) ? getV0Parameter(descr.constraint, config) : getV1Parameter(descr.dag.getValue(), config); auto stop = chrono::high_resolution_clock::now(); - if (sol.p_error == 1.0) { - // The optimizer return a p_error = 1 if there is no solution - return llvm::None; - } auto duration = chrono::duration_cast(stop - start); auto duration_s = chrono::duration_cast(duration); if (duration_s.count() > 3) { @@ -91,6 +92,17 @@ llvm::Optional getParameter(optimizer::Description &descr, display(descr.constraint, config, sol, duration); + if (sol.p_error == 1.0) { + // The optimizer return a p_error = 1 if there is no solution + return llvm::None; + } + + if (sol.use_wop_pbs) { + llvm::errs() + << "WARNING: a woppbs solution exists but woppbs is not available\n"; + return llvm::None; + } + return mlir::concretelang::V0Parameter{ sol.glwe_dimension, (size_t)std::log2l(sol.glwe_polynomial_size), diff --git a/compiler/src/main.cpp b/compiler/src/main.cpp index 52d7cbc4f..2e97abe7b 100644 --- a/compiler/src/main.cpp +++ b/compiler/src/main.cpp @@ -192,6 +192,13 @@ llvm::cl::opt llvm::cl::desc("Select the v0 parameters strategy"), llvm::cl::init(false)); +llvm::cl::opt fallbackLogNormWoppbs( + "optimizer-fallback-log-norm-woppbs", + llvm::cl::desc("Select a fallback value for multisum log norm in woppbs " + "when the precise value can't be computed."), + llvm::cl::init(mlir::concretelang::optimizer::DEFAULT_CONFIG + .fallback_log_norm_woppbs)); + llvm::cl::list fhelinalgTileSizes( "fhelinalg-tile-sizes", llvm::cl::desc(