-
Notifications
You must be signed in to change notification settings - Fork 114
Open
Labels
python frontendIssues related to the python frontendIssues related to the python frontend
Description
Version: heir-py 0.0.2
When I use HEIR, sometimes I found the FHE output was not the same as the expected output. After reducing my program, I discovered the root cause was negative numbers:
If I write my program in this way:
from heir import compile
from heir.mlir import I32, Secret
@compile()
def func(x: Secret[I32]):
res = -1 * x
return res
if __name__ == "__main__":
x = 1
func.setup()
enc_x = func.encrypt_x(x)
result_enc = func.eval(enc_x)
result = func.decrypt_result(result_enc)
print(f"Expected result: {func.original(x)}")
print(f"FHE result: {result}")
It will output:
Expected result: -1
FHE result: 255
If I write my program in this way(Only change the value of x and the scalar in func):
from heir import compile
from heir.mlir import I32, Secret
@compile()
def func(x: Secret[I32]):
res = 1 * x
return res
if __name__ == "__main__":
x = -1
func.setup()
enc_x = func.encrypt_x(x)
result_enc = func.eval(enc_x)
result = func.decrypt_result(result_enc)
print(f"Expected result: {func.original(x)}")
print(f"FHE result: {result}")
It will output:
HEIR Error at xxxxxx.py (4): HEIR compilation for function func failed:
running `heir-opt --canonicalize --mlir-to-bgv --mlir-print-debuginfo` produced these errors:
<stdin>:0:0: error: 'builtin.module' op Noise validation failed.
<stdin>:0:0: note: see current operation:
"builtin.module"() ({
"func.func"() <{arg_attrs = [{mgmt.mgmt = #mgmt.mgmt<level = 0>, tensor_ext.original_type = #tensor_ext.original_type<originalType = i32, layout = <map = (d0) -> (d0 mod 1024), alignment = <in = [], out = [1024], insertedDims = [0]>>>}], function_type = (!secret.secret<tensor<1024xi32>>) -> !secret.secret<tensor<1024xi32>>, res_attrs = [{mgmt.mgmt = #mgmt.mgmt<level = 0>, tensor_ext.original_type = #tensor_ext.original_type<originalType = i32, layout = <map = (d0) -> (d0 mod 1024), alignment = <in = [], out = [1024], insertedDims = [0]>>>}], sym_name = "func"}> ({
^bb0(%arg2: !secret.secret<tensor<1024xi32>> loc("xxxxxx.py":4:0)):
"func.return"(%arg2) : (!secret.secret<tensor<1024xi32>>) -> () loc("xxxxxx.py":4:0)
}) : () -> () loc("xxxxxx.py":4:0)
"func.func"() <{function_type = (i32) -> !secret.secret<tensor<1024xi32>>, res_attrs = [{mgmt.mgmt = #mgmt.mgmt<level = 0>}], sym_name = "func__encrypt__arg0"}> ({
^bb0(%arg1: i32 loc("<stdin>":0:0)):
%3 = "tensor.splat"(%arg1) : (i32) -> tensor<1024xi32> loc("<stdin>":0:0)
%4 = "secret.conceal"(%3) {mgmt.mgmt = #mgmt.mgmt<level = 0>} : (tensor<1024xi32>) -> !secret.secret<tensor<1024xi32>> loc("<stdin>":0:0)
"func.return"(%4) : (!secret.secret<tensor<1024xi32>>) -> () loc("<stdin>":0:0)
}) {client.enc_func = {func_name = "func", index = 0 : i64}} : () -> () loc("<stdin>":0:0)
"func.func"() <{arg_attrs = [{mgmt.mgmt = #mgmt.mgmt<level = 0>}], function_type = (!secret.secret<tensor<1024xi32>>) -> i32, sym_name = "func__decrypt__result0"}> ({
^bb0(%arg0: !secret.secret<tensor<1024xi32>> loc("<stdin>":0:0)):
%0 = "arith.constant"() <{value = 0 : index}> : () -> index loc(unknown)
%1 = "secret.reveal"(%arg0) : (!secret.secret<tensor<1024xi32>>) -> tensor<1024xi32> loc("<stdin>":0:0)
%2 = "tensor.extract"(%1, %0) : (tensor<1024xi32>, index) -> i32 loc("<stdin>":0:0)
"func.return"(%2) : (i32) -> () loc("<stdin>":0:0)
}) {client.dec_func = {func_name = "func", index = 0 : i64}} : () -> () loc("<stdin>":0:0)
}) {bgv.schemeParam = #bgv.scheme_param<logN = 11, Q = [1073153], P = [1093633], plaintextModulus = 65537>, scheme.bgv} : () -> () loc("<stdin>":0:0)
I wonder if these two are bugs?
Metadata
Metadata
Assignees
Labels
python frontendIssues related to the python frontendIssues related to the python frontend