mirror of
https://github.com/zama-ai/concrete.git
synced 2026-02-08 19:44:57 -05:00
feat: create a method in the new interface to compile using an inputset in one go
This commit is contained in:
@@ -249,6 +249,26 @@ class NPFHECompiler:
|
||||
dtype.bit_width = 128
|
||||
dtype.is_signed = True
|
||||
|
||||
def compile_on_inputset(
|
||||
self,
|
||||
inputset: Union[Iterable[Any], Iterable[Tuple[Any, ...]]],
|
||||
show_mlir: bool = False,
|
||||
) -> FHECircuit:
|
||||
"""Compile the function on an inputset and get resulting FHECircuit.
|
||||
|
||||
Args:
|
||||
inputset (Union[Iterable[Any], Iterable[Tuple[Any, ...]]]):
|
||||
The inputset on which the function is evaluated.
|
||||
show_mlir (bool, optional, defaults to False):
|
||||
The flag to enable printing the MLIR that is being compiled for debugging purposes.
|
||||
|
||||
Returns:
|
||||
FHECircuit: the compiled FHECircuit
|
||||
"""
|
||||
|
||||
self.eval_on_inputset(inputset)
|
||||
return self.get_compiled_fhe_circuit(show_mlir)
|
||||
|
||||
def get_compiled_fhe_circuit(self, show_mlir: bool = False) -> FHECircuit:
|
||||
"""Return a compiled FHECircuit if the instance was evaluated on an inputset.
|
||||
|
||||
|
||||
@@ -121,8 +121,8 @@ class QuantizedModule:
|
||||
compilation_configuration,
|
||||
compilation_artifacts,
|
||||
)
|
||||
compiler.eval_on_inputset((numpy.expand_dims(arr, 0) for arr in self.q_input.qvalues))
|
||||
|
||||
self.forward_fhe = compiler.get_compiled_fhe_circuit(show_mlir)
|
||||
self.forward_fhe = compiler.compile_on_inputset(
|
||||
(numpy.expand_dims(arr, 0) for arr in self.q_input.qvalues), show_mlir
|
||||
)
|
||||
|
||||
return self.forward_fhe
|
||||
|
||||
@@ -21,8 +21,8 @@ def f(x, y):
|
||||
compiler = hnp.NPFHECompiler(f, {"x": "encrypted", "y": "encrypted"})
|
||||
|
||||
# Compile an FHE Circuit using an inputset
|
||||
compiler.eval_on_inputset([(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 0), (3, 1)])
|
||||
circuit = compiler.get_compiled_fhe_circuit()
|
||||
inputset = [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 0), (3, 1)]
|
||||
circuit = compiler.compile_on_inputset(inputset)
|
||||
|
||||
# Make homomorphic inference
|
||||
circuit.run(1, 0)
|
||||
|
||||
@@ -44,6 +44,9 @@ Finally, we can compile our function to its homomorphic equivalent.
|
||||
compiler = hnp.NPFHECompiler(
|
||||
f, {"x": x, "y": y},
|
||||
)
|
||||
circuit = compiler.compile_on_inputset(inputset)
|
||||
|
||||
# If you want, you can separate tracing and compilation steps like so:
|
||||
|
||||
# You can either evaluate in one go:
|
||||
compiler.eval_on_inputset(inputset)
|
||||
|
||||
@@ -15,8 +15,7 @@ def f(x):
|
||||
return 42 * x
|
||||
|
||||
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
|
||||
compiler.eval_on_inputset(range(2 ** 3))
|
||||
compiler.get_compiled_fhe_circuit()
|
||||
circuit = compiler.compile_on_inputset(range(2 ** 3))
|
||||
```
|
||||
|
||||
results in
|
||||
|
||||
@@ -125,7 +125,7 @@ def f(x):
|
||||
artifacts = hnp.CompilationArtifacts(pathlib.Path("/tmp/custom/export/path"))
|
||||
|
||||
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"}, compilation_artifacts=artifacts)
|
||||
compiler.eval_on_inputset(range(2 ** 3))
|
||||
compiler.compile_on_inputset(range(2 ** 3))
|
||||
|
||||
artifacts.export()
|
||||
```
|
||||
|
||||
@@ -18,8 +18,7 @@ def f(x):
|
||||
inputset = [np.random.randint(0, 2 ** 3, size=(3,), dtype=np.uint8) for _ in range(10)]
|
||||
|
||||
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
|
||||
compiler.eval_on_inputset(inputset)
|
||||
circuit = compiler.get_compiled_fhe_circuit()
|
||||
circuit = compiler.compile_on_inputset(inputset)
|
||||
|
||||
test_input = np.array([4, 2, 6], dtype=np.uint8)
|
||||
expected_output = 2
|
||||
@@ -39,8 +38,7 @@ def f(x):
|
||||
inputset = [np.random.randint(0, 2 ** 3, size=(3,), dtype=np.uint8) for _ in range(10)]
|
||||
|
||||
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
|
||||
compiler.eval_on_inputset(inputset)
|
||||
circuit = compiler.get_compiled_fhe_circuit()
|
||||
circuit = compiler.compile_on_inputset(inputset)
|
||||
|
||||
test_input = np.array([4, 2, 6], dtype=np.uint8)
|
||||
expected_output = 6
|
||||
@@ -60,8 +58,7 @@ def f(x):
|
||||
inputset = [np.random.randint(0, 2 ** 3, size=(3, 2), dtype=np.uint8) for _ in range(10)]
|
||||
|
||||
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
|
||||
compiler.eval_on_inputset(inputset)
|
||||
circuit = compiler.get_compiled_fhe_circuit()
|
||||
circuit = compiler.compile_on_inputset(inputset)
|
||||
|
||||
test_input = np.array([[4, 2], [1, 5], [7, 6]], dtype=np.uint8)
|
||||
expected_output = 6
|
||||
@@ -81,8 +78,7 @@ def f(x):
|
||||
inputset = [np.random.randint(0, 2 ** 3, size=(5,), dtype=np.uint8) for _ in range(10)]
|
||||
|
||||
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
|
||||
compiler.eval_on_inputset(inputset)
|
||||
circuit = compiler.get_compiled_fhe_circuit()
|
||||
circuit = compiler.compile_on_inputset(inputset)
|
||||
|
||||
test_input = np.array([4, 2, 6, 1, 7], dtype=np.uint8)
|
||||
expected_output = np.array([2, 6, 1], dtype=np.uint8)
|
||||
|
||||
@@ -13,9 +13,7 @@ def f(x):
|
||||
|
||||
# Compiling with x encrypted
|
||||
compiler = hnp.NPFHECompiler(f, {"x": "encrypted"})
|
||||
compiler.eval_on_inputset(range(64))
|
||||
|
||||
circuit = compiler.get_compiled_fhe_circuit()
|
||||
circuit = compiler.compile_on_inputset(range(64))
|
||||
|
||||
assert circuit.run(3) == f(3)
|
||||
assert circuit.run(0) == f(0)
|
||||
|
||||
Reference in New Issue
Block a user