mirror of
https://github.com/zama-ai/concrete.git
synced 2026-02-09 03:55:04 -05:00
doc(compiler): Enhance FHE Dialect documentation
This commit is contained in:
@@ -18,9 +18,17 @@ include "concretelang/Dialect/FHE/IR/FHETypes.td"
|
||||
class FHE_Op<string mnemonic, list<OpTrait> traits = []> :
|
||||
Op<FHE_Dialect, mnemonic, traits>;
|
||||
|
||||
// Generates an encrypted zero constant
|
||||
def ZeroEintOp : FHE_Op<"zero", [NoSideEffect]> {
|
||||
let summary = "Return an encryption of 0";
|
||||
let summary = "Returns a trivial encrypted integer of 0";
|
||||
|
||||
let description = [{
|
||||
Returns a trivial encrypted integer of 0
|
||||
|
||||
Example:
|
||||
```mlir
|
||||
"FHE.zero"() : () -> !FHE.eint<2>
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins);
|
||||
let results = (outs EncryptedIntegerType:$out);
|
||||
@@ -30,6 +38,22 @@ def AddEintIntOp : FHE_Op<"add_eint_int"> {
|
||||
|
||||
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.
|
||||
|
||||
Example:
|
||||
```mlir
|
||||
// ok
|
||||
"FHE.add_eint_int"(%a, %i) : (!FHE.eint<2>, i3) -> !FHE.eint<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>
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins EncryptedIntegerType:$a, AnyInteger:$b);
|
||||
let results = (outs EncryptedIntegerType);
|
||||
|
||||
@@ -48,6 +72,21 @@ def AddEintOp : FHE_Op<"add_eint"> {
|
||||
|
||||
let summary = "Adds two encrypted integers";
|
||||
|
||||
let description = [{
|
||||
Adds two encrypted integers
|
||||
The encrypted integers and the result must have the same width.
|
||||
|
||||
Example:
|
||||
```mlir
|
||||
// ok
|
||||
"FHE.add_eint"(%a, %b): (!FHE.eint<2>, !FHE.eint<2>) -> (!FHE.eint<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>)
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins EncryptedIntegerType:$a, EncryptedIntegerType:$b);
|
||||
let results = (outs EncryptedIntegerType);
|
||||
|
||||
@@ -66,6 +105,22 @@ def SubIntEintOp : FHE_Op<"sub_int_eint"> {
|
||||
|
||||
let summary = "Substract a clear integer and an encrypted 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.
|
||||
|
||||
Example:
|
||||
```mlir
|
||||
// ok
|
||||
"FHE.sub_int_eint"(%i, %a) : (i3, !FHE.eint<2>) -> !FHE.eint<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>
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins AnyInteger:$a, EncryptedIntegerType:$b);
|
||||
let results = (outs EncryptedIntegerType);
|
||||
|
||||
@@ -84,6 +139,20 @@ def NegEintOp : FHE_Op<"neg_eint"> {
|
||||
|
||||
let summary = "Negates an encrypted integer";
|
||||
|
||||
let description = [{
|
||||
Negates an encrypted integer.
|
||||
The result must have the same width than the encrypted integer.
|
||||
|
||||
Example:
|
||||
```mlir
|
||||
// ok
|
||||
"FHE.neg_eint"(%a): (!FHE.eint<2>) -> (!FHE.eint<2>)
|
||||
|
||||
// error
|
||||
"FHE.neg_eint"(%a): (!FHE.eint<2>) -> (!FHE.eint<3>)
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins EncryptedIntegerType:$a);
|
||||
let results = (outs EncryptedIntegerType);
|
||||
|
||||
@@ -102,6 +171,22 @@ def MulEintIntOp : FHE_Op<"mul_eint_int"> {
|
||||
|
||||
let summary = "Mulitplies an encrypted integer and 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.
|
||||
|
||||
Example:
|
||||
```mlir
|
||||
// ok
|
||||
"FHE.mul_eint_int"(%a, %i) : (!FHE.eint<2>, i3) -> !FHE.eint<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>
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins EncryptedIntegerType:$a, AnyInteger:$b);
|
||||
let results = (outs EncryptedIntegerType);
|
||||
|
||||
@@ -120,8 +205,24 @@ def ApplyLookupTableEintOp : FHE_Op<"apply_lookup_table"> {
|
||||
|
||||
let summary = "Applies a clear lookup table to an encrypted integer";
|
||||
|
||||
let arguments = (ins EncryptedIntegerType:$ct,
|
||||
TensorOf<[AnyInteger]>:$l_cst);
|
||||
let description = [{
|
||||
Applies a clear lookup table to an encrypted integer, the width of the result can be different than the width of the operand.
|
||||
The lookup table must be a tensor of size equals to `2^p` where `p` is the width of the encrypted integer.
|
||||
|
||||
Example:
|
||||
```mlir
|
||||
// ok
|
||||
"FHE.apply_lookup_table"(%a, %lut): (!FHE.eint<2>, tensor<4xi64>) -> (!FHE.eint<2>)
|
||||
"FHE.apply_lookup_table"(%a, %lut): (!FHE.eint<2>, tensor<4xi64>) -> (!FHE.eint<3>)
|
||||
"FHE.apply_lookup_table"(%a, %lut): (!FHE.eint<3>, tensor<4xi64>) -> (!FHE.eint<2>)
|
||||
|
||||
// error
|
||||
"FHE.apply_lookup_table"(%a, %lut): (!FHE.eint<2>, tensor<8xi64>) -> (!FHE.eint<2>)
|
||||
```
|
||||
}];
|
||||
|
||||
let arguments = (ins EncryptedIntegerType:$a,
|
||||
TensorOf<[AnyInteger]>:$lut);
|
||||
let results = (outs EncryptedIntegerType);
|
||||
|
||||
let verifier = [{
|
||||
|
||||
@@ -14,7 +14,13 @@ def EncryptedIntegerType : FHE_Type<"EncryptedInteger",
|
||||
let summary = "An encrypted integer";
|
||||
|
||||
let description = [{
|
||||
An encrypted integer with clear precision of width.
|
||||
An encrypted integer with `width` bits to performs FHE Operations.
|
||||
|
||||
Examples:
|
||||
```mlir
|
||||
!FHE.eint<7>
|
||||
!FHE.eint<6>
|
||||
```
|
||||
}];
|
||||
|
||||
let parameters = (ins "unsigned":$width);
|
||||
|
||||
@@ -107,20 +107,20 @@ bool verifyEncryptedIntegerInputsConsistency(::mlir::OpState &op,
|
||||
}
|
||||
|
||||
::mlir::LogicalResult verifyApplyLookupTable(ApplyLookupTableEintOp &op) {
|
||||
auto ct = op.ct().getType().cast<EncryptedIntegerType>();
|
||||
auto l_cst = op.l_cst().getType().cast<TensorType>();
|
||||
auto ct = op.a().getType().cast<EncryptedIntegerType>();
|
||||
auto lut = op.lut().getType().cast<TensorType>();
|
||||
auto result = op.getResult().getType().cast<EncryptedIntegerType>();
|
||||
|
||||
// Check the shape of l_cst argument
|
||||
// Check the shape of lut argument
|
||||
auto width = ct.getWidth();
|
||||
auto expectedSize = 1 << width;
|
||||
auto lCstShape = l_cst.getShape();
|
||||
auto lCstShape = lut.getShape();
|
||||
mlir::SmallVector<int64_t, 1> expectedShape{expectedSize};
|
||||
if (!l_cst.hasStaticShape(expectedShape)) {
|
||||
emitErrorBadLutSize(op, "l_cst", "ct", expectedSize, width);
|
||||
if (!lut.hasStaticShape(expectedShape)) {
|
||||
emitErrorBadLutSize(op, "lut", "ct", expectedSize, width);
|
||||
return mlir::failure();
|
||||
}
|
||||
if (!l_cst.getElementType().isInteger(64)) {
|
||||
if (!lut.getElementType().isInteger(64)) {
|
||||
op.emitOpError() << "should have the i64 constant";
|
||||
return mlir::failure();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// RUN: not concretecompiler --action=roundtrip %s 2>&1| FileCheck %s
|
||||
|
||||
// CHECK-LABEL: error: 'FHE.apply_lookup_table' op : `l_cst` (operand #2) inner dimension should have size 4(=2^2) to match `ct` (operand #1) elements bitwidth (2)
|
||||
// CHECK-LABEL: error: 'FHE.apply_lookup_table' op : `lut` (operand #2) inner dimension should have size 4(=2^2) to match `ct` (operand #1) elements bitwidth (2)
|
||||
func @apply_lookup_table(%arg0: !FHE.eint<2>, %arg1: tensor<8xi3>) -> !FHE.eint<2> {
|
||||
%1 = "FHE.apply_lookup_table"(%arg0, %arg1): (!FHE.eint<2>, tensor<8xi3>) -> (!FHE.eint<2>)
|
||||
return %1: !FHE.eint<2>
|
||||
|
||||
Reference in New Issue
Block a user