feat: introduce new API to encrypt/run/decrypt separetely

Also introduce new compilation options for parallel execution
bump concrete-compiler to 0.6.0 which support loop parallelization
This commit is contained in:
youben11
2022-03-28 17:44:42 +01:00
committed by Umut
parent a2b3205b6e
commit 2e831e4415
15 changed files with 345 additions and 160 deletions

View File

@@ -1540,7 +1540,7 @@ def main(function, inputs, accuracy_alert_threshold):
correct = 0
for sample_i, expectation_i in zip(samples, expectations):
with progress.measure(id="evaluation-time-ms", label="Evaluation Time (ms)"):
result_i = circuit.run(*sample_i)
result_i = circuit.encrypt_run_decrypt(*sample_i)
np_result_i = np.array(result_i, dtype=np.uint8)
np_expectation_i = np.array(expectation_i, dtype=np.uint8)

View File

@@ -11,7 +11,11 @@ class CompilationConfiguration:
enable_unsafe_features: bool
random_inputset_samples: int
use_insecure_key_cache: bool
auto_parallelize: bool
loop_parallelize: bool
dataflow_parallelize: bool
# pylint: disable=too-many-arguments
def __init__(
self,
dump_artifacts_on_unexpected_failures: bool = True,
@@ -21,6 +25,9 @@ class CompilationConfiguration:
enable_unsafe_features: bool = False,
random_inputset_samples: int = 30,
use_insecure_key_cache: bool = False,
auto_parallelize: bool = False,
loop_parallelize: bool = True,
dataflow_parallelize: bool = False,
):
self.dump_artifacts_on_unexpected_failures = dump_artifacts_on_unexpected_failures
self.enable_topological_optimizations = enable_topological_optimizations
@@ -29,6 +36,11 @@ class CompilationConfiguration:
self.enable_unsafe_features = enable_unsafe_features
self.random_inputset_samples = random_inputset_samples
self.use_insecure_key_cache = use_insecure_key_cache
self.auto_parallelize = auto_parallelize
self.loop_parallelize = loop_parallelize
self.dataflow_parallelize = dataflow_parallelize
# pylint: enable=too-many-arguments
def __eq__(self, other) -> bool:
return isinstance(other, CompilationConfiguration) and self.__dict__ == other.__dict__

View File

@@ -1,10 +1,21 @@
"""Module to hold the result of compilation."""
from pathlib import Path
from typing import List, Optional, Union
from typing import Optional, Union
import numpy
from concrete.compiler import CompilerEngine
from concrete.compiler import (
ClientParameters,
ClientSupport,
CompilationOptions,
JITCompilationResult,
JITLambda,
JITSupport,
KeySet,
KeySetCache,
PublicArguments,
PublicResult,
)
from .debugging import draw_graph, format_operation_graph
from .operator_graph import OPGraph
@@ -14,11 +25,38 @@ class FHECircuit:
"""Class which is the result of compilation."""
op_graph: OPGraph
engine: CompilerEngine
_jit_support: JITSupport
_compilation_result: JITCompilationResult
_client_parameters: ClientParameters
_server_lambda: JITLambda
_keyset_cache: KeySetCache
_keyset: KeySet
def __init__(self, op_graph: OPGraph, engine: CompilerEngine):
def __init__(
self,
op_graph: OPGraph,
mlir_str: str,
unsecure_key_set_cache_path: Optional[str] = None,
auto_parallelize: bool = False,
loop_parallelize: bool = False,
dataflow_parallelize: bool = False,
):
self.op_graph = op_graph
self.engine = engine
self._jit_support = JITSupport.new()
# Set compilation options
options = CompilationOptions.new("main")
options.set_auto_parallelize(auto_parallelize)
options.set_loop_parallelize(loop_parallelize)
options.set_dataflow_parallelize(dataflow_parallelize)
# Compile
self._compilation_result = self._jit_support.compile(mlir_str, options)
self._client_parameters = self._jit_support.load_client_parameters(self._compilation_result)
self._server_lambda = self._jit_support.load_server_lambda(self._compilation_result)
# Setup keyset cache
self._keyset_cache = None
if unsecure_key_set_cache_path:
self._keyset_cache = KeySetCache.new(unsecure_key_set_cache_path)
self._keyset = None
def __str__(self):
return format_operation_graph(self.op_graph)
@@ -44,15 +82,63 @@ class FHECircuit:
return draw_graph(self.op_graph, show, vertical, save_to)
def run(self, *args: List[Union[int, numpy.ndarray]]) -> Union[int, numpy.ndarray]:
"""Encrypt, evaluate, and decrypt the inputs on the circuit.
def keygen(self, force: bool = False):
"""Generate the keys required for the encrypted circuit.
Args:
*args (List[Union[int, numpy.ndarray]]): inputs to the circuit
force (bool, optional): generate even if keyset already exists. Defaults to False.
"""
if self._keyset is None or force:
self._keyset = ClientSupport.key_set(self._client_parameters, self._keyset_cache)
def encrypt(self, *args: Union[int, numpy.ndarray]) -> PublicArguments:
"""Encrypt the inputs of the circuit.
Args:
*args (Union[int, numpy.ndarray]): plain input of the circuit
Returns:
Union[int, numpy.ndarray]: homomorphic evaluation result
PublicArguments: encrypted and plain arguments as well as public keys
"""
# Make sure keys are available: shouldn't regenerate if they already exist
self.keygen(force=False)
return ClientSupport.encrypt_arguments(self._client_parameters, self._keyset, args)
return self.engine.run(*args)
def run(self, args: PublicArguments) -> PublicResult:
"""Evaluate the the encrypted circuit (no encryption or decryption involved).
Args:
args (PublicArguments): encrypted inputs to the circuit
Returns:
PublicResult: encrypted result
"""
return self._jit_support.server_call(self._server_lambda, args)
def decrypt(self, result: PublicResult) -> Union[int, numpy.ndarray]:
"""Decrypt the result of the circuit.
Args:
result (PublicResult): encrypted result of the circuit
Returns:
Union[int, numpy.ndarray]: plain result of the circuit
"""
return ClientSupport.decrypt_result(self._keyset, result)
def encrypt_run_decrypt(self, *args: Union[int, numpy.ndarray]) -> Union[int, numpy.ndarray]:
"""Encrypt, evaluate, and decrypt the inputs on the circuit.
Generate keyset automatically if not yet done.
Args:
*args (Union[int, numpy.ndarray]): plain inputs of the circuit
Returns:
Union[int, numpy.ndarray]: plain result of the circuit
"""
self.keygen(force=False)
public_args = self.encrypt(*args)
encrypted_result = self.run(public_args)
decrypted_result = self.decrypt(encrypted_result)
return decrypted_result

View File

@@ -6,7 +6,6 @@ from copy import deepcopy
from typing import Any, Callable, Dict, Iterable, Optional, Tuple, Union, cast
import numpy
from concrete.compiler import CompilerEngine
from ..common.bounds_measurement.inputset_eval import eval_op_graph_bounds_on_inputset
from ..common.common_helpers import check_op_graph_is_integer_program
@@ -653,11 +652,14 @@ def _compile_op_graph_to_fhe_circuit_internal(
"compilation_configuration"
)
# Compile the MLIR representation
engine = CompilerEngine()
engine.compile_fhe(mlir_result, unsecure_key_set_cache_path=_COMPILE_FHE_INSECURE_KEY_CACHE_DIR)
return FHECircuit(op_graph, engine)
return FHECircuit(
op_graph,
mlir_result,
unsecure_key_set_cache_path=_COMPILE_FHE_INSECURE_KEY_CACHE_DIR,
auto_parallelize=compilation_configuration.auto_parallelize,
loop_parallelize=compilation_configuration.loop_parallelize,
dataflow_parallelize=compilation_configuration.dataflow_parallelize,
)
def compile_op_graph_to_fhe_circuit(

View File

@@ -1,20 +1,20 @@
Name Version License
Pillow 9.0.1 Historical Permission Notice and Disclaimer (HPND)
PyYAML 6.0 MIT License
concrete-compiler 0.5.0 BSD-3
cycler 0.11.0 BSD License
fonttools 4.31.2 MIT License
kiwisolver 1.4.2 BSD License
loguru 0.5.3 MIT License
matplotlib 3.5.1 Python Software Foundation License
networkx 2.7.1 BSD License
numpy 1.22.3 BSD License
packaging 21.3 Apache Software License; BSD License
pygraphviz 1.9 BSD License
pyparsing 3.0.7 MIT License
python-dateutil 2.8.2 Apache Software License; BSD License
setuptools-scm 6.4.2 MIT License
six 1.16.0 MIT License
tomli 1.2.3 MIT License
torch 1.11.0 BSD License
typing-extensions 4.1.1 Python Software Foundation License
Name Version License
Pillow 9.1.0 Historical Permission Notice and Disclaimer (HPND)
PyYAML 6.0 MIT License
concrete-compiler 0.6.0 BSD-3
cycler 0.11.0 BSD License
fonttools 4.31.2 MIT License
kiwisolver 1.4.2 BSD License
loguru 0.5.3 MIT License
matplotlib 3.5.1 Python Software Foundation License
networkx 2.7.1 BSD License
numpy 1.22.3 BSD License
packaging 21.3 Apache Software License; BSD License
pygraphviz 1.9 BSD License
pyparsing 3.0.7 MIT License
python-dateutil 2.8.2 Apache Software License; BSD License
setuptools-scm 6.4.2 MIT License
six 1.16.0 MIT License
tomli 1.2.3 MIT License
torch 1.11.0 BSD License
typing-extensions 4.1.1 Python Software Foundation License

View File

@@ -34,7 +34,7 @@ def main():
correct = 0
for idx, (input_i, label_i) in enumerate(zip(inputs, labels), 1):
print(f"Inference #{idx}")
result_i = engine.run(*input_i)
result_i = engine.encrypt_run_decrypt(*input_i)
if result_i == label_i:
correct += 1

226
poetry.lock generated
View File

@@ -8,7 +8,7 @@ python-versions = "*"
[[package]]
name = "appnope"
version = "0.1.2"
version = "0.1.3"
description = "Disable App Nap on macOS >= 10.9"
category = "dev"
optional = false
@@ -243,7 +243,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "concrete-compiler"
version = "0.5.0"
version = "0.6.0"
description = "Concrete Compiler"
category = "main"
optional = false
@@ -378,6 +378,17 @@ category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "fastjsonschema"
version = "2.15.3"
description = "Fastest Python implementation of JSON schema"
category = "dev"
optional = false
python-versions = "*"
[package.extras]
devel = ["colorama", "jsonschema", "json-spec", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"]
[[package]]
name = "flake8"
version = "4.0.1"
@@ -532,7 +543,7 @@ python-versions = "*"
[[package]]
name = "ipykernel"
version = "6.10.0"
version = "6.12.1"
description = "IPython Kernel for Jupyter"
category = "dev"
optional = false
@@ -540,17 +551,18 @@ python-versions = ">=3.7"
[package.dependencies]
appnope = {version = "*", markers = "platform_system == \"Darwin\""}
debugpy = ">=1.0.0,<2.0"
debugpy = ">=1.0"
ipython = ">=7.23.1"
jupyter-client = "<8.0"
matplotlib-inline = ">=0.1.0,<0.2.0"
jupyter-client = ">=6.1.12"
matplotlib-inline = ">=0.1"
nest-asyncio = "*"
packaging = "*"
psutil = "*"
tornado = ">=5.0,<7.0"
traitlets = ">=5.1.0,<6.0"
tornado = ">=6.1"
traitlets = ">=5.1.0"
[package.extras]
test = ["pytest (!=5.3.4)", "pytest-cov", "flaky", "ipyparallel"]
test = ["pytest (>=6.0)", "pytest-cov", "flaky", "ipyparallel", "pre-commit", "pytest-timeout"]
[[package]]
name = "ipython"
@@ -646,14 +658,14 @@ testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"]
[[package]]
name = "jeepney"
version = "0.7.1"
version = "0.8.0"
description = "Low-level, pure Python DBus protocol wrapper."
category = "dev"
optional = false
python-versions = ">=3.6"
python-versions = ">=3.7"
[package.extras]
test = ["pytest", "pytest-trio", "pytest-asyncio", "testpath", "trio", "async-timeout"]
test = ["pytest", "pytest-trio", "pytest-asyncio (>=0.17)", "testpath", "trio", "async-timeout"]
trio = ["trio", "async-generator"]
[[package]]
@@ -705,24 +717,24 @@ qtconsole = "*"
[[package]]
name = "jupyter-client"
version = "7.1.2"
version = "7.2.1"
description = "Jupyter protocol implementation and client libraries"
category = "dev"
optional = false
python-versions = ">=3.6.1"
python-versions = ">=3.7"
[package.dependencies]
entrypoints = "*"
jupyter-core = ">=4.6.0"
nest-asyncio = ">=1.5"
python-dateutil = ">=2.1"
pyzmq = ">=13"
tornado = ">=4.1"
jupyter-core = ">=4.9.2"
nest-asyncio = ">=1.5.4"
python-dateutil = ">=2.8.2"
pyzmq = ">=22.3"
tornado = ">=6.0"
traitlets = "*"
[package.extras]
doc = ["myst-parser", "sphinx (>=1.3.6)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"]
test = ["codecov", "coverage", "ipykernel", "ipython", "mock", "mypy", "pre-commit", "pytest", "pytest-asyncio", "pytest-cov", "pytest-timeout", "jedi (<0.18)"]
doc = ["ipykernel", "myst-parser", "sphinx (>=1.3.6)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"]
test = ["codecov", "coverage", "ipykernel (>=6.5)", "ipython", "mypy", "pre-commit", "pytest", "pytest-asyncio (>=0.18)", "pytest-cov", "pytest-timeout"]
[[package]]
name = "jupyter-console"
@@ -1026,20 +1038,20 @@ webpdf = ["pyppeteer (>=1,<1.1)"]
[[package]]
name = "nbformat"
version = "5.2.0"
version = "5.3.0"
description = "The Jupyter Notebook format"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
jsonschema = ">=2.4,<2.5.0 || >2.5.0"
fastjsonschema = "*"
jsonschema = ">=2.6"
jupyter-core = "*"
traitlets = ">=4.1"
[package.extras]
fast = ["fastjsonschema"]
test = ["check-manifest", "fastjsonschema", "testpath", "pytest"]
test = ["check-manifest", "testpath", "pytest", "pre-commit"]
[[package]]
name = "nbmake"
@@ -1075,7 +1087,7 @@ traitlets = "*"
[[package]]
name = "nest-asyncio"
version = "1.5.4"
version = "1.5.5"
description = "Patch asyncio to allow nested event loops"
category = "dev"
optional = false
@@ -1205,12 +1217,16 @@ python-versions = "*"
[[package]]
name = "pillow"
version = "9.0.1"
version = "9.1.0"
description = "Python Imaging Library (Fork)"
category = "main"
optional = false
python-versions = ">=3.7"
[package.extras]
docs = ["olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-issues (>=3.0.1)", "sphinx-removed-in", "sphinx-rtd-theme (>=1.0)", "sphinxext-opengraph"]
tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"]
[[package]]
name = "pip-api"
version = "0.0.29"
@@ -1298,7 +1314,7 @@ python-versions = "*"
[[package]]
name = "prometheus-client"
version = "0.13.1"
version = "0.14.0"
description = "Python client for the Prometheus monitoring system."
category = "dev"
optional = false
@@ -1309,7 +1325,7 @@ twisted = ["twisted"]
[[package]]
name = "prompt-toolkit"
version = "3.0.28"
version = "3.0.29"
description = "Library for building powerful interactive command lines in Python"
category = "dev"
optional = false
@@ -1889,7 +1905,7 @@ python-versions = "*"
[[package]]
name = "soupsieve"
version = "2.3.1"
version = "2.3.2"
description = "A modern CSS selector implementation for Beautiful Soup."
category = "dev"
optional = false
@@ -2134,7 +2150,7 @@ python-versions = ">= 3.5"
[[package]]
name = "tqdm"
version = "4.63.1"
version = "4.64.0"
description = "Fast, Extensible Progress Meter"
category = "dev"
optional = false
@@ -2146,6 +2162,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
[package.extras]
dev = ["py-make (>=0.1.0)", "twine", "wheel"]
notebook = ["ipywidgets (>=6)"]
slack = ["slack-sdk"]
telegram = ["requests"]
[[package]]
@@ -2181,7 +2198,7 @@ urllib3 = ">=1.26.0"
[[package]]
name = "types-setuptools"
version = "57.4.11"
version = "57.4.12"
description = "Typing stubs for setuptools"
category = "dev"
optional = false
@@ -2264,15 +2281,15 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
[[package]]
name = "zipp"
version = "3.7.0"
version = "3.8.0"
description = "Backport of pathlib-compatible object wrapper for zip files"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.extras]
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"]
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"]
[extras]
extras = ["pygraphviz"]
@@ -2281,7 +2298,7 @@ full = ["pygraphviz"]
[metadata]
lock-version = "1.1"
python-versions = ">=3.8,<3.10"
content-hash = "93f07f06d597a0312b59e1d00cfa3efd69575ebdf07668b2a97316511cf29ba9"
content-hash = "de159b6c6e74909e3f3d147002f21a135743a52bf65efe4ad93b1abad5205b67"
[metadata.files]
alabaster = [
@@ -2289,8 +2306,8 @@ alabaster = [
{file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"},
]
appnope = [
{file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"},
{file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"},
{file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"},
{file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"},
]
argon2-cffi = [
{file = "argon2-cffi-21.3.0.tar.gz", hash = "sha256:d384164d944190a7dd7ef22c6aa3ff197da12962bd04b17f64d4e93d934dba5b"},
@@ -2432,12 +2449,12 @@ colorama = [
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
]
concrete-compiler = [
{file = "concrete_compiler-0.5.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:467c7a59286718c43b87f6e070dcf17789ef17d5154960e9849e74e7e93da3fa"},
{file = "concrete_compiler-0.5.0-cp310-cp310-manylinux_2_24_x86_64.whl", hash = "sha256:c25be3c2cd84fd85963ec8a6078b2ce1e5e792e5d1665d6a208808b6084b6581"},
{file = "concrete_compiler-0.5.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:ab6d8079f6ed7998ce84ae16a26ddfa5239fe412cc25bf72312f2fc6dc6d17a3"},
{file = "concrete_compiler-0.5.0-cp38-cp38-manylinux_2_24_x86_64.whl", hash = "sha256:8e32437370748e98e18948e9cafbe7587e985fc59adb895e95a32275ce68a35f"},
{file = "concrete_compiler-0.5.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:e2fa9049aa31bb93614d465d07e89450131e5023f1799f26864addf9aac41187"},
{file = "concrete_compiler-0.5.0-cp39-cp39-manylinux_2_24_x86_64.whl", hash = "sha256:f797205f9c8058b19c7173734b03bd51b260f5e3f6134b06b138f0fdfe24fffa"},
{file = "concrete_compiler-0.6.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:7ba9148e8cbb1728b6a28da06499c3b7268fb25a7e059eab1b0dbe03aa26b8c2"},
{file = "concrete_compiler-0.6.0-cp310-cp310-manylinux_2_24_x86_64.whl", hash = "sha256:3cba505cb102d9f53bdb89550a126809501cb8e23aab86376bc5c62e05c425fb"},
{file = "concrete_compiler-0.6.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:379170f54543d6a12c5f3785e75df2f1ed26383818abe10f5978325c36a2f451"},
{file = "concrete_compiler-0.6.0-cp38-cp38-manylinux_2_24_x86_64.whl", hash = "sha256:069c7310ec22aa432a94451fd13873cb076083389d0c83504b3d89181c7de98c"},
{file = "concrete_compiler-0.6.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:4d633adc8b1b5b3bebe0a152ad1bf008ad0d31484be2ea6e28242541c5603b6b"},
{file = "concrete_compiler-0.6.0-cp39-cp39-manylinux_2_24_x86_64.whl", hash = "sha256:a7a29435c9485a4cda0ee8bafb1b9a94b64e2a845ca819d88aad38c9f9076439"},
]
coverage = [
{file = "coverage-6.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9b27d894748475fa858f9597c0ee1d4829f44683f3813633aaf94b19cb5453cf"},
@@ -2559,6 +2576,10 @@ executing = [
{file = "executing-0.8.3-py2.py3-none-any.whl", hash = "sha256:d1eef132db1b83649a3905ca6dd8897f71ac6f8cac79a7e58a1a09cf137546c9"},
{file = "executing-0.8.3.tar.gz", hash = "sha256:c6554e21c6b060590a6d3be4b82fb78f8f0194d809de5ea7df1c093763311501"},
]
fastjsonschema = [
{file = "fastjsonschema-2.15.3-py3-none-any.whl", hash = "sha256:ddb0b1d8243e6e3abb822bd14e447a89f4ab7439342912d590444831fa00b6a0"},
{file = "fastjsonschema-2.15.3.tar.gz", hash = "sha256:0a572f0836962d844c1fc435e200b2e4f4677e4e6611a2e3bdd01ba697c275ec"},
]
flake8 = [
{file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
{file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
@@ -2608,8 +2629,8 @@ invoke = [
{file = "invoke-1.7.0.tar.gz", hash = "sha256:e332e49de40463f2016315f51df42313855772be86435686156bc18f45b5cc6c"},
]
ipykernel = [
{file = "ipykernel-6.10.0-py3-none-any.whl", hash = "sha256:86ebe63f58cb68f299e06a2add4957df0eaebc7b0864de5711accd9c532d7810"},
{file = "ipykernel-6.10.0.tar.gz", hash = "sha256:d1c7d92daea5d9b55a33e523d4d17c09ad38e0df17a4e0ed2fa5c97f07f200ba"},
{file = "ipykernel-6.12.1-py3-none-any.whl", hash = "sha256:d840e3bf1c4b23bf6939f78dcdae639c9f6962e41d17e1c084a18c3c7f972d3a"},
{file = "ipykernel-6.12.1.tar.gz", hash = "sha256:0868f5561729ade444011f8ca7d3502dc9f27f7f44e20f1d5fee7e1f2b7183a1"},
]
ipython = [
{file = "ipython-8.2.0-py3-none-any.whl", hash = "sha256:1b672bfd7a48d87ab203d9af8727a3b0174a4566b4091e9447c22fb63ea32857"},
@@ -2632,8 +2653,8 @@ jedi = [
{file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"},
]
jeepney = [
{file = "jeepney-0.7.1-py3-none-any.whl", hash = "sha256:1b5a0ea5c0e7b166b2f5895b91a08c14de8915afda4407fb5022a195224958ac"},
{file = "jeepney-0.7.1.tar.gz", hash = "sha256:fa9e232dfa0c498bd0b8a3a73b8d8a31978304dcef0515adc859d4e096f96f4f"},
{file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"},
{file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"},
]
jinja2 = [
{file = "Jinja2-3.1.1-py3-none-any.whl", hash = "sha256:539835f51a74a69f41b848a9645dbdc35b4f20a3b601e2d9a7e22947b15ff119"},
@@ -2649,8 +2670,8 @@ jupyter = [
{file = "jupyter-1.0.0.zip", hash = "sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7"},
]
jupyter-client = [
{file = "jupyter_client-7.1.2-py3-none-any.whl", hash = "sha256:d56f1c57bef42ff31e61b1185d3348a5b2bcde7c9a05523ae4dbe5ee0871797c"},
{file = "jupyter_client-7.1.2.tar.gz", hash = "sha256:4ea61033726c8e579edb55626d8ee2e6bf0a83158ddf3751b8dd46b2c5cd1e96"},
{file = "jupyter_client-7.2.1-py3-none-any.whl", hash = "sha256:d10e31ac4b8364d1cb30ebcee9e5cc7b7eb5d23b76912be9ef3d4c75167fbc68"},
{file = "jupyter_client-7.2.1.tar.gz", hash = "sha256:aa177279e93205d0681ec0e2e210da01b22c5a1464a56abd455adcac64f0de91"},
]
jupyter-console = [
{file = "jupyter_console-6.4.3-py3-none-any.whl", hash = "sha256:e630bcb682c0088dda45688ad7c2424d4a825c8acf494cb036ced03ed0424841"},
@@ -2938,8 +2959,8 @@ nbconvert = [
{file = "nbconvert-6.4.5.tar.gz", hash = "sha256:21163a8e2073c07109ca8f398836e45efdba2aacea68d6f75a8a545fef070d4e"},
]
nbformat = [
{file = "nbformat-5.2.0-py3-none-any.whl", hash = "sha256:3e30424e8291b2188347f5c3ba5273ed3766f12f8c5137c2e456a0815f36e785"},
{file = "nbformat-5.2.0.tar.gz", hash = "sha256:93df0b9c67221d38fb970c48f6d361819a6c388299a0ef3171bbb912edfe1324"},
{file = "nbformat-5.3.0-py3-none-any.whl", hash = "sha256:38856d97de49e8292e2d5d8f595e9d26f02abfd87e075d450af4511870b40538"},
{file = "nbformat-5.3.0.tar.gz", hash = "sha256:fcc5ab8cb74e20b19570b5be809e2dba9b82836fd2761a89066ad43394ba29f5"},
]
nbmake = [
{file = "nbmake-1.3.0-py3-none-any.whl", hash = "sha256:8b38089dd232142ce894a9ad3e57a7c0f0a0edb0254662a8446346a84ac4079d"},
@@ -2950,8 +2971,8 @@ nbsphinx = [
{file = "nbsphinx-0.8.7.tar.gz", hash = "sha256:ff91b5b14ceb1a9d44193b5fc3dd3617e7b8ab59c788f7710049ce5faff2750c"},
]
nest-asyncio = [
{file = "nest_asyncio-1.5.4-py3-none-any.whl", hash = "sha256:3fdd0d6061a2bb16f21fe8a9c6a7945be83521d81a0d15cff52e9edee50101d6"},
{file = "nest_asyncio-1.5.4.tar.gz", hash = "sha256:f969f6013a16fadb4adcf09d11a68a4f617c6049d7af7ac2c676110169a63abd"},
{file = "nest_asyncio-1.5.5-py3-none-any.whl", hash = "sha256:b98e3ec1b246135e4642eceffa5a6c23a3ab12c82ff816a92c612d68205813b2"},
{file = "nest_asyncio-1.5.5.tar.gz", hash = "sha256:e442291cd942698be619823a17a86a5759eabe1f8613084790de189fe9e16d65"},
]
networkx = [
{file = "networkx-2.7.1-py3-none-any.whl", hash = "sha256:011e85d277c89681e8fa661cf5ff0743443445049b0b68789ad55ef09340c6e0"},
@@ -3012,41 +3033,44 @@ pickleshare = [
{file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
]
pillow = [
{file = "Pillow-9.0.1-1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4"},
{file = "Pillow-9.0.1-1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2632d0f846b7c7600edf53c48f8f9f1e13e62f66a6dbc15191029d950bfed976"},
{file = "Pillow-9.0.1-1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9618823bd237c0d2575283f2939655f54d51b4527ec3972907a927acbcc5bfc"},
{file = "Pillow-9.0.1-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:9bfdb82cdfeccec50aad441afc332faf8606dfa5e8efd18a6692b5d6e79f00fd"},
{file = "Pillow-9.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5100b45a4638e3c00e4d2320d3193bdabb2d75e79793af7c3eb139e4f569f16f"},
{file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:528a2a692c65dd5cafc130de286030af251d2ee0483a5bf50c9348aefe834e8a"},
{file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f29d831e2151e0b7b39981756d201f7108d3d215896212ffe2e992d06bfe049"},
{file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:855c583f268edde09474b081e3ddcd5cf3b20c12f26e0d434e1386cc5d318e7a"},
{file = "Pillow-9.0.1-cp310-cp310-win32.whl", hash = "sha256:d9d7942b624b04b895cb95af03a23407f17646815495ce4547f0e60e0b06f58e"},
{file = "Pillow-9.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:81c4b81611e3a3cb30e59b0cf05b888c675f97e3adb2c8672c3154047980726b"},
{file = "Pillow-9.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:413ce0bbf9fc6278b2d63309dfeefe452835e1c78398efb431bab0672fe9274e"},
{file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80fe64a6deb6fcfdf7b8386f2cf216d329be6f2781f7d90304351811fb591360"},
{file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cef9c85ccbe9bee00909758936ea841ef12035296c748aaceee535969e27d31b"},
{file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d19397351f73a88904ad1aee421e800fe4bbcd1aeee6435fb62d0a05ccd1030"},
{file = "Pillow-9.0.1-cp37-cp37m-win32.whl", hash = "sha256:d21237d0cd37acded35154e29aec853e945950321dd2ffd1a7d86fe686814669"},
{file = "Pillow-9.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ede5af4a2702444a832a800b8eb7f0a7a1c0eed55b644642e049c98d589e5092"},
{file = "Pillow-9.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b5b3f092fe345c03bca1e0b687dfbb39364b21ebb8ba90e3fa707374b7915204"},
{file = "Pillow-9.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:335ace1a22325395c4ea88e00ba3dc89ca029bd66bd5a3c382d53e44f0ccd77e"},
{file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db6d9fac65bd08cea7f3540b899977c6dee9edad959fa4eaf305940d9cbd861c"},
{file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f154d173286a5d1863637a7dcd8c3437bb557520b01bddb0be0258dcb72696b5"},
{file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d4b1341ac07ae07eb2cc682f459bec932a380c3b122f5540432d8977e64eae"},
{file = "Pillow-9.0.1-cp38-cp38-win32.whl", hash = "sha256:effb7749713d5317478bb3acb3f81d9d7c7f86726d41c1facca068a04cf5bb4c"},
{file = "Pillow-9.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:7f7609a718b177bf171ac93cea9fd2ddc0e03e84d8fa4e887bdfc39671d46b00"},
{file = "Pillow-9.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:80ca33961ced9c63358056bd08403ff866512038883e74f3a4bf88ad3eb66838"},
{file = "Pillow-9.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c3c33ac69cf059bbb9d1a71eeaba76781b450bc307e2291f8a4764d779a6b28"},
{file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12875d118f21cf35604176872447cdb57b07126750a33748bac15e77f90f1f9c"},
{file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:514ceac913076feefbeaf89771fd6febde78b0c4c1b23aaeab082c41c694e81b"},
{file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3c5c79ab7dfce6d88f1ba639b77e77a17ea33a01b07b99840d6ed08031cb2a7"},
{file = "Pillow-9.0.1-cp39-cp39-win32.whl", hash = "sha256:718856856ba31f14f13ba885ff13874be7fefc53984d2832458f12c38205f7f7"},
{file = "Pillow-9.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:f25ed6e28ddf50de7e7ea99d7a976d6a9c415f03adcaac9c41ff6ff41b6d86ac"},
{file = "Pillow-9.0.1-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:011233e0c42a4a7836498e98c1acf5e744c96a67dd5032a6f666cc1fb97eab97"},
{file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:253e8a302a96df6927310a9d44e6103055e8fb96a6822f8b7f514bb7ef77de56"},
{file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6295f6763749b89c994fcb6d8a7f7ce03c3992e695f89f00b741b4580b199b7e"},
{file = "Pillow-9.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70"},
{file = "Pillow-9.0.1.tar.gz", hash = "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa"},
{file = "Pillow-9.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:af79d3fde1fc2e33561166d62e3b63f0cc3e47b5a3a2e5fea40d4917754734ea"},
{file = "Pillow-9.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:55dd1cf09a1fd7c7b78425967aacae9b0d70125f7d3ab973fadc7b5abc3de652"},
{file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:66822d01e82506a19407d1afc104c3fcea3b81d5eb11485e593ad6b8492f995a"},
{file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5eaf3b42df2bcda61c53a742ee2c6e63f777d0e085bbc6b2ab7ed57deb13db7"},
{file = "Pillow-9.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01ce45deec9df310cbbee11104bae1a2a43308dd9c317f99235b6d3080ddd66e"},
{file = "Pillow-9.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aea7ce61328e15943d7b9eaca87e81f7c62ff90f669116f857262e9da4057ba3"},
{file = "Pillow-9.1.0-cp310-cp310-win32.whl", hash = "sha256:7a053bd4d65a3294b153bdd7724dce864a1d548416a5ef61f6d03bf149205160"},
{file = "Pillow-9.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:97bda660702a856c2c9e12ec26fc6d187631ddfd896ff685814ab21ef0597033"},
{file = "Pillow-9.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:21dee8466b42912335151d24c1665fcf44dc2ee47e021d233a40c3ca5adae59c"},
{file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b6d4050b208c8ff886fd3db6690bf04f9a48749d78b41b7a5bf24c236ab0165"},
{file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5cfca31ab4c13552a0f354c87fbd7f162a4fafd25e6b521bba93a57fe6a3700a"},
{file = "Pillow-9.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed742214068efa95e9844c2d9129e209ed63f61baa4d54dbf4cf8b5e2d30ccf2"},
{file = "Pillow-9.1.0-cp37-cp37m-win32.whl", hash = "sha256:c9efef876c21788366ea1f50ecb39d5d6f65febe25ad1d4c0b8dff98843ac244"},
{file = "Pillow-9.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:de344bcf6e2463bb25179d74d6e7989e375f906bcec8cb86edb8b12acbc7dfef"},
{file = "Pillow-9.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:17869489de2fce6c36690a0c721bd3db176194af5f39249c1ac56d0bb0fcc512"},
{file = "Pillow-9.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:25023a6209a4d7c42154073144608c9a71d3512b648a2f5d4465182cb93d3477"},
{file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8782189c796eff29dbb37dd87afa4ad4d40fc90b2742704f94812851b725964b"},
{file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:463acf531f5d0925ca55904fa668bb3461c3ef6bc779e1d6d8a488092bdee378"},
{file = "Pillow-9.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f42364485bfdab19c1373b5cd62f7c5ab7cc052e19644862ec8f15bb8af289e"},
{file = "Pillow-9.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3fddcdb619ba04491e8f771636583a7cc5a5051cd193ff1aa1ee8616d2a692c5"},
{file = "Pillow-9.1.0-cp38-cp38-win32.whl", hash = "sha256:4fe29a070de394e449fd88ebe1624d1e2d7ddeed4c12e0b31624561b58948d9a"},
{file = "Pillow-9.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:c24f718f9dd73bb2b31a6201e6db5ea4a61fdd1d1c200f43ee585fc6dcd21b34"},
{file = "Pillow-9.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fb89397013cf302f282f0fc998bb7abf11d49dcff72c8ecb320f76ea6e2c5717"},
{file = "Pillow-9.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c870193cce4b76713a2b29be5d8327c8ccbe0d4a49bc22968aa1e680930f5581"},
{file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69e5ddc609230d4408277af135c5b5c8fe7a54b2bdb8ad7c5100b86b3aab04c6"},
{file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35be4a9f65441d9982240e6966c1eaa1c654c4e5e931eaf580130409e31804d4"},
{file = "Pillow-9.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82283af99c1c3a5ba1da44c67296d5aad19f11c535b551a5ae55328a317ce331"},
{file = "Pillow-9.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a325ac71914c5c043fa50441b36606e64a10cd262de12f7a179620f579752ff8"},
{file = "Pillow-9.1.0-cp39-cp39-win32.whl", hash = "sha256:a598d8830f6ef5501002ae85c7dbfcd9c27cc4efc02a1989369303ba85573e58"},
{file = "Pillow-9.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0c51cb9edac8a5abd069fd0758ac0a8bfe52c261ee0e330f363548aca6893595"},
{file = "Pillow-9.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a336a4f74baf67e26f3acc4d61c913e378e931817cd1e2ef4dfb79d3e051b481"},
{file = "Pillow-9.1.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb1b89b11256b5b6cad5e7593f9061ac4624f7651f7a8eb4dfa37caa1dfaa4d0"},
{file = "Pillow-9.1.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:255c9d69754a4c90b0ee484967fc8818c7ff8311c6dddcc43a4340e10cd1636a"},
{file = "Pillow-9.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5a3ecc026ea0e14d0ad7cd990ea7f48bfcb3eb4271034657dc9d06933c6629a7"},
{file = "Pillow-9.1.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5b0ff59785d93b3437c3703e3c64c178aabada51dea2a7f2c5eccf1bcf565a3"},
{file = "Pillow-9.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7110ec1701b0bf8df569a7592a196c9d07c764a0a74f65471ea56816f10e2c8"},
{file = "Pillow-9.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8d79c6f468215d1a8415aa53d9868a6b40c4682165b8cb62a221b1baa47db458"},
{file = "Pillow-9.1.0.tar.gz", hash = "sha256:f401ed2bbb155e1ade150ccc63db1a4f6c1909d3d378f7d1235a44e90d75fb97"},
]
pip-api = [
{file = "pip-api-0.0.29.tar.gz", hash = "sha256:f701584eb1c3e01021c846f89d629ab9373b6624f0626757774ad54fc4c29571"},
@@ -3076,12 +3100,12 @@ progress = [
{file = "progress-1.6.tar.gz", hash = "sha256:c9c86e98b5c03fa1fe11e3b67c1feda4788b8d0fe7336c2ff7d5644ccfba34cd"},
]
prometheus-client = [
{file = "prometheus_client-0.13.1-py3-none-any.whl", hash = "sha256:357a447fd2359b0a1d2e9b311a0c5778c330cfbe186d880ad5a6b39884652316"},
{file = "prometheus_client-0.13.1.tar.gz", hash = "sha256:ada41b891b79fca5638bd5cfe149efa86512eaa55987893becd2c6d8d0a5dfc5"},
{file = "prometheus_client-0.14.0-py3-none-any.whl", hash = "sha256:f4aba3fdd1735852049f537c1f0ab177159b7ab76f271ecc4d2f45aa2a1d01f2"},
{file = "prometheus_client-0.14.0.tar.gz", hash = "sha256:8f7a922dd5455ad524b6ba212ce8eb2b4b05e073f4ec7218287f88b1cac34750"},
]
prompt-toolkit = [
{file = "prompt_toolkit-3.0.28-py3-none-any.whl", hash = "sha256:30129d870dcb0b3b6a53efdc9d0a83ea96162ffd28ffe077e94215b233dc670c"},
{file = "prompt_toolkit-3.0.28.tar.gz", hash = "sha256:9f1cd16b1e86c2968f2519d7fb31dd9d669916f515612c269d14e9ed52b51650"},
{file = "prompt_toolkit-3.0.29-py3-none-any.whl", hash = "sha256:62291dad495e665fca0bda814e342c69952086afb0f4094d0893d357e5c78752"},
{file = "prompt_toolkit-3.0.29.tar.gz", hash = "sha256:bd640f60e8cecd74f0dc249713d433ace2ddc62b65ee07f96d358e0b152b6ea7"},
]
psutil = [
{file = "psutil-5.9.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b"},
@@ -3444,8 +3468,8 @@ snowballstemmer = [
{file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
]
soupsieve = [
{file = "soupsieve-2.3.1-py3-none-any.whl", hash = "sha256:1a3cca2617c6b38c0343ed661b1fa5de5637f257d4fe22bd9f1338010a1efefb"},
{file = "soupsieve-2.3.1.tar.gz", hash = "sha256:b8d49b1cd4f037c7082a9683dfa1801aa2597fb11c3a1155b7a5b94829b4f1f9"},
{file = "soupsieve-2.3.2-py3-none-any.whl", hash = "sha256:a714129d3021ec17ce5be346b1007300558b378332c289a1a20e7d4de6ff18a5"},
{file = "soupsieve-2.3.2.tar.gz", hash = "sha256:0bcc6d7432153063e3df09c3ac9442af3eba488715bfcad6a4c38ccb2a523124"},
]
sphinx = [
{file = "Sphinx-4.3.0-py3-none-any.whl", hash = "sha256:7e2b30da5f39170efcd95c6270f07669d623c276521fee27ad6c380f49d2bf5b"},
@@ -3578,8 +3602,8 @@ tornado = [
{file = "tornado-6.1.tar.gz", hash = "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791"},
]
tqdm = [
{file = "tqdm-4.63.1-py2.py3-none-any.whl", hash = "sha256:6461b009d6792008d0000e1b0c7ca50195ec78c0e808a3a6b668a56a3236c3a5"},
{file = "tqdm-4.63.1.tar.gz", hash = "sha256:4230a49119a416c88cc47d0d2d32d5d90f1a282d5e497d49801950704e49863d"},
{file = "tqdm-4.64.0-py2.py3-none-any.whl", hash = "sha256:74a2cdefe14d11442cedf3ba4e21a3b84ff9a2dbdc6cfae2c34addb2a14a5ea6"},
{file = "tqdm-4.64.0.tar.gz", hash = "sha256:40be55d30e200777a307a7585aee69e4eabb46b4ec6a4b4a5f2d9f11e7d5408d"},
]
traitlets = [
{file = "traitlets-5.1.1-py3-none-any.whl", hash = "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033"},
@@ -3590,8 +3614,8 @@ twine = [
{file = "twine-3.8.0.tar.gz", hash = "sha256:8efa52658e0ae770686a13b675569328f1fba9837e5de1867bfe5f46a9aefe19"},
]
types-setuptools = [
{file = "types-setuptools-57.4.11.tar.gz", hash = "sha256:262f7406e0c7d705ad6bb4526b5b761fa500bf99eab74de85ac3592187d62935"},
{file = "types_setuptools-57.4.11-py3-none-any.whl", hash = "sha256:fbb0647569d6fb2f6bc472402265250c0ffa53e60180d2cbfee9e84f085921f0"},
{file = "types-setuptools-57.4.12.tar.gz", hash = "sha256:415a1c23101a05da17eb66bed5d5a865702e5a69f74c66dbf1af643dce9492ab"},
{file = "types_setuptools-57.4.12-py3-none-any.whl", hash = "sha256:c3aa952535dedc78654459dfdee49c66974a6c67bdd8026e7e69ae39f80d590b"},
]
types-toml = [
{file = "types-toml-0.10.4.tar.gz", hash = "sha256:9340e7c1587715581bb13905b3af30b79fe68afaccfca377665d5e63b694129a"},
@@ -3675,6 +3699,6 @@ wrapt = [
{file = "wrapt-1.13.3.tar.gz", hash = "sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185"},
]
zipp = [
{file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"},
{file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"},
{file = "zipp-3.8.0-py3-none-any.whl", hash = "sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099"},
{file = "zipp-3.8.0.tar.gz", hash = "sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad"},
]

View File

@@ -45,7 +45,7 @@ pygraphviz = { version = "^1.7", optional = true }
Pillow = "^9.0.0"
loguru = "^0.5.3"
setuptools = "*"
concrete-compiler = "^0.5.0"
concrete-compiler = "^0.6.0"
torch = "^1.10.2"
[tool.poetry.extras]

View File

@@ -36,7 +36,7 @@ def test_circuit_draw(default_compilation_configuration):
def test_circuit_run(default_compilation_configuration):
"""Test function for `run` method of `Circuit`"""
"""Test equivalence of encrypt/run/decrypt and encrypt_run_decrypt"""
def f(x):
return x + 42
@@ -46,5 +46,9 @@ def test_circuit_run(default_compilation_configuration):
inputset = range(2 ** 3)
circuit = hnp.compile_numpy_function(f, {"x": x}, inputset, default_compilation_configuration)
circuit.keygen()
for x in inputset:
assert circuit.run(x) == circuit.engine.run(x)
enc_x = circuit.encrypt(x)
enc_res = circuit.run(enc_x)
res = circuit.decrypt(enc_res)
assert circuit.encrypt_run_decrypt(x) == res

View File

@@ -404,7 +404,9 @@ def check_is_good_execution_impl(
for i in range(1, nb_tries + 1):
preprocessed_args = tuple(preprocess_input_func(val) for val in args)
last_engine_result = postprocess_output_func(fhe_circuit.run(*preprocessed_args))
last_engine_result = postprocess_output_func(
fhe_circuit.encrypt_run_decrypt(*preprocessed_args)
)
last_function_result = postprocess_output_func(function(*preprocessed_args))
ok_execution = check_function(last_engine_result, last_function_result)

View File

@@ -11,7 +11,7 @@ from concrete.common.data_types.integers import Integer, SignedInteger, Unsigned
from concrete.common.debugging import draw_graph, format_operation_graph
from concrete.common.extensions.multi_table import MultiLookupTable
from concrete.common.extensions.table import LookupTable
from concrete.common.values import ClearTensor, EncryptedScalar, EncryptedTensor
from concrete.common.values import ClearScalar, ClearTensor, EncryptedScalar, EncryptedTensor
from concrete.numpy import compile as compile_
from concrete.numpy import tracing
from concrete.numpy.compile import (
@@ -790,7 +790,7 @@ def test_compile_and_run_correctness(
)
args = [random.randint(low, high) for (low, high) in input_ranges]
assert compiler_engine.run(*args) == function(*args)
assert compiler_engine.encrypt_run_decrypt(*args) == function(*args)
@pytest.mark.parametrize(
@@ -1417,7 +1417,7 @@ def test_compile_and_run_tensor_correctness(
check_is_good_execution(circuit, function, numpy_test_input)
else:
check_array_equality(
circuit.run(*numpy_test_input),
circuit.encrypt_run_decrypt(*numpy_test_input),
numpy.array(function(*numpy_test_input), dtype=numpy.uint8),
)
@@ -1486,7 +1486,7 @@ def test_compile_and_run_dot_correctness(size, input_range, default_compilation_
args = [
numpy.random.randint(low, high + 1, size=shape, dtype=numpy.uint8) for __ in range(2)
]
assert compiler_engine.run(*args) == func_to_compile(*args)
assert compiler_engine.encrypt_run_decrypt(*args) == func_to_compile(*args)
@pytest.mark.parametrize(
@@ -1563,7 +1563,9 @@ def test_compile_and_run_dot_correctness_with_signed_cst(
args = [
numpy.random.randint(low_x, high_x + 1, size=(size,), dtype=numpy.uint8),
]
assert check_equality_modulo(compiler_engine.run(*args), function(*args), modulus)
assert check_equality_modulo(
compiler_engine.encrypt_run_decrypt(*args), function(*args), modulus
)
@pytest.mark.parametrize(
@@ -1624,8 +1626,8 @@ def test_compile_and_run_constant_dot_correctness(
)
args = (numpy.random.randint(low, high + 1, size=shape, dtype=numpy.uint8),)
assert left_circuit.run(*args) == left(*args)
assert right_circuit.run(*args) == right(*args)
assert left_circuit.encrypt_run_decrypt(*args) == left(*args)
assert right_circuit.encrypt_run_decrypt(*args) == right(*args)
@pytest.mark.parametrize(
@@ -1837,7 +1839,7 @@ def test_compile_and_run_matmul_correctness(
# Stay positive for input to FHE circuit
arg = numpy.clip(arg, 0, high).astype(numpy.uint8)
circuit_output = circuit.run(arg)
circuit_output = circuit.encrypt_run_decrypt(arg)
func_output = func(arg)
if check_mod:
@@ -2046,7 +2048,58 @@ def test_compile_and_run_transpose_correctness(input_shape, default_compilation_
)
x = numpy.random.randint(0, 120, size=input_shape, dtype=numpy.uint8)
expected = transpose(x)
result = compiler_engine.run(x)
result = compiler_engine.encrypt_run_decrypt(x)
assert (expected == result).all()
@pytest.mark.parametrize(
"input_shape",
[
pytest.param((8,)),
],
)
@pytest.mark.parametrize(
"loop_parallelize",
[
pytest.param(True),
pytest.param(False),
],
)
def test_compile_and_run_loop_parallelization(
input_shape, loop_parallelize, default_compilation_configuration
):
"""Test function to make sure compilation and execution with and without loop parallelization
works properly"""
def dot_and_add(x, y, a):
return numpy.dot(x, y) + a
# Enable/Disable loop parallelization
compilation_configuration = deepcopy(default_compilation_configuration)
compilation_configuration.loop_parallelize = loop_parallelize
compiler_engine = compile_numpy_function(
dot_and_add,
{
"x": EncryptedTensor(Integer(64, False), input_shape),
"y": ClearTensor(Integer(64, False), input_shape),
"a": ClearScalar(Integer(64, False)),
},
[
(
numpy.random.randint(0, 2, size=input_shape),
numpy.random.randint(0, 2, size=input_shape),
numpy.random.randint(0, 2, size=()),
)
for i in range(20)
],
compilation_configuration,
)
x = numpy.random.randint(0, 2, size=input_shape, dtype=numpy.uint8)
y = numpy.random.randint(0, 2, size=input_shape, dtype=numpy.uint8)
a = numpy.random.randint(0, 2, size=(), dtype=numpy.uint8)
expected = dot_and_add(x, y, a)
result = compiler_engine.encrypt_run_decrypt(x, y, a)
assert (expected == result).all()
@@ -2549,7 +2602,7 @@ def test_compile_and_run_correctness_with_negative_values(
)
args = [random.randint(low, high) for (low, high) in input_ranges]
assert compiler_engine.run(*args) == function(*args)
assert compiler_engine.encrypt_run_decrypt(*args) == function(*args)
@pytest.mark.parametrize(
@@ -2623,7 +2676,9 @@ def test_compile_and_run_correctness_with_negative_results(
)
args = [random.randint(low, high) for (low, high) in input_ranges]
assert check_equality_modulo(compiler_engine.run(*args), function(*args), modulus)
assert check_equality_modulo(
compiler_engine.encrypt_run_decrypt(*args), function(*args), modulus
)
@pytest.mark.parametrize(

View File

@@ -721,7 +721,7 @@ def test_constant_indexing_run_correctness(
item if isinstance(item, int) else np.array(item, dtype=np.uint8) for item in test_input
)
output = circuit.run(*numpy_test_input)
output = circuit.encrypt_run_decrypt(*numpy_test_input)
expected = np.array(expected_output, dtype=np.uint8)
check_array_equality(output, expected)

View File

@@ -40,5 +40,5 @@ def test_compile_and_run(
)
x = np.random.randint(0, 4, size=input_shape, dtype=np.uint8)
expected = conv(x)
result = compiler_engine.run(x)
result = compiler_engine.encrypt_run_decrypt(x)
assert (expected == result).all()

View File

@@ -198,7 +198,7 @@ def test_memory_operation_run_correctness(
default_compilation_configuration,
)
actual = circuit.run(numpy.array(test_input, dtype=numpy.uint8))
actual = circuit.encrypt_run_decrypt(numpy.array(test_input, dtype=numpy.uint8))
expected = numpy.array(expected_output, dtype=numpy.uint8)
check_array_equality(actual, expected)

View File

@@ -260,7 +260,7 @@ def test_np_fhe_compiler_full_compilation(default_compilation_configuration, che
fhe_circuit = compiler.get_compiled_fhe_circuit()
for i in range(64):
assert fhe_circuit.run(i) == function_to_compile(i)
assert fhe_circuit.encrypt_run_decrypt(i) == function_to_compile(i)
def test_np_fhe_compiler_compile_on_inputset(default_compilation_configuration):
@@ -277,4 +277,4 @@ def test_np_fhe_compiler_compile_on_inputset(default_compilation_configuration):
circuit = compiler.compile_on_inputset(numpy.arange(64))
for i in range(64):
assert circuit.run(i) == function_to_compile(i)
assert circuit.encrypt_run_decrypt(i) == function_to_compile(i)