docs(frontend): simplify the doc for the non-power user

This commit is contained in:
Benoit Chevallier-Mames
2024-06-11 18:10:31 +02:00
committed by Benoit Chevallier-Mames
parent ba7229e66f
commit 9fffe8be5a
9 changed files with 96 additions and 65 deletions

View File

@@ -0,0 +1,7 @@
# Combining compiled functions
In various cases, deploying a server that contains many compatible functions is important. By compatible, we mean that the functions will be used together, with outputs of some of them being used as inputs of some other ones, without decryption in the middle. It also encompasses the use of recursive functions.
To support this feature in Concrete, we have two ways:
- using the `composable` flag in the compilation, when there is a unique function. This option is described in [this document](composition.md)
- using the Concrete modules, when there are several functions, or when there is a unique function for which we want to more precisely detail how outputs are reused as further inputs. This functionality is described in [this document](composing_functions_with_modules.md)

View File

@@ -1,6 +1,6 @@
# Composing functions with modules
In various cases, deploying a server that contains many compatible functions is important. `concrete-python` is now able to compile FHE _modules_, which can contain as many functions as needed. More importantly, modules support _composition_ of the different functions. This means the encrypted result of one function execution can be used as input of a different function, without needing to decrypt in between. A module is [deployed in a single artifact](../guides/deploy.md#deployment-of-modules), making as simple to use a single function project.
In various cases, deploying a server that contains many compatible functions is important. `concrete-python` can compile FHE modules containing as many functions as needed. More importantly, modules support _composition_ of the different functions. This means the encrypted result of one function execution can be used as input of a different function, without needing to decrypt in between. A module is [deployed in a single artifact](../guides/deploy.md#deployment-of-modules), making as simple to use a single function project.
Here is a first simple example:
```python
@@ -280,6 +280,3 @@ class Doubler:
return noise_reset(counter * 2)
```
## Single function composition without modules.
It is also possible to compile a single function to be self-composable with the `fhe.AllComposable` policy without using modules. For this one simply has to set the [`composable`](../guides/configure.md#options) configuration setting to `True` when compiling.

View File

@@ -0,0 +1,36 @@
# Combining compiled functions with the composable flag
A simple way to say that a function `f` should be compiled such that its outputs can be reused as inputs is to use the
[`composable`](../guides/configure.md#options) configuration setting to `True` when compiling. Doing so, we can then easily compute `f(f(x))` or `f**i(x) = f(f(...(f(x) ..))` for a variable non-encrypted integer `i`, which is typically what happens for recursions.
```python
from concrete import fhe
@fhe.compiler({"counter": "encrypted"})
def increment(counter):
return (counter + 1) % 100
print("Compiling `increment` function")
increment_fhe = increment.compile(list(range(0, 100)), composable=True)
print("Generating keyset ...")
increment_fhe.keygen()
print("Encrypting the initial counter value")
counter = 0
counter_enc = increment_fhe.encrypt(counter)
print(f"| iteration || decrypted | cleartext |")
for i in range(10):
counter_enc = increment_fhe.run(counter_enc)
counter = increment(counter)
# For demo purpose; no decryption is needed.
counter_dec = increment_fhe.decrypt(counter_enc)
print(f"| {i} || {counter_dec:<9} | {counter:<9} |")
```
Remark that this option is the equivalent of using the `fhe.AllComposable` policy of [modules](composing_functions_with_modules.md). In particular, the same limitations may occur (see [limitations documentation](composing_functions_with_modules.md#limitations) section).

View File

@@ -1,20 +0,0 @@
# Decorator
If you are trying to compile a regular function, you can use the decorator interface instead of the explicit `Compiler` interface to simplify your code:
```python
from concrete import fhe
@fhe.compiler({"x": "encrypted"})
def f(x):
return x + 42
inputset = range(10)
circuit = f.compile(inputset)
assert circuit.encrypt_run_decrypt(10) == f(10)
```
{% hint style="info" %}
This decorator is a way to add the `compile` method to the function object without changing its name elsewhere.
{% endhint %}