feat: create encrypted signed integer type

This commit is contained in:
Umut
2022-08-26 14:17:58 +03:00
parent 39e7313348
commit 41c9f86803
39 changed files with 1144 additions and 260 deletions

View File

@@ -1,3 +1,7 @@
set(LLVM_TARGET_DEFINITIONS FHEInterfaces.td)
mlir_tablegen(FHETypesInterfaces.h.inc -gen-type-interface-decls)
mlir_tablegen(FHETypesInterfaces.cpp.inc -gen-type-interface-defs)
set(LLVM_TARGET_DEFINITIONS FHEOps.td)
mlir_tablegen(FHEOps.h.inc -gen-op-decls)
mlir_tablegen(FHEOps.cpp.inc -gen-op-defs)

View File

@@ -0,0 +1,32 @@
#ifndef CONCRETELANG_DIALECT_FHE_IR_FHE_INTERFACES
#define CONCRETELANG_DIALECT_FHE_IR_FHE_INTERFACES
include "mlir/IR/OpBase.td"
def FheIntegerInterface : TypeInterface<"FheIntegerInterface"> {
let cppNamespace = "mlir::concretelang::FHE";
let description = [{
Interface for encapsulating the common properties of encrypted integer types.
}];
let methods = [
InterfaceMethod<
/*description=*/"Get bit-width of the integer.",
/*retTy=*/"unsigned",
/*methodName=*/"getWidth"
>,
InterfaceMethod<
/*description=*/"Get whether the integer is signed.",
/*retTy=*/"bool",
/*methodName=*/"isSigned"
>,
InterfaceMethod<
/*description=*/"Get whether the integer is unsigned.",
/*retTy=*/"bool",
/*methodName=*/"isUnsigned"
>
];
}
#endif

View File

@@ -18,10 +18,10 @@ namespace concretelang {
namespace FHE {
bool verifyEncryptedIntegerInputAndResultConsistency(
Operation &op, EncryptedIntegerType &input, EncryptedIntegerType &result);
Operation &op, FheIntegerInterface &input, FheIntegerInterface &result);
bool verifyEncryptedIntegerAndIntegerInputsConsistency(Operation &op,
EncryptedIntegerType &a,
FheIntegerInterface &a,
IntegerType &b);
/// Shared error message for all ApplyLookupTable variant Op (several Dialect)

View File

@@ -27,14 +27,14 @@ def FHE_ZeroEintOp : FHE_Op<"zero", [NoSideEffect]> {
Example:
```mlir
"FHE.zero"() : () -> !FHE.eint<2>
"FHE.zero"() : () -> !FHE.esint<2>
```
}];
let arguments = (ins);
let results = (outs FHE_EncryptedIntegerType:$out);
let results = (outs FHE_AnyEncryptedInteger:$out);
}
def FHE_ZeroTensorOp : FHE_Op<"zero_tensor", [NoSideEffect]> {
let summary = "Creates a new tensor with all elements initialized to an encrypted zero.";
@@ -44,36 +44,38 @@ def FHE_ZeroTensorOp : FHE_Op<"zero_tensor", [NoSideEffect]> {
Example:
```mlir
%tensor = "FHE.zero_tensor"() : () -> tensor<5x!FHE.eint<4>>
%tensor = "FHE.zero_tensor"() : () -> tensor<5x!FHE.esint<4>>
```
}];
let arguments = (ins);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$tensor);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$tensor);
}
def FHE_AddEintIntOp : FHE_Op<"add_eint_int", [NoSideEffect]> {
let summary = "Adds an encrypted integer and a clear integer";
let description = [{
Adds an encrypted integer and a clear integer.
The clear integer must have at most one more bit than the encrypted integer
and the result must have the same width than the encrypted integer.
and the result must have the same width and the same signedness as the encrypted integer.
Example:
```mlir
// ok
"FHE.add_eint_int"(%a, %i) : (!FHE.eint<2>, i3) -> !FHE.eint<2>
"FHE.add_eint_int"(%a, %i) : (!FHE.esint<2>, i3) -> !FHE.esint<2>
// error
"FHE.add_eint_int"(%a, %i) : (!FHE.eint<2>, i4) -> !FHE.eint<2>
"FHE.add_eint_int"(%a, %i) : (!FHE.eint<2>, i3) -> !FHE.eint<3>
"FHE.add_eint_int"(%a, %i) : (!FHE.eint<2>, i3) -> !FHE.esint<2>
```
}];
let arguments = (ins FHE_EncryptedIntegerType:$a, AnyInteger:$b);
let results = (outs FHE_EncryptedIntegerType);
let arguments = (ins FHE_AnyEncryptedInteger:$a, AnyInteger:$b);
let results = (outs FHE_AnyEncryptedInteger);
let builders = [
OpBuilder<(ins "Value":$a, "Value":$b), [{
@@ -86,26 +88,28 @@ def FHE_AddEintIntOp : FHE_Op<"add_eint_int", [NoSideEffect]> {
}
def FHE_AddEintOp : FHE_Op<"add_eint", [NoSideEffect]> {
let summary = "Adds two encrypted integers";
let description = [{
let description = [{
Adds two encrypted integers
The encrypted integers and the result must have the same width.
The encrypted integers and the result must have the same width and the same signedness.
Example:
```mlir
// ok
"FHE.add_eint"(%a, %b): (!FHE.eint<2>, !FHE.eint<2>) -> (!FHE.eint<2>)
"FHE.add_eint"(%a, %b): (!FHE.esint<2>, !FHE.esint<2>) -> (!FHE.esint<2>)
// error
"FHE.add_eint"(%a, %b): (!FHE.eint<2>, !FHE.eint<3>) -> (!FHE.eint<2>)
"FHE.add_eint"(%a, %b): (!FHE.eint<2>, !FHE.eint<2>) -> (!FHE.eint<3>)
"FHE.add_eint"(%a, %b): (!FHE.eint<2>, !FHE.eint<2>) -> (!FHE.esint<2>)
"FHE.add_eint"(%a, %b): (!FHE.esint<2>, !FHE.eint<2>) -> (!FHE.eint<2>)
```
}];
let arguments = (ins FHE_EncryptedIntegerType:$a, FHE_EncryptedIntegerType:$b);
let results = (outs FHE_EncryptedIntegerType);
let arguments = (ins FHE_AnyEncryptedInteger:$a, FHE_AnyEncryptedInteger:$b);
let results = (outs FHE_AnyEncryptedInteger);
let builders = [
OpBuilder<(ins "Value":$a, "Value":$b), [{
@@ -117,27 +121,28 @@ def FHE_AddEintOp : FHE_Op<"add_eint", [NoSideEffect]> {
}
def FHE_SubIntEintOp : FHE_Op<"sub_int_eint", [NoSideEffect]> {
let summary = "Substract a clear integer and an encrypted integer";
let summary = "Subtract an encrypted integer from a clear integer";
let description = [{
Substract a clear integer and an encrypted integer.
The clear integer must have at most one more bit than the encrypted integer
and the result must have the same width than the encrypted integer.
Subtract an encrypted integer from a clear integer.
The clear integer must have one more bit than the encrypted integer
and the result must have the same width and the same signedness as the encrypted integer.
Example:
```mlir
// ok
"FHE.sub_int_eint"(%i, %a) : (i3, !FHE.eint<2>) -> !FHE.eint<2>
"FHE.sub_int_eint"(%i, %a) : (i3, !FHE.esint<2>) -> !FHE.esint<2>
// error
"FHE.sub_int_eint"(%i, %a) : (i4, !FHE.eint<2>) -> !FHE.eint<2>
"FHE.sub_int_eint"(%i, %a) : (i3, !FHE.eint<2>) -> !FHE.eint<3>
"FHE.sub_int_eint"(%i, %a) : (i3, !FHE.eint<2>) -> !FHE.esint<2>
```
}];
let arguments = (ins AnyInteger:$a, FHE_EncryptedIntegerType:$b);
let results = (outs FHE_EncryptedIntegerType);
let arguments = (ins AnyInteger:$a, FHE_AnyEncryptedInteger:$b);
let results = (outs FHE_AnyEncryptedInteger);
let builders = [
OpBuilder<(ins "Value":$a, "Value":$b), [{
@@ -149,27 +154,28 @@ def FHE_SubIntEintOp : FHE_Op<"sub_int_eint", [NoSideEffect]> {
}
def FHE_SubEintIntOp : FHE_Op<"sub_eint_int", [NoSideEffect]> {
let summary = "Substract a clear integer from an encrypted integer";
let summary = "Subtract a clear integer from an encrypted integer";
let description = [{
Substract a clear integer from an encrypted integer.
The clear integer must have at most one more bit than the encrypted integer
and the result must have the same width than the encrypted integer.
Subtract a clear integer from an encrypted integer.
The clear integer must have one more bit than the encrypted integer
and the result must have the same width and the same signedness as the encrypted integer.
Example:
```mlir
// ok
"FHE.sub_eint_int"(%i, %a) : (!FHE.eint<2>, i3) -> !FHE.eint<2>
"FHE.sub_eint_int"(%i, %a) : (!FHE.esint<2>, i3) -> !FHE.esint<2>
// error
"FHE.sub_eint_int"(%i, %a) : (!FHE.eint<2>, i4) -> !FHE.eint<2>
"FHE.sub_eint_int"(%i, %a) : (!FHE.eint<2>, i3) -> !FHE.eint<3>
"FHE.sub_eint_int"(%i, %a) : (!FHE.eint<2>, i3) -> !FHE.esint<2>
```
}];
let arguments = (ins FHE_EncryptedIntegerType:$a, AnyInteger:$b);
let results = (outs FHE_EncryptedIntegerType);
let arguments = (ins FHE_AnyEncryptedInteger:$a, AnyInteger:$b);
let results = (outs FHE_AnyEncryptedInteger);
let builders = [
OpBuilder<(ins "Value":$a, "Value":$b), [{
@@ -178,31 +184,32 @@ def FHE_SubEintIntOp : FHE_Op<"sub_eint_int", [NoSideEffect]> {
];
let hasVerifier = 1;
let hasFolder = 1;
}
def FHE_SubEintOp : FHE_Op<"sub_eint", [NoSideEffect]> {
let summary = "Subtracts two encrypted integers";
let summary = "Subtract an encrypted integer from an encrypted integer";
let description = [{
Subtracts two encrypted integers
The encrypted integers and the result must have the same width.
Subtract an encrypted integer from an encrypted integer.
The encrypted integers and the result must have the same width and the same signedness.
Example:
```mlir
// ok
"FHE.sub_eint"(%a, %b): (!FHE.eint<2>, !FHE.eint<2>) -> (!FHE.eint<2>)
"FHE.sub_eint"(%a, %b): (!FHE.esint<2>, !FHE.esint<2>) -> (!FHE.esint<2>)
// error
"FHE.sub_eint"(%a, %b): (!FHE.eint<2>, !FHE.eint<3>) -> (!FHE.eint<2>)
"FHE.sub_eint"(%a, %b): (!FHE.eint<2>, !FHE.eint<2>) -> (!FHE.eint<3>)
"FHE.sub_eint"(%a, %b): (!FHE.eint<2>, !FHE.esint<2>) -> (!FHE.esint<2>)
"FHE.sub_eint"(%a, %b): (!FHE.eint<2>, !FHE.eint<2>) -> (!FHE.esint<2>)
```
}];
let arguments = (ins FHE_EncryptedIntegerType:$a, FHE_EncryptedIntegerType:$b);
let results = (outs FHE_EncryptedIntegerType);
let arguments = (ins FHE_AnyEncryptedInteger:$a, FHE_AnyEncryptedInteger:$b);
let results = (outs FHE_AnyEncryptedInteger);
let builders = [
OpBuilder<(ins "Value":$a, "Value":$b), [{
@@ -219,20 +226,22 @@ def FHE_NegEintOp : FHE_Op<"neg_eint", [NoSideEffect]> {
let description = [{
Negates an encrypted integer.
The result must have the same width than the encrypted integer.
The result must have the same width and the same signedness as the encrypted integer.
Example:
```mlir
// ok
"FHE.neg_eint"(%a): (!FHE.eint<2>) -> (!FHE.eint<2>)
"FHE.neg_eint"(%a): (!FHE.esint<2>) -> (!FHE.esint<2>)
// error
"FHE.neg_eint"(%a): (!FHE.eint<2>) -> (!FHE.eint<3>)
"FHE.neg_eint"(%a): (!FHE.eint<2>) -> (!FHE.esint<2>)
```
}];
let arguments = (ins FHE_EncryptedIntegerType:$a);
let results = (outs FHE_EncryptedIntegerType);
let arguments = (ins FHE_AnyEncryptedInteger:$a);
let results = (outs FHE_AnyEncryptedInteger);
let builders = [
OpBuilder<(ins "Value":$a), [{
@@ -243,27 +252,28 @@ def FHE_NegEintOp : FHE_Op<"neg_eint", [NoSideEffect]> {
}
def FHE_MulEintIntOp : FHE_Op<"mul_eint_int", [NoSideEffect]> {
let summary = "Mulitplies an encrypted integer and a clear integer";
let summary = "Multiply an encrypted integer with a clear integer";
let description = [{
Mulitplies an encrypted integer and a clear integer.
The clear integer must have at most one more bit than the encrypted integer
and the result must have the same width than the encrypted integer.
Multiply an encrypted integer with a clear integer.
The clear integer must have one more bit than the encrypted integer
and the result must have the same width and the same signedness as the encrypted integer.
Example:
```mlir
// ok
"FHE.mul_eint_int"(%a, %i) : (!FHE.eint<2>, i3) -> !FHE.eint<2>
"FHE.mul_eint_int"(%a, %i) : (!FHE.esint<2>, i3) -> !FHE.esint<2>
// error
"FHE.mul_eint_int"(%a, %i) : (!FHE.eint<2>, i4) -> !FHE.eint<2>
"FHE.mul_eint_int"(%a, %i) : (!FHE.eint<2>, i3) -> !FHE.eint<3>
"FHE.mul_eint_int"(%a, %i) : (!FHE.eint<2>, i3) -> !FHE.esint<2>
```
}];
let arguments = (ins FHE_EncryptedIntegerType:$a, AnyInteger:$b);
let results = (outs FHE_EncryptedIntegerType);
let arguments = (ins FHE_AnyEncryptedInteger:$a, AnyInteger:$b);
let results = (outs FHE_AnyEncryptedInteger);
let builders = [
OpBuilder<(ins "Value":$a, "Value":$b), [{
@@ -275,6 +285,56 @@ def FHE_MulEintIntOp : FHE_Op<"mul_eint_int", [NoSideEffect]> {
let hasFolder = 1;
}
def FHE_ToSignedOp : FHE_Op<"to_signed", [NoSideEffect]> {
let summary = "Cast an unsigned integer to a signed one";
let description = [{
Cast an unsigned integer to a signed one.
The result must have the same width as the input.
The behavior is undefined on overflow/underflow.
Examples:
```mlir
// ok
"FHE.to_signed"(%x) : (!FHE.eint<2>) -> !FHE.esint<2>
// error
"FHE.to_signed"(%x) : (!FHE.eint<2>) -> !FHE.esint<3>
```
}];
let arguments = (ins FHE_EncryptedIntegerType:$input);
let results = (outs FHE_EncryptedSignedIntegerType);
let hasVerifier = 1;
}
def FHE_ToUnsignedOp : FHE_Op<"to_unsigned", [NoSideEffect]> {
let summary = "Cast a signed integer to an unsigned one";
let description = [{
Cast a signed integer to an unsigned one.
The result must have the same width as the input.
The behavior is undefined on overflow/underflow.
Examples:
```mlir
// ok
"FHE.to_unsigned"(%x) : (!FHE.esint<2>) -> !FHE.eint<2>
// error
"FHE.to_unsigned"(%x) : (!FHE.esint<2>) -> !FHE.eint<3>
```
}];
let arguments = (ins FHE_EncryptedSignedIntegerType:$input);
let results = (outs FHE_EncryptedIntegerType);
let hasVerifier = 1;
}
def FHE_ApplyLookupTableEintOp : FHE_Op<"apply_lookup_table", [NoSideEffect]> {
let summary = "Applies a clear lookup table to an encrypted integer";

View File

@@ -11,6 +11,8 @@
#include <mlir/IR/BuiltinTypes.h>
#include <mlir/IR/DialectImplementation.h>
#include "concretelang/Dialect/FHE/IR/FHETypesInterfaces.h.inc"
#define GET_TYPEDEF_CLASSES
#include "concretelang/Dialect/FHE/IR/FHEOpsTypes.h.inc"

View File

@@ -2,13 +2,14 @@
#define CONCRETELANG_DIALECT_FHE_IR_FHE_TYPES
include "concretelang/Dialect/FHE/IR/FHEDialect.td"
include "concretelang/Dialect/FHE/IR/FHEInterfaces.td"
include "mlir/IR/BuiltinTypes.td"
class FHE_Type<string name, list<Trait> traits = []> :
TypeDef<FHE_Dialect, name, traits> { }
def FHE_EncryptedIntegerType : FHE_Type<"EncryptedInteger",
[MemRefElementTypeInterface]> {
[MemRefElementTypeInterface, FheIntegerInterface]> {
let mnemonic = "eint";
let summary = "An encrypted integer";
@@ -28,6 +29,44 @@ def FHE_EncryptedIntegerType : FHE_Type<"EncryptedInteger",
let hasCustomAssemblyFormat = 1;
let genVerifyDecl = true;
let extraClassDeclaration = [{
bool isSigned() const { return false; }
bool isUnsigned() const { return true; }
}];
}
def FHE_EncryptedSignedIntegerType : FHE_Type<"EncryptedSignedInteger",
[MemRefElementTypeInterface, FheIntegerInterface]> {
let mnemonic = "esint";
let summary = "An encrypted signed integer";
let description = [{
An encrypted signed integer with `width` bits to performs FHE Operations.
Examples:
```mlir
!FHE.esint<7>
!FHE.esint<6>
```
}];
let parameters = (ins "unsigned":$width);
let hasCustomAssemblyFormat = 1;
let genVerifyDecl = true;
let extraClassDeclaration = [{
bool isSigned() const { return true; }
bool isUnsigned() const { return false; }
}];
}
def FHE_AnyEncryptedInteger : Type<Or<[
FHE_EncryptedIntegerType.predicate,
FHE_EncryptedSignedIntegerType.predicate
]>>;
#endif

View File

@@ -22,8 +22,8 @@ def FHELinalg_AddEintIntOp : FHELinalg_Op<"add_eint_int", [TensorBroadcastingRul
let summary = "Returns a tensor that contains the addition of a tensor of encrypted integers and a tensor of clear integers.";
let description = [{
Performs an addition follwing the broadcasting rules between a tensor of encrypted integers and a tensor of clear integers.
The width of the clear integers must be less than or equals to the witdh of encrypted integers.
Performs an addition following the broadcasting rules between a tensor of encrypted integers and a tensor of clear integers.
The width of the clear integers must be less than or equals to the width of encrypted integers.
Examples:
```mlir
@@ -58,11 +58,11 @@ def FHELinalg_AddEintIntOp : FHELinalg_Op<"add_eint_int", [TensorBroadcastingRul
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[AnyInteger]>.predicate, HasStaticShapePred]>>:$rhs
);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>);
let builders = [
OpBuilder<(ins "Value":$rhs, "Value":$lhs), [{
@@ -77,7 +77,7 @@ def FHELinalg_AddEintOp : FHELinalg_Op<"add_eint", [TensorBroadcastingRules, Ten
let summary = "Returns a tensor that contains the addition of two tensor of encrypted integers.";
let description = [{
Performs an addition follwing the broadcasting rules between two tensors of encrypted integers.
Performs an addition following the broadcasting rules between two tensors of encrypted integers.
The width of the encrypted integers must be equals.
Examples:
@@ -112,11 +112,11 @@ def FHELinalg_AddEintOp : FHELinalg_Op<"add_eint", [TensorBroadcastingRules, Ten
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$rhs
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$rhs
);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>);
let builders = [
OpBuilder<(ins "Value":$rhs, "Value":$lhs), [{
@@ -126,21 +126,21 @@ def FHELinalg_AddEintOp : FHELinalg_Op<"add_eint", [TensorBroadcastingRules, Ten
}
def FHELinalg_SubIntEintOp : FHELinalg_Op<"sub_int_eint", [TensorBroadcastingRules, TensorBinaryIntEint]> {
let summary = "Returns a tensor that contains the substraction of a tensor of clear integers and a tensor of encrypted integers.";
let summary = "Returns a tensor that contains the subtraction of a tensor of clear integers and a tensor of encrypted integers.";
let description = [{
Performs a substraction following the broadcasting rules between a tensor of clear integers and a tensor of encrypted integers.
The width of the clear integers must be less than or equals to the witdh of encrypted integers.
Performs a subtraction following the broadcasting rules between a tensor of clear integers and a tensor of encrypted integers.
The width of the clear integers must be less than or equals to the width of encrypted integers.
Examples:
```mlir
// Returns the term to term substraction of `%a0` with `%a1`
// Returns the term to term subtraction of `%a0` with `%a1`
"FHELinalg.sub_int_eint"(%a0, %a1) : (tensor<4xi5>, tensor<4x!FHE.eint<4>>) -> tensor<4x!FHE.eint<4>>
// Returns the term to term substraction of `%a0` with `%a1`, where dimensions equal to one are stretched.
// Returns the term to term subtraction of `%a0` with `%a1`, where dimensions equal to one are stretched.
"FHELinalg.sub_int_eint"(%a0, %a1) : (tensor<4x1x4xi5>, tensor<1x4x4x!FHE.eint<4>>) -> tensor<4x4x4x!FHE.eint<4>>
// Returns the substraction of a 3x3 matrix of integers and a 3x1 matrix (a column) of encrypted integers.
// Returns the subtraction of a 3x3 matrix of integers and a 3x1 matrix (a column) of encrypted integers.
//
// [1,2,3] [1] [0,2,3]
// [4,5,6] - [2] = [2,3,4]
@@ -149,7 +149,7 @@ def FHELinalg_SubIntEintOp : FHELinalg_Op<"sub_int_eint", [TensorBroadcastingRul
// The dimension #1 of operand #2 is stretched as it is equals to 1.
"FHELinalg.sub_int_eint"(%a0, %a1) : (tensor<3x3xi5>, tensor<3x1x!FHE.eint<4>>) -> tensor<3x3x!FHE.eint<4>>
// Returns the substraction of a 3x3 matrix of integers and a 1x3 matrix (a line) of encrypted integers.
// Returns the subtraction of a 3x3 matrix of integers and a 1x3 matrix (a line) of encrypted integers.
//
// [1,2,3] [0,0,0]
// [4,5,6] - [1,2,3] = [3,3,3]
@@ -166,10 +166,10 @@ def FHELinalg_SubIntEintOp : FHELinalg_Op<"sub_int_eint", [TensorBroadcastingRul
let arguments = (ins
Type<And<[TensorOf<[AnyInteger]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$rhs
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$rhs
);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>);
let builders = [
OpBuilder<(ins "Value":$rhs, "Value":$lhs), [{
@@ -179,21 +179,21 @@ def FHELinalg_SubIntEintOp : FHELinalg_Op<"sub_int_eint", [TensorBroadcastingRul
}
def FHELinalg_SubEintIntOp : FHELinalg_Op<"sub_eint_int", [TensorBroadcastingRules, TensorBinaryEintInt]> {
let summary = "Returns a tensor that contains the substraction of a tensor of clear integers from a tensor of encrypted integers.";
let summary = "Returns a tensor that contains the subtraction of a tensor of clear integers from a tensor of encrypted integers.";
let description = [{
Performs a substraction following the broadcasting rules between a tensor of clear integers from a tensor of encrypted integers.
The width of the clear integers must be less than or equals to the witdh of encrypted integers.
Performs a subtraction following the broadcasting rules between a tensor of clear integers from a tensor of encrypted integers.
The width of the clear integers must be less than or equals to the width of encrypted integers.
Examples:
```mlir
// Returns the term to term substraction of `%a0` with `%a1`
// Returns the term to term subtraction of `%a0` with `%a1`
"FHELinalg.sub_eint_int"(%a0, %a1) : (tensor<4x!FHE.eint<4>>, tensor<4xi5>) -> tensor<4x!FHE.eint<4>>
// Returns the term to term substraction of `%a0` with `%a1`, where dimensions equal to one are stretched.
// Returns the term to term subtraction of `%a0` with `%a1`, where dimensions equal to one are stretched.
"FHELinalg.sub_eint_int"(%a0, %a1) : (tensor<1x4x4x!FHE.eint<4>>, tensor<4x1x4xi5>) -> tensor<4x4x4x!FHE.eint<4>>
// Returns the substraction of a 3x3 matrix of integers and a 3x1 matrix (a column) of encrypted integers.
// Returns the subtraction of a 3x3 matrix of integers and a 3x1 matrix (a column) of encrypted integers.
//
// [1,2,3] [1] [0,2,3]
// [4,5,6] - [2] = [2,3,4]
@@ -202,7 +202,7 @@ def FHELinalg_SubEintIntOp : FHELinalg_Op<"sub_eint_int", [TensorBroadcastingRul
// The dimension #1 of operand #2 is stretched as it is equals to 1.
"FHELinalg.sub_eint_int"(%a0, %a1) : (tensor<3x1x!FHE.eint<4>>, tensor<3x3xi5>) -> tensor<3x3x!FHE.eint<4>>
// Returns the substraction of a 3x3 matrix of integers and a 1x3 matrix (a line) of encrypted integers.
// Returns the subtraction of a 3x3 matrix of integers and a 1x3 matrix (a line) of encrypted integers.
//
// [1,2,3] [0,0,0]
// [4,5,6] - [1,2,3] = [3,3,3]
@@ -218,11 +218,11 @@ def FHELinalg_SubEintIntOp : FHELinalg_Op<"sub_eint_int", [TensorBroadcastingRul
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[AnyInteger]>.predicate, HasStaticShapePred]>>:$rhs
);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>);
let builders = [
OpBuilder<(ins "Value":$lhs, "Value":$rhs), [{
@@ -238,7 +238,7 @@ def FHELinalg_SubEintOp : FHELinalg_Op<"sub_eint", [TensorBroadcastingRules, Ten
let summary = "Returns a tensor that contains the subtraction of two tensor of encrypted integers.";
let description = [{
Performs an subtraction follwing the broadcasting rules between two tensors of encrypted integers.
Performs an subtraction following the broadcasting rules between two tensors of encrypted integers.
The width of the encrypted integers must be equal.
Examples:
@@ -249,7 +249,7 @@ def FHELinalg_SubEintOp : FHELinalg_Op<"sub_eint", [TensorBroadcastingRules, Ten
// Returns the term to term subtraction of `%a0` with `%a1`, where dimensions equal to one are stretched.
"FHELinalg.sub_eint"(%a0, %a1) : (tensor<4x1x4x!FHE.eint<4>>, tensor<1x4x4x!FHE.eint<4>>) -> tensor<4x4x4x!FHE.eint<4>>
// Returns the substraction of a 3x3 matrix of integers and a 3x1 matrix (a column) of encrypted integers.
// Returns the subtraction of a 3x3 matrix of integers and a 3x1 matrix (a column) of encrypted integers.
//
// [1,2,3] [1] [0,2,3]
// [4,5,6] - [2] = [2,3,4]
@@ -258,7 +258,7 @@ def FHELinalg_SubEintOp : FHELinalg_Op<"sub_eint", [TensorBroadcastingRules, Ten
// The dimension #1 of operand #2 is stretched as it is equals to 1.
"FHELinalg.sub_eint"(%a0, %a1) : (tensor<3x3x!FHE.eint<4>>, tensor<3x1x!FHE.eint<4>>) -> tensor<3x3x!FHE.eint<4>>
// Returns the substraction of a 3x3 matrix of integers and a 1x3 matrix (a line) of encrypted integers.
// Returns the subtraction of a 3x3 matrix of integers and a 1x3 matrix (a line) of encrypted integers.
//
// [1,2,3] [0,0,0]
// [4,5,6] - [1,2,3] = [3,3,3]
@@ -273,11 +273,11 @@ def FHELinalg_SubEintOp : FHELinalg_Op<"sub_eint", [TensorBroadcastingRules, Ten
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$rhs
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$rhs
);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>);
let builders = [
OpBuilder<(ins "Value":$lhs, "Value":$rhs), [{
@@ -306,10 +306,10 @@ def FHELinalg_NegEintOp : FHELinalg_Op<"neg_eint", [TensorUnaryEint]> {
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$tensor
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$tensor
);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>);
let builders = [
OpBuilder<(ins "Value":$tensor), [{
@@ -323,7 +323,7 @@ def FHELinalg_MulEintIntOp : FHELinalg_Op<"mul_eint_int", [TensorBroadcastingRul
let description = [{
Performs a multiplication following the broadcasting rules between a tensor of encrypted integers and a tensor of clear integers.
The width of the clear integers must be less than or equals to the witdh of encrypted integers.
The width of the clear integers must be less than or equals to the width of encrypted integers.
Examples:
```mlir
@@ -358,11 +358,11 @@ def FHELinalg_MulEintIntOp : FHELinalg_Op<"mul_eint_int", [TensorBroadcastingRul
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[AnyInteger]>.predicate, HasStaticShapePred]>>:$rhs
);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>);
let hasFolder = 1;
}
@@ -394,11 +394,11 @@ def FHELinalg_ApplyLookupTableEintOp : FHELinalg_Op<"apply_lookup_table", []> {
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$t,
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$t,
Type<And<[TensorOf<[AnyInteger]>.predicate, HasStaticShapePred]>>:$lut
);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>);
let hasVerifier = 1;
}
@@ -519,10 +519,10 @@ def FHELinalg_Dot : FHELinalg_Op<"dot_eint_int"> {
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred, HasAnyRankOfPred<[1]>]>>:$lhs,
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred, HasAnyRankOfPred<[1]>]>>:$lhs,
Type<And<[TensorOf<[AnyInteger]>.predicate, HasStaticShapePred, HasAnyRankOfPred<[1]>]>>:$rhs);
let results = (outs FHE_EncryptedIntegerType:$out);
let results = (outs FHE_AnyEncryptedInteger:$out);
let hasVerifier = 1;
}
@@ -656,11 +656,11 @@ def FHELinalg_MatMulEintIntOp : FHELinalg_Op<"matmul_eint_int", [TensorBinaryEin
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[AnyInteger]>.predicate, HasStaticShapePred]>>:$rhs
);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>);
let hasVerifier = 1;
}
@@ -795,10 +795,10 @@ def FHELinalg_MatMulIntEintOp : FHELinalg_Op<"matmul_int_eint", [TensorBinaryInt
let arguments = (ins
Type<And<[TensorOf<[AnyInteger]>.predicate, HasStaticShapePred]>>:$lhs,
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$rhs
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$rhs
);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>);
let hasVerifier = 1;
}
@@ -871,15 +871,15 @@ def FHELinalg_SumOp : FHELinalg_Op<"sum", [TensorUnaryEint]> {
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$tensor,
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$tensor,
DefaultValuedAttr<I64ArrayAttr, "{}">:$axes,
DefaultValuedAttr<BoolAttr, "false">:$keep_dims
);
let results = (outs
TypeConstraint<Or<[
FHE_EncryptedIntegerType.predicate,
And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>
FHE_AnyEncryptedInteger.predicate,
And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>
]>>:$out
);
@@ -917,12 +917,12 @@ def FHELinalg_ConcatOp : FHELinalg_Op<"concat"> {
}];
let arguments = (ins
Variadic<Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>>:$ins,
Variadic<Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>>:$ins,
DefaultValuedAttr<I64Attr, "0">:$axis
);
let results = (outs
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$out
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$out
);
let hasVerifier = 1;
@@ -931,7 +931,7 @@ def FHELinalg_ConcatOp : FHELinalg_Op<"concat"> {
def FHELinalg_Conv2dOp : FHELinalg_Op<"conv2d", []> {
let summary = "Returns the 2D convolution of a tensor in the form NCHW with weights in the form FCHW";
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$input,
Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>:$input,
Type<And<[TensorOf<[AnyInteger]>.predicate, HasStaticShapePred]>>:$weight,
Optional<Type<And<[TensorOf<[AnyInteger]>.predicate, HasStaticShapePred]>>>:$bias,
// Since there is no U64ElementsAttr, we use I64 and make sure there is no neg values during verification
@@ -940,7 +940,7 @@ def FHELinalg_Conv2dOp : FHELinalg_Op<"conv2d", []> {
OptionalAttr<I64ElementsAttr>:$dilations,
OptionalAttr<I64Attr>:$group
);
let results = (outs Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>);
let results = (outs Type<And<[TensorOf<[FHE_AnyEncryptedInteger]>.predicate, HasStaticShapePred]>>);
let hasVerifier = 1;
}
@@ -989,4 +989,64 @@ def FHELinalg_FromElementOp : FHELinalg_Op<"from_element", []> {
let hasVerifier = 1;
}
def FHELinalg_ToSignedOp : FHELinalg_Op<"to_signed", []> {
let summary = "Cast an unsigned integer tensor to a signed one";
let description = [{
Cast an unsigned integer tensor to a signed one.
The result must have the same width and the same shape as the input.
The behavior is undefined on overflow/underflow.
Examples:
```mlir
// ok
"FHELinalg.to_signed"(%x) : (tensor<3x2x!FHE.eint<2>>) -> tensor<3x2x!FHE.esint<2>>
// error
"FHELinalg.to_signed"(%x) : (tensor<3x2x!FHE.eint<2>>) -> tensor<3x2x!FHE.esint<3>>
```
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$input
);
let results = (outs
Type<And<[TensorOf<[FHE_EncryptedSignedIntegerType]>.predicate, HasStaticShapePred]>>:$output
);
let hasVerifier = 1;
}
def FHELinalg_ToUnsignedOp : FHELinalg_Op<"to_unsigned", []> {
let summary = "Cast a signed integer tensor to an unsigned one";
let description = [{
Cast a signed integer tensor to an unsigned one.
The result must have the same width and the same shape as the input.
The behavior is undefined on overflow/underflow.
Examples:
```mlir
// ok
"FHELinalg.to_unsigned"(%x) : (tensor<3x2x!FHE.esint<2>>) -> tensor<3x2x!FHE.eint<2>>
// error
"FHELinalg.to_unsigned"(%x) : (tensor<3x2x!FHE.esint<2>>) -> tensor<3x2x!FHE.eint<3>>
```
}];
let arguments = (ins
Type<And<[TensorOf<[FHE_EncryptedSignedIntegerType]>.predicate, HasStaticShapePred]>>:$input
);
let results = (outs
Type<And<[TensorOf<[FHE_EncryptedIntegerType]>.predicate, HasStaticShapePred]>>:$output
);
let hasVerifier = 1;
}
#endif