From 9fffe8be5a626f8be30ee67408eb9c1946f18bb0 Mon Sep 17 00:00:00 2001 From: Benoit Chevallier-Mames Date: Tue, 11 Jun 2024 18:10:31 +0200 Subject: [PATCH] docs(frontend): simplify the doc for the non-power user --- docs/SUMMARY.md | 52 ++++++++++--------- docs/compilation/combining.md | 7 +++ .../composing_functions_with_modules.md | 5 +- docs/compilation/composition.md | 36 +++++++++++++ docs/compilation/decorator.md | 20 ------- docs/core-features/non_linear_operations.md | 2 +- docs/core-features/table_lookups.md | 4 +- docs/dev/compilation/compiler_internals.md | 14 ----- docs/get-started/quick_start.md | 21 ++++++++ 9 files changed, 96 insertions(+), 65 deletions(-) create mode 100644 docs/compilation/combining.md create mode 100644 docs/compilation/composition.md delete mode 100644 docs/compilation/decorator.md delete mode 100644 docs/dev/compilation/compiler_internals.md diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 7c78b5d09e..33c815fdce 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -14,30 +14,32 @@ * [Overview](core-features/fhe_basics.md) * [Table lookups (basics)](core-features/table_lookups.md) -* [Bit extraction](core-features/bit_extraction.md) * [Non-linear operations](core-features/non_linear_operations.md) -* [Common tips](core-features/workarounds.md) -* [Extensions](core-features/extensions.md) -* [Tagging](core-features/tagging.md) +* Advanced features + * [Bit extraction](core-features/bit_extraction.md) + * [Common tips](core-features/workarounds.md) + * [Extensions](core-features/extensions.md) ## Compilation -* [Composing functions with modules](compilation/composing_functions_with_modules.md) +* [Combining compiled functions](compilation/combining.md) + * [With composition](compilation/composition.md) + * [With modules](compilation/composing_functions_with_modules.md) +* Key-related options for faster execution + * [Multi precision](compilation/multi_precision.md) + * [Multi parameters](compilation/multi_parameters.md) * [Compression](compilation/compression.md) -* [Reuse arguments](compilation/reuse_arguments.md) -* [Multi precision](compilation/multi_precision.md) -* [Multi parameters](compilation/multi_parameters.md) -* [Decorator](compilation/decorator.md) -* [Direct circuits](compilation/direct_circuits.md) +* [Reusing arguments](compilation/reuse_arguments.md) ## Execution / Analysis * [Simulation](execution-analysis/simulation.md) -* [Progressbar](execution-analysis/progressbar.md) -* [Statistics](compilation/statistics.md) -* [Formatting and drawing](execution-analysis/formatting_and_drawing.md) -* [Debug](execution-analysis/debug.md) +* [Debugging and artifact](execution-analysis/debug.md) * [GPU acceleration](execution-analysis/gpu_acceleration.md) +* Other + * [Statistics](compilation/statistics.md) + * [Progressbar](execution-analysis/progressbar.md) + * [Formatting and drawing](execution-analysis/formatting_and_drawing.md) ## Guides @@ -58,7 +60,7 @@ ## Explanations * [Compiler workflow](dev/compilation/compiler_workflow.md) -* [Compiler internals](dev/compilation/compiler_internals.md) +* Compiler internals * [Table lookups](core-features/table_lookups_advanced.md) * [Rounding](core-features/rounding.md) * [Truncating](core-features/truncating.md) @@ -66,7 +68,18 @@ * [Comparisons](core-features/comparisons.md) * [Min/Max operations](core-features/minmax.md) * [Bitwise operations](core-features/bitwise.md) + * [Direct circuits](compilation/direct_circuits.md) + * [Tagging](core-features/tagging.md) +* [Security](explanations/security.md) * [Frontend fusing](explanations/fusing.md) + +## Developers + +* [Contributing](dev/contributing.md) +* [Release note](https://github.com/zama-ai/concrete/releases) +* [Feature request](https://github.com/zama-ai/concrete/issues/new?assignees=\&labels=feature\&projects=\&template=features.md) +* [Bug report](https://github.com/zama-ai/concrete/issues/new?assignees=\&labels=bug%2C+triage\&projects=\&template=bug_report.md) +* [Project layout](explanations/layout.md) * [Compiler backend](explanations/backends/README.md) * [Adding a new backend](explanations/backends/new_backend.md) * [Optimizer](explanations/optimizer.md) @@ -78,13 +91,4 @@ * [Tracing dialect](explanations/TracingDialect.md) * [Runtime dialect](explanations/RTDialect.md) * [SDFG dialect](explanations/SDFGDialect.md) -* [Security](explanations/security.md) * [Call FHE circuits from other languages](explanations/call_from_other_language.md) -* [Project layout](explanations/layout.md) - -## Developers - -* [Contributing](dev/contributing.md) -* [Release note](https://github.com/zama-ai/concrete/releases) -* [Feature request](https://github.com/zama-ai/concrete/issues/new?assignees=\&labels=feature\&projects=\&template=features.md) -* [Bug report](https://github.com/zama-ai/concrete/issues/new?assignees=\&labels=bug%2C+triage\&projects=\&template=bug_report.md) diff --git a/docs/compilation/combining.md b/docs/compilation/combining.md new file mode 100644 index 0000000000..4967ae8bff --- /dev/null +++ b/docs/compilation/combining.md @@ -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) diff --git a/docs/compilation/composing_functions_with_modules.md b/docs/compilation/composing_functions_with_modules.md index 739eddcdf1..371e672043 100644 --- a/docs/compilation/composing_functions_with_modules.md +++ b/docs/compilation/composing_functions_with_modules.md @@ -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. diff --git a/docs/compilation/composition.md b/docs/compilation/composition.md new file mode 100644 index 0000000000..bc7c947c0a --- /dev/null +++ b/docs/compilation/composition.md @@ -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). + + + diff --git a/docs/compilation/decorator.md b/docs/compilation/decorator.md deleted file mode 100644 index c9aab27064..0000000000 --- a/docs/compilation/decorator.md +++ /dev/null @@ -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 %} diff --git a/docs/core-features/non_linear_operations.md b/docs/core-features/non_linear_operations.md index 9b8dc5395c..c065abc397 100644 --- a/docs/core-features/non_linear_operations.md +++ b/docs/core-features/non_linear_operations.md @@ -7,7 +7,7 @@ In Concrete, there are basically two types of operations: TLU are essential to be able to compile all functions, by keeping the semantic of user's program, but they can be slower, depending on the bitwidth of the inputs of the TLU. -In this document, we explain briefly, from a user point of view, how it works for non-linear operations as comparisons, min/max, bitwise operations, shifts. In [the poweruser documentation](../dev/compilation/compiler_internals.md), we enter a bit more into the details. +In this document, we explain briefly, from a user point of view, how it works for non-linear operations as comparisons, min/max, bitwise operations, shifts. In [the poweruser documentation](table_lookups_advanced.md), we enter a bit more into the details. ## Changing bit width in the MLIR or dynamically with a TLU diff --git a/docs/core-features/table_lookups.md b/docs/core-features/table_lookups.md index c87555ba72..973b76b0e2 100644 --- a/docs/core-features/table_lookups.md +++ b/docs/core-features/table_lookups.md @@ -1,6 +1,6 @@ # Table lookup -In TFHE, there exists mainly two operations: the linear operations (additions, subtractions, multiplications by integers) and the rest. And the rest is done with table lookups (TLUs), which means that a lot of things are done with TLU. In this document, we explain briefly, from a user point of view, how TLU can be used. In [the poweruser documentation](../dev/compilation/compiler_internals.md), we enter a bit more into the details. +In TFHE, there exists mainly two operations: the linear operations (additions, subtractions, multiplications by integers) and the rest. And the rest is done with table lookups (TLUs), which means that a lot of things are done with TLU. In this document, we explain briefly, from a user point of view, how TLU can be used. In [the poweruser documentation](table_lookups_advanced.md), we enter a bit more into the details. ## Performance @@ -133,7 +133,7 @@ As we said in the beginning of this document, bitsize of the inputs of TLU are c For lot of use-cases, like for example in Machine Learning, it is possible to replace the table lookup `y = T[i]` by some `y = T'[i']`, where `i'` only has the most significant bits of `i` and `T'` is a much shorter table, and still maintain a good accuracy of the function. The interest of such a method stands in the fact that, since the table `T'` is much smaller, the corresponding TLU will be done much more quickly. -There are different flavors of doing this in Concrete. We describe them quickly here, and refer the user to the [poweruser documentation](../dev/compilation/compiler_internals.md) for more explanations. +There are different flavors of doing this in Concrete. We describe them quickly here, and refer the user to the [poweruser documentation](table_lookups_advanced.md) for more explanations. The first possibility is to set `i'` as the truncation of `i`: here, we just take the most significant bits of `i`. This is done with `fhe.truncate_bit_pattern`. diff --git a/docs/dev/compilation/compiler_internals.md b/docs/dev/compilation/compiler_internals.md deleted file mode 100644 index 703cf39573..0000000000 --- a/docs/dev/compilation/compiler_internals.md +++ /dev/null @@ -1,14 +0,0 @@ -# Concrete internals - -This section of the documentation is for more advanced users, who want to go further with the use of the compiler. - -In particular, we have subsections for: -- [Table lookups](../../core-features/table_lookups.md) -- [Rounding](../../core-features/rounding.md) -- [Truncating](../../core-features/truncating.md) -- [Floating points](../../core-features/floating_points.md) -- [Comparisons](../../core-features/comparisons.md) -- [Min/Max operations](../../core-features/minmax.md) -- [Bitwise operations](../../core-features/bitwise.md) - - diff --git a/docs/get-started/quick_start.md b/docs/get-started/quick_start.md index 7befe5feea..be585471ca 100644 --- a/docs/get-started/quick_start.md +++ b/docs/get-started/quick_start.md @@ -34,6 +34,27 @@ result = circuit.decrypt(encrypted_result) assert result == add(2, 6) ``` +## Decorator + +Another simple way to compile a function is to use a decorator. + +```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 %} + ## Importing the library Import the `fhe` module, which includes everything you need to perform homomorphic evaluation: