diff --git a/compiler/include/concretelang/Support/CompilerEngine.h b/compiler/include/concretelang/Support/CompilerEngine.h index c29cf07eb..54e243100 100644 --- a/compiler/include/concretelang/Support/CompilerEngine.h +++ b/compiler/include/concretelang/Support/CompilerEngine.h @@ -45,6 +45,7 @@ struct CompilationOptions { bool autoParallelize; bool loopParallelize; bool dataflowParallelize; + bool optimizeConcrete; llvm::Optional> fhelinalgTileSizes; llvm::Optional clientParametersFuncName; @@ -54,7 +55,8 @@ struct CompilationOptions { CompilationOptions() : v0FHEConstraints(llvm::None), verifyDiagnostics(false), autoParallelize(false), loopParallelize(false), - dataflowParallelize(false), clientParametersFuncName(llvm::None), + dataflowParallelize(false), optimizeConcrete(true), + clientParametersFuncName(llvm::None), optimizerConfig(optimizer::DEFAULT_CONFIG){}; CompilationOptions(std::string funcname) : CompilationOptions() { diff --git a/compiler/lib/Bindings/Python/CompilerAPIModule.cpp b/compiler/lib/Bindings/Python/CompilerAPIModule.cpp index 8280542c5..417b56e69 100644 --- a/compiler/lib/Bindings/Python/CompilerAPIModule.cpp +++ b/compiler/lib/Bindings/Python/CompilerAPIModule.cpp @@ -52,6 +52,10 @@ void mlir::concretelang::python::populateCompilerAPISubmodule( [](CompilationOptions &options, bool b) { options.dataflowParallelize = b; }) + .def("set_optimize_concrete", + [](CompilationOptions &options, bool b) { + options.optimizeConcrete = b; + }) .def("set_p_error", [](CompilationOptions &options, double p_error) { options.optimizerConfig.p_error = p_error; diff --git a/compiler/lib/Bindings/Python/concrete/compiler/compilation_options.py b/compiler/lib/Bindings/Python/concrete/compiler/compilation_options.py index 9b0281f7e..b866af923 100644 --- a/compiler/lib/Bindings/Python/concrete/compiler/compilation_options.py +++ b/compiler/lib/Bindings/Python/concrete/compiler/compilation_options.py @@ -108,6 +108,19 @@ class CompilationOptions(WrapperCpp): raise TypeError("can't set the option to a non-boolean value") self.cpp().set_dataflow_parallelize(dataflow_parallelize) + def set_optimize_concrete(self, optimize: bool): + """Set flag to enable/disable optimization of concrete intermediate representation. + + Args: + optimize (bool): whether to turn it on or off + + Raises: + TypeError: if the value to set is not boolean + """ + if not isinstance(optimize, bool): + raise TypeError("can't set the option to a non-boolean value") + self.cpp().set_optimize_concrete(optimize) + def set_funcname(self, funcname: str): """Set entrypoint function name. diff --git a/compiler/lib/Support/CompilerEngine.cpp b/compiler/lib/Support/CompilerEngine.cpp index 4a632caed..8c37e3f07 100644 --- a/compiler/lib/Support/CompilerEngine.cpp +++ b/compiler/lib/Support/CompilerEngine.cpp @@ -248,7 +248,8 @@ CompilerEngine::compile(llvm::SourceMgr &sm, Target target, OptionalLib lib) { } // Optimizing Concrete - if (mlir::concretelang::pipeline::optimizeConcrete(mlirContext, module, + if (this->compilerOptions.optimizeConcrete && + mlir::concretelang::pipeline::optimizeConcrete(mlirContext, module, this->enablePass) .failed()) { return errorDiag("Optimizing Concrete failed"); @@ -288,13 +289,6 @@ CompilerEngine::compile(llvm::SourceMgr &sm, Target target, OptionalLib lib) { } } - // Optimize Concrete - if (mlir::concretelang::pipeline::optimizeConcrete(mlirContext, module, - this->enablePass) - .failed()) { - return StreamStringError("Optimizing Concrete failed"); - } - // Concrete -> BConcrete if (mlir::concretelang::pipeline::lowerConcreteToBConcrete( mlirContext, module, this->enablePass, loopParallelize) diff --git a/compiler/src/main.cpp b/compiler/src/main.cpp index ef64bbd2b..b584bff33 100644 --- a/compiler/src/main.cpp +++ b/compiler/src/main.cpp @@ -91,6 +91,12 @@ llvm::cl::opt output("o", llvm::cl::opt verbose("verbose", llvm::cl::desc("verbose logs"), llvm::cl::init(false)); +llvm::cl::opt + optimizeConcrete("optimize-concrete", + llvm::cl::desc("enable/disable optimizations of concrete " + "dialects. (Enabled by default)"), + llvm::cl::init(true)); + llvm::cl::list passes( "passes", llvm::cl::desc("Specify the passes to run (use only for compiler tests)"), @@ -220,6 +226,7 @@ mlir::concretelang::CompilationOptions cmdlineCompilationOptions() { options.autoParallelize = cmdline::autoParallelize; options.loopParallelize = cmdline::loopParallelize; options.dataflowParallelize = cmdline::dataflowParallelize; + options.optimizeConcrete = cmdline::optimizeConcrete; if (cmdline::assumeMaxEintPrecision.hasValue() && cmdline::assumeMaxMANP.hasValue()) { diff --git a/compiler/tests/Dialect/Concrete/Concrete/no_optimization.mlir b/compiler/tests/Dialect/Concrete/Concrete/no_optimization.mlir new file mode 100644 index 000000000..4b8a8ca2e --- /dev/null +++ b/compiler/tests/Dialect/Concrete/Concrete/no_optimization.mlir @@ -0,0 +1,14 @@ +// RUN: concretecompiler --optimize-concrete=false --action=dump-concrete %s 2>&1| FileCheck %s + +// CHECK-LABEL: func @mul_cleartext_lwe_ciphertext_0(%arg0: !Concrete.lwe_ciphertext<2048,7>) -> !Concrete.lwe_ciphertext<2048,7> +func @mul_cleartext_lwe_ciphertext_0(%arg0: !Concrete.lwe_ciphertext<2048,7>) -> !Concrete.lwe_ciphertext<2048,7> { + // CHECK-NEXT: %[[V0:.*]] = arith.constant 0 : i7 + // CHECK-NEXT: %[[V1:.*]] = "Concrete.int_to_cleartext"(%[[V0]]) : (i7) -> !Concrete.cleartext<7> + // CHECK-NEXT: %[[V2:.*]] = "Concrete.mul_cleartext_lwe_ciphertext"(%arg0, %[[V1]]) : (!Concrete.lwe_ciphertext<2048,7>, !Concrete.cleartext<7>) -> !Concrete.lwe_ciphertext<2048,7> + // CHECK-NEXT: return %[[V2]] : !Concrete.lwe_ciphertext<2048,7> + + %0 = arith.constant 0 : i7 + %1 = "Concrete.int_to_cleartext"(%0) : (i7) -> !Concrete.cleartext<7> + %2 = "Concrete.mul_cleartext_lwe_ciphertext"(%arg0, %1): (!Concrete.lwe_ciphertext<2048,7>, !Concrete.cleartext<7>) -> (!Concrete.lwe_ciphertext<2048,7>) + return %2: !Concrete.lwe_ciphertext<2048,7> +}