Skip to content

Commit e444771

Browse files
lattigo: lattigo.bootstrap needs ResetsLevelOpInterface
1 parent 8cf6844 commit e444771

3 files changed

Lines changed: 25 additions & 1 deletion

File tree

lib/Dialect/Lattigo/IR/LattigoCKKSOps.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,9 @@ def Lattigo_CKKSRotateOp : Lattigo_CKKSUnaryInPlaceOp<"rotate", [
331331
let hasVerifier = 1;
332332
}
333333

334-
def Lattigo_CKKSBootstrapOp : Lattigo_CKKSUnaryOp<"bootstrap"> {
334+
def Lattigo_CKKSBootstrapOp : Lattigo_CKKSUnaryOp<"bootstrap", [
335+
DeclareOpInterfaceMethods<ResetsLevelOpInterface, ["getOperandToReset"]>
336+
]> {
335337
let summary = "Bootstrap a ciphertext in the Lattigo CKKS dialect";
336338
let description = [{
337339
Bootstraps a ciphertext value in the Lattigo CKKS dialect.

lib/Dialect/Lattigo/IR/LattigoOps.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ ::mlir::OpOperand& CKKSRescaleOp::getOperandToReduce() {
7070
return getOperation()->getOpOperand(1);
7171
}
7272

73+
::mlir::OpOperand& CKKSBootstrapOp::getOperandToReset() {
74+
return getOperation()->getOpOperand(1);
75+
}
76+
7377
::mlir::OpOperand& RLWEDropLevelNewOp::getOperandToReduce() {
7478
return getOperation()->getOpOperand(1);
7579
}

tests/Dialect/Lattigo/Transforms/alloc_to_in_place_levels.mlir

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// Use the minimum level level of the two operands for the result storage
44

55
!evaluator = !lattigo.bgv.evaluator
6+
!ckks_evaluator = !lattigo.ckks.evaluator
7+
!bootstrapping_evaluator = !lattigo.ckks.bootstrapping_evaluator
68
!ct = !lattigo.rlwe.ciphertext
79

810
// CHECK: ![[evaluator:.*]] = !lattigo.bgv.evaluator
@@ -20,3 +22,19 @@ func.func @drop_level(%evaluator : !evaluator, %ct : !ct) -> !ct {
2022
%2 = lattigo.bgv.add_new %evaluator, %0, %1 : (!evaluator, !ct, !ct) -> !ct
2123
return %2 : !ct
2224
}
25+
26+
// A bootstrap resets depth to zero. Do not reuse its exhausted input as
27+
// storage for the refreshed result's users, or the user will be coereced
28+
// down to level 0, which will then cause failures down the line.
29+
// CHECK: func.func @bootstrap_resets_level
30+
func.func @bootstrap_resets_level(%evaluator: !ckks_evaluator, %bootstrapping_evaluator: !bootstrapping_evaluator, %ct: !ct) -> !ct {
31+
// CHECK: %[[LOW:.*]] = lattigo.ckks.rescale_new
32+
%0 = lattigo.ckks.rescale_new %evaluator, %ct : (!ckks_evaluator, !ct) -> !ct
33+
// CHECK: %[[BOOT:.*]] = lattigo.ckks.bootstrap %{{.*}}, %[[LOW]]
34+
%1 = lattigo.ckks.bootstrap %bootstrapping_evaluator, %0 : (!bootstrapping_evaluator, !ct) -> !ct
35+
// CHECK: %[[MUL:.*]] = lattigo.ckks.mul %{{.*}}, %[[BOOT]], %[[BOOT]], %[[BOOT]]
36+
%2 = lattigo.ckks.mul_new %evaluator, %1, %1 : (!ckks_evaluator, !ct, !ct) -> !ct
37+
// CHECK: %[[RESCALED:.*]] = lattigo.ckks.rescale %{{.*}}, %[[MUL]], %[[LOW]]
38+
%3 = lattigo.ckks.rescale_new %evaluator, %2 : (!ckks_evaluator, !ct) -> !ct
39+
return %3 : !ct
40+
}

0 commit comments

Comments
 (0)