-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve python frontend (incl. basic type inference)
- Loading branch information
1 parent
772dc4d
commit 359a68f
Showing
33 changed files
with
1,067 additions
and
473 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
"""Example of HEIR Python usage.""" | ||
|
||
from heir import compile | ||
from heir.mlir import * | ||
|
||
# TODO (#1162): Also add the tensorflow-to-tosa-to-HEIR example in example.py, even it doesn't use the main Python frontend? | ||
|
||
### Simple Example | ||
@compile() # defaults to scheme="bgv", OpenFHE backend, and debug=False | ||
def foo(x : Secret[I16], y : Secret[I16]): | ||
sum = x + y | ||
diff = x - y | ||
mul = x * y | ||
expression = sum * diff + mul | ||
deadcode = expression * mul | ||
return expression | ||
|
||
foo.setup() # runs keygen/etc | ||
enc_x = foo.encrypt_x(7) | ||
enc_y = foo.encrypt_y(8) | ||
result_enc = foo.eval(enc_x, enc_y) | ||
result = foo.decrypt_result(result_enc) | ||
print(f"Expected result for `foo`: {foo(7,8)}, decrypted result: {result}") | ||
|
||
|
||
# TODO (#1162) : Fix "ImportError: generic_type: type "PublicKey" is already registered!" when doing setup twice. (Required to allow multiple compilations in same python file) | ||
### CKKS Example | ||
# @compile(scheme="ckks") | ||
# def bar(x : Secret[F32], y : Secret[F32]): | ||
# sum = x + y | ||
# diff = x - y | ||
# mul = x * y | ||
# expression = sum * diff + mul | ||
# deadcode = expression * mul | ||
# return expression | ||
|
||
# bar.setup() # runs keygen/etc | ||
# enc_x = bar.encrypt_x(7) | ||
# enc_y = bar.encrypt_y(8) | ||
# result_enc = bar.eval(enc_x, enc_y) | ||
# result = bar.decrypt_result(result_enc) | ||
# print(f"Expected result for `bar`: {bar(7,8)}, decrypted result: {result}") | ||
|
||
|
||
# ### Ciphertext-Plaintext Example | ||
# @compile() | ||
# def baz2(x: Secret[I16], y : Secret[I16], z : I16): | ||
# ptxt_mul = x * z | ||
# ctxt_mul = x * x | ||
# ctxt_mul2 = y * y | ||
# add = ctxt_mul + ctxt_mul2 | ||
# return ptxt_mul + add | ||
|
||
# baz2.setup() # runs keygen/etc | ||
# enc_x = baz2.encrypt_x(7) | ||
# enc_y = baz2.encrypt_y(8) | ||
# result_enc = baz2.eval(enc_x, enc_y, 9) | ||
# result = baz2.decrypt_result(result_enc) | ||
# print(f"Expected result for `baz2`: {baz2(7,8,9)}, decrypted result: {result}") | ||
|
||
|
||
|
||
# ### Custom Pipeline Example | ||
# @compile(heir_opt_options=["--mlir-to-secret-arithmetic", "--canonicalize", "--cse"], backend=None, debug=True) | ||
# def foo(x : Secret[I16], y : Secret[I16]): | ||
# sum = x + y | ||
# diff = x - y | ||
# mul = x * y | ||
# expression = sum * diff + mul | ||
# deadcode = expression * mul | ||
# return expression | ||
|
||
# # The below are basically no-ops/plain python with the Dummy Backend | ||
# foo.setup() | ||
# enc_x = foo.encrypt_x(7) | ||
# enc_y = foo.encrypt_y(8) | ||
# result_enc = foo.eval(enc_x, enc_y) | ||
# result = foo.decrypt_result(result_enc) | ||
# print(f"Expected result for `foo`: {foo(7,8)}, decrypted result: {result}") | ||
|
||
|
||
# ### Matmul Example (WIP) | ||
# # #TODO (#1330): Implement Shape Inference and support, e.g., matmul in Frontend) | ||
# from heir.mlir.linalg import matmul | ||
# import numpy as np | ||
# @compile(scheme='ckks', debug=True) | ||
# def qux(a : Secret[Tensor[4,4,F32]], b : Secret[Tensor[4,4,F32]]): | ||
# AB = matmul(a,b) | ||
# AABB = matmul(a+a, b+b) | ||
# return AB + AABB | ||
|
||
# a = np.array([[1,2],[3,4]]) | ||
# b = np.array([[5,6],[7,8]]) | ||
# print(qux(a,b)) | ||
|
||
# qux.setup() | ||
# enc_a = qux.encrypt_a(a) | ||
# enc_b = qux.encrypt_b(b) | ||
# result_enc = qux.eval(enc_a, enc_b) | ||
# result = qux.decrypt_result(result_enc) | ||
# print(f"Expected result: {np.matmul(a,b)}, decrypted result: {result}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from .pipeline import compile | ||
|
||
__all__ = ["compile"] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
"""Dummy Backend.""" | ||
|
||
from colorama import Fore, Style, init | ||
|
||
from heir.core import BackendInterface, CompilationResult, ClientInterface | ||
|
||
class DummyClientInterface(ClientInterface): | ||
|
||
def __init__(self, compilation_result: CompilationResult): | ||
self.compilation_result = compilation_result | ||
|
||
def setup(self): | ||
print("HEIR Warning (Dummy Backend): " + Fore.YELLOW + Style.BRIGHT + f"{self.compilation_result.func_name}.setup() is a no-op in the Dummy Backend") | ||
|
||
def decrypt_result(self, result): | ||
print("HEIR Warning (Dummy Backend): " + Fore.YELLOW + Style.BRIGHT + f"{self.compilation_result.func_name}.decrypt() is a no-op in the Dummy Backend") | ||
return result | ||
|
||
def __getattr__(self, key): | ||
|
||
if key.startswith("encrypt_"): | ||
arg_name = key[len("encrypt_") :] | ||
|
||
def wrapper(arg): | ||
print("HEIR Warning (Dummy Backend): " + Fore.YELLOW + Style.BRIGHT + f"{self.compilation_result.func_name}.{key}() is a no-op in the Dummy Backend") | ||
return arg | ||
|
||
return wrapper | ||
|
||
if key == self.compilation_result.func_name or key == "eval": | ||
print("HEIR Warning (Dummy Backend): " + Fore.YELLOW + Style.BRIGHT + f"{self.compilation_result.func_name}.eval() is the same as {self.compilation_result.func_name}() in the Dummy Backend.") | ||
return self.func | ||
|
||
raise AttributeError(f"Attribute {key} not found") | ||
|
||
|
||
class DummyBackend(BackendInterface): | ||
|
||
def run_backend(self, workspace_dir, heir_opt, heir_translate, func_name, arg_names, secret_args, heir_opt_output, debug): | ||
|
||
result = CompilationResult( | ||
module=None, | ||
func_name=func_name, | ||
secret_args=secret_args, | ||
arg_names=arg_names, | ||
arg_enc_funcs=None, | ||
result_dec_func=None, | ||
main_func=None, | ||
setup_funcs=None | ||
) | ||
|
||
return DummyClientInterface(result) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
from .backend import OpenFHEBackend | ||
from .config import OpenFHEConfig, DEFAULT_INSTALLED_OPENFHE_CONFIG, from_os_env | ||
|
||
__all__ = ["OpenFHEBackend", "OpenFHEConfig", "DEFAULT_INSTALLED_OPENFHE_CONFIG", "from_os_env"] |
Oops, something went wrong.