docs(compiler): reorganize the doc

This commit is contained in:
Benoit Chevallier-Mames
2024-03-01 18:21:44 +01:00
committed by Benoit Chevallier-Mames
parent 68cada3963
commit 089b5e8d6c
8 changed files with 112 additions and 113 deletions

View File

@@ -1,27 +0,0 @@
# Exactness
One of the most common operations in Concrete is `Table Lookups` (TLUs). TLUs are performed with an FHE operation called `Programmable Bootstrapping` (PBS). PBS's have a certain probability of error, which, when triggered, result in inaccurate results.
Let's say you have the table:
```python
lut = [0, 1, 4, 9, 16, 25, 36, 49, 64]
```
And you perform a Table Lookup using `4`. The result you should get is `lut[4] = 16`, but because of the possibility of error, you could get any other value in the table.
The probability of this error can be configured through the `p_error` and `global_p_error` configuration options. The difference between these two options is that, `p_error` is for individual TLUs but `global_p_error` is for the whole circuit.
If you set `p_error` to `0.01`, for example, it means every TLU in the circuit will have a 99% chance of being exact with a 1% probability of error. If you have a single TLU in the circuit, `global_p_error` would be 1% as well. But if you have 2 TLUs for example, `global_p_error` would be almost 2% (`1 - (0.99 * 0.99)`).
However, if you set `global_p_error` to `0.01`, the whole circuit will have 1% probability of error, no matter how many Table Lookups are included.
If you set both of them, both will be satisfied. Essentially, the stricter one will be used.
By default, both `p_error` and `global_p_error` is set to `None`, which results in a `global_p_error` of `1 / 100_000` being used. 
Feel free to play with these configuration options to pick the one best suited for your needs! See [How to Configure](../howto/configure.md) to learn how you can set a custom `p_error` and/or `global_p_error`.
{% hint style="info" %}
Configuring either of those variables impacts computation time (compilation, keys generation, circuit execution) and space requirements (size of the keys on disk and in memory). Lower error probabilities would result in longer computation times and larger space requirements.
{% endhint %}

View File

@@ -1,35 +0,0 @@
# Performance
One of the most common operations in **Concrete** is `Table Lookups` (TLUs). All operations except addition, subtraction, multiplication with non-encrypted values, tensor manipulation operations, and a few operations built with those primitive operations (e.g. matmul, conv) are converted to Table Lookups under the hood:
```python
from concrete import fhe
@fhe.compiler({"x": "encrypted"})
def f(x):
return x ** 2
inputset = range(2 ** 4)
circuit = f.compile(inputset)
```
is exactly the same as
```python
from concrete import fhe
table = fhe.LookupTable([x ** 2 for x in range(2 ** 4)])
@fhe.compiler({"x": "encrypted"})
def f(x):
return table[x]
inputset = range(2 ** 4)
circuit = f.compile(inputset)
```
Table Lookups are very flexible. They allow Concrete to support many operations, but they are expensive. The exact cost depends on many variables (hardware used, error probability, etc.), but they are always much more expensive compared to other operations. You should try to avoid them as much as possible. It's not always possible to avoid them completely, but you might remove the number of TLUs or replace some of them with other primitive operations.
{% hint style="info" %}
Concrete automatically parallelizes TLUs if they are applied to tensors.
{% endhint %}

View File

@@ -9,16 +9,3 @@ Some terms used throughout the project include:
* **bounds:** Before computation graphs are converted to MLIR, we need to know which value should have which type (e.g., uint3 vs int5). We use inputsets for this purpose. We simulate the graph with the inputs in the inputset to remember the minimum and the maximum value for each node, which is what we call bounds, and use bounds to determine the appropriate type for each node.
* **circuit:** The result of compilation. A circuit is made of the client and server components. It has methods for everything from printing to evaluation.
## Module structure
In this section, we briefly discuss the module structure of **Concrete Python**. You are encouraged to check individual `.py` files to learn more.
* concrete
* fhe
* **dtypes:** data type specifications (e.g., int4, uint5, float32)
* **values:** value specifications (i.e., data type + shape + encryption status)
* **representation:** representation of computation (e.g., computation graphs, nodes)
* **tracing:** tracing of python functions
* **extensions:** custom functionality (see [Extensions](../tutorial/extensions.md))
* **mlir:** computation graph to mlir conversion
* **compilation:** configuration, compiler, artifacts, circuit, client/server, and anything else related to compilation