From b842bb6f96ec9bc32ab6e3e44fe31ae1893d9b7a Mon Sep 17 00:00:00 2001 From: Umut Date: Wed, 21 Dec 2022 09:52:47 +0100 Subject: [PATCH] feat: add error probability properties to circuits --- concrete/numpy/compilation/circuit.py | 14 ++++++++++++++ concrete/numpy/compilation/server.py | 14 ++++++++++++++ tests/compilation/test_circuit.py | 14 +++++++++++--- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/concrete/numpy/compilation/circuit.py b/concrete/numpy/compilation/circuit.py index c5c633326..02c7cdce6 100644 --- a/concrete/numpy/compilation/circuit.py +++ b/concrete/numpy/compilation/circuit.py @@ -203,3 +203,17 @@ class Circuit: Get size of the outputs of the circuit. """ return self.server.size_of_outputs + + @property + def p_error(self) -> int: + """ + Get probability of error for each simple TLU (on a scalar). + """ + return self.server.p_error + + @property + def global_p_error(self) -> int: + """ + Get the probability of having at least one simple TLU error during the entire execution. + """ + return self.server.global_p_error diff --git a/concrete/numpy/compilation/server.py b/concrete/numpy/compilation/server.py index 816b44995..4a0b35565 100644 --- a/concrete/numpy/compilation/server.py +++ b/concrete/numpy/compilation/server.py @@ -317,3 +317,17 @@ class Server: Get size of the outputs of the compiled program. """ return self._compilation_feedback.total_output_size + + @property + def p_error(self) -> int: + """ + Get the probability of error for each simple TLU (on a scalar). + """ + return self._compilation_feedback.p_error + + @property + def global_p_error(self) -> int: + """ + Get the probability of having at least one simple TLU error during the entire execution. + """ + return self._compilation_feedback.global_p_error diff --git a/tests/compilation/test_circuit.py b/tests/compilation/test_circuit.py index 224e0adb9..f93917dcd 100644 --- a/tests/compilation/test_circuit.py +++ b/tests/compilation/test_circuit.py @@ -35,12 +35,15 @@ def test_circuit_feedback(helpers): configuration = helpers.configuration() + p_error = 0.1 + global_p_error = 0.05 + @compiler({"x": "encrypted", "y": "encrypted"}) def f(x, y): - return x + y + return np.sqrt(((x + y) ** 2) + 10).astype(np.int64) - inputset = [(np.random.randint(0, 2**4), np.random.randint(0, 2**5)) for _ in range(100)] - circuit = f.compile(inputset, configuration) + inputset = [(np.random.randint(0, 2**2), np.random.randint(0, 2**2)) for _ in range(100)] + circuit = f.compile(inputset, configuration, p_error=p_error, global_p_error=global_p_error) assert isinstance(circuit.complexity, float) assert isinstance(circuit.size_of_secret_keys, int) @@ -48,6 +51,11 @@ def test_circuit_feedback(helpers): assert isinstance(circuit.size_of_keyswitch_keys, int) assert isinstance(circuit.size_of_inputs, int) assert isinstance(circuit.size_of_outputs, int) + assert isinstance(circuit.p_error, float) + assert isinstance(circuit.global_p_error, float) + + assert circuit.p_error <= p_error + assert circuit.global_p_error <= global_p_error def test_circuit_bad_run(helpers):