feat(optimizer): connect to new entry point supporting woppbs

This commit is contained in:
rudy
2022-06-22 16:08:07 +02:00
committed by Quentin Bourgerie
parent 73fbb20f6b
commit f3933aeddc
5 changed files with 45 additions and 27 deletions

View File

@@ -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<concrete_optimizer::OperationDag>;
using Solution = concrete_optimizer::v0::Solution;
using DagSolution = concrete_optimizer::dag::DagSolution;
/* Contains any circuit description usable by the concrete-optimizer */
struct Description {

View File

@@ -295,11 +295,6 @@ struct DagPass : ConcreteOptimizerBase<DagPass> {
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(

View File

@@ -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<V0Parameter> 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<chrono::milliseconds>(stop - start);
auto duration_s = chrono::duration_cast<chrono::seconds>(duration);
if (duration_s.count() > 3) {
@@ -91,6 +92,17 @@ llvm::Optional<V0Parameter> 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),

View File

@@ -192,6 +192,13 @@ llvm::cl::opt<bool>
llvm::cl::desc("Select the v0 parameters strategy"),
llvm::cl::init(false));
llvm::cl::opt<double> 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<int64_t> fhelinalgTileSizes(
"fhelinalg-tile-sizes",
llvm::cl::desc(