mirror of
https://github.com/zama-ai/concrete.git
synced 2026-02-10 04:35:03 -05:00
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:
@@ -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();
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"> {
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
add_subdirectory(IR)
|
||||
add_subdirectory(Transforms)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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 ®istry);
|
||||
} // namespace BConcrete
|
||||
} // namespace Concrete
|
||||
} // namespace concretelang
|
||||
} // namespace mlir
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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
|
||||
@@ -1 +1,2 @@
|
||||
add_subdirectory(IR)
|
||||
add_subdirectory(Transforms)
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
File diff suppressed because it is too large
Load Diff
14
compiler/lib/Conversion/ConcreteToCAPI/CMakeLists.txt
Normal file
14
compiler/lib/Conversion/ConcreteToCAPI/CMakeLists.txt
Normal 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)
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
add_subdirectory(IR)
|
||||
add_subdirectory(Transforms)
|
||||
@@ -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"
|
||||
>();
|
||||
}
|
||||
@@ -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"
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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 ®istry) {
|
||||
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);
|
||||
});
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ®istry) {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
add_subdirectory(IR)
|
||||
add_subdirectory(Transforms)
|
||||
|
||||
12
compiler/lib/Dialect/TFHE/Transforms/CMakeLists.txt
Normal file
12
compiler/lib/Dialect/TFHE/Transforms/CMakeLists.txt
Normal 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)
|
||||
@@ -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
|
||||
@@ -27,11 +27,11 @@ add_mlir_library(
|
||||
FHEDialectTransforms
|
||||
RTDialectAnalysis
|
||||
ConcretelangTransforms
|
||||
ConcretelangBConcreteTransforms
|
||||
ConcretelangConcreteTransforms
|
||||
ConcretelangSDFGTransforms
|
||||
ConcretelangSDFGInterfaces
|
||||
LinalgExtras
|
||||
ConcreteDialectTransforms
|
||||
TFHEDialectTransforms
|
||||
concrete_optimizer
|
||||
MLIRExecutionEngine
|
||||
${LLVM_PTHREAD_LIB}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ target_link_libraries(
|
||||
PRIVATE ${dialect_libs}
|
||||
${conversion_libs}
|
||||
MLIRTransforms
|
||||
BConcreteDialect
|
||||
ConcreteDialect
|
||||
TFHEDialect
|
||||
FHEDialect
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
@@ -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>>
|
||||
}
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
@@ -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}>>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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}>> {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}>>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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}> {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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}>)
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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}>
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user