feat(compiler): Determine FHE circuit constraints instead of using default values

This replaces the default FHE circuit constrains (maximum encrypted
integer width of 7 bits and a Minimal Arithmetic Noise Padding of 10
with the results of the `MaxMANP` pass, which determines these values
automatically from the input program.

Since the maximum encrypted integer width and the maximum value for
the Minimal Arithmetic Noise Padding can only be derived from HLFHE
operations, the circuit constraints are determined automatically by
`zamacompiler` only if the option `--entry-dialect=hlfhe` was
specified.

For lower-level dialects, `zamacompiler` has been provided with the
options `--assume-max-eint-precision=...` and `--assume-max-manp=...`
that allow a user to specify the values for the maximum required
precision and maximum values for the Minimal Arithmetic Noise Padding.
This commit is contained in:
Andi Drebes
2021-09-24 23:43:41 +02:00
committed by Quentin Bourgerie
parent 2ed1720234
commit 2acfa63eb7
12 changed files with 250 additions and 59 deletions

View File

@@ -31,23 +31,55 @@ std::string CompilerEngine::getCompiledModule() {
return os.str();
}
llvm::Error CompilerEngine::compile(std::string mlirStr) {
llvm::Error CompilerEngine::compile(
std::string mlirStr,
llvm::Optional<mlir::zamalang::V0FHEConstraint> overrideConstraints) {
module_ref = mlir::parseSourceString(mlirStr, context);
if (!module_ref) {
return llvm::make_error<llvm::StringError>("mlir parsing failed",
llvm::inconvertibleErrorCode());
}
mlir::zamalang::V0FHEConstraint defaultGlobalFHECircuitConstraint{.norm2 = 10,
.p = 7};
const mlir::zamalang::V0Parameter *parameter =
getV0Parameter(defaultGlobalFHECircuitConstraint);
mlir::zamalang::V0FHEContext fheContext{defaultGlobalFHECircuitConstraint,
*parameter};
mlir::ModuleOp module = module_ref.get();
llvm::Optional<mlir::zamalang::V0FHEConstraint> fheConstraintsOpt =
overrideConstraints;
if (!fheConstraintsOpt.hasValue()) {
llvm::Expected<llvm::Optional<mlir::zamalang::V0FHEConstraint>>
fheConstraintsOrErr =
mlir::zamalang::pipeline::getFHEConstraintsFromHLFHE(*context,
module);
if (auto err = fheConstraintsOrErr.takeError())
return std::move(err);
if (!fheConstraintsOrErr.get().hasValue()) {
return llvm::make_error<llvm::StringError>(
"Could not determine maximum required precision for encrypted "
"integers "
"and maximum value for the Minimal Arithmetic Noise Padding",
llvm::inconvertibleErrorCode());
}
fheConstraintsOpt = fheConstraintsOrErr.get();
}
mlir::zamalang::V0FHEConstraint fheConstraints = fheConstraintsOpt.getValue();
const mlir::zamalang::V0Parameter *parameter = getV0Parameter(fheConstraints);
if (!parameter) {
std::string buffer;
llvm::raw_string_ostream strs(buffer);
strs << "Could not determine V0 parameters for 2-norm of "
<< fheConstraints.norm2 << " and p of " << fheConstraints.p;
return llvm::make_error<llvm::StringError>(strs.str(),
llvm::inconvertibleErrorCode());
}
mlir::zamalang::V0FHEContext fheContext{fheConstraints, *parameter};
// Lower to MLIR Std
if (mlir::zamalang::pipeline::lowerHLFHEToStd(*context, module, fheContext,
false)