refactor: remove BConcrete dialect

- no more Concrete ciphertext/plaintext types: they are represented using standard MLIR types (int/tensor)
- Technically BConcrete was renamed to Concrete, and old Concrete was
  removed
- TFHE -> Concrete now takes into account the conversion of tensor of
  ciphertext into tensors of an additional dimension (LWE dim)
- Bufferization now works in Concrete
- Old Concrete optimization were moved to TFHE
- Concrete is now the dialect that lowers to CAPI calls
- TFHE -> Concrete now uses OpConversionPattern and is much cleaner in
  terms of type conversion
- Disabled tests for batching, as there was something weird about it:
  batchable operations implemented in Concrete but pass run in FHELinalg
This commit is contained in:
youben11
2023-02-20 17:50:56 +01:00
committed by Ayoub Benaissa
parent d8eafabd22
commit 2e5f92b6b8
115 changed files with 1322 additions and 2937 deletions

View File

@@ -124,7 +124,6 @@ enum CompilationTarget {
FHE,
TFHE,
CONCRETE,
BCONCRETE,
STD,
LLVM,
LLVM_IR,
@@ -138,8 +137,7 @@ typedef enum CompilationTarget CompilationTarget;
MLIR_CAPI_EXPORTED CompilationOptions compilationOptionsCreate(
MlirStringRef funcName, bool autoParallelize, bool batchConcreteOps,
bool dataflowParallelize, bool emitGPUOps, bool loopParallelize,
bool optimizeConcrete, OptimizerConfig optimizerConfig,
bool verifyDiagnostics);
bool optimizeTFHE, OptimizerConfig optimizerConfig, bool verifyDiagnostics);
MLIR_CAPI_EXPORTED CompilationOptions compilationOptionsCreateDefault();

View File

@@ -2,5 +2,3 @@ set(LLVM_TARGET_DEFINITIONS Passes.td)
mlir_tablegen(Passes.h.inc -gen-pass-decls -name Conversion)
add_public_tablegen_target(ConcretelangConversionPassIncGen)
add_dependencies(mlir-headers ConcretelangConversionPassIncGen)
add_subdirectory(TFHEToConcrete)

View File

@@ -1,18 +0,0 @@
// Part of the Concrete Compiler Project, under the BSD3 License with Zama
// Exceptions. See
// https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt
// for license information.
#ifndef ZAMALANG_CONVERSION_CONCRETETOBCONCRETE_PASS_H_
#define ZAMALANG_CONVERSION_CONCRETETOBCONCRETE_PASS_H_
#include "mlir/Pass/Pass.h"
namespace mlir {
namespace concretelang {
/// Create a pass to convert `Concrete` dialect to `BConcrete` dialect.
std::unique_ptr<OperationPass<ModuleOp>> createConvertConcreteToBConcretePass();
} // namespace concretelang
} // namespace mlir
#endif

View File

@@ -3,16 +3,16 @@
// https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt
// for license information.
#ifndef ZAMALANG_CONVERSION_BCONCRETETOCAPI_PASS_H_
#define ZAMALANG_CONVERSION_BCONCRETETOCAPI_PASS_H_
#ifndef ZAMALANG_CONVERSION_CONCRETETOCAPI_PASS_H_
#define ZAMALANG_CONVERSION_CONCRETETOCAPI_PASS_H_
#include "mlir/Pass/Pass.h"
namespace mlir {
namespace concretelang {
/// Create a pass to convert `BConcrete` dialect to CAPI calls.
/// Create a pass to convert `Concrete` dialect to CAPI calls.
std::unique_ptr<OperationPass<ModuleOp>>
createConvertBConcreteToCAPIPass(bool gpu);
createConvertConcreteToCAPIPass(bool gpu);
} // namespace concretelang
} // namespace mlir

View File

@@ -13,8 +13,7 @@
#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "mlir/Dialect/SCF/IR/SCF.h"
#include "concretelang/Conversion/BConcreteToCAPI/Pass.h"
#include "concretelang/Conversion/ConcreteToBConcrete/Pass.h"
#include "concretelang/Conversion/ConcreteToCAPI/Pass.h"
#include "concretelang/Conversion/ExtractSDFGOps/Pass.h"
#include "concretelang/Conversion/FHETensorOpsToLinalg/Pass.h"
#include "concretelang/Conversion/FHEToTFHECrt/Pass.h"
@@ -25,7 +24,6 @@
#include "concretelang/Conversion/TFHEGlobalParametrization/Pass.h"
#include "concretelang/Conversion/TFHEToConcrete/Pass.h"
#include "concretelang/Conversion/TracingToCAPI/Pass.h"
#include "concretelang/Dialect/BConcrete/IR/BConcreteDialect.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteDialect.h"
#include "concretelang/Dialect/FHE/IR/FHEDialect.h"
#include "concretelang/Dialect/SDFG/IR/SDFGDialect.h"

View File

@@ -48,13 +48,6 @@ def LinalgGenericOpWithTensorsToLoops : Pass<"linalg-generic-op-with-tensors-to-
let dependentDialects = ["mlir::linalg::LinalgDialect", "mlir::scf::SCFDialect"];
}
def ConcreteToBConcrete : Pass<"concrete-to-bconcrete", "mlir::ModuleOp"> {
let summary = "Lowers operations from the Concrete dialect to Bufferized Concrete";
let description = [{ Lowers operations from the Concrete dialect to Bufferized Concrete }];
let constructor = "mlir::concretelang::createConvertConcreteToBConcretePass()";
let dependentDialects = ["mlir::linalg::LinalgDialect", "mlir::concretelang::Concrete::ConcreteDialect", "mlir::concretelang::BConcrete::BConcreteDialect"];
}
def ExtractSDFGOps : Pass<"extract-sdfg-ops", "::mlir::func::FuncOp"> {
let summary = "Extracts SDFG ops and creates a static data flow graph";
let description = [{ Extracts SDFG ops and creates a static data flow graph }];
@@ -62,11 +55,11 @@ def ExtractSDFGOps : Pass<"extract-sdfg-ops", "::mlir::func::FuncOp"> {
let dependentDialects = ["mlir::concretelang::SDFG::SDFGDialect"];
}
def BConcreteToCAPI : Pass<"bconcrete-to-capi", "mlir::ModuleOp"> {
let summary = "Lowers operations from the BConcrete dialect to CAPI calls";
let description = [{ Lowers operations from the BConcrete dialect to CAPI calls }];
let constructor = "mlir::concretelang::createConvertBConcreteToCAPIPass()";
let dependentDialects = ["mlir::concretelang::BConcrete::BConcreteDialect"];
def ConcreteToCAPI : Pass<"concrete-to-capi", "mlir::ModuleOp"> {
let summary = "Lowers operations from the Concrete dialect to CAPI calls";
let description = [{ Lowers operations from the Concrete dialect to CAPI calls }];
let constructor = "mlir::concretelang::createConvertConcreteToCAPIPass()";
let dependentDialects = ["mlir::concretelang::Concrete::ConcreteDialect"];
}
def TracingToCAPI : Pass<"tracing-to-capi", "mlir::ModuleOp"> {

View File

@@ -1,6 +0,0 @@
set(LLVM_TARGET_DEFINITIONS Patterns.td)
mlir_tablegen(Patterns.h.inc -gen-rewriters -name TFHE)
add_public_tablegen_target(TFHEToConcretePatternsIncGen)
add_dependencies(mlir-headers TFHEToConcretePatternsIncGen)
add_concretelang_doc(Patterns TFHEToConcretePatterns concretelang/ -gen-pass-doc)

View File

@@ -1,187 +0,0 @@
// Part of the Concrete Compiler Project, under the BSD3 License with Zama
// Exceptions. See
// https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt
// for license information.
#ifndef CONCRETELANG_CONVERSION_TFHETOCONCRETE_PATTERNS_H_
#define CONCRETELANG_CONVERSION_TFHETOCONCRETE_PATTERNS_H_
#include "concretelang/Conversion/Utils/GenericOpTypeConversionPattern.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteOps.h"
#include "concretelang/Dialect/TFHE/IR/TFHEOps.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/PatternMatch.h"
namespace mlir {
namespace concretelang {
using Concrete::CleartextType;
using Concrete::LweCiphertextType;
using Concrete::PlaintextType;
using TFHE::GLWECipherTextType;
LweCiphertextType convertTypeToLWE(mlir::MLIRContext *context,
mlir::Type type) {
auto glwe = type.dyn_cast_or_null<GLWECipherTextType>();
if (glwe != nullptr) {
assert(glwe.getPolynomialSize() == 1);
return LweCiphertextType::get(context, glwe.getDimension(), glwe.getP());
}
auto lwe = type.dyn_cast_or_null<LweCiphertextType>();
if (lwe != nullptr) {
return lwe;
}
assert(false && "expect glwe or lwe");
return nullptr;
}
/// Converts the type `t` to an LWE type if `t` is a
/// `TFHE::GLWECipherTextType`, otherwise just returns `t`.
mlir::Type convertTypeToLWEIfTFHEType(mlir::MLIRContext *context,
mlir::Type t) {
if (auto eint = t.dyn_cast<TFHE::GLWECipherTextType>())
return convertTypeToLWE(context, eint);
return t;
}
template <typename PType>
PlaintextType convertPlaintextTypeFromPType(mlir::MLIRContext *context,
PType &type) {
return PlaintextType::get(context, type.getP() + 1);
}
/// convertPlaintextTypeFromType create a plaintext type according the
/// precision of the given type argument. The type should be a GLWECipherText
/// (if operand is not yet lowered) or a LWECipherTextType (if operand is
/// already lowered).
PlaintextType convertPlaintextTypeFromType(mlir::MLIRContext *context,
mlir::Type &type) {
auto glwe = type.dyn_cast_or_null<GLWECipherTextType>();
if (glwe != nullptr) {
return convertPlaintextTypeFromPType<GLWECipherTextType>(context, glwe);
}
auto lwe = type.dyn_cast_or_null<LweCiphertextType>();
if (lwe != nullptr) {
return convertPlaintextTypeFromPType<LweCiphertextType>(context, lwe);
}
assert(false && "expect glwe or lwe");
return nullptr;
}
template <typename PType>
CleartextType convertCleartextTypeFromPType(mlir::MLIRContext *context,
PType &type) {
return CleartextType::get(context, type.getP() + 1);
}
/// convertCleartextTypeFromType create a cleartext type according the
/// precision of the given type argument. The type should be a GLWECipherText
/// (if operand is not yet lowered) or a LWECipherTextType (if operand is
/// already lowered).
CleartextType convertCleartextTypeFromType(mlir::MLIRContext *context,
mlir::Type &type) {
auto glwe = type.dyn_cast_or_null<GLWECipherTextType>();
if (glwe != nullptr) {
return convertCleartextTypeFromPType<GLWECipherTextType>(context, glwe);
}
auto lwe = type.dyn_cast_or_null<LweCiphertextType>();
if (lwe != nullptr) {
return convertCleartextTypeFromPType<LweCiphertextType>(context, lwe);
}
assert(false && "expect glwe or lwe");
return nullptr;
}
mlir::Value createZeroLWEOpFromTFHE(mlir::PatternRewriter &rewriter,
mlir::Location loc, mlir::OpResult result) {
mlir::SmallVector<mlir::Value> args{};
mlir::SmallVector<mlir::NamedAttribute, 0> attrs;
auto glwe = result.getType().cast<GLWECipherTextType>();
mlir::SmallVector<mlir::Type, 1> resTypes{
convertTypeToLWE(rewriter.getContext(), glwe)};
Concrete::ZeroLWEOp op =
rewriter.create<Concrete::ZeroLWEOp>(loc, resTypes, args, attrs);
return op.getODSResults(0).front();
}
template <class Operator>
mlir::Value createConcreteOpFromTFHE(mlir::PatternRewriter &rewriter,
mlir::Location loc, mlir::Value arg0,
mlir::Value arg1, mlir::OpResult result) {
mlir::SmallVector<mlir::Value, 2> args{arg0, arg1};
mlir::SmallVector<mlir::NamedAttribute, 0> attrs;
mlir::SmallVector<mlir::Type, 1> resTypes{result.getType()};
Operator op = rewriter.create<Operator>(loc, resTypes, args, attrs);
convertOperandAndResultTypes(rewriter, op, convertTypeToLWE);
return op.getODSResults(0).front();
}
mlir::Value createAddPlainLweCiphertextWithGlwe(
mlir::PatternRewriter &rewriter, mlir::Location loc, mlir::Value arg0,
mlir::Value arg1, mlir::OpResult result, mlir::Type encryptedType) {
auto op =
rewriter
.create<mlir::concretelang::Concrete::AddPlaintextLweCiphertextOp>(
loc, result.getType(), arg0, arg1);
convertOperandAndResultTypes(rewriter, op, convertTypeToLWEIfTFHEType);
return op.getODSResults(0).front();
}
mlir::Value createAddPlainLweCiphertext(mlir::PatternRewriter &rewriter,
mlir::Location loc, mlir::Value arg0,
mlir::Value arg1,
mlir::OpResult result) {
return createAddPlainLweCiphertextWithGlwe(rewriter, loc, arg0, arg1, result,
arg0.getType());
}
mlir::Value createNegLweCiphertext(mlir::PatternRewriter &rewriter,
mlir::Location loc, mlir::Value arg0,
mlir::OpResult result) {
auto negated =
rewriter.create<mlir::concretelang::Concrete::NegateLweCiphertextOp>(
loc, arg0.getType(), arg0);
convertOperandAndResultTypes(rewriter, negated, convertTypeToLWEIfTFHEType);
return negated.getODSResults(0).front();
}
mlir::Value createSubIntLweCiphertext(mlir::PatternRewriter &rewriter,
mlir::Location loc, mlir::Value arg0,
mlir::Value arg1, mlir::OpResult result) {
auto negated_arg1 = createNegLweCiphertext(rewriter, loc, arg1, result);
return createAddPlainLweCiphertextWithGlwe(rewriter, loc, negated_arg1, arg0,
result, arg1.getType());
}
mlir::Value createMulClearLweCiphertext(mlir::PatternRewriter &rewriter,
mlir::Location loc, mlir::Value arg0,
mlir::Value arg1,
mlir::OpResult result) {
// replace op using the encoded plaintext instead of int
auto op =
rewriter
.create<mlir::concretelang::Concrete::MulCleartextLweCiphertextOp>(
loc, result.getType(), arg0, arg1);
convertOperandAndResultTypes(rewriter, op, convertTypeToLWEIfTFHEType);
return op.getODSResults(0).front();
}
} // namespace concretelang
} // namespace mlir
namespace {
#include "concretelang/Conversion/TFHEToConcrete/Patterns.h.inc"
}
void populateWithGeneratedTFHEToConcrete(mlir::RewritePatternSet &patterns) {
populateWithGenerated(patterns);
}
#endif

View File

@@ -1,45 +0,0 @@
#ifndef CONCRETELANG_CONVERSION_TFHETOCONCRETE_PATTERNS
#define CONCRETELANG_CONVERSION_TFHETOCONCRETE_PATTERNS
include "mlir/Pass/PassBase.td"
include "mlir/IR/PatternBase.td"
include "concretelang/Dialect/Concrete/IR/ConcreteOps.td"
include "concretelang/Dialect/TFHE/IR/TFHEOps.td"
def createZeroLWEOp : NativeCodeCall<"mlir::concretelang::createZeroLWEOpFromTFHE($_builder, $_loc, $0)">;
def ZeroGLWEPattern : Pat<
(TFHE_ZeroGLWEOp:$result),
(createZeroLWEOp $result)>;
def createAddLWEOp : NativeCodeCall<"mlir::concretelang::createConcreteOpFromTFHE<mlir::concretelang::Concrete::AddLweCiphertextsOp>($_builder, $_loc, $0, $1, $2)">;
def AddGLWEPattern : Pat<
(TFHE_AddGLWEOp:$result $arg0, $arg1),
(createAddLWEOp $arg0, $arg1, $result)>;
def createAddPlainLweOp : NativeCodeCall<"mlir::concretelang::createAddPlainLweCiphertext($_builder, $_loc, $0, $1, $2)">;
def AddGLWEIntPattern : Pat<
(TFHE_AddGLWEIntOp:$result $arg0, $arg1),
(createAddPlainLweOp $arg0, $arg1, $result)>;
def createMulClearLweOp : NativeCodeCall<"mlir::concretelang::createMulClearLweCiphertext($_builder, $_loc, $0, $1, $2)">;
def MulGLWEIntPattern : Pat<
(TFHE_MulGLWEIntOp:$result $arg0, $arg1),
(createMulClearLweOp $arg0, $arg1, $result)>;
def createSubIntLweOp : NativeCodeCall<"mlir::concretelang::createSubIntLweCiphertext($_builder, $_loc, $0, $1, $2)">;
def SubGLWEIntPattern : Pat<
(TFHE_SubGLWEIntOp:$result $arg0, $arg1),
(createSubIntLweOp $arg0, $arg1, $result)>;
def createNegLweOp : NativeCodeCall<"mlir::concretelang::createNegLweCiphertext($_builder, $_loc, $0, $1)">;
def NegGLWEPattern : Pat<
(TFHE_NegGLWEOp:$result $arg0),
(createNegLweOp $arg0, $result)>;
#endif

View File

@@ -1,2 +0,0 @@
add_subdirectory(IR)
add_subdirectory(Transforms)

View File

@@ -1,18 +0,0 @@
// Part of the Concrete Compiler Project, under the BSD3 License with Zama
// Exceptions. See
// https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt
// for license information.
#ifndef ZAMALANG_DIALECT_BConcrete_IR_BConcreteDIALECT_H
#define ZAMALANG_DIALECT_BConcrete_IR_BConcreteDIALECT_H
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Dialect.h"
#include "concretelang/Dialect/BConcrete/IR/BConcreteOpsDialect.h.inc"
#endif

View File

@@ -1,15 +0,0 @@
#ifndef ZAMALANG_DIALECT_BConcrete_IR_BConcrete_DIALECT
#define ZAMALANG_DIALECT_BConcrete_IR_BConcrete_DIALECT
include "mlir/IR/OpBase.td"
def BConcrete_Dialect : Dialect {
let name = "BConcrete";
let summary = "Bufferized concrete dialect";
let description = [{
A dialect for representation of bufferized concrete operations on fully homomorphic ciphertext.
}];
let cppNamespace = "::mlir::concretelang::BConcrete";
}
#endif

View File

@@ -1,22 +0,0 @@
// Part of the Concrete Compiler Project, under the BSD3 License with Zama
// Exceptions. See
// https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt
// for license information.
#ifndef ZAMALANG_DIALECT_BConcrete_BConcrete_OPS_H
#define ZAMALANG_DIALECT_BConcrete_BConcrete_OPS_H
#include <mlir/Dialect/LLVMIR/LLVMDialect.h>
#include <mlir/IR/Builders.h>
#include <mlir/IR/BuiltinOps.h>
#include <mlir/IR/BuiltinTypes.h>
#include <mlir/Interfaces/ControlFlowInterfaces.h>
#include <mlir/Interfaces/SideEffectInterfaces.h>
#include "concretelang/Dialect/Concrete/IR/ConcreteTypes.h"
#include "concretelang/Dialect/RT/IR/RTTypes.h"
#define GET_OP_CLASSES
#include "concretelang/Dialect/BConcrete/IR/BConcreteOps.h.inc"
#endif

View File

@@ -1,314 +0,0 @@
#ifndef ZAMALANG_DIALECT_BConcrete_IR_BConcrete_OPS
#define ZAMALANG_DIALECT_BConcrete_IR_BConcrete_OPS
include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/Interfaces/ControlFlowInterfaces.td"
include "mlir/IR/BuiltinTypes.td"
include "mlir/Dialect/MemRef/IR/MemRefBase.td"
include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
include "concretelang/Dialect/BConcrete/IR/BConcreteDialect.td"
include "concretelang/Dialect/Concrete/IR/ConcreteTypes.td"
include "concretelang/Dialect/RT/IR/RTDialect.td"
include "concretelang/Dialect/RT/IR/RTTypes.td"
class BConcrete_Op<string mnemonic, list<Trait> traits = []> :
Op<BConcrete_Dialect, mnemonic, traits>;
// BConcrete tensor operators /////////////////////////////////////////////////
def BConcrete_AddLweTensorOp : BConcrete_Op<"add_lwe_tensor", [NoSideEffect]> {
let arguments = (ins
1DTensorOf<[I64]>:$lhs,
1DTensorOf<[I64]>:$rhs
);
let results = (outs 1DTensorOf<[I64]>:$result);
}
def BConcrete_AddPlaintextLweTensorOp : BConcrete_Op<"add_plaintext_lwe_tensor", [NoSideEffect]> {
let arguments = (ins 1DTensorOf<[I64]>:$lhs, I64:$rhs);
let results = (outs 1DTensorOf<[I64]>:$result);
}
def BConcrete_MulCleartextLweTensorOp : BConcrete_Op<"mul_cleartext_lwe_tensor", [NoSideEffect]> {
let arguments = (ins 1DTensorOf<[I64]>:$lhs, I64:$rhs);
let results = (outs 1DTensorOf<[I64]>:$result);
}
def BConcrete_NegateLweTensorOp : BConcrete_Op<"negate_lwe_tensor", [NoSideEffect]> {
let arguments = (ins 1DTensorOf<[I64]>:$ciphertext);
let results = (outs 1DTensorOf<[I64]>:$result);
}
def BConcrete_KeySwitchLweTensorOp : BConcrete_Op<"keyswitch_lwe_tensor", [NoSideEffect]> {
let arguments = (ins
// LweKeySwitchKeyType:$keyswitch_key,
1DTensorOf<[I64]>:$ciphertext,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$lwe_dim_in,
I32Attr:$lwe_dim_out
);
let results = (outs 1DTensorOf<[I64]>:$result);
}
def BConcrete_BatchedKeySwitchLweTensorOp : BConcrete_Op<"batched_keyswitch_lwe_tensor", [NoSideEffect]> {
let arguments = (ins
// LweKeySwitchKeyType:$keyswitch_key,
2DTensorOf<[I64]>:$ciphertext,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$lwe_dim_in,
I32Attr:$lwe_dim_out
);
let results = (outs 2DTensorOf<[I64]>:$result);
}
def BConcrete_EncodeExpandLutForBootstrapTensorOp : BConcrete_Op<"encode_expand_lut_for_bootstrap_tensor", [NoSideEffect]> {
let summary =
"Encode and expand a lookup table so that it can be used for a bootstrap.";
let arguments = (ins
1DTensorOf<[I64]> : $input_lookup_table,
I32Attr: $polySize,
I32Attr: $outputBits,
BoolAttr: $isSigned
);
let results = (outs 1DTensorOf<[I64]> : $result);
}
def BConcrete_EncodeExpandLutForWopPBSTensorOp : BConcrete_Op<"encode_expand_lut_for_woppbs_tensor", [NoSideEffect]> {
let summary =
"Encode and expand a lookup table so that it can be used for a wop pbs.";
let arguments = (ins
1DTensorOf<[I64]> : $input_lookup_table,
I64ArrayAttr: $crtDecomposition,
I64ArrayAttr: $crtBits,
I32Attr : $polySize,
I32Attr : $modulusProduct,
BoolAttr: $isSigned
);
let results = (outs 1DTensorOf<[I64]> : $result);
}
def BConcrete_EncodePlaintextWithCrtTensorOp : BConcrete_Op<"encode_plaintext_with_crt_tensor", [NoSideEffect]> {
let summary =
"Encodes a plaintext by decomposing it on a crt basis.";
let arguments = (ins
I64 : $input,
I64ArrayAttr: $mods,
I64Attr: $modsProd
);
let results = (outs 1DTensorOf<[I64]> : $result);
}
def BConcrete_BootstrapLweTensorOp : BConcrete_Op<"bootstrap_lwe_tensor", [NoSideEffect]> {
let arguments = (ins
1DTensorOf<[I64]>:$input_ciphertext,
1DTensorOf<[I64]>:$lookup_table,
I32Attr:$inputLweDim,
I32Attr:$polySize,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$glweDimension,
I32Attr:$outPrecision
);
let results = (outs 1DTensorOf<[I64]>:$result);
}
def BConcrete_BatchedBootstrapLweTensorOp : BConcrete_Op<"batched_bootstrap_lwe_tensor", [NoSideEffect]> {
let arguments = (ins
2DTensorOf<[I64]>:$input_ciphertext,
1DTensorOf<[I64]>:$lookup_table,
I32Attr:$inputLweDim,
I32Attr:$polySize,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$glweDimension,
I32Attr:$outPrecision
);
let results = (outs 2DTensorOf<[I64]>:$result);
}
def BConcrete_WopPBSCRTLweTensorOp : BConcrete_Op<"wop_pbs_crt_lwe_tensor", [NoSideEffect]> {
let arguments = (ins
2DTensorOf<[I64]>:$ciphertext,
1DTensorOf<[I64]>:$lookupTable,
// Bootstrap parameters
I32Attr : $bootstrapLevel,
I32Attr : $bootstrapBaseLog,
// Keyswitch parameters
I32Attr : $keyswitchLevel,
I32Attr : $keyswitchBaseLog,
// Packing keyswitch key parameters
I32Attr : $packingKeySwitchInputLweDimension,
I32Attr : $packingKeySwitchoutputPolynomialSize,
I32Attr : $packingKeySwitchLevel,
I32Attr : $packingKeySwitchBaseLog,
// Circuit bootstrap parameters
I32Attr : $circuitBootstrapLevel,
I32Attr : $circuitBootstrapBaseLog
);
let results = (outs 2DTensorOf<[I64]>:$result);
}
// BConcrete memref operators /////////////////////////////////////////////////
def BConcrete_LweBuffer : MemRefRankOf<[I64], [1]>;
def BConcrete_LutBuffer : MemRefRankOf<[I64], [1]>;
def BConcrete_CrtPlaintextBuffer : MemRefRankOf<[I64], [1]>;
def BConcrete_LweCRTBuffer : MemRefRankOf<[I64], [2]>;
def BConcrete_BatchLweBuffer : MemRefRankOf<[I64], [2]>;
def BConcrete_AddLweBufferOp : BConcrete_Op<"add_lwe_buffer"> {
let arguments = (ins
BConcrete_LweBuffer:$result,
BConcrete_LweBuffer:$lhs,
BConcrete_LweBuffer:$rhs
);
}
def BConcrete_AddPlaintextLweBufferOp : BConcrete_Op<"add_plaintext_lwe_buffer"> {
let arguments = (ins
BConcrete_LweBuffer:$result,
BConcrete_LweBuffer:$lhs,
I64:$rhs
);
}
def BConcrete_MulCleartextLweBufferOp : BConcrete_Op<"mul_cleartext_lwe_buffer"> {
let arguments = (ins
BConcrete_LweBuffer:$result,
BConcrete_LweBuffer:$lhs,
I64:$rhs
);
}
def BConcrete_NegateLweBufferOp : BConcrete_Op<"negate_lwe_buffer"> {
let arguments = (ins
BConcrete_LweBuffer:$result,
BConcrete_LweBuffer:$ciphertext
);
}
def BConcrete_KeySwitchLweBufferOp : BConcrete_Op<"keyswitch_lwe_buffer"> {
let arguments = (ins
BConcrete_LweBuffer:$result,
BConcrete_LweBuffer:$ciphertext,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$lwe_dim_in,
I32Attr:$lwe_dim_out
);
}
def BConcrete_BatchedKeySwitchLweBufferOp : BConcrete_Op<"batched_keyswitch_lwe_buffer"> {
let arguments = (ins
BConcrete_BatchLweBuffer:$result,
BConcrete_BatchLweBuffer:$ciphertext,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$lwe_dim_in,
I32Attr:$lwe_dim_out
);
}
def BConcrete_EncodeExpandLutForBootstrapBufferOp : BConcrete_Op<"encode_expand_lut_for_bootstrap_buffer"> {
let summary =
"Encode and expand a lookup table so that it can be used for a bootstrap.";
let arguments = (ins
BConcrete_LutBuffer: $result,
BConcrete_LutBuffer: $input_lookup_table,
I32Attr: $polySize,
I32Attr: $outputBits,
BoolAttr : $isSigned
);
}
def BConcrete_EncodeExpandLutForWopPBSBufferOp : BConcrete_Op<"encode_expand_lut_for_woppbs_buffer"> {
let summary =
"Encode and expand a lookup table so that it can be used for a wop pbs.";
let arguments = (ins
BConcrete_LutBuffer : $result,
BConcrete_LutBuffer : $input_lookup_table,
I64ArrayAttr: $crtDecomposition,
I64ArrayAttr: $crtBits,
I32Attr : $polySize,
I32Attr : $modulusProduct,
BoolAttr: $isSigned
);
}
def BConcrete_EncodePlaintextWithCrtBufferOp : BConcrete_Op<"encode_plaintext_with_crt_buffer"> {
let summary =
"Encodes a plaintext by decomposing it on a crt basis.";
let arguments = (ins
BConcrete_CrtPlaintextBuffer: $result,
I64 : $input,
I64ArrayAttr: $mods,
I64Attr: $modsProd
);
}
def BConcrete_BootstrapLweBufferOp : BConcrete_Op<"bootstrap_lwe_buffer"> {
let arguments = (ins
BConcrete_LweBuffer:$result,
BConcrete_LweBuffer:$input_ciphertext,
BConcrete_LutBuffer:$lookup_table,
I32Attr:$inputLweDim,
I32Attr:$polySize,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$glweDimension,
I32Attr:$outPrecision
);
}
def BConcrete_BatchedBootstrapLweBufferOp : BConcrete_Op<"batched_bootstrap_lwe_buffer"> {
let arguments = (ins
BConcrete_BatchLweBuffer:$result,
BConcrete_BatchLweBuffer:$input_ciphertext,
BConcrete_LutBuffer:$lookup_table,
I32Attr:$inputLweDim,
I32Attr:$polySize,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$glweDimension,
I32Attr:$outPrecision
);
}
def BConcrete_WopPBSCRTLweBufferOp : BConcrete_Op<"wop_pbs_crt_lwe_buffer"> {
let arguments = (ins
BConcrete_LweCRTBuffer:$result,
BConcrete_LweCRTBuffer:$ciphertext,
BConcrete_LutBuffer:$lookup_table,
// Bootstrap parameters
I32Attr : $bootstrapLevel,
I32Attr : $bootstrapBaseLog,
// Keyswitch parameters
I32Attr : $keyswitchLevel,
I32Attr : $keyswitchBaseLog,
// Packing keyswitch key parameters
I32Attr : $packingKeySwitchInputLweDimension,
I32Attr : $packingKeySwitchoutputPolynomialSize,
I32Attr : $packingKeySwitchLevel,
I32Attr : $packingKeySwitchBaseLog,
// Circuit bootstrap parameters
I32Attr : $circuitBootstrapLevel,
I32Attr : $circuitBootstrapBaseLog,
I64ArrayAttr:$crtDecomposition
);
}
#endif

View File

@@ -1,9 +0,0 @@
set(LLVM_TARGET_DEFINITIONS BConcreteOps.td)
mlir_tablegen(BConcreteOps.h.inc -gen-op-decls)
mlir_tablegen(BConcreteOps.cpp.inc -gen-op-defs)
mlir_tablegen(BConcreteOpsTypes.h.inc -gen-typedef-decls -typedefs-dialect=BConcrete)
mlir_tablegen(BConcreteOpsTypes.cpp.inc -gen-typedef-defs -typedefs-dialect=BConcrete)
mlir_tablegen(BConcreteOpsDialect.h.inc -gen-dialect-decls -dialect=BConcrete)
mlir_tablegen(BConcreteOpsDialect.cpp.inc -gen-dialect-defs -dialect=BConcrete)
add_public_tablegen_target(MLIRBConcreteOpsIncGen)
add_dependencies(mlir-headers MLIRBConcreteOpsIncGen)

View File

@@ -1,3 +0,0 @@
set(LLVM_TARGET_DEFINITIONS Passes.td)
mlir_tablegen(Passes.h.inc -gen-pass-decls -name BConcrete)
add_public_tablegen_target(BConcreteTransformsIncGen)

View File

@@ -2,7 +2,6 @@ add_subdirectory(FHE)
add_subdirectory(FHELinalg)
add_subdirectory(TFHE)
add_subdirectory(Concrete)
add_subdirectory(BConcrete)
add_subdirectory(RT)
add_subdirectory(SDFG)
add_subdirectory(Tracing)

View File

@@ -3,76 +3,135 @@
include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/Interfaces/ControlFlowInterfaces.td"
include "mlir/IR/BuiltinTypes.td"
include "mlir/Dialect/MemRef/IR/MemRefBase.td"
include "mlir/Dialect/LLVMIR/LLVMOpBase.td"
include "concretelang/Dialect/Concrete/IR/ConcreteDialect.td"
include "concretelang/Dialect/Concrete/IR/ConcreteTypes.td"
include "concretelang/Interfaces/BatchableInterface.td"
include "concretelang/Dialect/RT/IR/RTDialect.td"
include "concretelang/Dialect/RT/IR/RTTypes.td"
def Concrete_LweTensor : 1DTensorOf<[I64]>;
def Concrete_LutTensor : 1DTensorOf<[I64]>;
def Concrete_CrtPlaintextTensor : 1DTensorOf<[I64]>;
def Concrete_LweCRTTensor : 2DTensorOf<[I64]>;
def Concrete_BatchLweTensor : 2DTensorOf<[I64]>;
def Concrete_LweBuffer : MemRefRankOf<[I64], [1]>;
def Concrete_LutBuffer : MemRefRankOf<[I64], [1]>;
def Concrete_CrtPlaintextBuffer : MemRefRankOf<[I64], [1]>;
def Concrete_LweCRTBuffer : MemRefRankOf<[I64], [2]>;
def Concrete_BatchLweBuffer : MemRefRankOf<[I64], [2]>;
class Concrete_Op<string mnemonic, list<Trait> traits = []> :
Op<Concrete_Dialect, mnemonic, traits>;
def Concrete_ZeroLWEOp : Concrete_Op<"zero"> {
let summary = "Returns a trivial encyption of 0";
let arguments = (ins);
let results = (outs Concrete_LweCiphertextType:$out);
}
def Concrete_ZeroTensorLWEOp : Concrete_Op<"zero_tensor"> {
let summary = "Returns a trivial encyption of 0";
let arguments = (ins);
let results = (outs Type<And<[TensorOf<[Concrete_LweCiphertextType]>.predicate, HasStaticShapePred]>>:$tensor);
}
def Concrete_AddLweCiphertextsOp : Concrete_Op<"add_lwe_ciphertexts"> {
def Concrete_AddLweTensorOp : Concrete_Op<"add_lwe_tensor", [NoSideEffect]> {
let summary = "Returns the sum of 2 lwe ciphertexts";
let arguments = (ins Concrete_LweCiphertextType:$lhs, Concrete_LweCiphertextType:$rhs);
let results = (outs Concrete_LweCiphertextType:$result);
let arguments = (ins
Concrete_LweTensor:$lhs,
Concrete_LweTensor:$rhs
);
let results = (outs Concrete_LweTensor:$result);
}
def Concrete_AddPlaintextLweCiphertextOp : Concrete_Op<"add_plaintext_lwe_ciphertext"> {
let summary = "Returns the sum of a clear integer and a lwe ciphertext";
def Concrete_AddLweBufferOp : Concrete_Op<"add_lwe_buffer"> {
let summary = "Returns the sum of 2 lwe ciphertexts";
let arguments = (ins Concrete_LweCiphertextType:$lhs, AnyInteger:$rhs);
let results = (outs Concrete_LweCiphertextType:$result);
let arguments = (ins
Concrete_LweBuffer:$result,
Concrete_LweBuffer:$lhs,
Concrete_LweBuffer:$rhs
);
}
def Concrete_MulCleartextLweCiphertextOp : Concrete_Op<"mul_cleartext_lwe_ciphertext"> {
def Concrete_AddPlaintextLweTensorOp : Concrete_Op<"add_plaintext_lwe_tensor", [NoSideEffect]> {
let summary = "Returns the sum of a clear integer and an lwe ciphertext";
let arguments = (ins Concrete_LweTensor:$lhs, I64:$rhs);
let results = (outs Concrete_LweTensor:$result);
}
def Concrete_AddPlaintextLweBufferOp : Concrete_Op<"add_plaintext_lwe_buffer"> {
let summary = "Returns the sum of a clear integer and an lwe ciphertext";
let arguments = (ins
Concrete_LweBuffer:$result,
Concrete_LweBuffer:$lhs,
I64:$rhs
);
}
def Concrete_MulCleartextLweTensorOp : Concrete_Op<"mul_cleartext_lwe_tensor", [NoSideEffect]> {
let summary = "Returns the product of a clear integer and a lwe ciphertext";
let arguments = (ins Concrete_LweCiphertextType:$lhs, AnyInteger:$rhs);
let results = (outs Concrete_LweCiphertextType:$result);
let arguments = (ins Concrete_LweTensor:$lhs, I64:$rhs);
let results = (outs Concrete_LweTensor:$result);
}
def Concrete_NegateLweCiphertextOp : Concrete_Op<"negate_lwe_ciphertext"> {
def Concrete_MulCleartextLweBufferOp : Concrete_Op<"mul_cleartext_lwe_buffer"> {
let summary = "Returns the product of a clear integer and a lwe ciphertext";
let arguments = (ins
Concrete_LweBuffer:$result,
Concrete_LweBuffer:$lhs,
I64:$rhs
);
}
def Concrete_NegateLweTensorOp : Concrete_Op<"negate_lwe_tensor", [NoSideEffect]> {
let summary = "Negates a lwe ciphertext";
let arguments = (ins Concrete_LweCiphertextType:$ciphertext);
let results = (outs Concrete_LweCiphertextType:$result);
let arguments = (ins Concrete_LweTensor:$ciphertext);
let results = (outs Concrete_LweTensor:$result);
}
def Concrete_EncodeExpandLutForBootstrapOp : Concrete_Op<"encode_expand_lut_for_bootstrap"> {
let summary =
"Encode and expand a lookup table so that it can be used for a bootstrap.";
def Concrete_NegateLweBufferOp : Concrete_Op<"negate_lwe_buffer"> {
let summary = "Negates a lwe ciphertext";
let arguments = (ins
1DTensorOf<[I64]> : $input_lookup_table,
I32Attr: $polySize,
I32Attr: $outputBits,
BoolAttr: $isSigned
Concrete_LweBuffer:$result,
Concrete_LweBuffer:$ciphertext
);
}
def Concrete_EncodeExpandLutForBootstrapTensorOp : Concrete_Op<"encode_expand_lut_for_bootstrap_tensor", [NoSideEffect]> {
let summary =
"Encode and expand a lookup table so that it can be used for a bootstrap";
let arguments = (ins
Concrete_LutTensor : $input_lookup_table,
I32Attr: $polySize,
I32Attr: $outputBits,
BoolAttr: $isSigned
);
let results = (outs 1DTensorOf<[I64]> : $result);
let results = (outs Concrete_LutTensor : $result);
}
def Concrete_EncodeExpandLutForWopPBSOp : Concrete_Op<"encode_expand_lut_for_woppbs"> {
let summary =
"Encode and expand a lookup table so that it can be used for a wop pbs.";
def Concrete_EncodeExpandLutForBootstrapBufferOp : Concrete_Op<"encode_expand_lut_for_bootstrap_buffer"> {
let summary =
"Encode and expand a lookup table so that it can be used for a bootstrap";
let arguments = (ins
1DTensorOf<[I64]> : $input_lookup_table,
Concrete_LutBuffer: $result,
Concrete_LutBuffer: $input_lookup_table,
I32Attr: $polySize,
I32Attr: $outputBits,
BoolAttr : $isSigned
);
}
def Concrete_EncodeExpandLutForWopPBSTensorOp : Concrete_Op<"encode_expand_lut_for_woppbs_tensor", [NoSideEffect]> {
let summary =
"Encode and expand a lookup table so that it can be used for a wop pbs";
let arguments = (ins
Concrete_LutTensor : $input_lookup_table,
I64ArrayAttr: $crtDecomposition,
I64ArrayAttr: $crtBits,
I32Attr : $polySize,
@@ -80,12 +139,27 @@ let summary =
BoolAttr: $isSigned
);
let results = (outs 1DTensorOf<[I64]> : $result);
let results = (outs Concrete_LutTensor : $result);
}
def Concrete_EncodePlaintextWithCrtOp : Concrete_Op<"encode_plaintext_with_crt"> {
def Concrete_EncodeExpandLutForWopPBSBufferOp : Concrete_Op<"encode_expand_lut_for_woppbs_buffer"> {
let summary =
"Encodes a plaintext by decomposing it on a crt basis.";
"Encode and expand a lookup table so that it can be used for a wop pbs";
let arguments = (ins
Concrete_LutBuffer : $result,
Concrete_LutBuffer : $input_lookup_table,
I64ArrayAttr: $crtDecomposition,
I64ArrayAttr: $crtBits,
I32Attr : $polySize,
I32Attr : $modulusProduct,
BoolAttr: $isSigned
);
}
def Concrete_EncodePlaintextWithCrtTensorOp : Concrete_Op<"encode_plaintext_with_crt_tensor", [NoSideEffect]> {
let summary =
"Encodes a plaintext by decomposing it on a crt basis";
let arguments = (ins
I64 : $input,
@@ -93,21 +167,35 @@ def Concrete_EncodePlaintextWithCrtOp : Concrete_Op<"encode_plaintext_with_crt">
I64Attr: $modsProd
);
let results = (outs 1DTensorOf<[I64]> : $result);
let results = (outs Concrete_CrtPlaintextTensor : $result);
}
def Concrete_BootstrapLweOp : Concrete_Op<"bootstrap_lwe", [BatchableOpInterface]> {
let summary = "Bootstraps a LWE ciphertext with a GLWE trivial encryption of the lookup table";
def Concrete_EncodePlaintextWithCrtBufferOp : Concrete_Op<"encode_plaintext_with_crt_buffer"> {
let summary =
"Encodes a plaintext by decomposing it on a crt basis";
let arguments = (ins
Concrete_LweCiphertextType:$input_ciphertext,
1DTensorOf<[I64]>:$lookup_table,
let arguments = (ins
Concrete_CrtPlaintextBuffer: $result,
I64 : $input,
I64ArrayAttr: $mods,
I64Attr: $modsProd
);
}
def Concrete_BootstrapLweTensorOp : Concrete_Op<"bootstrap_lwe_tensor", [NoSideEffect]> {
let summary = "Bootstraps an LWE ciphertext with a GLWE trivial encryption of the lookup table";
let arguments = (ins
Concrete_LweTensor:$input_ciphertext,
Concrete_LweTensor:$lookup_table,
I32Attr:$inputLweDim,
I32Attr:$polySize,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$polySize,
I32Attr:$glweDimension
I32Attr:$glweDimension,
I32Attr:$outPrecision
);
let results = (outs Concrete_LweCiphertextType:$result);
let results = (outs Concrete_LweTensor:$result);
let extraClassDeclaration = [{
::mlir::OpOperand& getBatchableOperand() {
@@ -124,38 +212,74 @@ def Concrete_BootstrapLweOp : Concrete_Op<"bootstrap_lwe", [BatchableOpInterface
batchedOperands.getType().cast<::mlir::RankedTensorType>().getShape(),
getResult().getType());
return builder.create<BatchedBootstrapLweOp>(
return builder.create<BatchedBootstrapLweTensorOp>(
mlir::TypeRange{resType},
mlir::ValueRange{batchedOperands, lookup_table()},
getOperation()->getAttrs());
}
}];
}
def Concrete_BatchedBootstrapLweOp : Concrete_Op<"batched_bootstrap_lwe"> {
let summary = "Batched version of BootstrapLweOp, which performs the same operation on a tensor of elements";
def Concrete_BootstrapLweBufferOp : Concrete_Op<"bootstrap_lwe_buffer"> {
let summary = "Bootstraps a LWE ciphertext with a GLWE trivial encryption of the lookup table";
let arguments = (ins
1DTensorOf<[Concrete_LweCiphertextType]>:$input_ciphertexts,
1DTensorOf<[I64]>:$lookup_table,
Concrete_LweBuffer:$result,
Concrete_LweBuffer:$input_ciphertext,
Concrete_LutBuffer:$lookup_table,
I32Attr:$inputLweDim,
I32Attr:$polySize,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$polySize,
I32Attr:$glweDimension
I32Attr:$glweDimension,
I32Attr:$outPrecision
);
let results = (outs 1DTensorOf<[Concrete_LweCiphertextType]>:$result);
}
def Concrete_KeySwitchLweOp : Concrete_Op<"keyswitch_lwe", [BatchableOpInterface]> {
let summary = "Keyswitches a LWE ciphertext";
def Concrete_BatchedBootstrapLweTensorOp : Concrete_Op<"batched_bootstrap_lwe_tensor", [NoSideEffect]> {
let summary = "Batched version of BootstrapLweOp, which performs the same operation on multiple elements";
let arguments = (ins
Concrete_LweCiphertextType:$ciphertext,
Concrete_BatchLweTensor:$input_ciphertext,
Concrete_LutTensor:$lookup_table,
I32Attr:$inputLweDim,
I32Attr:$polySize,
I32Attr:$level,
I32Attr:$baseLog
I32Attr:$baseLog,
I32Attr:$glweDimension,
I32Attr:$outPrecision
);
let results = (outs Concrete_LweCiphertextType:$result);
let results = (outs Concrete_BatchLweTensor:$result);
}
def Concrete_BatchedBootstrapLweBufferOp : Concrete_Op<"batched_bootstrap_lwe_buffer"> {
let summary = "Batched version of BootstrapLweOp, which performs the same operation on multiple elements";
let arguments = (ins
Concrete_BatchLweBuffer:$result,
Concrete_BatchLweBuffer:$input_ciphertext,
Concrete_LutBuffer:$lookup_table,
I32Attr:$inputLweDim,
I32Attr:$polySize,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$glweDimension,
I32Attr:$outPrecision
);
}
def Concrete_KeySwitchLweTensorOp : Concrete_Op<"keyswitch_lwe_tensor", [NoSideEffect]> {
let summary = "Keyswitches an LWE ciphertext";
let arguments = (ins
// LweKeySwitchKeyType:$keyswitch_key,
Concrete_LweTensor:$ciphertext,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$lwe_dim_in,
I32Attr:$lwe_dim_out
);
let results = (outs Concrete_LweTensor:$result);
let extraClassDeclaration = [{
::mlir::OpOperand& getBatchableOperand() {
@@ -172,7 +296,7 @@ def Concrete_KeySwitchLweOp : Concrete_Op<"keyswitch_lwe", [BatchableOpInterface
batchedOperands.getType().cast<::mlir::RankedTensorType>().getShape(),
getResult().getType());
return builder.create<BatchedKeySwitchLweOp>(
return builder.create<BatchedKeySwitchLweTensorOp>(
mlir::TypeRange{resType},
mlir::ValueRange{batchedOperands},
getOperation()->getAttrs());
@@ -180,24 +304,73 @@ def Concrete_KeySwitchLweOp : Concrete_Op<"keyswitch_lwe", [BatchableOpInterface
}];
}
def Concrete_BatchedKeySwitchLweOp : Concrete_Op<"batched_keyswitch_lwe"> {
let summary = "Batched version of KeySwitchLweOp, which performs the same operation on a tensor of elements";
def Concrete_KeySwitchLweBufferOp : Concrete_Op<"keyswitch_lwe_buffer"> {
let summary = "Keyswitches an LWE ciphertext";
let arguments = (ins
1DTensorOf<[Concrete_LweCiphertextType]>:$ciphertexts,
Concrete_LweBuffer:$result,
Concrete_LweBuffer:$ciphertext,
I32Attr:$level,
I32Attr:$baseLog
I32Attr:$baseLog,
I32Attr:$lwe_dim_in,
I32Attr:$lwe_dim_out
);
let results = (outs 1DTensorOf<[Concrete_LweCiphertextType]>:$result);
}
// TODO(16bits): hack
def Concrete_WopPBSLweOp : Concrete_Op<"wop_pbs_lwe"> {
let summary = "";
def Concrete_BatchedKeySwitchLweTensorOp : Concrete_Op<"batched_keyswitch_lwe_tensor", [NoSideEffect]> {
let summary = "Batched version of KeySwitchLweOp, which performs the same operation on multiple elements";
let arguments = (ins
Type<And<[TensorOf<[Concrete_LweCiphertextType]>.predicate, HasStaticShapePred]>>:$ciphertexts,
1DTensorOf<[I64]>:$accumulator,
// LweKeySwitchKeyType:$keyswitch_key,
Concrete_BatchLweTensor:$ciphertext,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$lwe_dim_in,
I32Attr:$lwe_dim_out
);
let results = (outs Concrete_BatchLweTensor:$result);
}
def Concrete_BatchedKeySwitchLweBufferOp : Concrete_Op<"batched_keyswitch_lwe_buffer"> {
let summary = "Batched version of KeySwitchLweOp, which performs the same operation on multiple elements";
let arguments = (ins
Concrete_BatchLweBuffer:$result,
Concrete_BatchLweBuffer:$ciphertext,
I32Attr:$level,
I32Attr:$baseLog,
I32Attr:$lwe_dim_in,
I32Attr:$lwe_dim_out
);
}
def Concrete_WopPBSCRTLweTensorOp : Concrete_Op<"wop_pbs_crt_lwe_tensor", [NoSideEffect]> {
let arguments = (ins
Concrete_LweCRTTensor:$ciphertext,
Concrete_LutTensor:$lookupTable,
// Bootstrap parameters
I32Attr : $bootstrapLevel,
I32Attr : $bootstrapBaseLog,
// Keyswitch parameters
I32Attr : $keyswitchLevel,
I32Attr : $keyswitchBaseLog,
// Packing keyswitch key parameters
I32Attr : $packingKeySwitchInputLweDimension,
I32Attr : $packingKeySwitchoutputPolynomialSize,
I32Attr : $packingKeySwitchLevel,
I32Attr : $packingKeySwitchBaseLog,
// Circuit bootstrap parameters
I32Attr : $circuitBootstrapLevel,
I32Attr : $circuitBootstrapBaseLog
);
let results = (outs Concrete_LweCRTTensor:$result);
}
def Concrete_WopPBSCRTLweBufferOp : Concrete_Op<"wop_pbs_crt_lwe_buffer"> {
let arguments = (ins
Concrete_LweCRTBuffer:$result,
Concrete_LweCRTBuffer:$ciphertext,
Concrete_LutBuffer:$lookup_table,
// Bootstrap parameters
I32Attr : $bootstrapLevel,
I32Attr : $bootstrapBaseLog,
@@ -212,10 +385,8 @@ def Concrete_WopPBSLweOp : Concrete_Op<"wop_pbs_lwe"> {
// Circuit bootstrap parameters
I32Attr : $circuitBootstrapLevel,
I32Attr : $circuitBootstrapBaseLog,
// Crt decomposition
I64ArrayAttr: $crtDecomposition
I64ArrayAttr:$crtDecomposition
);
let results = (outs Type<And<[TensorOf<[Concrete_LweCiphertextType]>.predicate, HasStaticShapePred]>>:$result);
}
#endif

View File

@@ -7,80 +7,6 @@ include "concretelang/Dialect/Concrete/IR/ConcreteDialect.td"
class Concrete_Type<string name, list<Trait> traits = []> : TypeDef<Concrete_Dialect, name, traits> { }
def Concrete_GlweCiphertextType : Concrete_Type<"GlweCiphertext"> {
let mnemonic = "glwe_ciphertext";
let summary = "A GLWE ciphertext (encryption of a polynomial of fixed-precision integers)";
let description = [{
GLWE ciphertext.
}];
let hasCustomAssemblyFormat = 1;
let parameters = (ins
"signed":$glweDimension,
"signed":$polynomialSize,
// Precision of the lwe ciphertext
"signed":$p
);
}
def Concrete_LweCiphertextType : Concrete_Type<"LweCiphertext", [MemRefElementTypeInterface]> {
let mnemonic = "lwe_ciphertext";
let summary = "A LWE ciphertext (encryption of a fixed-precision integer)";
let description = [{
Learning With Error ciphertext.
}];
let parameters = (ins
// The dimension of the lwe ciphertext
"signed":$dimension,
// Precision of the lwe ciphertext
"signed":$p
);
let hasCustomAssemblyFormat = 1;
}
def Concrete_CleartextType : Concrete_Type<"Cleartext"> {
let mnemonic = "cleartext";
let summary = "A cleartext (a fixed-precision integer) ready to be multiplied to a LWE ciphertext";
let description = [{
Cleartext.
}];
let parameters = (ins
// Number of bits of the cleartext representation
"signed":$p
);
let hasCustomAssemblyFormat = 1;
}
def Concrete_PlaintextType : Concrete_Type<"Plaintext"> {
let mnemonic = "plaintext";
let summary = "A Plaintext (a fixed-precision integer) ready to be added to a LWE ciphertext";
let description = [{
Plaintext.
}];
let parameters = (ins
// Number of bits of the cleartext representation
"signed":$p
);
let hasCustomAssemblyFormat = 1;
}
def Concrete_Context : Concrete_Type<"Context"> {
let mnemonic = "context";

View File

@@ -3,16 +3,16 @@
// https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt
// for license information.
#ifndef CONCRETELANG_DIALECT_BCONCRETE_BUFFERIZABLEOPINTERFACEIMPL_H
#define CONCRETELANG_DIALECT_BCONCRETE_BUFFERIZABLEOPINTERFACEIMPL_H
#ifndef CONCRETELANG_DIALECT_CONCRETE_BUFFERIZABLEOPINTERFACEIMPL_H
#define CONCRETELANG_DIALECT_CONCRETE_BUFFERIZABLEOPINTERFACEIMPL_H
namespace mlir {
class DialectRegistry;
namespace concretelang {
namespace BConcrete {
namespace Concrete {
void registerBufferizableOpInterfaceExternalModels(DialectRegistry &registry);
} // namespace BConcrete
} // namespace Concrete
} // namespace concretelang
} // namespace mlir

View File

@@ -1,4 +1,3 @@
set(LLVM_TARGET_DEFINITIONS Optimization.td)
mlir_tablegen(Optimization.h.inc -gen-pass-decls -name Transforms)
add_public_tablegen_target(ConcretelangConcreteOptimizationPassIncGen)
add_dependencies(mlir-headers ConcretelangConcreteOptimizationPassIncGen)
set(LLVM_TARGET_DEFINITIONS Passes.td)
mlir_tablegen(Passes.h.inc -gen-pass-decls -name Concrete)
add_public_tablegen_target(ConcreteTransformsIncGen)

View File

@@ -1,13 +0,0 @@
#ifndef CONCRETELANG_CONCRETE_OPTIMIZATION_PASS
#define CONCRETELANG_CONCRETE_OPTIMIZATION_PASS
include "mlir/Pass/PassBase.td"
def ConcreteOptimization : Pass<"concrete-optimization"> {
let summary = "Optimize Concrete operations";
let constructor = "mlir::concretelang::createConcreteOptimizationPass()";
let options = [];
let dependentDialects = [ "mlir::concretelang::Concrete::ConcreteDialect" ];
}
#endif

View File

@@ -3,19 +3,18 @@
// https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt
// for license information.
#ifndef CONCRETELANG_DIALECT_BCONCRETE_TRANSFORMS_PASSES_H_
#define CONCRETELANG_DIALECT_BCONCRETE_TRANSFORMS_PASSES_H_
#ifndef CONCRETELANG_DIALECT_CONCRETE_TRANSFORMS_PASSES_H_
#define CONCRETELANG_DIALECT_CONCRETE_TRANSFORMS_PASSES_H_
#include "mlir/Pass/Pass.h"
#define GEN_PASS_CLASSES
#include "concretelang/Dialect/BConcrete/Transforms/Passes.h.inc"
#include "concretelang/Dialect/Concrete/Transforms/Passes.h.inc"
namespace mlir {
namespace concretelang {
std::unique_ptr<OperationPass<ModuleOp>> createAddRuntimeContext();
std::unique_ptr<OperationPass<func::FuncOp>> createEliminateCRTOps();
} // namespace concretelang
} // namespace mlir
#endif // CONCRETELANG_DIALECT_BCONCRETE_TRANSFORMS_PASSES_H_
#endif // CONCRETELANG_DIALECT_CONCRETE_TRANSFORMS_PASSES_H_

View File

@@ -16,10 +16,4 @@ def AddRuntimeContext : Pass<"add-runtime-context", "mlir::ModuleOp"> {
let constructor = "mlir::concretelang::createAddRuntimeContext()";
}
def EliminateCRTOps
: Pass<"eliminate-bconcrete-crt-ops", "mlir::func::FuncOp"> {
let summary = "Eliminate the crt bconcrete operators.";
let constructor = "mlir::concretelang::createEliminateCRTOpsPass()";
}
#endif // MLIR_DIALECT_TENSOR_TRANSFORMS_PASSES

View File

@@ -1 +1,2 @@
add_subdirectory(IR)
add_subdirectory(Transforms)

View File

@@ -0,0 +1,4 @@
set(LLVM_TARGET_DEFINITIONS Optimization.td)
mlir_tablegen(Optimization.h.inc -gen-pass-decls -name Transforms)
add_public_tablegen_target(ConcretelangTFHEOptimizationPassIncGen)
add_dependencies(mlir-headers ConcretelangTFHEOptimizationPassIncGen)

View File

@@ -3,18 +3,18 @@
// https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt
// for license information.
#ifndef CONCRETELANG_CONCRETE_OPTIMIZATION_PASS_H
#define CONCRETELANG_CONCRETE_OPTIMIZATION_PASS_H
#ifndef CONCRETELANG_TFHE_OPTIMIZATION_PASS_H
#define CONCRETELANG_TFHE_OPTIMIZATION_PASS_H
#include <concretelang/Dialect/Concrete/IR/ConcreteDialect.h>
#include <concretelang/Dialect/TFHE/IR/TFHEDialect.h>
#include <mlir/Pass/Pass.h>
#define GEN_PASS_CLASSES
#include <concretelang/Dialect/Concrete/Transforms/Optimization.h.inc>
#include <concretelang/Dialect/TFHE/Transforms/Optimization.h.inc>
namespace mlir {
namespace concretelang {
std::unique_ptr<mlir::OperationPass<>> createConcreteOptimizationPass();
std::unique_ptr<mlir::OperationPass<>> createTFHEOptimizationPass();
} // namespace concretelang
} // namespace mlir

View File

@@ -0,0 +1,13 @@
#ifndef CONCRETELANG_TFHE_OPTIMIZATION_PASS
#define CONCRETELANG_TFHE_OPTIMIZATION_PASS
include "mlir/Pass/PassBase.td"
def TFHEOptimization : Pass<"tfhe-optimization"> {
let summary = "Optimize TFHE operations";
let constructor = "mlir::concretelang::createTFHEOptimizationPass()";
let options = [];
let dependentDialects = [ "mlir::concretelang::TFHE::TFHEDialect" ];
}
#endif

View File

@@ -29,7 +29,6 @@ def Tracing_TraceCiphertextOp : Tracing_Op<"trace_ciphertext"> {
FHE_EncryptedIntegerType.predicate,
FHE_EncryptedSignedIntegerType.predicate,
TFHE_GLWECipherTextType.predicate,
Concrete_LweCiphertextType.predicate,
1DTensorOf<[I64]>.predicate,
MemRefRankOf<[I64], [1]>.predicate
]>>: $ciphertext,

View File

@@ -62,7 +62,7 @@ struct CompilationOptions {
bool emitSDFGOps;
bool unrollLoopsWithSDFGConvertibleOps;
bool dataflowParallelize;
bool optimizeConcrete;
bool optimizeTFHE;
/// use GPU during execution by generating GPU operations if possible
bool emitGPUOps;
llvm::Optional<std::vector<int64_t>> fhelinalgTileSizes;
@@ -82,7 +82,7 @@ struct CompilationOptions {
: v0FHEConstraints(llvm::None), verifyDiagnostics(false),
autoParallelize(false), loopParallelize(false), batchConcreteOps(false),
emitSDFGOps(false), unrollLoopsWithSDFGConvertibleOps(false),
dataflowParallelize(false), optimizeConcrete(true), emitGPUOps(false),
dataflowParallelize(false), optimizeTFHE(true), emitGPUOps(false),
clientParametersFuncName(llvm::None),
optimizerConfig(optimizer::DEFAULT_CONFIG), chunkIntegers(false),
chunkSize(4), chunkWidth(2){};
@@ -212,12 +212,8 @@ public:
/// operations
CONCRETE,
/// Read sources and lower all FHE, TFHE and Concrete operations to
/// BConcrete operations
BCONCRETE,
/// Read sources and lower all FHE, TFHE and Concrete operations to
/// BConcrete, then extract SDFG operations
/// Read sources and lower all FHE and TFHE operations to Concrete
/// then extract SDFG operations
SDFG,
/// Read sources and lower all FHE, TFHE and Concrete

View File

@@ -68,14 +68,9 @@ lowerConcreteLinalgToLoops(mlir::MLIRContext &context, mlir::ModuleOp &module,
std::function<bool(mlir::Pass *)> enablePass,
bool parallelizeLoops, bool batchOperations);
mlir::LogicalResult
lowerConcreteToBConcrete(mlir::MLIRContext &context, mlir::ModuleOp &module,
std::function<bool(mlir::Pass *)> enablePass,
bool parallelizeLoops);
mlir::LogicalResult
optimizeConcrete(mlir::MLIRContext &context, mlir::ModuleOp &module,
std::function<bool(mlir::Pass *)> enablePass);
mlir::LogicalResult optimizeTFHE(mlir::MLIRContext &context,
mlir::ModuleOp &module,
std::function<bool(mlir::Pass *)> enablePass);
mlir::LogicalResult extractSDFGOps(mlir::MLIRContext &context,
mlir::ModuleOp &module,
@@ -83,8 +78,8 @@ mlir::LogicalResult extractSDFGOps(mlir::MLIRContext &context,
bool unrollLoops);
mlir::LogicalResult
lowerBConcreteToStd(mlir::MLIRContext &context, mlir::ModuleOp &module,
std::function<bool(mlir::Pass *)> enablePass);
lowerConcreteToStd(mlir::MLIRContext &context, mlir::ModuleOp &module,
std::function<bool(mlir::Pass *)> enablePass);
mlir::LogicalResult
lowerSDFGToStd(mlir::MLIRContext &context, mlir::ModuleOp &module,

View File

@@ -53,10 +53,8 @@ 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_optimize_concrete", [](CompilationOptions &options,
bool b) { options.optimizeTFHE = b; })
.def("set_p_error",
[](CompilationOptions &options, double p_error) {
options.optimizerConfig.p_error = p_error;

View File

@@ -241,20 +241,19 @@ const LLVM_STATIC_LIBS: [&str; 51] = [
"LLVMX86Info",
];
const CONCRETE_COMPILER_LIBS: [&str; 35] = [
const CONCRETE_COMPILER_LIBS: [&str; 33] = [
"RTDialect",
"RTDialectTransforms",
"ConcretelangSupport",
"BConcreteToCAPI",
"ConcreteToCAPI",
"ConcretelangConversion",
"ConcretelangTransforms",
"FHETensorOpsToLinalg",
"ConcretelangServerLib",
"ConcreteToBConcrete",
"CONCRETELANGCAPIFHE",
"TFHEGlobalParametrization",
"ConcretelangClientLib",
"ConcretelangBConcreteTransforms",
"ConcretelangConcreteTransforms",
"ConcretelangSDFGInterfaces",
"ConcretelangSDFGTransforms",
"CONCRETELANGCAPISupport",
@@ -267,8 +266,7 @@ const CONCRETE_COMPILER_LIBS: [&str; 35] = [
"TFHEToConcrete",
"FHEToTFHECrt",
"FHEToTFHEScalar",
"ConcreteDialectTransforms",
"BConcreteDialect",
"TFHEDialectTransforms",
"concrete_optimizer",
"LinalgExtras",
"FHEDialectAnalysis",

View File

@@ -65,7 +65,7 @@ CompilationOptions
compilationOptionsCreate(MlirStringRef funcName, bool autoParallelize,
bool batchConcreteOps, bool dataflowParallelize,
bool emitGPUOps, bool loopParallelize,
bool optimizeConcrete, OptimizerConfig optimizerConfig,
bool optimizeTFHE, OptimizerConfig optimizerConfig,
bool verifyDiagnostics) {
std::string funcNameStr(funcName.data, funcName.length);
auto options = new mlir::concretelang::CompilationOptions(funcNameStr);
@@ -74,7 +74,7 @@ compilationOptionsCreate(MlirStringRef funcName, bool autoParallelize,
options->dataflowParallelize = dataflowParallelize;
options->emitGPUOps = emitGPUOps;
options->loopParallelize = loopParallelize;
options->optimizeConcrete = optimizeConcrete;
options->optimizeTFHE = optimizeTFHE;
options->optimizerConfig = *unwrap(optimizerConfig);
options->verifyDiagnostics = verifyDiagnostics;
return wrap(options);
@@ -133,8 +133,6 @@ llvm::Expected<mlir::concretelang::CompilerEngine::
return mlir::concretelang::CompilerEngine::Target::TFHE;
case CONCRETE:
return mlir::concretelang::CompilerEngine::Target::CONCRETE;
case BCONCRETE:
return mlir::concretelang::CompilerEngine::Target::BCONCRETE;
case STD:
return mlir::concretelang::CompilerEngine::Target::STD;
case LLVM:

View File

@@ -1,14 +0,0 @@
add_mlir_dialect_library(
BConcreteToCAPI
BConcreteToCAPI.cpp
ADDITIONAL_HEADER_DIRS
${PROJECT_SOURCE_DIR}/include/concretelang/Dialect/BConcrete
DEPENDS
BConcreteDialect
mlir-headers
LINK_LIBS
PUBLIC
MLIRIR
MLIRTransforms)
target_link_libraries(BConcreteToCAPI PUBLIC BConcreteDialect MLIRIR)

View File

@@ -3,9 +3,8 @@ add_subdirectory(FHEToTFHECrt)
add_subdirectory(TFHEGlobalParametrization)
add_subdirectory(TFHEToConcrete)
add_subdirectory(FHETensorOpsToLinalg)
add_subdirectory(ConcreteToBConcrete)
add_subdirectory(BConcreteToCAPI)
add_subdirectory(TracingToCAPI)
add_subdirectory(ConcreteToCAPI)
add_subdirectory(SDFGToStreamEmulator)
add_subdirectory(MLIRLowerableDialectsToLLVM)
add_subdirectory(LinalgExtras)

View File

@@ -1,17 +0,0 @@
add_mlir_dialect_library(
ConcreteToBConcrete
ConcreteToBConcrete.cpp
ADDITIONAL_HEADER_DIRS
${PROJECT_SOURCE_DIR}/include/concretelang/Dialect/Concrete
DEPENDS
ConcreteDialect
BConcreteDialect
mlir-headers
LINK_LIBS
PUBLIC
MLIRIR
MLIRTransforms
MLIRLinalgTransforms
MLIRMathDialect)
target_link_libraries(ConcreteToBConcrete PUBLIC BConcreteDialect MLIRIR)

View File

@@ -0,0 +1,14 @@
add_mlir_dialect_library(
ConcreteToCAPI
ConcreteToCAPI.cpp
ADDITIONAL_HEADER_DIRS
${PROJECT_SOURCE_DIR}/include/concretelang/Dialect/Concrete
DEPENDS
ConcreteDialect
mlir-headers
LINK_LIBS
PUBLIC
MLIRIR
MLIRTransforms)
target_link_libraries(ConcreteToCAPI PUBLIC ConcreteDialect MLIRIR)

View File

@@ -8,12 +8,13 @@
#include "concretelang/Conversion/Passes.h"
#include "concretelang/Conversion/Tools.h"
#include "concretelang/Dialect/BConcrete/IR/BConcreteOps.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteOps.h"
#include "concretelang/Dialect/RT/IR/RTOps.h"
#include "mlir/Dialect/Bufferization/Transforms/BufferUtils.h"
namespace {
namespace BConcrete = mlir::concretelang::BConcrete;
namespace Concrete = mlir::concretelang::Concrete;
namespace arith = mlir::arith;
namespace func = mlir::func;
namespace memref = mlir::memref;
@@ -200,23 +201,23 @@ mlir::LogicalResult insertForwardDeclarationOfTheCAPI(
return insertForwardDeclaration(op, rewriter, funcName, funcType);
}
template <typename BConcreteOp>
void addNoOperands(BConcreteOp op, mlir::SmallVector<mlir::Value> &operands,
template <typename ConcreteOp>
void addNoOperands(ConcreteOp op, mlir::SmallVector<mlir::Value> &operands,
mlir::RewriterBase &rewriter) {}
template <typename BConcreteOp, char const *callee>
struct BConcreteToCAPICallPattern : public mlir::OpRewritePattern<BConcreteOp> {
BConcreteToCAPICallPattern(
template <typename ConcreteOp, char const *callee>
struct ConcreteToCAPICallPattern : public mlir::OpRewritePattern<ConcreteOp> {
ConcreteToCAPICallPattern(
::mlir::MLIRContext *context,
std::function<void(BConcreteOp bOp, llvm::SmallVector<mlir::Value> &,
std::function<void(ConcreteOp bOp, llvm::SmallVector<mlir::Value> &,
mlir::RewriterBase &)>
addOperands = addNoOperands<BConcreteOp>,
addOperands = addNoOperands<ConcreteOp>,
mlir::PatternBenefit benefit = 1)
: ::mlir::OpRewritePattern<BConcreteOp>(context, benefit),
: ::mlir::OpRewritePattern<ConcreteOp>(context, benefit),
addOperands(addOperands) {}
::mlir::LogicalResult
matchAndRewrite(BConcreteOp bOp,
matchAndRewrite(ConcreteOp bOp,
::mlir::PatternRewriter &rewriter) const override {
// Create the operands
@@ -246,7 +247,7 @@ struct BConcreteToCAPICallPattern : public mlir::OpRewritePattern<BConcreteOp> {
};
private:
std::function<void(BConcreteOp bOp, llvm::SmallVector<mlir::Value> &,
std::function<void(ConcreteOp bOp, llvm::SmallVector<mlir::Value> &,
mlir::RewriterBase &)>
addOperands;
};
@@ -297,7 +298,7 @@ void bootstrapAddOperands(BootstrapOp op,
operands.push_back(getContextArgument(op));
}
void wopPBSAddOperands(BConcrete::WopPBSCRTLweBufferOp op,
void wopPBSAddOperands(Concrete::WopPBSCRTLweBufferOp op,
mlir::SmallVector<mlir::Value> &operands,
mlir::RewriterBase &rewriter) {
mlir::Type crtType = mlir::RankedTensorType::get(
@@ -333,7 +334,7 @@ void wopPBSAddOperands(BConcrete::WopPBSCRTLweBufferOp op,
}
void encodePlaintextWithCrtAddOperands(
BConcrete::EncodePlaintextWithCrtBufferOp op,
Concrete::EncodePlaintextWithCrtBufferOp op,
mlir::SmallVector<mlir::Value> &operands, mlir::RewriterBase &rewriter) {
// mods
mlir::Type modsType = mlir::RankedTensorType::get({(int)op.modsAttr().size()},
@@ -358,7 +359,7 @@ void encodePlaintextWithCrtAddOperands(
}
void encodeExpandLutForBootstrapAddOperands(
BConcrete::EncodeExpandLutForBootstrapBufferOp op,
Concrete::EncodeExpandLutForBootstrapBufferOp op,
mlir::SmallVector<mlir::Value> &operands, mlir::RewriterBase &rewriter) {
// poly_size
operands.push_back(
@@ -372,7 +373,7 @@ void encodeExpandLutForBootstrapAddOperands(
}
void encodeExpandLutForWopPBSAddOperands(
BConcrete::EncodeExpandLutForWopPBSBufferOp op,
Concrete::EncodeExpandLutForWopPBSBufferOp op,
mlir::SmallVector<mlir::Value> &operands, mlir::RewriterBase &rewriter) {
// crt_decomposition
@@ -424,9 +425,9 @@ void encodeExpandLutForWopPBSAddOperands(
rewriter.create<mlir::arith::ConstantOp>(op.getLoc(), op.isSignedAttr()));
}
struct BConcreteToCAPIPass : public BConcreteToCAPIBase<BConcreteToCAPIPass> {
struct ConcreteToCAPIPass : public ConcreteToCAPIBase<ConcreteToCAPIPass> {
BConcreteToCAPIPass(bool gpu) : gpu(gpu) {}
ConcreteToCAPIPass(bool gpu) : gpu(gpu) {}
void runOnOperation() override {
auto op = this->getOperation();
@@ -441,73 +442,73 @@ struct BConcreteToCAPIPass : public BConcreteToCAPIBase<BConcreteToCAPIPass> {
target.addLegalDialect<mlir::LLVM::LLVMDialect>();
// Make sure that no ops from `FHE` remain after the lowering
target.addIllegalDialect<BConcrete::BConcreteDialect>();
target.addIllegalDialect<Concrete::ConcreteDialect>();
// Add patterns to transform BConcrete operators to CAPI call
patterns.add<BConcreteToCAPICallPattern<BConcrete::AddLweBufferOp,
memref_add_lwe_ciphertexts_u64>>(
// Add patterns to transform Concrete operators to CAPI call
patterns.add<ConcreteToCAPICallPattern<Concrete::AddLweBufferOp,
memref_add_lwe_ciphertexts_u64>>(
&getContext());
patterns.add<
BConcreteToCAPICallPattern<BConcrete::AddPlaintextLweBufferOp,
memref_add_plaintext_lwe_ciphertext_u64>>(
ConcreteToCAPICallPattern<Concrete::AddPlaintextLweBufferOp,
memref_add_plaintext_lwe_ciphertext_u64>>(
&getContext());
patterns.add<
BConcreteToCAPICallPattern<BConcrete::MulCleartextLweBufferOp,
memref_mul_cleartext_lwe_ciphertext_u64>>(
ConcreteToCAPICallPattern<Concrete::MulCleartextLweBufferOp,
memref_mul_cleartext_lwe_ciphertext_u64>>(
&getContext());
patterns.add<BConcreteToCAPICallPattern<BConcrete::NegateLweBufferOp,
memref_negate_lwe_ciphertext_u64>>(
patterns.add<ConcreteToCAPICallPattern<Concrete::NegateLweBufferOp,
memref_negate_lwe_ciphertext_u64>>(
&getContext());
patterns
.add<ConcreteToCAPICallPattern<Concrete::EncodePlaintextWithCrtBufferOp,
memref_encode_plaintext_with_crt>>(
&getContext(), encodePlaintextWithCrtAddOperands);
patterns.add<
BConcreteToCAPICallPattern<BConcrete::EncodePlaintextWithCrtBufferOp,
memref_encode_plaintext_with_crt>>(
&getContext(), encodePlaintextWithCrtAddOperands);
patterns.add<BConcreteToCAPICallPattern<
BConcrete::EncodeExpandLutForBootstrapBufferOp,
memref_encode_expand_lut_for_bootstrap>>(
ConcreteToCAPICallPattern<Concrete::EncodeExpandLutForBootstrapBufferOp,
memref_encode_expand_lut_for_bootstrap>>(
&getContext(), encodeExpandLutForBootstrapAddOperands);
patterns.add<
BConcreteToCAPICallPattern<BConcrete::EncodeExpandLutForWopPBSBufferOp,
memref_encode_expand_lut_for_woppbs>>(
ConcreteToCAPICallPattern<Concrete::EncodeExpandLutForWopPBSBufferOp,
memref_encode_expand_lut_for_woppbs>>(
&getContext(), encodeExpandLutForWopPBSAddOperands);
if (gpu) {
patterns.add<BConcreteToCAPICallPattern<BConcrete::KeySwitchLweBufferOp,
memref_keyswitch_lwe_cuda_u64>>(
&getContext(), keyswitchAddOperands<BConcrete::KeySwitchLweBufferOp>);
patterns.add<BConcreteToCAPICallPattern<BConcrete::BootstrapLweBufferOp,
memref_bootstrap_lwe_cuda_u64>>(
&getContext(), bootstrapAddOperands<BConcrete::BootstrapLweBufferOp>);
patterns.add<ConcreteToCAPICallPattern<Concrete::KeySwitchLweBufferOp,
memref_keyswitch_lwe_cuda_u64>>(
&getContext(), keyswitchAddOperands<Concrete::KeySwitchLweBufferOp>);
patterns.add<ConcreteToCAPICallPattern<Concrete::BootstrapLweBufferOp,
memref_bootstrap_lwe_cuda_u64>>(
&getContext(), bootstrapAddOperands<Concrete::BootstrapLweBufferOp>);
patterns.add<
BConcreteToCAPICallPattern<BConcrete::BatchedKeySwitchLweBufferOp,
memref_batched_keyswitch_lwe_cuda_u64>>(
ConcreteToCAPICallPattern<Concrete::BatchedKeySwitchLweBufferOp,
memref_batched_keyswitch_lwe_cuda_u64>>(
&getContext(),
keyswitchAddOperands<BConcrete::BatchedKeySwitchLweBufferOp>);
keyswitchAddOperands<Concrete::BatchedKeySwitchLweBufferOp>);
patterns.add<
BConcreteToCAPICallPattern<BConcrete::BatchedBootstrapLweBufferOp,
memref_batched_bootstrap_lwe_cuda_u64>>(
ConcreteToCAPICallPattern<Concrete::BatchedBootstrapLweBufferOp,
memref_batched_bootstrap_lwe_cuda_u64>>(
&getContext(),
bootstrapAddOperands<BConcrete::BatchedBootstrapLweBufferOp>);
bootstrapAddOperands<Concrete::BatchedBootstrapLweBufferOp>);
} else {
patterns.add<BConcreteToCAPICallPattern<BConcrete::KeySwitchLweBufferOp,
memref_keyswitch_lwe_u64>>(
&getContext(), keyswitchAddOperands<BConcrete::KeySwitchLweBufferOp>);
patterns.add<BConcreteToCAPICallPattern<BConcrete::BootstrapLweBufferOp,
memref_bootstrap_lwe_u64>>(
&getContext(), bootstrapAddOperands<BConcrete::BootstrapLweBufferOp>);
patterns.add<
BConcreteToCAPICallPattern<BConcrete::BatchedKeySwitchLweBufferOp,
memref_batched_keyswitch_lwe_u64>>(
&getContext(),
keyswitchAddOperands<BConcrete::BatchedKeySwitchLweBufferOp>);
patterns.add<
BConcreteToCAPICallPattern<BConcrete::BatchedBootstrapLweBufferOp,
memref_batched_bootstrap_lwe_u64>>(
&getContext(),
bootstrapAddOperands<BConcrete::BatchedBootstrapLweBufferOp>);
patterns.add<ConcreteToCAPICallPattern<Concrete::KeySwitchLweBufferOp,
memref_keyswitch_lwe_u64>>(
&getContext(), keyswitchAddOperands<Concrete::KeySwitchLweBufferOp>);
patterns.add<ConcreteToCAPICallPattern<Concrete::BootstrapLweBufferOp,
memref_bootstrap_lwe_u64>>(
&getContext(), bootstrapAddOperands<Concrete::BootstrapLweBufferOp>);
patterns
.add<ConcreteToCAPICallPattern<Concrete::BatchedKeySwitchLweBufferOp,
memref_batched_keyswitch_lwe_u64>>(
&getContext(),
keyswitchAddOperands<Concrete::BatchedKeySwitchLweBufferOp>);
patterns
.add<ConcreteToCAPICallPattern<Concrete::BatchedBootstrapLweBufferOp,
memref_batched_bootstrap_lwe_u64>>(
&getContext(),
bootstrapAddOperands<Concrete::BatchedBootstrapLweBufferOp>);
}
patterns.add<BConcreteToCAPICallPattern<BConcrete::WopPBSCRTLweBufferOp,
memref_wop_pbs_crt_buffer>>(
patterns.add<ConcreteToCAPICallPattern<Concrete::WopPBSCRTLweBufferOp,
memref_wop_pbs_crt_buffer>>(
&getContext(), wopPBSAddOperands);
// Apply conversion
@@ -526,8 +527,8 @@ private:
namespace mlir {
namespace concretelang {
std::unique_ptr<OperationPass<ModuleOp>>
createConvertBConcreteToCAPIPass(bool gpu) {
return std::make_unique<BConcreteToCAPIPass>(gpu);
createConvertConcreteToCAPIPass(bool gpu) {
return std::make_unique<ConcreteToCAPIPass>(gpu);
}
} // namespace concretelang
} // namespace mlir

View File

@@ -111,14 +111,6 @@ void MLIRLowerableDialectsToLLVMPass::runOnOperation() {
mlir::LowerToLLVMOptions options(&getContext());
mlir::LLVMTypeConverter typeConverter(&getContext(), options);
typeConverter.addConversion(convertTypes);
typeConverter.addConversion(
[&](mlir::concretelang::Concrete::PlaintextType type) {
return mlir::IntegerType::get(type.getContext(), 64);
});
typeConverter.addConversion(
[&](mlir::concretelang::Concrete::CleartextType type) {
return mlir::IntegerType::get(type.getContext(), 64);
});
// Setup the set of the patterns rewriter. At this point we want to
// convert the `scf` operations to `std` and `std` operations to `llvm`.
@@ -153,9 +145,7 @@ void MLIRLowerableDialectsToLLVMPass::runOnOperation() {
llvm::Optional<mlir::Type>
MLIRLowerableDialectsToLLVMPass::convertTypes(mlir::Type type) {
if (type.isa<mlir::concretelang::Concrete::LweCiphertextType>() ||
type.isa<mlir::concretelang::Concrete::GlweCiphertextType>() ||
type.isa<mlir::concretelang::Concrete::ContextType>() ||
if (type.isa<mlir::concretelang::Concrete::ContextType>() ||
type.isa<mlir::concretelang::RT::FutureType>() ||
type.isa<mlir::concretelang::SDFG::DFGType>() ||
type.isa<mlir::concretelang::SDFG::StreamType>()) {
@@ -166,14 +156,6 @@ MLIRLowerableDialectsToLLVMPass::convertTypes(mlir::Type type) {
mlir::LowerToLLVMOptions options(type.getContext());
mlir::LLVMTypeConverter typeConverter(type.getContext(), options);
typeConverter.addConversion(convertTypes);
typeConverter.addConversion(
[&](mlir::concretelang::Concrete::PlaintextType type) {
return mlir::IntegerType::get(type.getContext(), 64);
});
typeConverter.addConversion(
[&](mlir::concretelang::Concrete::CleartextType type) {
return mlir::IntegerType::get(type.getContext(), 64);
});
mlir::Type subtype =
type.dyn_cast<mlir::concretelang::RT::PointerType>().getElementType();
mlir::Type convertedSubtype = typeConverter.convertType(subtype);

View File

@@ -368,8 +368,8 @@ void SDFGToStreamEmulatorPass::runOnOperation() {
target.addIllegalOp<SDFG::Init, SDFG::Start, SDFG::Shutdown,
SDFG::MakeProcess, SDFG::MakeStream, SDFG::Put>();
// All BConcrete ops are legal after the conversion
target.addLegalDialect<mlir::concretelang::BConcrete::BConcreteDialect>();
// All Concrete ops are legal after the conversion
target.addLegalDialect<mlir::concretelang::Concrete::ConcreteDialect>();
target.addLegalDialect<mlir::arith::ArithmeticDialect>();
target.addLegalOp<mlir::func::ReturnOp, mlir::func::FuncOp,
mlir::func::CallOp, SDFG::Get, mlir::tensor::CastOp>();

View File

@@ -10,16 +10,19 @@
#include "mlir/Transforms/DialectConversion.h"
#include "concretelang/Conversion/Passes.h"
#include "concretelang/Conversion/TFHEToConcrete/Patterns.h"
#include "concretelang/Conversion/Utils/FuncConstOpConversion.h"
#include "concretelang/Conversion/Utils/RegionOpTypeConverterPattern.h"
#include "concretelang/Conversion/Utils/ReinstantiatingOpTypeConversion.h"
#include "concretelang/Conversion/Utils/TensorOpTypeConversion.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteDialect.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteOps.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteTypes.h"
#include "concretelang/Dialect/RT/IR/RTOps.h"
#include "concretelang/Dialect/TFHE/IR/TFHEDialect.h"
#include "concretelang/Dialect/TFHE/IR/TFHEOps.h"
#include "concretelang/Dialect/TFHE/IR/TFHETypes.h"
#include "concretelang/Dialect/Tracing/IR/TracingOps.h"
#include "concretelang/Support/Constants.h"
namespace TFHE = mlir::concretelang::TFHE;
namespace Concrete = mlir::concretelang::Concrete;
@@ -31,27 +34,38 @@ struct TFHEToConcretePass : public TFHEToConcreteBase<TFHEToConcretePass> {
};
} // namespace
using mlir::concretelang::Concrete::LweCiphertextType;
using mlir::concretelang::TFHE::GLWECipherTextType;
/// TFHEToConcreteTypeConverter is a TypeConverter that transform
/// `TFHE.glwe<{_,_,_}{p}>` to Concrete.lwe_ciphertext
/// `TFHE.glwe<{dimension,1,bits}{p}>` to `tensor<dimension+1, i64>>`
/// `tensor<...xTFHE.glwe<{dimension,1,bits}{p}>>` to
/// `tensor<...xdimension+1, i64>>`
class TFHEToConcreteTypeConverter : public mlir::TypeConverter {
public:
TFHEToConcreteTypeConverter() {
addConversion([](mlir::Type type) { return type; });
addConversion([&](GLWECipherTextType type) {
return mlir::concretelang::convertTypeToLWE(type.getContext(), type);
assert(type.getPolynomialSize() <= 1 &&
"converter doesn't support polynomialSize > 1");
assert(type.getDimension() != -1);
llvm::SmallVector<int64_t, 2> shape;
shape.push_back(type.getDimension() + 1);
return mlir::RankedTensorType::get(
shape, mlir::IntegerType::get(type.getContext(), 64));
});
addConversion([&](mlir::RankedTensorType type) {
auto glwe = type.getElementType().dyn_cast_or_null<GLWECipherTextType>();
if (glwe == nullptr) {
return (mlir::Type)(type);
}
mlir::SmallVector<int64_t> newShape;
newShape.reserve(type.getShape().size() + 1);
newShape.append(type.getShape().begin(), type.getShape().end());
assert(glwe.getDimension() != -1);
newShape.push_back(glwe.getDimension() + 1);
mlir::Type r = mlir::RankedTensorType::get(
type.getShape(),
mlir::concretelang::convertTypeToLWE(glwe.getContext(), glwe));
newShape, mlir::IntegerType::get(type.getContext(), 64));
return r;
});
addConversion([&](mlir::concretelang::RT::FutureType type) {
@@ -69,73 +83,84 @@ public:
namespace {
struct BootstrapGLWEOpPattern
: public mlir::OpRewritePattern<TFHE::BootstrapGLWEOp> {
BootstrapGLWEOpPattern(mlir::MLIRContext *context,
mlir::TypeConverter &converter,
mlir::PatternBenefit benefit = 100)
: mlir::OpRewritePattern<TFHE::BootstrapGLWEOp>(context, benefit),
converter(converter) {}
struct SubIntGLWEOpPattern
: public mlir::OpConversionPattern<TFHE::SubGLWEIntOp> {
mlir::LogicalResult
matchAndRewrite(TFHE::BootstrapGLWEOp bsOp,
mlir::PatternRewriter &rewriter) const override {
mlir::Type resultType = converter.convertType(bsOp.getType());
SubIntGLWEOpPattern(mlir::MLIRContext *context,
mlir::TypeConverter &typeConverter)
: mlir::OpConversionPattern<TFHE::SubGLWEIntOp>(
typeConverter, context,
mlir::concretelang::DEFAULT_PATTERN_BENEFIT) {}
auto newOp = rewriter.replaceOpWithNewOp<Concrete::BootstrapLweOp>(
bsOp, resultType, bsOp.ciphertext(), bsOp.lookup_table(), bsOp.level(),
bsOp.baseLog(), bsOp.polySize(), bsOp.glweDimension());
::mlir::LogicalResult
matchAndRewrite(TFHE::SubGLWEIntOp subOp, TFHE::SubGLWEIntOp::Adaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const override {
mlir::Value negated = rewriter.create<Concrete::NegateLweTensorOp>(
subOp.getLoc(), adaptor.b().getType(), adaptor.b());
rewriter.startRootUpdate(newOp);
newOp.input_ciphertext().setType(
converter.convertType(bsOp.ciphertext().getType()));
rewriter.finalizeRootUpdate(newOp);
rewriter.replaceOpWithNewOp<Concrete::AddPlaintextLweTensorOp>(
subOp, this->getTypeConverter()->convertType(subOp.getType()), negated,
subOp.a());
return ::mlir::success();
return mlir::success();
}
private:
mlir::TypeConverter &converter;
};
struct WopPBSGLWEOpPattern : public mlir::OpRewritePattern<TFHE::WopPBSGLWEOp> {
WopPBSGLWEOpPattern(mlir::MLIRContext *context,
mlir::TypeConverter &converter,
mlir::PatternBenefit benefit = 100)
: mlir::OpRewritePattern<TFHE::WopPBSGLWEOp>(context, benefit),
converter(converter) {}
struct BootstrapGLWEOpPattern
: public mlir::OpConversionPattern<TFHE::BootstrapGLWEOp> {
mlir::LogicalResult
matchAndRewrite(TFHE::WopPBSGLWEOp wopOp,
mlir::PatternRewriter &rewriter) const override {
mlir::Type resultType = converter.convertType(wopOp.getType());
BootstrapGLWEOpPattern(mlir::MLIRContext *context,
mlir::TypeConverter &typeConverter)
: mlir::OpConversionPattern<TFHE::BootstrapGLWEOp>(
typeConverter, context,
mlir::concretelang::DEFAULT_PATTERN_BENEFIT) {}
auto newOp = rewriter.replaceOpWithNewOp<Concrete::WopPBSLweOp>(
wopOp, resultType, wopOp.ciphertexts(), wopOp.lookupTable(),
// Bootstrap parameters
wopOp.bootstrapLevel(), wopOp.bootstrapBaseLog(),
// Keyswitch parameters
wopOp.keyswitchLevel(), wopOp.keyswitchBaseLog(),
// Packing keyswitch key parameters
wopOp.packingKeySwitchInputLweDimension(),
wopOp.packingKeySwitchoutputPolynomialSize(),
wopOp.packingKeySwitchLevel(), wopOp.packingKeySwitchBaseLog(),
// Circuit bootstrap parameters
wopOp.circuitBootstrapLevel(), wopOp.circuitBootstrapBaseLog(),
// Crt Decomposition
wopOp.crtDecomposition());
::mlir::LogicalResult
matchAndRewrite(TFHE::BootstrapGLWEOp bsOp,
TFHE::BootstrapGLWEOp::Adaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const override {
rewriter.startRootUpdate(newOp);
TFHE::GLWECipherTextType resultType =
bsOp.getType().cast<TFHE::GLWECipherTextType>();
TFHE::GLWECipherTextType inputType =
bsOp.ciphertext().getType().cast<TFHE::GLWECipherTextType>();
newOp.ciphertexts().setType(
converter.convertType(wopOp.ciphertexts().getType()));
rewriter.replaceOpWithNewOp<Concrete::BootstrapLweTensorOp>(
bsOp, this->getTypeConverter()->convertType(resultType),
adaptor.ciphertext(), adaptor.lookup_table(), inputType.getDimension(),
adaptor.polySize(), adaptor.level(), adaptor.baseLog(),
adaptor.glweDimension(), resultType.getP());
rewriter.finalizeRootUpdate(newOp);
return ::mlir::success();
return mlir::success();
}
};
private:
mlir::TypeConverter &converter;
struct KeySwitchGLWEOpPattern
: public mlir::OpConversionPattern<TFHE::KeySwitchGLWEOp> {
KeySwitchGLWEOpPattern(mlir::MLIRContext *context,
mlir::TypeConverter &typeConverter)
: mlir::OpConversionPattern<TFHE::KeySwitchGLWEOp>(
typeConverter, context,
mlir::concretelang::DEFAULT_PATTERN_BENEFIT) {}
::mlir::LogicalResult
matchAndRewrite(TFHE::KeySwitchGLWEOp ksOp,
TFHE::KeySwitchGLWEOp::Adaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const override {
TFHE::GLWECipherTextType resultType =
ksOp.getType().cast<TFHE::GLWECipherTextType>();
TFHE::GLWECipherTextType inputType =
ksOp.ciphertext().getType().cast<TFHE::GLWECipherTextType>();
rewriter.replaceOpWithNewOp<Concrete::KeySwitchLweTensorOp>(
ksOp, this->getTypeConverter()->convertType(resultType),
adaptor.ciphertext(), adaptor.level(), adaptor.baseLog(),
inputType.getDimension(), resultType.getDimension());
return mlir::success();
}
};
struct TracePlaintextOpPattern
@@ -163,6 +188,419 @@ struct TracePlaintextOpPattern
}
};
template <typename ZeroOp>
struct ZeroOpPattern : public mlir::OpRewritePattern<ZeroOp> {
ZeroOpPattern(mlir::MLIRContext *context)
: mlir::OpRewritePattern<ZeroOp>(
context, mlir::concretelang::DEFAULT_PATTERN_BENEFIT) {}
::mlir::LogicalResult
matchAndRewrite(ZeroOp zeroOp,
mlir::PatternRewriter &rewriter) const override {
TFHEToConcreteTypeConverter converter;
auto newResultTy = converter.convertType(zeroOp.getType());
auto generateBody = [&](mlir::OpBuilder &nestedBuilder,
mlir::Location nestedLoc,
mlir::ValueRange blockArgs) {
// %c0 = 0 : i64
auto cstOp = nestedBuilder.create<mlir::arith::ConstantOp>(
nestedLoc, nestedBuilder.getI64IntegerAttr(0));
// tensor.yield %z : !FHE.eint<p>
nestedBuilder.create<mlir::tensor::YieldOp>(nestedLoc, cstOp.getResult());
};
// tensor.generate
rewriter.replaceOpWithNewOp<mlir::tensor::GenerateOp>(
zeroOp, newResultTy, mlir::ValueRange{}, generateBody);
return ::mlir::success();
};
};
/// Pattern that rewrites the ExtractSlice operation, taking into account the
/// additional LWE dimension introduced during type conversion
struct ExtractSliceOpPattern
: public mlir::OpConversionPattern<mlir::tensor::ExtractSliceOp> {
ExtractSliceOpPattern(mlir::MLIRContext *context,
mlir::TypeConverter &typeConverter)
: ::mlir::OpConversionPattern<mlir::tensor::ExtractSliceOp>(
typeConverter, context,
mlir::concretelang::DEFAULT_PATTERN_BENEFIT) {}
::mlir::LogicalResult
matchAndRewrite(mlir::tensor::ExtractSliceOp extractSliceOp,
mlir::tensor::ExtractSliceOp::Adaptor adaptor,
::mlir::ConversionPatternRewriter &rewriter) const override {
// is not a tensor of GLWEs that need to be extended with the LWE dimension
if (this->getTypeConverter()->isLegal(extractSliceOp.getType())) {
return mlir::failure();
}
auto resultTy = extractSliceOp.result().getType();
auto newResultTy = this->getTypeConverter()
->convertType(resultTy)
.cast<mlir::RankedTensorType>();
// add 0 to the static_offsets
mlir::SmallVector<mlir::Attribute> staticOffsets;
staticOffsets.append(adaptor.static_offsets().begin(),
adaptor.static_offsets().end());
staticOffsets.push_back(rewriter.getI64IntegerAttr(0));
// add the lweSize to the sizes
mlir::SmallVector<mlir::Attribute> staticSizes;
staticSizes.append(adaptor.static_sizes().begin(),
adaptor.static_sizes().end());
staticSizes.push_back(rewriter.getI64IntegerAttr(
newResultTy.getDimSize(newResultTy.getRank() - 1)));
// add 1 to the strides
mlir::SmallVector<mlir::Attribute> staticStrides;
staticStrides.append(adaptor.static_strides().begin(),
adaptor.static_strides().end());
staticStrides.push_back(rewriter.getI64IntegerAttr(1));
// replace tensor.extract_slice to the new one
rewriter.replaceOpWithNewOp<mlir::tensor::ExtractSliceOp>(
extractSliceOp, newResultTy, adaptor.source(), adaptor.offsets(),
adaptor.sizes(), adaptor.strides(),
rewriter.getArrayAttr(staticOffsets),
rewriter.getArrayAttr(staticSizes),
rewriter.getArrayAttr(staticStrides));
return ::mlir::success();
};
};
/// Pattern that rewrites the Extract operation, taking into account the
/// additional LWE dimension introduced during type conversion
struct ExtractOpPattern
: public mlir::OpConversionPattern<mlir::tensor::ExtractOp> {
ExtractOpPattern(::mlir::MLIRContext *context,
mlir::TypeConverter &typeConverter)
: ::mlir::OpConversionPattern<mlir::tensor::ExtractOp>(
typeConverter, context,
mlir::concretelang::DEFAULT_PATTERN_BENEFIT) {}
::mlir::LogicalResult
matchAndRewrite(mlir::tensor::ExtractOp extractOp,
mlir::tensor::ExtractOp::Adaptor adaptor,
::mlir::ConversionPatternRewriter &rewriter) const override {
// is not a tensor of GLWEs that need to be extended with the LWE dimension
if (this->getTypeConverter()->isLegal(extractOp.getType())) {
return mlir::failure();
}
auto newResultType = this->getTypeConverter()
->convertType(extractOp.getType())
.cast<mlir::RankedTensorType>();
auto tensorRank =
adaptor.tensor().getType().cast<mlir::RankedTensorType>().getRank();
// [min..., 0] for static_offsets ()
mlir::SmallVector<mlir::Attribute> staticOffsets(
tensorRank,
rewriter.getI64IntegerAttr(std::numeric_limits<int64_t>::min()));
staticOffsets[staticOffsets.size() - 1] = rewriter.getI64IntegerAttr(0);
// [1..., lweDimension+1] for static_sizes or
// [1..., nbBlock, lweDimension+1]
mlir::SmallVector<mlir::Attribute> staticSizes(
tensorRank, rewriter.getI64IntegerAttr(1));
staticSizes[staticSizes.size() - 1] = rewriter.getI64IntegerAttr(
newResultType.getDimSize(newResultType.getRank() - 1));
// [1...] for static_strides
mlir::SmallVector<mlir::Attribute> staticStrides(
tensorRank, rewriter.getI64IntegerAttr(1));
rewriter.replaceOpWithNewOp<mlir::tensor::ExtractSliceOp>(
extractOp, newResultType, adaptor.tensor(), adaptor.indices(),
mlir::SmallVector<mlir::Value>{}, mlir::SmallVector<mlir::Value>{},
rewriter.getArrayAttr(staticOffsets),
rewriter.getArrayAttr(staticSizes),
rewriter.getArrayAttr(staticStrides));
return ::mlir::success();
};
};
/// Pattern that rewrites the InsertSlice operation, taking into account the
/// additional LWE dimension introduced during type conversion
struct InsertSliceOpPattern
: public mlir::OpConversionPattern<mlir::tensor::InsertSliceOp> {
InsertSliceOpPattern(mlir::MLIRContext *context,
mlir::TypeConverter &typeConverter)
: ::mlir::OpConversionPattern<mlir::tensor::InsertSliceOp>(
typeConverter, context,
mlir::concretelang::DEFAULT_PATTERN_BENEFIT) {}
::mlir::LogicalResult
matchAndRewrite(mlir::tensor::InsertSliceOp insertSliceOp,
mlir::tensor::InsertSliceOp::Adaptor adaptor,
::mlir::ConversionPatternRewriter &rewriter) const override {
// is not a tensor of GLWEs that need to be extended with the LWE dimension
if (this->getTypeConverter()->isLegal(insertSliceOp.getType())) {
return mlir::failure();
}
auto newResultTy = this->getTypeConverter()
->convertType(insertSliceOp.result().getType())
.cast<mlir::RankedTensorType>();
// add 0 to static_offsets
mlir::SmallVector<mlir::Attribute> staticOffsets;
staticOffsets.append(adaptor.static_offsets().begin(),
adaptor.static_offsets().end());
staticOffsets.push_back(rewriter.getI64IntegerAttr(0));
// add lweDimension+1 to static_sizes
mlir::SmallVector<mlir::Attribute> staticSizes;
staticSizes.append(adaptor.static_sizes().begin(),
adaptor.static_sizes().end());
staticSizes.push_back(rewriter.getI64IntegerAttr(
newResultTy.getDimSize(newResultTy.getRank() - 1)));
// add 1 to the strides
mlir::SmallVector<mlir::Attribute> staticStrides;
staticStrides.append(adaptor.static_strides().begin(),
adaptor.static_strides().end());
staticStrides.push_back(rewriter.getI64IntegerAttr(1));
// replace tensor.insert_slice with the new one
rewriter.replaceOpWithNewOp<mlir::tensor::InsertSliceOp>(
insertSliceOp, newResultTy, adaptor.source(), adaptor.dest(),
adaptor.offsets(), adaptor.sizes(), adaptor.strides(),
rewriter.getArrayAttr(staticOffsets),
rewriter.getArrayAttr(staticSizes),
rewriter.getArrayAttr(staticStrides));
return ::mlir::success();
};
};
/// Pattern that rewrites the Insert operation, taking into account the
/// additional LWE dimension introduced during type conversion
struct InsertOpPattern
: public mlir::OpConversionPattern<mlir::tensor::InsertOp> {
InsertOpPattern(mlir::MLIRContext *context,
mlir::TypeConverter &typeConverter)
: ::mlir::OpConversionPattern<mlir::tensor::InsertOp>(
typeConverter, context,
mlir::concretelang::DEFAULT_PATTERN_BENEFIT) {}
::mlir::LogicalResult
matchAndRewrite(mlir::tensor::InsertOp insertOp,
mlir::tensor::InsertOp::Adaptor adaptor,
::mlir::ConversionPatternRewriter &rewriter) const override {
// is not a tensor of GLWEs that need to be extended with the LWE dimension
if (this->getTypeConverter()->isLegal(insertOp.getType())) {
return mlir::failure();
}
mlir::RankedTensorType newResultTy =
this->getTypeConverter()
->convertType(insertOp.result().getType())
.cast<mlir::RankedTensorType>();
// add zeros to static_offsets
mlir::SmallVector<mlir::OpFoldResult> offsets;
offsets.append(adaptor.indices().begin(), adaptor.indices().end());
offsets.push_back(rewriter.getIndexAttr(0));
// Inserting a smaller tensor into a (potentially) bigger one. Set
// dimensions for all leading dimensions of the target tensor not
// present in the source to 1.
mlir::SmallVector<mlir::OpFoldResult> sizes(adaptor.indices().size(),
rewriter.getI64IntegerAttr(1));
// Add size for the bufferized source element
sizes.push_back(rewriter.getI64IntegerAttr(
newResultTy.getDimSize(newResultTy.getRank() - 1)));
// Set stride of all dimensions to 1
mlir::SmallVector<mlir::OpFoldResult> strides(
newResultTy.getRank(), rewriter.getI64IntegerAttr(1));
// replace tensor.insert_slice with the new one
rewriter.replaceOpWithNewOp<mlir::tensor::InsertSliceOp>(
insertOp, adaptor.scalar(), adaptor.dest(), offsets, sizes, strides);
return ::mlir::success();
};
};
/// FromElementsOpPatterns transform each tensor.from_elements that operates on
/// TFHE.glwe
///
/// refs: check_tests/Conversion/TFHEToConcrete/tensor_from_elements.mlir
struct FromElementsOpPattern
: public mlir::OpConversionPattern<mlir::tensor::FromElementsOp> {
FromElementsOpPattern(mlir::MLIRContext *context,
mlir::TypeConverter &typeConverter)
: ::mlir::OpConversionPattern<mlir::tensor::FromElementsOp>(
typeConverter, context,
mlir::concretelang::DEFAULT_PATTERN_BENEFIT) {}
::mlir::LogicalResult
matchAndRewrite(mlir::tensor::FromElementsOp fromElementsOp,
mlir::tensor::FromElementsOp::Adaptor adaptor,
::mlir::ConversionPatternRewriter &rewriter) const override {
// is not a tensor of GLWEs that need to be extended with the LWE dimension
if (this->getTypeConverter()->isLegal(fromElementsOp.getType())) {
return mlir::failure();
}
auto converter = this->getTypeConverter();
auto resultTy = fromElementsOp.result().getType();
if (converter->isLegal(resultTy)) {
return mlir::failure();
}
auto oldTensorResultTy = resultTy.cast<mlir::RankedTensorType>();
auto oldRank = oldTensorResultTy.getRank();
auto newTensorResultTy =
converter->convertType(resultTy).cast<mlir::RankedTensorType>();
auto newRank = newTensorResultTy.getRank();
auto newShape = newTensorResultTy.getShape();
mlir::Value tensor = rewriter.create<mlir::bufferization::AllocTensorOp>(
fromElementsOp.getLoc(), newTensorResultTy, mlir::ValueRange{});
// sizes are [1, ..., 1, diffShape...]
llvm::SmallVector<mlir::OpFoldResult> sizes(oldRank,
rewriter.getI64IntegerAttr(1));
for (auto i = newRank - oldRank; i > 0; i--) {
sizes.push_back(rewriter.getI64IntegerAttr(*(newShape.end() - i)));
}
// strides are [1, ..., 1]
llvm::SmallVector<mlir::OpFoldResult> oneStrides(
newShape.size(), rewriter.getI64IntegerAttr(1));
// start with offets [0, ..., 0]
llvm::SmallVector<int64_t> currentOffsets(newRank, 0);
// for each elements insert_slice with right offet
for (auto elt : llvm::enumerate(adaptor.elements())) {
// Just create offsets as attributes
llvm::SmallVector<mlir::OpFoldResult, 4> offsets;
offsets.reserve(currentOffsets.size());
std::transform(currentOffsets.begin(), currentOffsets.end(),
std::back_inserter(offsets),
[&](auto v) { return rewriter.getI64IntegerAttr(v); });
mlir::tensor::InsertSliceOp insOp =
rewriter.create<mlir::tensor::InsertSliceOp>(
fromElementsOp.getLoc(),
/* src: */ elt.value(),
/* dst: */ tensor,
/* offs: */ offsets,
/* sizes: */ sizes,
/* strides: */ oneStrides);
tensor = insOp.getResult();
// Increment the offsets
for (auto i = newRank - 2; i >= 0; i--) {
if (currentOffsets[i] == newShape[i] - 1) {
currentOffsets[i] = 0;
continue;
}
currentOffsets[i]++;
break;
}
}
rewriter.replaceOp(fromElementsOp, tensor);
return ::mlir::success();
};
};
// This template rewrite pattern transforms any instance of
// `ShapeOp` operators that operates on tensor of lwe ciphertext by adding
// the lwe size as a size of the tensor result and by adding a trivial
// reassociation at the end of the reassociations map.
//
// Example:
//
// ```mlir
// %0 = "ShapeOp" %arg0 [reassocations...]
// : tensor<...x!TFHE.glwe<{dimension,1,bits}{p}>> into
// tensor<...x!TFHE.glwe<{dimension,1,bits}{p}>>
// ```
//
// becomes:
//
// ```mlir
// %0 = "ShapeOp" %arg0 [reassociations..., [inRank or outRank]]
// : tensor<...xdimension+1xi64> into
// tensor<...xdimension+1xi64>
// ```
template <typename ShapeOp, typename ShapeOpAdaptor, typename VecTy,
bool inRank>
struct TensorShapeOpPattern : public mlir::OpConversionPattern<ShapeOp> {
TensorShapeOpPattern(mlir::MLIRContext *context,
mlir::TypeConverter &typeConverter)
: ::mlir::OpConversionPattern<ShapeOp>(
typeConverter, context,
mlir::concretelang::DEFAULT_PATTERN_BENEFIT) {}
::mlir::LogicalResult
matchAndRewrite(ShapeOp shapeOp, ShapeOpAdaptor adaptor,
::mlir::ConversionPatternRewriter &rewriter) const override {
// is not a tensor of GLWEs that need to be extended with the LWE dimension
if (this->getTypeConverter()->isLegal(shapeOp.getType())) {
return mlir::failure();
}
auto newResultTy =
((mlir::Type)this->getTypeConverter()->convertType(shapeOp.getType()))
.cast<VecTy>();
auto reassocTy =
((mlir::Type)this->getTypeConverter()->convertType(
(inRank ? shapeOp.src() : shapeOp.result()).getType()))
.cast<VecTy>();
auto oldReassocs = shapeOp.getReassociationIndices();
mlir::SmallVector<mlir::ReassociationIndices> newReassocs;
newReassocs.append(oldReassocs.begin(), oldReassocs.end());
// add [rank] to reassociations
{
mlir::ReassociationIndices lweAssoc;
lweAssoc.push_back(reassocTy.getRank() - 1);
newReassocs.push_back(lweAssoc);
}
rewriter.replaceOpWithNewOp<ShapeOp>(shapeOp, newResultTy, adaptor.src(),
newReassocs);
return ::mlir::success();
};
};
/// Add the instantiated TensorShapeOpPattern rewrite pattern with the
/// `ShapeOp` to the patterns set and populate the conversion target.
template <typename ShapeOp, typename ShapeOpAdaptor, typename VecTy,
bool inRank>
void insertTensorShapeOpPattern(mlir::MLIRContext &context,
mlir::TypeConverter &converter,
mlir::RewritePatternSet &patterns,
mlir::ConversionTarget &target) {
patterns.insert<TensorShapeOpPattern<ShapeOp, ShapeOpAdaptor, VecTy, inRank>>(
&context, converter);
target.addDynamicallyLegalOp<ShapeOp>([&](mlir::Operation *op) {
return converter.isLegal(op->getResultTypes()) &&
converter.isLegal(op->getOperandTypes());
});
}
// The pass is supposed to endup with no TFHE.glwe type. Tensors should be
// extended with an additional dimension at the end, and some patterns in this
// pass are fully dedicated to rewrite tensor ops with this additional dimension
// in mind
void TFHEToConcretePass::runOnOperation() {
auto op = this->getOperation();
@@ -205,60 +643,86 @@ void TFHEToConcretePass::runOnOperation() {
patterns.add<FunctionConstantOpConversion<TFHEToConcreteTypeConverter>>(
&getContext(), converter);
populateWithGeneratedTFHEToConcrete(patterns);
// populateWithGeneratedTFHEToConcrete(patterns);
patterns.add<mlir::concretelang::GenericTypeAndOpConverterPattern<
mlir::concretelang::TFHE::ZeroTensorGLWEOp,
mlir::concretelang::Concrete::ZeroTensorLWEOp>>(&getContext(), converter);
patterns.add<mlir::concretelang::GenericTypeAndOpConverterPattern<
mlir::concretelang::TFHE::EncodeExpandLutForBootstrapOp,
mlir::concretelang::Concrete::EncodeExpandLutForBootstrapOp>>(
// Generic patterns
patterns.insert<
mlir::concretelang::GenericOneToOneOpConversionPattern<
mlir::concretelang::TFHE::AddGLWEOp,
mlir::concretelang::Concrete::AddLweTensorOp>,
mlir::concretelang::GenericOneToOneOpConversionPattern<
mlir::concretelang::TFHE::AddGLWEIntOp,
mlir::concretelang::Concrete::AddPlaintextLweTensorOp>,
mlir::concretelang::GenericOneToOneOpConversionPattern<
mlir::concretelang::TFHE::MulGLWEIntOp,
mlir::concretelang::Concrete::MulCleartextLweTensorOp>,
mlir::concretelang::GenericOneToOneOpConversionPattern<
mlir::concretelang::TFHE::NegGLWEOp,
mlir::concretelang::Concrete::NegateLweTensorOp>,
mlir::concretelang::GenericOneToOneOpConversionPattern<
mlir::concretelang::TFHE::EncodeExpandLutForBootstrapOp,
mlir::concretelang::Concrete::EncodeExpandLutForBootstrapTensorOp,
true>,
mlir::concretelang::GenericOneToOneOpConversionPattern<
mlir::concretelang::TFHE::EncodeExpandLutForWopPBSOp,
mlir::concretelang::Concrete::EncodeExpandLutForWopPBSTensorOp, true>,
mlir::concretelang::GenericOneToOneOpConversionPattern<
mlir::concretelang::TFHE::EncodePlaintextWithCrtOp,
mlir::concretelang::Concrete::EncodePlaintextWithCrtTensorOp, true>,
mlir::concretelang::GenericOneToOneOpConversionPattern<
mlir::concretelang::TFHE::WopPBSGLWEOp,
mlir::concretelang::Concrete::WopPBSCRTLweTensorOp, true>>(
&getContext(), converter);
patterns.add<mlir::concretelang::GenericTypeAndOpConverterPattern<
mlir::concretelang::TFHE::EncodeExpandLutForWopPBSOp,
mlir::concretelang::Concrete::EncodeExpandLutForWopPBSOp>>(&getContext(),
converter);
patterns.add<mlir::concretelang::GenericTypeAndOpConverterPattern<
mlir::concretelang::TFHE::EncodePlaintextWithCrtOp,
mlir::concretelang::Concrete::EncodePlaintextWithCrtOp>>(&getContext(),
converter);
patterns.add<BootstrapGLWEOpPattern>(&getContext(), converter);
patterns.add<WopPBSGLWEOpPattern>(&getContext(), converter);
target.addDynamicallyLegalOp<Concrete::BootstrapLweOp>(
[&](Concrete::BootstrapLweOp op) {
return (converter.isLegal(op->getOperandTypes()) &&
converter.isLegal(op->getResultTypes()));
// pattern of remaining TFHE ops
patterns.insert<ZeroOpPattern<mlir::concretelang::TFHE::ZeroGLWEOp>,
ZeroOpPattern<mlir::concretelang::TFHE::ZeroTensorGLWEOp>>(
&getContext());
patterns.insert<SubIntGLWEOpPattern, BootstrapGLWEOpPattern,
KeySwitchGLWEOpPattern>(&getContext(), converter);
// Add patterns to rewrite tensor operators that works on tensors of TFHE GLWE
// types
patterns.insert<ExtractSliceOpPattern, ExtractOpPattern, InsertSliceOpPattern,
InsertOpPattern, FromElementsOpPattern>(&getContext(),
converter);
// Add patterns to rewrite some of tensor ops that were introduced by the
// linalg bufferization of encrypted tensor
insertTensorShapeOpPattern<mlir::tensor::ExpandShapeOp,
mlir::tensor::ExpandShapeOp::Adaptor,
mlir::TensorType, false>(getContext(), converter,
patterns, target);
insertTensorShapeOpPattern<mlir::tensor::CollapseShapeOp,
mlir::tensor::CollapseShapeOp::Adaptor,
mlir::TensorType, true>(getContext(), converter,
patterns, target);
// legalize ops only if operand and result types are legal
target.addDynamicallyLegalOp<
mlir::tensor::YieldOp, mlir::scf::YieldOp, mlir::tensor::GenerateOp,
mlir::tensor::ExtractSliceOp, mlir::tensor::ExtractOp,
mlir::tensor::InsertSliceOp, mlir::tensor::ExpandShapeOp,
mlir::tensor::CollapseShapeOp, mlir::bufferization::AllocTensorOp>(
[&](mlir::Operation *op) {
return converter.isLegal(op->getResultTypes()) &&
converter.isLegal(op->getOperandTypes());
});
patterns.add<mlir::concretelang::GenericTypeAndOpConverterPattern<
TFHE::KeySwitchGLWEOp, Concrete::KeySwitchLweOp>>(&getContext(),
converter);
patterns.add<RegionOpTypeConverterPattern<mlir::linalg::GenericOp,
TFHEToConcreteTypeConverter>>(
&getContext(), converter);
patterns.add<
mlir::concretelang::GenericTypeConverterPattern<mlir::func::ReturnOp>>(
patterns.getContext(), converter);
patterns.add<
mlir::concretelang::GenericTypeConverterPattern<mlir::linalg::YieldOp>>(
patterns.getContext(), converter);
patterns.add<RegionOpTypeConverterPattern<mlir::tensor::GenerateOp,
TFHEToConcreteTypeConverter>>(
&getContext(), converter);
// rewrite scf for loops if working on illegal types
patterns.add<RegionOpTypeConverterPattern<mlir::scf::ForOp,
TFHEToConcreteTypeConverter>>(
&getContext(), converter);
mlir::concretelang::populateWithTensorTypeConverterPatterns(patterns, target,
converter);
target.addDynamicallyLegalOp<mlir::scf::ForOp>([&](mlir::scf::ForOp forOp) {
return converter.isLegal(forOp.getInitArgs().getTypes()) &&
converter.isLegal(forOp.getResults().getTypes());
});
mlir::concretelang::addDynamicallyLegalTypeOp<mlir::func::ReturnOp>(
target, converter);
mlir::populateFunctionOpInterfaceTypeConversionPattern<mlir::func::FuncOp>(
patterns, converter);
// Conversion of Tracing dialect
patterns.add<mlir::concretelang::GenericTypeConverterPattern<
Tracing::TraceCiphertextOp>>(&getContext(), converter);
patterns.add<mlir::concretelang::TypeConvertingReinstantiationPattern<
Tracing::TraceCiphertextOp, true>>(&getContext(), converter);
mlir::concretelang::addDynamicallyLegalTypeOp<Tracing::TraceCiphertextOp>(
target, converter);
patterns.add<TracePlaintextOpPattern>(&getContext(), converter);
@@ -271,25 +735,27 @@ void TFHEToConcretePass::runOnOperation() {
// Conversion of RT Dialect Ops
patterns.add<
mlir::concretelang::GenericTypeConverterPattern<mlir::func::ReturnOp>,
mlir::concretelang::GenericTypeConverterPattern<mlir::scf::YieldOp>,
mlir::concretelang::GenericTypeConverterPattern<
mlir::bufferization::AllocTensorOp>,
mlir::concretelang::GenericTypeConverterPattern<
mlir::concretelang::TypeConvertingReinstantiationPattern<
mlir::func::ReturnOp>,
mlir::concretelang::TypeConvertingReinstantiationPattern<
mlir::scf::YieldOp>,
mlir::concretelang::TypeConvertingReinstantiationPattern<
mlir::bufferization::AllocTensorOp, true>,
mlir::concretelang::TypeConvertingReinstantiationPattern<
mlir::concretelang::RT::MakeReadyFutureOp>,
mlir::concretelang::GenericTypeConverterPattern<
mlir::concretelang::TypeConvertingReinstantiationPattern<
mlir::concretelang::RT::AwaitFutureOp>,
mlir::concretelang::GenericTypeConverterPattern<
mlir::concretelang::RT::CreateAsyncTaskOp>,
mlir::concretelang::GenericTypeConverterPattern<
mlir::concretelang::TypeConvertingReinstantiationPattern<
mlir::concretelang::RT::CreateAsyncTaskOp, true>,
mlir::concretelang::TypeConvertingReinstantiationPattern<
mlir::concretelang::RT::BuildReturnPtrPlaceholderOp>,
mlir::concretelang::GenericTypeConverterPattern<
mlir::concretelang::TypeConvertingReinstantiationPattern<
mlir::concretelang::RT::DerefWorkFunctionArgumentPtrPlaceholderOp>,
mlir::concretelang::GenericTypeConverterPattern<
mlir::concretelang::TypeConvertingReinstantiationPattern<
mlir::concretelang::RT::DerefReturnPtrPlaceholderOp>,
mlir::concretelang::GenericTypeConverterPattern<
mlir::concretelang::TypeConvertingReinstantiationPattern<
mlir::concretelang::RT::WorkFunctionReturnOp>,
mlir::concretelang::GenericTypeConverterPattern<
mlir::concretelang::TypeConvertingReinstantiationPattern<
mlir::concretelang::RT::RegisterTaskWorkFunctionOp>>(&getContext(),
converter);
mlir::concretelang::addDynamicallyLegalTypeOp<
@@ -310,13 +776,6 @@ void TFHEToConcretePass::runOnOperation() {
mlir::concretelang::addDynamicallyLegalTypeOp<
mlir::concretelang::RT::RegisterTaskWorkFunctionOp>(target, converter);
mlir::concretelang::addDynamicallyLegalTypeOp<mlir::func::ReturnOp>(
target, converter);
mlir::concretelang::addDynamicallyLegalTypeOp<mlir::linalg::YieldOp>(
target, converter);
mlir::concretelang::addDynamicallyLegalTypeOp<
mlir::bufferization::AllocTensorOp>(target, converter);
// Apply conversion
if (mlir::applyPartialConversion(op, target, std::move(patterns)).failed()) {
this->signalPassFailure();

View File

@@ -1,2 +0,0 @@
add_subdirectory(IR)
add_subdirectory(Transforms)

View File

@@ -1,26 +0,0 @@
// Part of the Concrete Compiler Project, under the BSD3 License with Zama
// Exceptions. See
// https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt
// for license information.
#include "concretelang/Dialect/BConcrete/IR/BConcreteDialect.h"
#include "concretelang/Dialect/BConcrete/IR/BConcreteOps.h"
#define GET_TYPEDEF_CLASSES
#include "concretelang/Dialect/BConcrete/IR/BConcreteOpsTypes.cpp.inc"
#include "concretelang/Dialect/BConcrete/IR/BConcreteOpsDialect.cpp.inc"
using namespace mlir::concretelang::BConcrete;
void BConcreteDialect::initialize() {
addOperations<
#define GET_OP_LIST
#include "concretelang/Dialect/BConcrete/IR/BConcreteOps.cpp.inc"
>();
addTypes<
#define GET_TYPEDEF_LIST
#include "concretelang/Dialect/BConcrete/IR/BConcreteOpsTypes.cpp.inc"
>();
}

View File

@@ -1,9 +0,0 @@
// Part of the Concrete Compiler Project, under the BSD3 License with Zama
// Exceptions. See
// https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt
// for license information.
#include "concretelang/Dialect/BConcrete/IR/BConcreteOps.h"
#define GET_OP_CLASSES
#include "concretelang/Dialect/BConcrete/IR/BConcreteOps.cpp.inc"

View File

@@ -1,13 +0,0 @@
add_mlir_dialect_library(
BConcreteDialect
BConcreteDialect.cpp
BConcreteOps.cpp
ADDITIONAL_HEADER_DIRS
${PROJECT_SOURCE_DIR}/include/concretelang/Dialect/BConcrete
DEPENDS
mlir-headers
LINK_LIBS
PUBLIC
MLIRIR)
target_link_libraries(BConcreteDialect PUBLIC MLIRIR)

View File

@@ -1,19 +0,0 @@
add_mlir_dialect_library(
ConcretelangBConcreteTransforms
BufferizableOpInterfaceImpl.cpp
AddRuntimeContext.cpp
ADDITIONAL_HEADER_DIRS
${PROJECT_SOURCE_DIR}/include/concretelang/Dialect/BConcrete
DEPENDS
BConcreteTransformsIncGen
mlir-headers
LINK_LIBS
PUBLIC
ConcretelangConversion
MLIRArithmeticDialect
MLIRBufferizationDialect
MLIRBufferizationTransforms
MLIRIR
MLIRMemRefDialect
MLIRPass
MLIRTransforms)

View File

@@ -2,7 +2,6 @@ add_subdirectory(FHELinalg)
add_subdirectory(FHE)
add_subdirectory(TFHE)
add_subdirectory(Concrete)
add_subdirectory(BConcrete)
add_subdirectory(RT)
add_subdirectory(SDFG)
add_subdirectory(Tracing)

View File

@@ -24,122 +24,3 @@ void ConcreteDialect::initialize() {
#include "concretelang/Dialect/Concrete/IR/ConcreteOpsTypes.cpp.inc"
>();
}
void printSigned(mlir::AsmPrinter &p, signed i) {
if (i == -1)
p << "_";
else
p << i;
}
mlir::Type GlweCiphertextType::parse(mlir::AsmParser &parser) {
if (parser.parseLess())
return Type();
int glweDimension = -1;
if (parser.parseOptionalKeyword("_") && parser.parseInteger(glweDimension))
return Type();
if (parser.parseComma())
return Type();
int polynomialSize = -1;
if (parser.parseOptionalKeyword("_") && parser.parseInteger(polynomialSize))
return Type();
if (parser.parseComma())
return Type();
int p = -1;
if (parser.parseOptionalKeyword("_") && parser.parseInteger(p))
return Type();
if (parser.parseGreater())
return Type();
Location loc = parser.getEncodedSourceLoc(parser.getNameLoc());
return getChecked(loc, loc.getContext(), glweDimension, polynomialSize, p);
}
void GlweCiphertextType::print(mlir::AsmPrinter &p) const {
p << "<";
printSigned(p, getGlweDimension());
p << ",";
printSigned(p, getPolynomialSize());
p << ",";
printSigned(p, getP());
p << ">";
}
void LweCiphertextType::print(mlir::AsmPrinter &p) const {
p << "<";
printSigned(p, getDimension());
p << ",";
printSigned(p, getP());
p << ">";
}
mlir::Type LweCiphertextType::parse(mlir::AsmParser &parser) {
if (parser.parseLess())
return mlir::Type();
int dimension = -1;
if (parser.parseOptionalKeyword("_") && parser.parseInteger(dimension))
return mlir::Type();
if (parser.parseComma())
return mlir::Type();
int p = -1;
if (parser.parseOptionalKeyword("_") && parser.parseInteger(p))
return mlir::Type();
if (parser.parseGreater())
return mlir::Type();
mlir::Location loc = parser.getEncodedSourceLoc(parser.getNameLoc());
return getChecked(loc, loc.getContext(), dimension, p);
}
void CleartextType::print(mlir::AsmPrinter &p) const {
p << "<";
if (getP() == -1)
p << "_";
else
p << getP();
p << ">";
}
mlir::Type CleartextType::parse(mlir::AsmParser &parser) {
if (parser.parseLess())
return mlir::Type();
int p = -1;
if (parser.parseOptionalKeyword("_") && parser.parseInteger(p))
return mlir::Type();
if (parser.parseGreater())
return mlir::Type();
Location loc = parser.getEncodedSourceLoc(parser.getNameLoc());
return getChecked(loc, loc.getContext(), p);
}
void PlaintextType::print(mlir::AsmPrinter &p) const {
p << "<";
if (getP() == -1)
p << "_";
else
p << getP();
p << ">";
}
mlir::Type PlaintextType::parse(mlir::AsmParser &parser) {
if (parser.parseLess())
return mlir::Type();
int p = -1;
if (parser.parseOptionalKeyword("_") && parser.parseInteger(p))
return mlir::Type();
if (parser.parseGreater())
return mlir::Type();
Location loc = parser.getEncodedSourceLoc(parser.getNameLoc());
return getChecked(loc, loc.getContext(), p);
}

View File

@@ -8,9 +8,9 @@
#include "mlir/IR/PatternMatch.h"
#include "mlir/Transforms/DialectConversion.h"
#include "concretelang/Dialect/BConcrete/IR/BConcreteDialect.h"
#include "concretelang/Dialect/BConcrete/IR/BConcreteOps.h"
#include "concretelang/Dialect/BConcrete/Transforms/Passes.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteDialect.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteOps.h"
#include "concretelang/Dialect/Concrete/Transforms/Passes.h"
namespace {
struct AddRuntimeContextToFuncOpPattern

View File

@@ -15,9 +15,9 @@
#include "mlir/IR/Operation.h"
#include "concretelang/Conversion/Tools.h"
#include "concretelang/Dialect/BConcrete/IR/BConcreteDialect.h"
#include "concretelang/Dialect/BConcrete/IR/BConcreteOps.h"
#include "concretelang/Dialect/BConcrete/Transforms/BufferizableOpInterfaceImpl.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteDialect.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteOps.h"
#include "concretelang/Dialect/Concrete/Transforms/BufferizableOpInterfaceImpl.h"
#include "concretelang/Dialect/Tracing/IR/TracingOps.h"
#include "concretelang/Support/CompilerEngine.h"
#include <mlir/IR/AffineExpr.h>
@@ -30,8 +30,8 @@ using namespace mlir::tensor;
namespace {
namespace BConcrete = mlir::concretelang::BConcrete;
namespace Tracing = mlir::concretelang::Tracing;
namespace Concrete = mlir::concretelang::Concrete;
template <typename TensorOp, typename MemrefOp>
struct TensorToMemrefOp : public BufferizableOpInterface::ExternalModel<
@@ -95,61 +95,58 @@ struct TensorToMemrefOp : public BufferizableOpInterface::ExternalModel<
} // namespace
void mlir::concretelang::BConcrete::
void mlir::concretelang::Concrete::
registerBufferizableOpInterfaceExternalModels(DialectRegistry &registry) {
registry.addExtension(+[](MLIRContext *ctx,
BConcrete::BConcreteDialect *dialect) {
Concrete::ConcreteDialect *dialect) {
// add_lwe_tensor => add_lwe_buffer
BConcrete::AddLweTensorOp::attachInterface<
TensorToMemrefOp<BConcrete::AddLweTensorOp, BConcrete::AddLweBufferOp>>(
Concrete::AddLweTensorOp::attachInterface<
TensorToMemrefOp<Concrete::AddLweTensorOp, Concrete::AddLweBufferOp>>(
*ctx);
// add_plaintext_lwe_tensor => add_plaintext_lwe_buffer
BConcrete::AddPlaintextLweTensorOp::attachInterface<
TensorToMemrefOp<BConcrete::AddPlaintextLweTensorOp,
BConcrete::AddPlaintextLweBufferOp>>(*ctx);
Concrete::AddPlaintextLweTensorOp::attachInterface<TensorToMemrefOp<
Concrete::AddPlaintextLweTensorOp, Concrete::AddPlaintextLweBufferOp>>(
*ctx);
// mul_cleartext_lwe_tensor => mul_cleartext_lwe_buffer
BConcrete::MulCleartextLweTensorOp::attachInterface<
TensorToMemrefOp<BConcrete::MulCleartextLweTensorOp,
BConcrete::MulCleartextLweBufferOp>>(*ctx);
Concrete::MulCleartextLweTensorOp::attachInterface<TensorToMemrefOp<
Concrete::MulCleartextLweTensorOp, Concrete::MulCleartextLweBufferOp>>(
*ctx);
// negate_cleartext_lwe_tensor => negate_cleartext_lwe_buffer
BConcrete::NegateLweTensorOp::attachInterface<TensorToMemrefOp<
BConcrete::NegateLweTensorOp, BConcrete::NegateLweBufferOp>>(*ctx);
Concrete::NegateLweTensorOp::attachInterface<TensorToMemrefOp<
Concrete::NegateLweTensorOp, Concrete::NegateLweBufferOp>>(*ctx);
// negate_cleartext_lwe_tensor => negate_cleartext_lwe_buffer
BConcrete::NegateLweTensorOp::attachInterface<TensorToMemrefOp<
BConcrete::NegateLweTensorOp, BConcrete::NegateLweBufferOp>>(*ctx);
Concrete::NegateLweTensorOp::attachInterface<TensorToMemrefOp<
Concrete::NegateLweTensorOp, Concrete::NegateLweBufferOp>>(*ctx);
// keyswitch_lwe_tensor => keyswitch_lwe_buffer
BConcrete::KeySwitchLweTensorOp::attachInterface<TensorToMemrefOp<
BConcrete::KeySwitchLweTensorOp, BConcrete::KeySwitchLweBufferOp>>(
*ctx);
Concrete::KeySwitchLweTensorOp::attachInterface<TensorToMemrefOp<
Concrete::KeySwitchLweTensorOp, Concrete::KeySwitchLweBufferOp>>(*ctx);
// bootstrap_lwe_tensor => bootstrap_lwe_buffer
BConcrete::BootstrapLweTensorOp::attachInterface<TensorToMemrefOp<
BConcrete::BootstrapLweTensorOp, BConcrete::BootstrapLweBufferOp>>(
*ctx);
Concrete::BootstrapLweTensorOp::attachInterface<TensorToMemrefOp<
Concrete::BootstrapLweTensorOp, Concrete::BootstrapLweBufferOp>>(*ctx);
// batched_keyswitch_lwe_tensor => batched_keyswitch_lwe_buffer
BConcrete::BatchedKeySwitchLweTensorOp::attachInterface<
TensorToMemrefOp<BConcrete::BatchedKeySwitchLweTensorOp,
BConcrete::BatchedKeySwitchLweBufferOp>>(*ctx);
Concrete::BatchedKeySwitchLweTensorOp::attachInterface<
TensorToMemrefOp<Concrete::BatchedKeySwitchLweTensorOp,
Concrete::BatchedKeySwitchLweBufferOp>>(*ctx);
// batched_bootstrap_lwe_tensor => batched_bootstrap_lwe_buffer
BConcrete::BatchedBootstrapLweTensorOp::attachInterface<
TensorToMemrefOp<BConcrete::BatchedBootstrapLweTensorOp,
BConcrete::BatchedBootstrapLweBufferOp>>(*ctx);
Concrete::BatchedBootstrapLweTensorOp::attachInterface<
TensorToMemrefOp<Concrete::BatchedBootstrapLweTensorOp,
Concrete::BatchedBootstrapLweBufferOp>>(*ctx);
// wop_pbs_crt_lwe_tensor => wop_pbs_crt_lwe_buffer
BConcrete::WopPBSCRTLweTensorOp::attachInterface<TensorToMemrefOp<
BConcrete::WopPBSCRTLweTensorOp, BConcrete::WopPBSCRTLweBufferOp>>(
*ctx);
Concrete::WopPBSCRTLweTensorOp::attachInterface<TensorToMemrefOp<
Concrete::WopPBSCRTLweTensorOp, Concrete::WopPBSCRTLweBufferOp>>(*ctx);
// encode_plaintext_with_crt_tensor => encode_plaintext_with_crt_buffer
BConcrete::EncodePlaintextWithCrtTensorOp::attachInterface<
TensorToMemrefOp<BConcrete::EncodePlaintextWithCrtTensorOp,
BConcrete::EncodePlaintextWithCrtBufferOp>>(*ctx);
Concrete::EncodePlaintextWithCrtTensorOp::attachInterface<
TensorToMemrefOp<Concrete::EncodePlaintextWithCrtTensorOp,
Concrete::EncodePlaintextWithCrtBufferOp>>(*ctx);
// encode_expand_lut_for_bootstrap_tensor =>
// encode_expand_lut_for_bootstrap_buffer
BConcrete::EncodeExpandLutForBootstrapTensorOp::attachInterface<
TensorToMemrefOp<BConcrete::EncodeExpandLutForBootstrapTensorOp,
BConcrete::EncodeExpandLutForBootstrapBufferOp>>(*ctx);
Concrete::EncodeExpandLutForBootstrapTensorOp::attachInterface<
TensorToMemrefOp<Concrete::EncodeExpandLutForBootstrapTensorOp,
Concrete::EncodeExpandLutForBootstrapBufferOp>>(*ctx);
// encode_expand_lut_for_woppbs_tensor =>
// encode_expand_lut_for_woppbs_buffer
BConcrete::EncodeExpandLutForWopPBSTensorOp::attachInterface<
TensorToMemrefOp<BConcrete::EncodeExpandLutForWopPBSTensorOp,
BConcrete::EncodeExpandLutForWopPBSBufferOp>>(*ctx);
Concrete::EncodeExpandLutForWopPBSTensorOp::attachInterface<
TensorToMemrefOp<Concrete::EncodeExpandLutForWopPBSTensorOp,
Concrete::EncodeExpandLutForWopPBSBufferOp>>(*ctx);
});
}

View File

@@ -1,12 +1,19 @@
add_mlir_library(
ConcreteDialectTransforms
Optimization.cpp
add_mlir_dialect_library(
ConcretelangConcreteTransforms
BufferizableOpInterfaceImpl.cpp
AddRuntimeContext.cpp
ADDITIONAL_HEADER_DIRS
${PROJECT_SOURCE_DIR}/include/concretelang/Dialect/Concrete
DEPENDS
ConcreteDialect
ConcreteTransformsIncGen
mlir-headers
LINK_LIBS
PUBLIC
ConcretelangConversion
MLIRArithmeticDialect
MLIRBufferizationDialect
MLIRBufferizationTransforms
MLIRIR
ConcreteDialect)
MLIRMemRefDialect
MLIRPass
MLIRTransforms)

View File

@@ -15,8 +15,8 @@
#include "mlir/IR/Operation.h"
#include "concretelang/Conversion/Tools.h"
#include "concretelang/Dialect/BConcrete/IR/BConcreteDialect.h"
#include "concretelang/Dialect/BConcrete/IR/BConcreteOps.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteDialect.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteOps.h"
#include "concretelang/Dialect/SDFG/IR/SDFGDialect.h"
#include "concretelang/Dialect/SDFG/IR/SDFGOps.h"
#include "concretelang/Dialect/SDFG/IR/SDFGTypes.h"

View File

@@ -3,7 +3,7 @@ add_mlir_dialect_library(
BufferizableOpInterfaceImpl.cpp
SDFGConvertibleOpInterfaceImpl.cpp
ADDITIONAL_HEADER_DIRS
${PROJECT_SOURCE_DIR}/include/concretelang/Dialect/BConcrete
${PROJECT_SOURCE_DIR}/include/concretelang/Dialect/Concrete
${PROJECT_SOURCE_DIR}/include/concretelang/Dialect/SDFG
DEPENDS
mlir-headers

View File

@@ -3,8 +3,8 @@
// https://github.com/zama-ai/concrete-compiler-internal/blob/main/LICENSE.txt
// for license information.
#include "concretelang/Dialect/BConcrete/IR/BConcreteDialect.h"
#include "concretelang/Dialect/BConcrete/IR/BConcreteOps.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteDialect.h"
#include "concretelang/Dialect/Concrete/IR/ConcreteOps.h"
#include "concretelang/Dialect/SDFG/IR/SDFGDialect.h"
#include "concretelang/Dialect/SDFG/IR/SDFGOps.h"
#include "concretelang/Dialect/SDFG/Interfaces/SDFGConvertibleInterface.h"
@@ -54,33 +54,33 @@ struct ReplaceWithProcessSDFGConversionInterface
void registerSDFGConvertibleOpInterfaceExternalModels(
DialectRegistry &registry) {
registry.addExtension(+[](MLIRContext *ctx,
BConcrete::BConcreteDialect *dialect) {
mlir::concretelang::BConcrete::AddLweTensorOp::attachInterface<
Concrete::ConcreteDialect *dialect) {
mlir::concretelang::Concrete::AddLweTensorOp::attachInterface<
ReplaceWithProcessSDFGConversionInterface<
mlir::concretelang::BConcrete::AddLweTensorOp, add_eint>>(*ctx);
mlir::concretelang::Concrete::AddLweTensorOp, add_eint>>(*ctx);
mlir::concretelang::BConcrete::AddPlaintextLweTensorOp::attachInterface<
mlir::concretelang::Concrete::AddPlaintextLweTensorOp::attachInterface<
ReplaceWithProcessSDFGConversionInterface<
mlir::concretelang::BConcrete::AddPlaintextLweTensorOp,
mlir::concretelang::Concrete::AddPlaintextLweTensorOp,
add_eint_int>>(*ctx);
mlir::concretelang::BConcrete::MulCleartextLweTensorOp::attachInterface<
mlir::concretelang::Concrete::MulCleartextLweTensorOp::attachInterface<
ReplaceWithProcessSDFGConversionInterface<
mlir::concretelang::BConcrete::MulCleartextLweTensorOp,
mlir::concretelang::Concrete::MulCleartextLweTensorOp,
mul_eint_int>>(*ctx);
mlir::concretelang::BConcrete::NegateLweTensorOp::attachInterface<
mlir::concretelang::Concrete::NegateLweTensorOp::attachInterface<
ReplaceWithProcessSDFGConversionInterface<
mlir::concretelang::BConcrete::NegateLweTensorOp, neg_eint>>(*ctx);
mlir::concretelang::Concrete::NegateLweTensorOp, neg_eint>>(*ctx);
mlir::concretelang::BConcrete::KeySwitchLweTensorOp::attachInterface<
mlir::concretelang::Concrete::KeySwitchLweTensorOp::attachInterface<
ReplaceWithProcessSDFGConversionInterface<
mlir::concretelang::BConcrete::KeySwitchLweTensorOp, keyswitch,
mlir::concretelang::Concrete::KeySwitchLweTensorOp, keyswitch,
true>>(*ctx);
mlir::concretelang::BConcrete::BootstrapLweTensorOp::attachInterface<
mlir::concretelang::Concrete::BootstrapLweTensorOp::attachInterface<
ReplaceWithProcessSDFGConversionInterface<
mlir::concretelang::BConcrete::BootstrapLweTensorOp, bootstrap,
mlir::concretelang::Concrete::BootstrapLweTensorOp, bootstrap,
true>>(*ctx);
});
}

View File

@@ -1 +1,2 @@
add_subdirectory(IR)
add_subdirectory(Transforms)

View File

@@ -0,0 +1,12 @@
add_mlir_library(
TFHEDialectTransforms
Optimization.cpp
ADDITIONAL_HEADER_DIRS
${PROJECT_SOURCE_DIR}/include/concretelang/Dialect/TFHE
DEPENDS
TFHEDialect
mlir-headers
LINK_LIBS
PUBLIC
MLIRIR
TFHEDialect)

View File

@@ -7,8 +7,8 @@
#include <mlir/IR/PatternMatch.h>
#include <mlir/Transforms/GreedyPatternRewriteDriver.h>
#include <concretelang/Dialect/Concrete/IR/ConcreteOps.h>
#include <concretelang/Dialect/Concrete/Transforms/Optimization.h>
#include <concretelang/Dialect/TFHE/IR/TFHEOps.h>
#include <concretelang/Dialect/TFHE/Transforms/Optimization.h>
#include <concretelang/Support/Constants.h>
namespace mlir {
@@ -30,20 +30,18 @@ getConstantIntFromCleartextIfExists(mlir::Value cleartext) {
return {};
}
/// Rewrite a `Concrete.mul_cleartext_lwe_ciphertext` operation as a
/// `Concrete.zero` operation if it's being multiplied with a constant 0, or as
/// a `Concrete.negate_lwe_ciphertext` if multiplied with a constant -1.
/// Rewrite a TFHE multiplication with an integer operation as a
/// Zero operation if it's being multiplied with a constant 0, or as
/// a Negate operation if multiplied with a constant -1.
class MulCleartextLweCiphertextOpPattern
: public mlir::OpRewritePattern<
mlir::concretelang::Concrete::MulCleartextLweCiphertextOp> {
: public mlir::OpRewritePattern<mlir::concretelang::TFHE::MulGLWEIntOp> {
public:
MulCleartextLweCiphertextOpPattern(mlir::MLIRContext *context)
: mlir::OpRewritePattern<
mlir::concretelang::Concrete::MulCleartextLweCiphertextOp>(
: mlir::OpRewritePattern<mlir::concretelang::TFHE::MulGLWEIntOp>(
context, ::mlir::concretelang::DEFAULT_PATTERN_BENEFIT) {}
mlir::LogicalResult
matchAndRewrite(mlir::concretelang::Concrete::MulCleartextLweCiphertextOp op,
matchAndRewrite(mlir::concretelang::TFHE::MulGLWEIntOp op,
mlir::PatternRewriter &rewriter) const override {
auto cleartext = op.getOperand(1);
auto constIntToMul = getConstantIntFromCleartextIfExists(cleartext);
@@ -51,13 +49,12 @@ public:
if (constIntToMul.hasValue()) {
auto toMul = constIntToMul.getValue().getInt();
if (toMul == 0) {
rewriter.replaceOpWithNewOp<mlir::concretelang::Concrete::ZeroLWEOp>(
rewriter.replaceOpWithNewOp<mlir::concretelang::TFHE::ZeroGLWEOp>(
op, op.getResult().getType());
return mlir::success();
}
if (toMul == -1) {
rewriter.replaceOpWithNewOp<
mlir::concretelang::Concrete::NegateLweCiphertextOp>(
rewriter.replaceOpWithNewOp<mlir::concretelang::TFHE::NegGLWEOp>(
op, op.getResult().getType(), op.getOperand(0));
return mlir::success();
}
@@ -68,8 +65,7 @@ public:
/// Optimization pass that should choose more efficient ways of performing
/// crypto operations.
class ConcreteOptimizationPass
: public ConcreteOptimizationBase<ConcreteOptimizationPass> {
class TFHEOptimizationPass : public TFHEOptimizationBase<TFHEOptimizationPass> {
public:
void runOnOperation() override {
mlir::Operation *op = getOperation();
@@ -85,8 +81,8 @@ public:
} // end anonymous namespace
std::unique_ptr<mlir::OperationPass<>> createConcreteOptimizationPass() {
return std::make_unique<ConcreteOptimizationPass>();
std::unique_ptr<mlir::OperationPass<>> createTFHEOptimizationPass() {
return std::make_unique<TFHEOptimizationPass>();
}
} // namespace concretelang

View File

@@ -27,11 +27,11 @@ add_mlir_library(
FHEDialectTransforms
RTDialectAnalysis
ConcretelangTransforms
ConcretelangBConcreteTransforms
ConcretelangConcreteTransforms
ConcretelangSDFGTransforms
ConcretelangSDFGInterfaces
LinalgExtras
ConcreteDialectTransforms
TFHEDialectTransforms
concrete_optimizer
MLIRExecutionEngine
${LLVM_PTHREAD_LIB}

View File

@@ -27,9 +27,8 @@
#include "concretelang/Conversion/Utils/GlobalFHEContext.h"
#include <concretelang/ClientLib/ClientParameters.h>
#include <concretelang/Dialect/BConcrete/IR/BConcreteDialect.h>
#include <concretelang/Dialect/BConcrete/Transforms/BufferizableOpInterfaceImpl.h>
#include <concretelang/Dialect/Concrete/IR/ConcreteDialect.h>
#include <concretelang/Dialect/Concrete/Transforms/BufferizableOpInterfaceImpl.h>
#include <concretelang/Dialect/FHE/IR/FHEDialect.h>
#include <concretelang/Dialect/FHELinalg/IR/FHELinalgDialect.h>
#include <concretelang/Dialect/RT/IR/RTDialect.h>
@@ -80,13 +79,12 @@ mlir::MLIRContext *CompilationContext::getMLIRContext() {
mlir::concretelang::TFHE::TFHEDialect,
mlir::concretelang::FHELinalg::FHELinalgDialect,
mlir::concretelang::Concrete::ConcreteDialect,
mlir::concretelang::BConcrete::BConcreteDialect,
mlir::concretelang::SDFG::SDFGDialect, mlir::func::FuncDialect,
mlir::memref::MemRefDialect, mlir::linalg::LinalgDialect,
mlir::LLVM::LLVMDialect, mlir::scf::SCFDialect,
mlir::omp::OpenMPDialect, mlir::bufferization::BufferizationDialect>();
BConcrete::registerBufferizableOpInterfaceExternalModels(registry);
Tracing::registerBufferizableOpInterfaceExternalModels(registry);
Concrete::registerBufferizableOpInterfaceExternalModels(registry);
SDFG::registerSDFGConvertibleOpInterfaceExternalModels(registry);
SDFG::registerBufferizableOpInterfaceExternalModels(registry);
arith::registerBufferizableOpInterfaceExternalModels(registry);
@@ -392,6 +390,15 @@ CompilerEngine::compile(llvm::SourceMgr &sm, Target target, OptionalLib lib) {
.failed()) {
return errorDiag("Lowering from FHE to TFHE failed");
}
// Optimizing TFHE
if (this->compilerOptions.optimizeTFHE &&
mlir::concretelang::pipeline::optimizeTFHE(mlirContext, module,
this->enablePass)
.failed()) {
return errorDiag("Optimizing TFHE failed");
}
if (target == Target::TFHE)
return std::move(res);
@@ -402,37 +409,17 @@ CompilerEngine::compile(llvm::SourceMgr &sm, Target target, OptionalLib lib) {
return errorDiag("Lowering from TFHE to Concrete failed");
}
// Optimizing Concrete
if (this->compilerOptions.optimizeConcrete &&
mlir::concretelang::pipeline::optimizeConcrete(mlirContext, module,
this->enablePass)
.failed()) {
return errorDiag("Optimizing Concrete failed");
}
if (target == Target::CONCRETE)
return std::move(res);
// Concrete -> BConcrete
if (mlir::concretelang::pipeline::lowerConcreteToBConcrete(
mlirContext, module, this->enablePass, loopParallelize)
.failed()) {
return StreamStringError(
"Lowering from Concrete to Bufferized Concrete failed");
}
if (target == Target::BCONCRETE) {
return std::move(res);
}
// Extract SDFG data flow graph from BConcrete representation
// Extract SDFG data flow graph from Concrete representation
if (options.emitSDFGOps) {
if (mlir::concretelang::pipeline::extractSDFGOps(
mlirContext, module, enablePass,
options.unrollLoopsWithSDFGConvertibleOps)
.failed()) {
return errorDiag("Extraction of SDFG operations from BConcrete "
return errorDiag("Extraction of SDFG operations from Concrete "
"representation failed");
}
}
@@ -441,9 +428,9 @@ CompilerEngine::compile(llvm::SourceMgr &sm, Target target, OptionalLib lib) {
return std::move(res);
}
// BConcrete -> Canonical dialects
if (mlir::concretelang::pipeline::lowerBConcreteToStd(mlirContext, module,
enablePass)
// Concrete -> Canonical dialects
if (mlir::concretelang::pipeline::lowerConcreteToStd(mlirContext, module,
enablePass)
.failed()) {
return errorDiag("Lowering from Bufferized Concrete to canonical MLIR "
"dialects failed");

View File

@@ -31,8 +31,7 @@
#include "concretelang/Support/CompilerEngine.h"
#include "concretelang/Support/Error.h"
#include <concretelang/Conversion/Passes.h>
#include <concretelang/Dialect/BConcrete/Transforms/Passes.h>
#include <concretelang/Dialect/Concrete/Transforms/Optimization.h>
#include <concretelang/Dialect/Concrete/Transforms/Passes.h>
#include <concretelang/Dialect/FHE/Analysis/ConcreteOptimizer.h>
#include <concretelang/Dialect/FHE/Analysis/MANP.h>
#include <concretelang/Dialect/FHE/Transforms/BigInt/BigInt.h>
@@ -41,6 +40,7 @@
#include <concretelang/Dialect/FHE/Transforms/Max/Max.h>
#include <concretelang/Dialect/FHELinalg/Transforms/Tiling.h>
#include <concretelang/Dialect/RT/Analysis/Autopar.h>
#include <concretelang/Dialect/TFHE/Transforms/Optimization.h>
#include <concretelang/Support/Pipeline.h>
#include <concretelang/Support/logging.h>
#include <concretelang/Support/math.h>
@@ -290,27 +290,13 @@ lowerTFHEToConcrete(mlir::MLIRContext &context, mlir::ModuleOp &module,
return pm.run(module.getOperation());
}
mlir::LogicalResult
optimizeConcrete(mlir::MLIRContext &context, mlir::ModuleOp &module,
std::function<bool(mlir::Pass *)> enablePass) {
mlir::LogicalResult optimizeTFHE(mlir::MLIRContext &context,
mlir::ModuleOp &module,
std::function<bool(mlir::Pass *)> enablePass) {
mlir::PassManager pm(&context);
pipelinePrinting("ConcreteOptimization", pm, context);
addPotentiallyNestedPass(
pm, mlir::concretelang::createConcreteOptimizationPass(), enablePass);
return pm.run(module.getOperation());
}
mlir::LogicalResult
lowerConcreteToBConcrete(mlir::MLIRContext &context, mlir::ModuleOp &module,
std::function<bool(mlir::Pass *)> enablePass,
bool parallelizeLoops) {
mlir::PassManager pm(&context);
pipelinePrinting("ConcreteToBConcrete", pm, context);
addPotentiallyNestedPass(
pm, mlir::concretelang::createConvertConcreteToBConcretePass(),
enablePass);
pipelinePrinting("TFHEOptimization", pm, context);
addPotentiallyNestedPass(pm, mlir::concretelang::createTFHEOptimizationPass(),
enablePass);
return pm.run(module.getOperation());
}
@@ -320,7 +306,7 @@ mlir::LogicalResult extractSDFGOps(mlir::MLIRContext &context,
std::function<bool(mlir::Pass *)> enablePass,
bool unroll) {
mlir::PassManager pm(&context);
pipelinePrinting("extract SDFG ops from BConcrete", pm, context);
pipelinePrinting("extract SDFG ops from Concrete", pm, context);
addPotentiallyNestedPass(
pm, mlir::concretelang::createExtractSDFGOpsPass(unroll), enablePass);
LogicalResult res = pm.run(module.getOperation());
@@ -329,10 +315,10 @@ mlir::LogicalResult extractSDFGOps(mlir::MLIRContext &context,
}
mlir::LogicalResult
lowerBConcreteToStd(mlir::MLIRContext &context, mlir::ModuleOp &module,
std::function<bool(mlir::Pass *)> enablePass) {
lowerConcreteToStd(mlir::MLIRContext &context, mlir::ModuleOp &module,
std::function<bool(mlir::Pass *)> enablePass) {
mlir::PassManager pm(&context);
pipelinePrinting("BConcreteToStd", pm, context);
pipelinePrinting("ConcreteToStd", pm, context);
addPotentiallyNestedPass(pm, mlir::concretelang::createAddRuntimeContext(),
enablePass);
return pm.run(module.getOperation());
@@ -399,8 +385,7 @@ lowerStdToLLVMDialect(mlir::MLIRContext &context, mlir::ModuleOp &module,
pm, mlir::concretelang::createFixupBufferDeallocationPass(), enablePass);
addPotentiallyNestedPass(
pm, mlir::concretelang::createConvertBConcreteToCAPIPass(gpu),
enablePass);
pm, mlir::concretelang::createConvertConcreteToCAPIPass(gpu), enablePass);
addPotentiallyNestedPass(
pm, mlir::concretelang::createConvertTracingToCAPIPass(), enablePass);

View File

@@ -12,7 +12,6 @@ target_link_libraries(
PRIVATE ${dialect_libs}
${conversion_libs}
MLIRTransforms
BConcreteDialect
ConcreteDialect
TFHEDialect
FHEDialect

View File

@@ -49,7 +49,6 @@ enum Action {
DUMP_FHE_NO_LINALG,
DUMP_TFHE,
DUMP_CONCRETE,
DUMP_BCONCRETE,
DUMP_SDFG,
DUMP_STD,
DUMP_LLVM_DIALECT,
@@ -95,10 +94,10 @@ llvm::cl::opt<bool> verbose("verbose", llvm::cl::desc("verbose logs"),
llvm::cl::init<bool>(false));
llvm::cl::opt<bool>
optimizeConcrete("optimize-concrete",
llvm::cl::desc("enable/disable optimizations of concrete "
"dialects. (Enabled by default)"),
llvm::cl::init<bool>(true));
optimizeTFHE("optimize-tfhe",
llvm::cl::desc("enable/disable optimizations of TFHE "
"dialects. (Enabled by default)"),
llvm::cl::init<bool>(true));
llvm::cl::opt<bool> emitGPUOps(
"emit-gpu-ops",
@@ -126,9 +125,6 @@ static llvm::cl::opt<enum Action> action(
"Lower to TFHE and dump result")),
llvm::cl::values(clEnumValN(Action::DUMP_CONCRETE, "dump-concrete",
"Lower to Concrete and dump result")),
llvm::cl::values(
clEnumValN(Action::DUMP_BCONCRETE, "dump-bconcrete",
"Lower to Bufferized Concrete and dump result")),
llvm::cl::values(clEnumValN(Action::DUMP_SDFG, "dump-sdfg",
"Lower to SDFG operations annd dump result")),
llvm::cl::values(clEnumValN(Action::DUMP_STD, "dump-std",
@@ -354,7 +350,7 @@ cmdlineCompilationOptions() {
options.emitSDFGOps = cmdline::emitSDFGOps;
options.unrollLoopsWithSDFGConvertibleOps =
cmdline::unrollLoopsWithSDFGConvertibleOps;
options.optimizeConcrete = cmdline::optimizeConcrete;
options.optimizeTFHE = cmdline::optimizeTFHE;
options.emitGPUOps = cmdline::emitGPUOps;
options.chunkIntegers = cmdline::chunkIntegers;
options.chunkSize = cmdline::chunkSize;
@@ -531,9 +527,6 @@ mlir::LogicalResult processInputBuffer(
case Action::DUMP_CONCRETE:
target = mlir::concretelang::CompilerEngine::Target::CONCRETE;
break;
case Action::DUMP_BCONCRETE:
target = mlir::concretelang::CompilerEngine::Target::BCONCRETE;
break;
case Action::DUMP_SDFG:
target = mlir::concretelang::CompilerEngine::Target::SDFG;
break;

View File

@@ -1,10 +0,0 @@
// RUN: concretecompiler --passes concrete-to-bconcrete --action=dump-bconcrete %s 2>&1| FileCheck %s
//CHECK: func @add_lwe_ciphertexts(%[[A0:.*]]: tensor<2049xi64>, %[[A1:.*]]: tensor<2049xi64>) -> tensor<2049xi64> {
//CHECK: %[[V0:.*]] = "BConcrete.add_lwe_tensor"(%[[A0]], %[[A1]]) : (tensor<2049xi64>, tensor<2049xi64>) -> tensor<2049xi64>
//CHECK: return %[[V0]] : tensor<2049xi64>
//CHECK: }
func.func @add_lwe_ciphertexts(%arg0: !Concrete.lwe_ciphertext<2048,7>, %arg1: !Concrete.lwe_ciphertext<2048,7>) -> !Concrete.lwe_ciphertext<2048,7> {
%0 = "Concrete.add_lwe_ciphertexts"(%arg0, %arg1) : (!Concrete.lwe_ciphertext<2048,7>, !Concrete.lwe_ciphertext<2048,7>) -> !Concrete.lwe_ciphertext<2048,7>
return %0 : !Concrete.lwe_ciphertext<2048,7>
}

View File

@@ -1,22 +0,0 @@
// RUN: concretecompiler --passes concrete-to-bconcrete --action=dump-bconcrete %s 2>&1| FileCheck %s
//CHECK: func.func @add_glwe_const_int(%[[A0:.*]]: tensor<1025xi64>) -> tensor<1025xi64> {
//CHECK: %c1_i64 = arith.constant 1 : i64
//CHECK: %[[V2:.*]] = "BConcrete.add_plaintext_lwe_tensor"(%[[A0]], %c1_i64) : (tensor<1025xi64>, i64) -> tensor<1025xi64>
//CHECK: return %[[V2]] : tensor<1025xi64>
//CHECK: }
func.func @add_glwe_const_int(%arg0: !Concrete.lwe_ciphertext<1024,7>) -> !Concrete.lwe_ciphertext<1024,7> {
%0 = arith.constant 1 : i64
%2 = "Concrete.add_plaintext_lwe_ciphertext"(%arg0, %0) : (!Concrete.lwe_ciphertext<1024,7>, i64) -> !Concrete.lwe_ciphertext<1024,7>
return %2 : !Concrete.lwe_ciphertext<1024,7>
}
//CHECK: func.func @add_glwe_int(%[[A0:.*]]: tensor<1025xi64>, %[[A1:.*]]: i64) -> tensor<1025xi64> {
//CHECK: %[[V2:.*]] = "BConcrete.add_plaintext_lwe_tensor"(%[[A0]], %[[A1]]) : (tensor<1025xi64>, i64) -> tensor<1025xi64>
//CHECK: return %[[V2]] : tensor<1025xi64>
//CHECK: }
func.func @add_glwe_int(%arg0: !Concrete.lwe_ciphertext<1024,4>, %arg1: i64) -> !Concrete.lwe_ciphertext<1024,4> {
%1 = "Concrete.add_plaintext_lwe_ciphertext"(%arg0, %arg1) : (!Concrete.lwe_ciphertext<1024,4>, i64) -> !Concrete.lwe_ciphertext<1024,4>
return %1 : !Concrete.lwe_ciphertext<1024,4>
}

View File

@@ -1,12 +0,0 @@
// RUN: concretecompiler --passes concrete-to-bconcrete --action=dump-bconcrete %s 2>&1| FileCheck %s
//CHECK: func.func @apply_lookup_table(%[[A0:.*]]: tensor<1025xi64>, %[[A1:.*]]: tensor<16xi64>) -> tensor<1025xi64> {
//CHECK: %[[V1:.*]] = "BConcrete.keyswitch_lwe_tensor"(%[[A0]]) {baseLog = 2 : i32, level = 3 : i32, lwe_dim_in = 1024 : i32, lwe_dim_out = 600 : i32} : (tensor<1025xi64>) -> tensor<601xi64>
//CHECK: %[[V2:.*]] = "BConcrete.bootstrap_lwe_tensor"(%[[V1]], %arg1) {baseLog = 2 : i32, glweDimension = 4 : i32, inputLweDim = 600 : i32, level = 3 : i32, outPrecision = 4 : i32, polySize = 1024 : i32} : (tensor<601xi64>, tensor<16xi64>) -> tensor<1025xi64>
//CHECK: return %[[V2]] : tensor<1025xi64>
//CHECK: }
func.func @apply_lookup_table(%arg0: !Concrete.lwe_ciphertext<1024,4>, %arg1: tensor<16xi64>) -> !Concrete.lwe_ciphertext<1024,4> {
%1 = "Concrete.keyswitch_lwe"(%arg0) {baseLog = 2 : i32, level = 3 : i32} : (!Concrete.lwe_ciphertext<1024,4>) -> !Concrete.lwe_ciphertext<600,4>
%2 = "Concrete.bootstrap_lwe"(%1, %arg1) {baseLog = 2 : i32, polySize = 1024 : i32, level = 3 : i32, glweDimension = 4 : i32} : (!Concrete.lwe_ciphertext<600,4>, tensor<16xi64> ) -> !Concrete.lwe_ciphertext<1024,4>
return %2 : !Concrete.lwe_ciphertext<1024,4>
}

View File

@@ -1,14 +0,0 @@
// RUN: concretecompiler --passes concrete-to-bconcrete --action=dump-bconcrete %s 2>&1| FileCheck %s
//CHECK: func.func @apply_lookup_table_cst(%[[A0:.*]]: tensor<2049xi64>) -> tensor<2049xi64> {
//CHECK: %cst = arith.constant dense<[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]> : tensor<16xi64>
//CHECK: %[[V1:.*]] = "BConcrete.keyswitch_lwe_tensor"(%[[A0]]) {baseLog = 2 : i32, level = 3 : i32, lwe_dim_in = 2048 : i32, lwe_dim_out = 600 : i32} : (tensor<2049xi64>) -> tensor<601xi64>
//CHECK: %[[V2:.*]] = "BConcrete.bootstrap_lwe_tensor"(%[[V1]], %cst) {baseLog = 2 : i32, glweDimension = 4 : i32, inputLweDim = 600 : i32, level = 3 : i32, outPrecision = 4 : i32, polySize = 2048 : i32} : (tensor<601xi64>, tensor<16xi64>) -> tensor<2049xi64>
//CHECK: return %[[V2]] : tensor<2049xi64>
//CHECK: }
func.func @apply_lookup_table_cst(%arg0: !Concrete.lwe_ciphertext<2048,4>) -> !Concrete.lwe_ciphertext<2048,4> {
%tlu = arith.constant dense<[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]> : tensor<16xi64>
%1 = "Concrete.keyswitch_lwe"(%arg0) {baseLog = 2 : i32, level = 3 : i32} : (!Concrete.lwe_ciphertext<2048,4>) -> !Concrete.lwe_ciphertext<600,4>
%2 = "Concrete.bootstrap_lwe"(%1, %tlu) {baseLog = 2 : i32, polySize = 2048 : i32, level = 3 : i32, glweDimension = 4 : i32} : (!Concrete.lwe_ciphertext<600,4>, tensor<16xi64>) -> !Concrete.lwe_ciphertext<2048,4>
return %2 : !Concrete.lwe_ciphertext<2048,4>
}

View File

@@ -1,10 +0,0 @@
// RUN: concretecompiler --passes concrete-to-bconcrete --action=dump-bconcrete %s 2>&1| FileCheck %s
// CHECK: func.func @apply_lookup_table(%arg0: tensor<4xi64>) -> tensor<1024xi64> {
// CHECK-NEXT: %0 = "BConcrete.encode_expand_lut_for_bootstrap_tensor"(%arg0) {isSigned = true, outputBits = 3 : i32, polySize = 1024 : i32} : (tensor<4xi64>) -> tensor<1024xi64>
// CHECK-NEXT: return %0 : tensor<1024xi64>
// CHECK-NEXT: }
func.func @apply_lookup_table(%arg0: tensor<4xi64>) -> tensor<1024xi64> {
%0 = "Concrete.encode_expand_lut_for_bootstrap"(%arg0) {outputBits = 3 : i32, polySize = 1024 : i32, isSigned = true} : (tensor<4xi64>) -> tensor<1024xi64>
return %0 : tensor<1024xi64>
}

View File

@@ -1,10 +0,0 @@
// RUN: concretecompiler --passes concrete-to-bconcrete --action=dump-bconcrete %s 2>&1| FileCheck %s
// CHECK: func.func @main(%arg0: tensor<4xi64>) -> tensor<40960xi64> {
// CHECK-NEXT: %0 = "BConcrete.encode_expand_lut_for_woppbs_tensor"(%arg0) {crtBits = [1, 2, 3, 3, 4], crtDecomposition = [2, 3, 5, 7, 11], isSigned = false, modulusProduct = 2310 : i32, polySize = 1024 : i32} : (tensor<4xi64>) -> tensor<40960xi64>
// CHECK-NEXT: return %0 : tensor<40960xi64>
// CHECK-NEXT: }
func.func @main(%arg0: tensor<4xi64>) -> tensor<40960xi64> {
%0 = "Concrete.encode_expand_lut_for_woppbs"(%arg0) {crtBits = [1, 2, 3, 3, 4], crtDecomposition = [2, 3, 5, 7, 11], isSigned = false, modulusProduct = 2310 : i32, polySize = 1024 : i32} : (tensor<4xi64>) -> tensor<40960xi64>
return %0 : tensor<40960xi64>
}

View File

@@ -1,10 +0,0 @@
// RUN: concretecompiler --passes concrete-to-bconcrete --action=dump-bconcrete %s 2>&1| FileCheck %s
// CHECK: func.func @main(%arg0: i64) -> tensor<5xi64> {
// CHECK-NEXT: %0 = "BConcrete.encode_plaintext_with_crt_tensor"(%arg0) {mods = [2, 3, 5, 7, 11], modsProd = 2310 : i64} : (i64) -> tensor<5xi64>
// CHECK-NEXT: return %0 : tensor<5xi64>
// CHECK-NEXT: }
func.func @main(%arg0: i64) -> tensor<5xi64> {
%0 = "Concrete.encode_plaintext_with_crt"(%arg0) {mods = [2, 3, 5, 7, 11], modsProd = 2310 : i64} : (i64) -> tensor<5xi64>
return %0 : tensor<5xi64>
}

View File

@@ -1,8 +0,0 @@
// RUN: concretecompiler --passes concrete-to-bconcrete --action=dump-bconcrete %s 2>&1| FileCheck %s
// CHECK: func.func @identity(%arg0: tensor<1025xi64>) -> tensor<1025xi64> {
// CHECK-NEXT: return %arg0 : tensor<1025xi64>
// CHECK-NEXT: }
func.func @identity(%arg0: !Concrete.lwe_ciphertext<1024,7>) -> !Concrete.lwe_ciphertext<1024,7> {
return %arg0 : !Concrete.lwe_ciphertext<1024,7>
}

View File

@@ -1,21 +0,0 @@
// RUN: concretecompiler --passes concrete-to-bconcrete --action=dump-bconcrete %s 2>&1| FileCheck %s
//CHECK: func.func @mul_lwe_const_int(%[[A0:.*]]: tensor<1025xi64>) -> tensor<1025xi64> {
//CHECK: %c1_i64 = arith.constant 1 : i64
//CHECK: %[[V1:.*]] = "BConcrete.mul_cleartext_lwe_tensor"(%[[A0]], %c1_i64) : (tensor<1025xi64>, i64) -> tensor<1025xi64>
//CHECK: return %[[V1]] : tensor<1025xi64>
//CHECK: }
func.func @mul_lwe_const_int(%arg0: !Concrete.lwe_ciphertext<1024,7>) -> !Concrete.lwe_ciphertext<1024,7> {
%0 = arith.constant 1 : i64
%2 = "Concrete.mul_cleartext_lwe_ciphertext"(%arg0, %0) : (!Concrete.lwe_ciphertext<1024,7>, i64) -> !Concrete.lwe_ciphertext<1024,7>
return %2 : !Concrete.lwe_ciphertext<1024,7>
}
//CHECK: func.func @mul_lwe_int(%[[A0:.*]]: tensor<1025xi64>, %[[A1:.*]]: i64) -> tensor<1025xi64> {
//CHECK: %[[V1:.*]] = "BConcrete.mul_cleartext_lwe_tensor"(%[[A0]], %[[A1]]) : (tensor<1025xi64>, i64) -> tensor<1025xi64>
//CHECK: return %[[V1]] : tensor<1025xi64>
//CHECK: }
func.func @mul_lwe_int(%arg0: !Concrete.lwe_ciphertext<1024,4>, %arg1: i64) -> !Concrete.lwe_ciphertext<1024,4> {
%1 = "Concrete.mul_cleartext_lwe_ciphertext"(%arg0, %arg1) : (!Concrete.lwe_ciphertext<1024,4>, i64) -> !Concrete.lwe_ciphertext<1024,4>
return %1 : !Concrete.lwe_ciphertext<1024,4>
}

View File

@@ -1,10 +0,0 @@
// RUN: concretecompiler --passes concrete-to-bconcrete --action=dump-bconcrete %s 2>&1| FileCheck %s
//CHECK: func.func @neg_lwe(%[[A0:.*]]: tensor<1025xi64>) -> tensor<1025xi64> {
//CHECK: %[[V0:.*]] = "BConcrete.negate_lwe_tensor"(%[[A0]]) : (tensor<1025xi64>) -> tensor<1025xi64>
//CHECK: return %[[V0]] : tensor<1025xi64>
//CHECK: }
func.func @neg_lwe(%arg0: !Concrete.lwe_ciphertext<1024,4>) -> !Concrete.lwe_ciphertext<1024,4> {
%0 = "Concrete.negate_lwe_ciphertext"(%arg0) : (!Concrete.lwe_ciphertext<1024,4>) -> !Concrete.lwe_ciphertext<1024,4>
return %0 : !Concrete.lwe_ciphertext<1024,4>
}

View File

@@ -1,8 +0,0 @@
// RUN: concretecompiler --passes concrete-to-bconcrete --action=dump-bconcrete %s 2>&1| FileCheck %s
// CHECK: func.func @tensor_identity(%arg0: tensor<2x3x4x1025xi64>) -> tensor<2x3x4x1025xi64> {
// CHECK-NEXT: return %arg0 : tensor<2x3x4x1025xi64>
// CHECK-NEXT: }
func.func @tensor_identity(%arg0: tensor<2x3x4x!Concrete.lwe_ciphertext<1024,7>>) -> tensor<2x3x4x!Concrete.lwe_ciphertext<1024,7>> {
return %arg0 : tensor<2x3x4x!Concrete.lwe_ciphertext<1024,7>>
}

View File

@@ -2,9 +2,9 @@
//CHECK: llvm.call @memref_keyswitch_lwe_cuda_u64
//CHECK: llvm.call @memref_bootstrap_lwe_cuda_u64
func.func @main(%arg0: !Concrete.lwe_ciphertext<1024,2>) -> !Concrete.lwe_ciphertext<1024,2> {
func.func @main(%arg0: tensor<1025xi64>) -> tensor<1025xi64> {
%cst = arith.constant dense<[1, 2, 3, 4]> : tensor<4xi64>
%0 = "Concrete.keyswitch_lwe"(%arg0) {baseLog = 2 : i32, level = 5 : i32} : (!Concrete.lwe_ciphertext<1024,2>) -> !Concrete.lwe_ciphertext<575,2>
%1 = "Concrete.bootstrap_lwe"(%0, %cst) {baseLog = 2 : i32, level = 5 : i32, polySize = 1024: i32, glweDimension = 1 : i32} : (!Concrete.lwe_ciphertext<575,2>, tensor<4xi64>) -> !Concrete.lwe_ciphertext<1024,2>
return %1 : !Concrete.lwe_ciphertext<1024,2>
%0 = "Concrete.keyswitch_lwe_tensor"(%arg0) {baseLog = 2 : i32, level = 5 : i32, lwe_dim_in = 1025 : i32, lwe_dim_out = 576 : i32} : (tensor<1025xi64>) -> tensor<576xi64>
%1 = "Concrete.bootstrap_lwe_tensor"(%0, %cst) {baseLog = 2 : i32, level = 5 : i32, polySize = 1024: i32, glweDimension = 1 : i32, inputLweDim = 576 : i32, outPrecision = 2 : i32} : (tensor<576xi64>, tensor<4xi64>) -> tensor<1025xi64>
return %1 : tensor<1025xi64>
}

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// RUN: concretecompiler --optimize-tfhe=false --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
//CHECK-LABEL: func.func @add_eint(%arg0: tensor<5x!TFHE.glwe<{_,_,_}{7}>>, %arg1: tensor<5x!TFHE.glwe<{_,_,_}{7}>>) -> tensor<5x!TFHE.glwe<{_,_,_}{7}>> {
//CHECK-NEXT: %0 = bufferization.alloc_tensor() : tensor<5x!TFHE.glwe<{_,_,_}{7}>>

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// RUN: concretecompiler --optimize-tfhe=false --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// CHECK-LABEL: func.func @add_eint_int(%arg0: tensor<5x!TFHE.glwe<{_,_,_}{7}>>) -> tensor<5x!TFHE.glwe<{_,_,_}{7}>> {
// CHECK-NEXT: %c1_i8 = arith.constant 1 : i8

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// RUN: concretecompiler --optimize-tfhe=false --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// CHECK: func.func @apply_lookup_table(%arg0: tensor<5x!TFHE.glwe<{_,_,_}{2}>>, %arg1: tensor<4xi64>) -> tensor<5x!TFHE.glwe<{_,_,_}{3}>>
// CHECK-NEXT: %0 = "TFHE.encode_expand_lut_for_woppbs"(%arg1) {crtBits = [1, 2, 3, 3, 4], crtDecomposition = [2, 3, 5, 7, 11], isSigned = false, modulusProduct = 2310 : i32, polySize = 1024 : i32} : (tensor<4xi64>) -> tensor<40960xi64>

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// RUN: concretecompiler --optimize-tfhe=false --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// CHECK: func.func @apply_lookup_table_cst(%arg0: tensor<5x!TFHE.glwe<{_,_,_}{7}>>) -> tensor<5x!TFHE.glwe<{_,_,_}{7}>> {
// CHECK-NEXT: %cst = arith.constant dense<"0x00000000000000000100000000000000020000000000000003000000000000000400000000000000050000000000000006000000000000000700000000000000080000000000000009000000000000000A000000000000000B000000000000000C000000000000000D000000000000000E000000000000000F0000000000000010000000000000001100000000000000120000000000000013000000000000001400000000000000150000000000000016000000000000001700000000000000180000000000000019000000000000001A000000000000001B000000000000001C000000000000001D000000000000001E000000000000001F0000000000000020000000000000002100000000000000220000000000000023000000000000002400000000000000250000000000000026000000000000002700000000000000280000000000000029000000000000002A000000000000002B000000000000002C000000000000002D000000000000002E000000000000002F0000000000000030000000000000003100000000000000320000000000000033000000000000003400000000000000350000000000000036000000000000003700000000000000380000000000000039000000000000003A000000000000003B000000000000003C000000000000003D000000000000003E000000000000003F0000000000000040000000000000004100000000000000420000000000000043000000000000004400000000000000450000000000000046000000000000004700000000000000480000000000000049000000000000004A000000000000004B000000000000004C000000000000004D000000000000004E000000000000004F0000000000000050000000000000005100000000000000520000000000000053000000000000005400000000000000550000000000000056000000000000005700000000000000580000000000000059000000000000005A000000000000005B000000000000005C000000000000005D000000000000005E000000000000005F0000000000000060000000000000006100000000000000620000000000000063000000000000006400000000000000650000000000000066000000000000006700000000000000680000000000000069000000000000006A000000000000006B000000000000006C000000000000006D000000000000006E000000000000006F0000000000000070000000000000007100000000000000720000000000000073000000000000007400000000000000750000000000000076000000000000007700000000000000780000000000000079000000000000007A000000000000007B000000000000007C000000000000007D000000000000007E000000000000007F00000000000000"> : tensor<128xi64>

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// RUN: concretecompiler --optimize-tfhe=false --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
//CHECK-LABEL: func.func @conv2d(%arg0: tensor<100x3x28x28x5x!TFHE.glwe<{_,_,_}{2}>>, %arg1: tensor<4x3x14x14xi3>, %arg2: tensor<4xi3>) -> tensor<100x4x15x15x5x!TFHE.glwe<{_,_,_}{2}>> {

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// RUN: concretecompiler --optimize-tfhe=false --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// CHECK-LABEL: func.func @mul_eint_int(%arg0: tensor<5x!TFHE.glwe<{_,_,_}{7}>>) -> tensor<5x!TFHE.glwe<{_,_,_}{7}>> {
// CHECK-NEXT: %c2_i8 = arith.constant 2 : i8

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// RUN: concretecompiler --optimize-tfhe=false --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// CHECK-LABEL: func.func @neg_eint(%arg0: tensor<5x!TFHE.glwe<{_,_,_}{7}>>) -> tensor<5x!TFHE.glwe<{_,_,_}{7}>> {
// CHECK-NEXT: %0 = bufferization.alloc_tensor() : tensor<5x!TFHE.glwe<{_,_,_}{7}>>

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// RUN: concretecompiler --optimize-tfhe=false --action=dump-tfhe %s --large-integer-crt-decomposition=2,3,5,7,11 --large-integer-circuit-bootstrap=2,9 --large-integer-packing-keyswitch=694,1024,4,9 --v0-parameter=2,10,693,4,9,7,2 2>&1| FileCheck %s
// CHECK-LABEL: func.func @sub_int_eint(%arg0: tensor<5x!TFHE.glwe<{_,_,_}{7}>>) -> tensor<5x!TFHE.glwe<{_,_,_}{7}>> {
// CHECK-NEXT: %c1_i8 = arith.constant 1 : i8

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler %s --action=dump-tfhe 2>&1| FileCheck %s
// RUN: concretecompiler %s --optimize-tfhe=false --action=dump-tfhe 2>&1| FileCheck %s
// CHECK-LABEL: func.func @add_eint(%arg0: !TFHE.glwe<{_,_,_}{7}>, %arg1: !TFHE.glwe<{_,_,_}{7}>) -> !TFHE.glwe<{_,_,_}{7}>
func.func @add_eint(%arg0: !FHE.eint<7>, %arg1: !FHE.eint<7>) -> !FHE.eint<7> {

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler %s --action=dump-tfhe 2>&1| FileCheck %s
// RUN: concretecompiler %s --optimize-tfhe=false --action=dump-tfhe 2>&1| FileCheck %s
// CHECK-LABEL: func.func @add_eint_int(%arg0: !TFHE.glwe<{_,_,_}{7}>) -> !TFHE.glwe<{_,_,_}{7}>
func.func @add_eint_int(%arg0: !FHE.eint<7>) -> !FHE.eint<7> {

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler %s --action=dump-tfhe 2>&1| FileCheck %s
// RUN: concretecompiler %s --optimize-tfhe=false --action=dump-tfhe 2>&1| FileCheck %s
// CHECK: func.func @apply_lookup_table(%arg0: !TFHE.glwe<{_,_,_}{2}>, %arg1: tensor<4xi64>) -> !TFHE.glwe<{_,_,_}{3}> {
// CHECK-NEXT: %0 = "TFHE.encode_expand_lut_for_bootstrap"(%arg1) {isSigned = false, outputBits = 3 : i32, polySize = 256 : i32} : (tensor<4xi64>) -> tensor<256xi64>

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler %s --action=dump-tfhe 2>&1| FileCheck %s
// RUN: concretecompiler %s --optimize-tfhe=false --action=dump-tfhe 2>&1| FileCheck %s
//CHECK: func.func @apply_lookup_table_cst(%[[A0:.*]]: !TFHE.glwe<{_,_,_}{7}>) -> !TFHE.glwe<{_,_,_}{7}> {

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler %s --action=dump-tfhe 2>&1| FileCheck %s
// RUN: concretecompiler %s --optimize-tfhe=false --action=dump-tfhe 2>&1| FileCheck %s
//CHECK: func.func @conv2d(%arg0: tensor<100x3x28x28x!TFHE.glwe<{_,_,_}{2}>>, %arg1: tensor<4x3x14x14xi3>, %arg2: tensor<4xi3>) -> tensor<100x4x15x15x!TFHE.glwe<{_,_,_}{2}>>
// CHECK-NEXT: %c4 = arith.constant 4 : index

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler %s --action=dump-tfhe 2>&1| FileCheck %s
// RUN: concretecompiler %s --optimize-tfhe=false --action=dump-tfhe 2>&1| FileCheck %s
// CHECK-LABEL: func.func @mul_eint_int(%arg0: !TFHE.glwe<{_,_,_}{7}>) -> !TFHE.glwe<{_,_,_}{7}>
func.func @mul_eint_int(%arg0: !FHE.eint<7>) -> !FHE.eint<7> {

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler %s --action=dump-tfhe 2>&1| FileCheck %s
// RUN: concretecompiler %s --optimize-tfhe=false --action=dump-tfhe 2>&1| FileCheck %s
// CHECK-LABEL: func.func @neg_eint(%arg0: !TFHE.glwe<{_,_,_}{7}>) -> !TFHE.glwe<{_,_,_}{7}>
func.func @neg_eint(%arg0: !FHE.eint<7>) -> !FHE.eint<7> {

View File

@@ -1,4 +1,4 @@
// RUN: concretecompiler %s --action=dump-tfhe 2>&1| FileCheck %s
// RUN: concretecompiler %s --optimize-tfhe=false --action=dump-tfhe 2>&1| FileCheck %s
// CHECK-LABEL: func.func @sub_int_eint(%arg0: !TFHE.glwe<{_,_,_}{7}>) -> !TFHE.glwe<{_,_,_}{7}>
func.func @sub_int_eint(%arg0: !FHE.eint<7>) -> !FHE.eint<7> {

View File

@@ -1,9 +1,9 @@
// RUN: concretecompiler --passes tfhe-to-concrete --action=dump-concrete %s 2>&1| FileCheck %s
// CHECK-LABEL: func.func @add_glwe(%arg0: !Concrete.lwe_ciphertext<2048,7>, %arg1: !Concrete.lwe_ciphertext<2048,7>) -> !Concrete.lwe_ciphertext<2048,7>
// CHECK-LABEL: func.func @add_glwe(%arg0: tensor<2049xi64>, %arg1: tensor<2049xi64>) -> tensor<2049xi64>
func.func @add_glwe(%arg0: !TFHE.glwe<{2048,1,64}{7}>, %arg1: !TFHE.glwe<{2048,1,64}{7}>) -> !TFHE.glwe<{2048,1,64}{7}> {
// CHECK-NEXT: %[[V1:.*]] = "Concrete.add_lwe_ciphertexts"(%arg0, %arg1) : (!Concrete.lwe_ciphertext<2048,7>, !Concrete.lwe_ciphertext<2048,7>) -> !Concrete.lwe_ciphertext<2048,7>
// CHECK-NEXT: return %[[V1]] : !Concrete.lwe_ciphertext<2048,7>
// CHECK-NEXT: %[[V1:.*]] = "Concrete.add_lwe_tensor"(%arg0, %arg1) : (tensor<2049xi64>, tensor<2049xi64>) -> tensor<2049xi64>
// CHECK-NEXT: return %[[V1]] : tensor<2049xi64>
%0 = "TFHE.add_glwe"(%arg0, %arg1): (!TFHE.glwe<{2048,1,64}{7}>, !TFHE.glwe<{2048,1,64}{7}>) -> (!TFHE.glwe<{2048,1,64}{7}>)
return %0: !TFHE.glwe<{2048,1,64}{7}>

View File

@@ -1,9 +1,9 @@
// RUN: concretecompiler --passes tfhe-to-concrete --action=dump-concrete %s 2>&1| FileCheck %s
//CHECK: func.func @add_glwe_const_int(%[[A0:.*]]: !Concrete.lwe_ciphertext<1024,7>) -> !Concrete.lwe_ciphertext<1024,7> {
//CHECK: func.func @add_glwe_const_int(%[[A0:.*]]: tensor<1025xi64>) -> tensor<1025xi64> {
//CHECK: %c1_i64 = arith.constant 1 : i64
//CHECK: %[[V0:.*]] = "Concrete.add_plaintext_lwe_ciphertext"(%[[A0]], %c1_i64) : (!Concrete.lwe_ciphertext<1024,7>, i64) -> !Concrete.lwe_ciphertext<1024,7>
//CHECK: return %[[V0]] : !Concrete.lwe_ciphertext<1024,7>
//CHECK: %[[V0:.*]] = "Concrete.add_plaintext_lwe_tensor"(%[[A0]], %c1_i64) : (tensor<1025xi64>, i64) -> tensor<1025xi64>
//CHECK: return %[[V0]] : tensor<1025xi64>
//CHECK: }
func.func @add_glwe_const_int(%arg0: !TFHE.glwe<{1024,1,64}{7}>) -> !TFHE.glwe<{1024,1,64}{7}> {
%0 = arith.constant 1 : i64
@@ -12,9 +12,9 @@ func.func @add_glwe_const_int(%arg0: !TFHE.glwe<{1024,1,64}{7}>) -> !TFHE.glwe<{
}
//CHECK: func.func @add_glwe_int(%[[A0:.*]]: !Concrete.lwe_ciphertext<1024,4>, %[[A1:.*]]: i64) -> !Concrete.lwe_ciphertext<1024,4> {
//CHECK: %[[V0:.*]] = "Concrete.add_plaintext_lwe_ciphertext"(%[[A0]], %[[A1]]) : (!Concrete.lwe_ciphertext<1024,4>, i64) -> !Concrete.lwe_ciphertext<1024,4>
//CHECK: return %[[V0]] : !Concrete.lwe_ciphertext<1024,4>
//CHECK: func.func @add_glwe_int(%[[A0:.*]]: tensor<1025xi64>, %[[A1:.*]]: i64) -> tensor<1025xi64> {
//CHECK: %[[V0:.*]] = "Concrete.add_plaintext_lwe_tensor"(%[[A0]], %[[A1]]) : (tensor<1025xi64>, i64) -> tensor<1025xi64>
//CHECK: return %[[V0]] : tensor<1025xi64>
//CHECK: }
func.func @add_glwe_int(%arg0: !TFHE.glwe<{1024,1,64}{4}>, %arg1: i64) -> !TFHE.glwe<{1024,1,64}{4}> {
%1 = "TFHE.add_glwe_int"(%arg0, %arg1): (!TFHE.glwe<{1024,1,64}{4}>, i64) -> (!TFHE.glwe<{1024,1,64}{4}>)

View File

@@ -1,9 +1,9 @@
// RUN: concretecompiler --passes tfhe-to-concrete --action=dump-concrete %s 2>&1| FileCheck %s
//CHECK: func.func @bootstrap_lwe(%[[A0:.*]]: !Concrete.lwe_ciphertext<600,7>) -> !Concrete.lwe_ciphertext<1024,4> {
//CHECK: func.func @bootstrap_lwe(%[[A0:.*]]: tensor<601xi64>) -> tensor<1025xi64> {
//CHECK: %cst = arith.constant dense<"0x00000000000000000100000000000000020000000000000003000000000000000400000000000000050000000000000006000000000000000700000000000000080000000000000009000000000000000A000000000000000B000000000000000C000000000000000D000000000000000E000000000000000F0000000000000010000000000000001100000000000000120000000000000013000000000000001400000000000000150000000000000016000000000000001700000000000000180000000000000019000000000000001A000000000000001B000000000000001C000000000000001D000000000000001E000000000000001F0000000000000020000000000000002100000000000000220000000000000023000000000000002400000000000000250000000000000026000000000000002700000000000000280000000000000029000000000000002A000000000000002B000000000000002C000000000000002D000000000000002E000000000000002F0000000000000030000000000000003100000000000000320000000000000033000000000000003400000000000000350000000000000036000000000000003700000000000000380000000000000039000000000000003A000000000000003B000000000000003C000000000000003D000000000000003E000000000000003F0000000000000040000000000000004100000000000000420000000000000043000000000000004400000000000000450000000000000046000000000000004700000000000000480000000000000049000000000000004A000000000000004B000000000000004C000000000000004D000000000000004E000000000000004F0000000000000050000000000000005100000000000000520000000000000053000000000000005400000000000000550000000000000056000000000000005700000000000000580000000000000059000000000000005A000000000000005B000000000000005C000000000000005D000000000000005E000000000000005F0000000000000060000000000000006100000000000000620000000000000063000000000000006400000000000000650000000000000066000000000000006700000000000000680000000000000069000000000000006A000000000000006B000000000000006C000000000000006D000000000000006E000000000000006F0000000000000070000000000000007100000000000000720000000000000073000000000000007400000000000000750000000000000076000000000000007700000000000000780000000000000079000000000000007A000000000000007B000000000000007C000000000000007D000000000000007E000000000000007F00000000000000"> : tensor<128xi64>
//CHECK: %[[V1:.*]] = "Concrete.bootstrap_lwe"(%arg0, %cst) {baseLog = 1 : i32, glweDimension = 1 : i32, level = 3 : i32, polySize = 1024 : i32} : (!Concrete.lwe_ciphertext<600,7>, tensor<128xi64>) -> !Concrete.lwe_ciphertext<1024,4>
//CHECK: return %[[V1]] : !Concrete.lwe_ciphertext<1024,4>
//CHECK: %[[V1:.*]] = "Concrete.bootstrap_lwe_tensor"(%arg0, %cst) {baseLog = 1 : i32, glweDimension = 1 : i32, inputLweDim = 600 : i32, level = 3 : i32, outPrecision = 4 : i32, polySize = 1024 : i32} : (tensor<601xi64>, tensor<128xi64>) -> tensor<1025xi64>
//CHECK: return %[[V1]] : tensor<1025xi64>
//CHECK: }
func.func @bootstrap_lwe(%ciphertext: !TFHE.glwe<{600,1,64}{7}>) -> !TFHE.glwe<{1024,1,64}{4}> {
%cst = arith.constant dense<"0x00000000000000000100000000000000020000000000000003000000000000000400000000000000050000000000000006000000000000000700000000000000080000000000000009000000000000000A000000000000000B000000000000000C000000000000000D000000000000000E000000000000000F0000000000000010000000000000001100000000000000120000000000000013000000000000001400000000000000150000000000000016000000000000001700000000000000180000000000000019000000000000001A000000000000001B000000000000001C000000000000001D000000000000001E000000000000001F0000000000000020000000000000002100000000000000220000000000000023000000000000002400000000000000250000000000000026000000000000002700000000000000280000000000000029000000000000002A000000000000002B000000000000002C000000000000002D000000000000002E000000000000002F0000000000000030000000000000003100000000000000320000000000000033000000000000003400000000000000350000000000000036000000000000003700000000000000380000000000000039000000000000003A000000000000003B000000000000003C000000000000003D000000000000003E000000000000003F0000000000000040000000000000004100000000000000420000000000000043000000000000004400000000000000450000000000000046000000000000004700000000000000480000000000000049000000000000004A000000000000004B000000000000004C000000000000004D000000000000004E000000000000004F0000000000000050000000000000005100000000000000520000000000000053000000000000005400000000000000550000000000000056000000000000005700000000000000580000000000000059000000000000005A000000000000005B000000000000005C000000000000005D000000000000005E000000000000005F0000000000000060000000000000006100000000000000620000000000000063000000000000006400000000000000650000000000000066000000000000006700000000000000680000000000000069000000000000006A000000000000006B000000000000006C000000000000006D000000000000006E000000000000006F0000000000000070000000000000007100000000000000720000000000000073000000000000007400000000000000750000000000000076000000000000007700000000000000780000000000000079000000000000007A000000000000007B000000000000007C000000000000007D000000000000007E000000000000007F00000000000000"> : tensor<128xi64>

View File

@@ -1,7 +1,7 @@
// RUN: concretecompiler --passes tfhe-to-concrete --action=dump-concrete %s 2>&1| FileCheck %s
// CHECK: func.func @apply_lookup_table(%arg0: tensor<4xi64>) -> tensor<1024xi64> {
// CHECK-NEXT: %0 = "Concrete.encode_expand_lut_for_bootstrap"(%arg0) {isSigned = true, outputBits = 3 : i32, polySize = 1024 : i32} : (tensor<4xi64>) -> tensor<1024xi64>
// CHECK-NEXT: %0 = "Concrete.encode_expand_lut_for_bootstrap_tensor"(%arg0) {isSigned = true, outputBits = 3 : i32, polySize = 1024 : i32} : (tensor<4xi64>) -> tensor<1024xi64>
// CHECK-NEXT: return %0 : tensor<1024xi64>
// CHECK-NEXT: }
func.func @apply_lookup_table(%arg1: tensor<4xi64>) -> tensor<1024xi64> {

View File

@@ -1,7 +1,7 @@
// RUN: concretecompiler --passes tfhe-to-concrete --action=dump-concrete %s 2>&1| FileCheck %s
// CHECK: func.func @main(%arg0: tensor<4xi64>) -> tensor<40960xi64> {
// CHECK-NEXT: %0 = "Concrete.encode_expand_lut_for_woppbs"(%arg0) {crtBits = [1, 2, 3, 3, 4], crtDecomposition = [2, 3, 5, 7, 11], isSigned = false, modulusProduct = 2310 : i32, polySize = 1024 : i32} : (tensor<4xi64>) -> tensor<40960xi64>
// CHECK-NEXT: %0 = "Concrete.encode_expand_lut_for_woppbs_tensor"(%arg0) {crtBits = [1, 2, 3, 3, 4], crtDecomposition = [2, 3, 5, 7, 11], isSigned = false, modulusProduct = 2310 : i32, polySize = 1024 : i32} : (tensor<4xi64>) -> tensor<40960xi64>
// CHECK-NEXT: return %0 : tensor<40960xi64>
// CHECK-NEXT: }
func.func @main(%arg1: tensor<4xi64>) -> tensor<40960xi64> {

View File

@@ -1,7 +1,7 @@
// RUN: concretecompiler --passes tfhe-to-concrete --action=dump-concrete %s 2>&1| FileCheck %s
// CHECK: func.func @main(%arg0: i64) -> tensor<5xi64> {
// CHECK-NEXT: %0 = "Concrete.encode_plaintext_with_crt"(%arg0) {mods = [2, 3, 5, 7, 11], modsProd = 2310 : i64} : (i64) -> tensor<5xi64>
// CHECK-NEXT: %0 = "Concrete.encode_plaintext_with_crt_tensor"(%arg0) {mods = [2, 3, 5, 7, 11], modsProd = 2310 : i64} : (i64) -> tensor<5xi64>
// CHECK-NEXT: return %0 : tensor<5xi64>
// CHECK-NEXT: }
func.func @main(%arg1: i64) -> tensor<5xi64> {

View File

@@ -1,8 +1,8 @@
// RUN: concretecompiler --passes tfhe-to-concrete --action=dump-concrete %s 2>&1| FileCheck %s
// CHECK: func.func @keyswitch_glwe(%[[A0:.*]]: !Concrete.lwe_ciphertext<1024,2>) -> !Concrete.lwe_ciphertext<567,2> {
// CHECK-NEXT: %[[V0:.*]] = "Concrete.keyswitch_lwe"(%[[A0]]) {baseLog = 3 : i32, level = 2 : i32} : (!Concrete.lwe_ciphertext<1024,2>) -> !Concrete.lwe_ciphertext<567,2>
// CHECK-NEXT: return %[[V0]] : !Concrete.lwe_ciphertext<567,2>
// CHECK: func.func @keyswitch_glwe(%[[A0:.*]]: tensor<1025xi64>) -> tensor<568xi64> {
// CHECK-NEXT: %[[V0:.*]] = "Concrete.keyswitch_lwe_tensor"(%[[A0]]) {baseLog = 3 : i32, level = 2 : i32, lwe_dim_in = 1024 : i32, lwe_dim_out = 567 : i32} : (tensor<1025xi64>) -> tensor<568xi64>
// CHECK-NEXT: return %[[V0]] : tensor<568xi64>
// CHECK-NEXT: }
func.func @keyswitch_glwe(%arg0: !TFHE.glwe<{1024,1,64}{2}>) -> !TFHE.glwe<{567,1,64}{2}> {
%0 = "TFHE.keyswitch_glwe"(%arg0) {baseLog = 3 : i32, level = 2 : i32} : (!TFHE.glwe<{1024,1,64}{2}>) -> !TFHE.glwe<{567,1,64}{2}>

View File

@@ -1,9 +1,9 @@
// RUN: concretecompiler --passes tfhe-to-concrete --action=dump-concrete %s 2>&1| FileCheck %s
//CHECK: func.func @mul_glwe_const_int(%[[A0:.*]]: !Concrete.lwe_ciphertext<1024,7>) -> !Concrete.lwe_ciphertext<1024,7> {
//CHECK: func.func @mul_glwe_const_int(%[[A0:.*]]: tensor<1025xi64>) -> tensor<1025xi64> {
//CHECK: %c1_i64 = arith.constant 1 : i64
//CHECK: %[[V0:.*]] = "Concrete.mul_cleartext_lwe_ciphertext"(%[[A0]], %c1_i64) : (!Concrete.lwe_ciphertext<1024,7>, i64) -> !Concrete.lwe_ciphertext<1024,7>
//CHECK: return %[[V0]] : !Concrete.lwe_ciphertext<1024,7>
//CHECK: %[[V0:.*]] = "Concrete.mul_cleartext_lwe_tensor"(%[[A0]], %c1_i64) : (tensor<1025xi64>, i64) -> tensor<1025xi64>
//CHECK: return %[[V0]] : tensor<1025xi64>
//CHECK: }
func.func @mul_glwe_const_int(%arg0: !TFHE.glwe<{1024,1,64}{7}>) -> !TFHE.glwe<{1024,1,64}{7}> {
%0 = arith.constant 1 : i64
@@ -12,9 +12,9 @@ func.func @mul_glwe_const_int(%arg0: !TFHE.glwe<{1024,1,64}{7}>) -> !TFHE.glwe<{
}
//CHECK: func.func @mul_glwe_int(%[[A0:.*]]: !Concrete.lwe_ciphertext<1024,4>, %[[A1:.*]]: i64) -> !Concrete.lwe_ciphertext<1024,4> {
//CHECK: %[[V0:.*]] = "Concrete.mul_cleartext_lwe_ciphertext"(%[[A0]], %[[A1]]) : (!Concrete.lwe_ciphertext<1024,4>, i64) -> !Concrete.lwe_ciphertext<1024,4>
//CHECK: return %[[V0]] : !Concrete.lwe_ciphertext<1024,4>
//CHECK: func.func @mul_glwe_int(%[[A0:.*]]: tensor<1025xi64>, %[[A1:.*]]: i64) -> tensor<1025xi64> {
//CHECK: %[[V0:.*]] = "Concrete.mul_cleartext_lwe_tensor"(%[[A0]], %[[A1]]) : (tensor<1025xi64>, i64) -> tensor<1025xi64>
//CHECK: return %[[V0]] : tensor<1025xi64>
//CHECK: }
func.func @mul_glwe_int(%arg0: !TFHE.glwe<{1024,1,64}{4}>, %arg1: i64) -> !TFHE.glwe<{1024,1,64}{4}> {
%1 = "TFHE.mul_glwe_int"(%arg0, %arg1): (!TFHE.glwe<{1024,1,64}{4}>, i64) -> (!TFHE.glwe<{1024,1,64}{4}>)

Some files were not shown because too many files have changed in this diff Show More