From 656761346aac326feaf85966c1f768f2c29538ef Mon Sep 17 00:00:00 2001 From: Umut Date: Tue, 7 Feb 2023 12:10:13 +0100 Subject: [PATCH] feat: improve accuracy of p_error simulation in virtual circuits --- concrete/numpy/representation/graph.py | 48 +++++++++++++++++++++---- docs/_static/p_error_simulation.pdf | Bin 0 -> 76635 bytes docs/linux.dependency.licenses.txt | 1 + poetry.lock | 44 ++++++++++++++++++++++- pyproject.toml | 1 + tests/compilation/test_circuit.py | 6 ++-- 6 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 docs/_static/p_error_simulation.pdf diff --git a/concrete/numpy/representation/graph.py b/concrete/numpy/representation/graph.py index 8c61cb7c5..1231214c7 100644 --- a/concrete/numpy/representation/graph.py +++ b/concrete/numpy/representation/graph.py @@ -2,17 +2,21 @@ Declaration of `Graph` class. """ +import math import re from copy import deepcopy from typing import Any, Dict, Iterable, List, Optional, Tuple, Union import networkx as nx import numpy as np +import scipy.special from ..dtypes import Float, Integer, UnsignedInteger from .node import Node from .operation import Operation +P_ERROR_PER_ERROR_SIZE_CACHE: Dict[float, Dict[int, float]] = {} + class Graph: """ @@ -81,6 +85,8 @@ class Graph: nodes and their values during computation """ + # pylint: disable=no-member,too-many-nested-blocks + if p_error is None: p_error = 0.0 @@ -106,16 +112,46 @@ class Graph: if pred_node.operation != Operation.Input: dtype = node.inputs[index].dtype if isinstance(dtype, Integer): - # this is not the real behavior of FHE - # it's a simplified model, and it will be replaced at one point + # see https://github.com/zama-ai/concrete-numpy/blob/main/docs/_static/p_error_simulation.pdf # noqa: E501 # pylint: disable=line-too-long + # to learn more about the distribution of error + + if p_error not in P_ERROR_PER_ERROR_SIZE_CACHE: + std_score = math.sqrt(2) * scipy.special.erfcinv(p_error) + p_error_per_error_size = {} + + error_size = 1 + last_p = 1 - p_error + while last_p != 1.0 or error_size == 1: + new_std_score = (2 * error_size + 1) * std_score + new_p = scipy.special.erf(new_std_score / math.sqrt(2)) + + p_error_per_error_size[error_size] = new_p - last_p + + last_p = new_p + error_size += 1 + + # ordering of `p_error_per_error_size` is relied on + # during the introduction of the error below + # thus we explicitly sort it to make sure it's ordered + p_error_per_error_size = dict( + sorted(p_error_per_error_size.items()) + ) + + P_ERROR_PER_ERROR_SIZE_CACHE[p_error] = p_error_per_error_size + else: # pragma: no cover + p_error_per_error_size = P_ERROR_PER_ERROR_SIZE_CACHE[p_error] error = np.random.rand(*pred_results[index].shape) - error = np.where(error < p_error**3, 3, error) - error = np.where(error < p_error**2, 2, error) - error = np.where(error < p_error, 1, np.where(error > 1, error, 0)) + + accumulated_p_error = 0.0 + for error_size, p_error_for_size in p_error_per_error_size.items(): + accumulated_p_error += p_error_for_size + error = np.where(error < accumulated_p_error, error_size, error) + + error = np.where(error < 1, 0, error).astype(np.int64) error_sign = np.random.rand(*pred_results[index].shape) - error_sign = np.where(error < 0.5, 1, -1) + error_sign = np.where(error_sign < 0.5, 1, -1).astype(np.int64) new_results = pred_results[index] + (error * error_sign) diff --git a/docs/_static/p_error_simulation.pdf b/docs/_static/p_error_simulation.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c9ff8e65541eae69767649dc25ab2d45e5323a8b GIT binary patch literal 76635 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 NG=^D3L`6sSzW`zi&8z?b literal 0 HcmV?d00001 diff --git a/docs/linux.dependency.licenses.txt b/docs/linux.dependency.licenses.txt index de36ad750..f68e9254c 100644 --- a/docs/linux.dependency.licenses.txt +++ b/docs/linux.dependency.licenses.txt @@ -15,6 +15,7 @@ packaging 23.0 Apache Software License; BSD License pyparsing 3.0.9 MIT License python-dateutil 2.8.2 Apache Software License; BSD License + scipy 1.7.3 BSD License six 1.16.0 MIT License torch 1.13.1 BSD License typing-extensions 3.10.0.2 Python Software Foundation License diff --git a/poetry.lock b/poetry.lock index 540fbdbc6..3921708cf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3274,6 +3274,48 @@ files = [ {file = "ruff-0.0.191.tar.gz", hash = "sha256:d698c4d5e3b2963cbbb7c2728f404091d5c47cdf8d94db3eb2f335e2a93a6b1b"}, ] +[[package]] +name = "scipy" +version = "1.7.3" +description = "SciPy: Scientific Library for Python" +category = "main" +optional = false +python-versions = ">=3.7,<3.11" +files = [ + {file = "scipy-1.7.3-1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:c9e04d7e9b03a8a6ac2045f7c5ef741be86727d8f49c45db45f244bdd2bcff17"}, + {file = "scipy-1.7.3-1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:b0e0aeb061a1d7dcd2ed59ea57ee56c9b23dd60100825f98238c06ee5cc4467e"}, + {file = "scipy-1.7.3-1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:b78a35c5c74d336f42f44106174b9851c783184a85a3fe3e68857259b37b9ffb"}, + {file = "scipy-1.7.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:173308efba2270dcd61cd45a30dfded6ec0085b4b6eb33b5eb11ab443005e088"}, + {file = "scipy-1.7.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:21b66200cf44b1c3e86495e3a436fc7a26608f92b8d43d344457c54f1c024cbc"}, + {file = "scipy-1.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceebc3c4f6a109777c0053dfa0282fddb8893eddfb0d598574acfb734a926168"}, + {file = "scipy-1.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7eaea089345a35130bc9a39b89ec1ff69c208efa97b3f8b25ea5d4c41d88094"}, + {file = "scipy-1.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:304dfaa7146cffdb75fbf6bb7c190fd7688795389ad060b970269c8576d038e9"}, + {file = "scipy-1.7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:033ce76ed4e9f62923e1f8124f7e2b0800db533828c853b402c7eec6e9465d80"}, + {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4d242d13206ca4302d83d8a6388c9dfce49fc48fdd3c20efad89ba12f785bf9e"}, + {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8499d9dd1459dc0d0fe68db0832c3d5fc1361ae8e13d05e6849b358dc3f2c279"}, + {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca36e7d9430f7481fc7d11e015ae16fbd5575615a8e9060538104778be84addf"}, + {file = "scipy-1.7.3-cp37-cp37m-win32.whl", hash = "sha256:e2c036492e673aad1b7b0d0ccdc0cb30a968353d2c4bf92ac8e73509e1bf212c"}, + {file = "scipy-1.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:866ada14a95b083dd727a845a764cf95dd13ba3dc69a16b99038001b05439709"}, + {file = "scipy-1.7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:65bd52bf55f9a1071398557394203d881384d27b9c2cad7df9a027170aeaef93"}, + {file = "scipy-1.7.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:f99d206db1f1ae735a8192ab93bd6028f3a42f6fa08467d37a14eb96c9dd34a3"}, + {file = "scipy-1.7.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5f2cfc359379c56b3a41b17ebd024109b2049f878badc1e454f31418c3a18436"}, + {file = "scipy-1.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb7ae2c4dbdb3c9247e07acc532f91077ae6dbc40ad5bd5dca0bb5a176ee9bda"}, + {file = "scipy-1.7.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c2d250074cfa76715d58830579c64dff7354484b284c2b8b87e5a38321672c"}, + {file = "scipy-1.7.3-cp38-cp38-win32.whl", hash = "sha256:87069cf875f0262a6e3187ab0f419f5b4280d3dcf4811ef9613c605f6e4dca95"}, + {file = "scipy-1.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:7edd9a311299a61e9919ea4192dd477395b50c014cdc1a1ac572d7c27e2207fa"}, + {file = "scipy-1.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eef93a446114ac0193a7b714ce67659db80caf940f3232bad63f4c7a81bc18df"}, + {file = "scipy-1.7.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:eb326658f9b73c07081300daba90a8746543b5ea177184daed26528273157294"}, + {file = "scipy-1.7.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:93378f3d14fff07572392ce6a6a2ceb3a1f237733bd6dcb9eb6a2b29b0d19085"}, + {file = "scipy-1.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edad1cf5b2ce1912c4d8ddad20e11d333165552aba262c882e28c78bbc09dbf6"}, + {file = "scipy-1.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d1cc2c19afe3b5a546ede7e6a44ce1ff52e443d12b231823268019f608b9b12"}, + {file = "scipy-1.7.3-cp39-cp39-win32.whl", hash = "sha256:2c56b820d304dffcadbbb6cbfbc2e2c79ee46ea291db17e288e73cd3c64fefa9"}, + {file = "scipy-1.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:3f78181a153fa21c018d346f595edd648344751d7f03ab94b398be2ad083ed3e"}, + {file = "scipy-1.7.3.tar.gz", hash = "sha256:ab5875facfdef77e0a47d5fd39ea178b58e60e454a4c85aa1e52fcb80db7babf"}, +] + +[package.dependencies] +numpy = ">=1.16.5,<1.23.0" + [[package]] name = "secretstorage" version = "3.3.3" @@ -3846,4 +3888,4 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "2.0" python-versions = ">=3.7,<3.11" -content-hash = "1ba82f6d92e8cfd1636e23c6ad7374408f27cf86bb3d80c77ae9c2b109e8e8b8" +content-hash = "34cb8b9ae8d4245e0d2f98b37cd5c11288e55e4968fa05313b853510019b0ef6" diff --git a/pyproject.toml b/pyproject.toml index c078a1db3..c6cb0d64e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,7 @@ numpy = "^1.21.0" Pillow = "^9.0.0" concrete-compiler = "^0.23.4" torch = "^1.13.1" +scipy = "1.7.3" [tool.poetry.dev-dependencies] isort = "^5.10.1" diff --git a/tests/compilation/test_circuit.py b/tests/compilation/test_circuit.py index 87ece5235..641e406e3 100644 --- a/tests/compilation/test_circuit.py +++ b/tests/compilation/test_circuit.py @@ -302,9 +302,9 @@ def test_bad_server_save(helpers): assert str(excinfo.value) == "Just-in-Time compilation cannot be saved" -@pytest.mark.parametrize("p_error", [0.5, 0.1, 0.01]) +@pytest.mark.parametrize("p_error", [0.75, 0.5, 0.4, 0.25, 0.2, 0.1, 0.01, 0.001]) @pytest.mark.parametrize("bit_width", [10]) -@pytest.mark.parametrize("sample_size", [100_000]) +@pytest.mark.parametrize("sample_size", [1_000_000]) @pytest.mark.parametrize("tolerance", [0.075]) def test_virtual_p_error(p_error, bit_width, sample_size, tolerance, helpers): """ @@ -333,7 +333,7 @@ def test_virtual_p_error(p_error, bit_width, sample_size, tolerance, helpers): expected_number_of_errors_on_average - (expected_number_of_errors_on_average * tolerance), expected_number_of_errors_on_average + (expected_number_of_errors_on_average * tolerance), ] - assert acceptable_number_of_errors[0] < errors < acceptable_number_of_errors[1] + assert acceptable_number_of_errors[0] <= errors <= acceptable_number_of_errors[1] def test_circuit_run_with_unused_arg(helpers):