Compare commits

...

53 Commits

Author SHA1 Message Date
Nicolas Sarlin
76123892a8 fix(core): use of deprecated rayon repeatn 2025-08-21 12:06:28 +02:00
David Testé
ebe4f4f4ca chore(ci): add permission to github token to release crates
When using crates.io trusted publishing feature GitHub token `id-token: write` permission to be able to authenticate the workflow on the registry.
2025-08-21 12:06:28 +02:00
David Testé
8da7214dcb chore(build): set maximum version of pulp to 0.21.4
Pulp v0.21.5 fails to pass post-commit checks.
2025-08-13 10:47:30 +02:00
David Testé
1a661e3eb3 chore(ci): fix documentation and code typos 2025-08-13 10:47:30 +02:00
David Testé
6cfdca7260 chore(ci): use crates.io trusted publishing feature 2025-08-13 10:47:30 +02:00
David Testé
f92207df66 chore(ci): cache backward compatibility data
Git LFS transfers use a lot of bandwidth. Since data used to test
backward compatibility won't change every day, we can leverage
GitHub cache action.
2025-03-24 17:15:30 +01:00
David Testé
5ef151a8d9 chore(ci): update aws ami for cpu
This is done to update python modules: pip, wheel and setuptools.
2025-03-24 17:15:30 +01:00
David Testé
566b7d3164 docs: change svg benchmark tables appearance for pbs 2025-03-11 11:05:52 +01:00
Arthur Meyre
2d4f6484be chore: pre-generate keyswitching keys for shortint tests
- we run in a cross process race condition which fucks up the key file
- no rust crate seems to help and linux locks are just a fucking mess
- also avoid truncating file when we are going to write to it, get a lock
first
2025-03-07 16:31:27 +01:00
David Testé
386dd738cf docs: change svg benchmark tables appearance
Reduce number of FheUint types displayed in the integer benchmark
tables. Increase policy size and better columns fitting.
Remove link to enlarge image.
2025-03-06 13:26:48 +01:00
Nicolas Sarlin
f60be3e9e6 chore(ci): update tfhe-lints for newer compiler version 2025-03-06 09:48:26 +01:00
Arthur Meyre
d402bc8a50 chore(ci): force installation of toolchain for tfhe-lints 2025-03-06 09:48:26 +01:00
Nicolas Sarlin
672751f9b1 chore(ci): re-enable tfhe_lints 2025-03-06 09:48:26 +01:00
Agnes Leroy
5566fa6c03 chore: bumb tfhe-rs and tfhe-cuda-backend versions 2025-03-06 09:28:56 +01:00
Agnes Leroy
71dc906c77 feat(gpu): add a function to set a CudaLweList to 0 2025-03-06 09:28:56 +01:00
Agnes Leroy
d162c10919 chore(gpu): plug in signed gpu tests in the hl api 2025-03-06 09:28:56 +01:00
Pedro Alves
04ca254644 fix(gpu): enforce tighter bounds on compression output 2025-03-06 09:28:56 +01:00
Agnes Leroy
c7d11d09c7 fix(gpu): fix scalar comparisons with 1 block 2025-03-06 09:28:56 +01:00
Guillermo Oyarzun
c6268f2ac7 fix(cpu): fix corner case when estimating the num blocks required 2025-03-06 09:28:56 +01:00
Pedro Alves
1a0e19bb9b feat(gpu): refactor the sample extract entry point so the user can pass how many LWEs should be extracted per GLWE 2025-03-06 09:28:56 +01:00
Pedro Alves
2e3e3e3e2d fix(gpu): fix wrong number of blocks used in cast 2025-03-06 09:28:56 +01:00
Guillermo Oyarzun
68fa3cb303 fix(gpu): fix wrong assert in division 2025-03-06 09:28:56 +01:00
Guillermo Oyarzun
9f8a88d2f8 feat(gpu): enable division in high level api 2025-03-06 09:28:56 +01:00
Guillermo Oyarzun
c2b63da4f5 feat(gpu): enable if then else for boolean ciphertexts in hlapi 2025-03-06 09:28:56 +01:00
Guillermo Oyarzun
928a716175 fix(gpu): enable large integers for the classical pbs flavors 2025-03-06 09:28:56 +01:00
Guillermo Oyarzun
68a66f231f fix(gpu): enable large integers other multi bit pbs 2025-03-06 09:28:56 +01:00
Pedro Alves
cd8276cd5e fix(gpu): Remove unnecessary and incorrect bound check for decompression
Removed unnecessary bounds check for the number of LWEs against polynomial size.
2025-03-06 09:28:56 +01:00
David Testé
14089604b1 chore(bench): run core_crypto benchmarks on all parameters p-fail
This also add KS-PBS benchmarks.
2025-03-05 08:23:10 +01:00
Arthur Meyre
aaf4cbaa65 fix: fix the atomic pattern used to cast in trivium and a test in shortint
- parameters are optimized for a clean ciphertext, the ciphertext being
keyswitched was noisy
2025-03-04 16:00:31 +01:00
Nicolas Sarlin
cba43c240e chore(ci): disable dylint until rustup issue is fixed 2025-03-04 15:58:02 +01:00
Agnes Leroy
b6370c9cfb chore(gpu): fix typo in doc 2025-02-28 11:12:27 +01:00
Mayeul@Zama
4b2a132140 chore: update toolchain 2025-02-28 10:21:28 +01:00
J-B Orfila
f13c4cdc3b docs: add link in the README 2025-02-27 16:31:44 +01:00
tmontaigu
e257545d1f docs: rename to README as its needed for link to work 2025-02-27 15:08:48 +01:00
tmontaigu
0aa7fce039 docs(js): update JS example
The example was still using CompactFheUint32List
which as been removed in favor of the more generic CompactCiphertextList
2025-02-27 14:59:34 +01:00
Arthur Meyre
8905c01158 chore: link CONTRIBUTING.md in the documentation 2025-02-26 15:18:39 +01:00
J-B Orfila
bb699527cf docs: security disclaimer updated 2025-02-26 15:18:06 +01:00
J-B Orfila
eee64873b0 docs: correcting parameter section 2025-02-26 15:18:06 +01:00
Nicolas Sarlin
d6407fffff chore(doc): add a doc page about parameters 2025-02-26 15:18:06 +01:00
David Testé
194bd97730 chore(ci): add should-run to tfhe-fft and tfhe-ntt tests
This is done to avoid testing tfhe-ftt/ntt crates if nothing
changes in their source files.
However, these tests would be run unconditionally on each push on
main branch.
2025-02-26 10:23:05 +01:00
Arthur Meyre
d507027e83 chore(docs): use tilde requirements to minimize breakage on users' end 2025-02-26 10:21:42 +01:00
Arthur Meyre
8f9b392e0b chore: update README 2025-02-26 10:21:42 +01:00
David Testé
73faccf108 chore(ci): add contributing guidance 2025-02-26 10:21:41 +01:00
David Testé
a9913f38c1 docs: refactor and update benchmarks pages
Benchmarks tables are rendered as descriptive SVG images.
Sort results by backend to have a clearer view in tree of content.
PBS benchmarks now display results for various p-fail and several
precisions.
2025-02-26 10:21:41 +01:00
David Testé
2dff35a2a4 chore(ci): update cpu aws ami and install git-lfs
Several network errors occurred while trying to install git-lfs
from within backward compatibility tests workflow. Having git-lfs
installed directly in the Amazon Machine Image fix this issue.
2025-02-26 10:21:41 +01:00
Arthur Meyre
6a9ec440c7 test: make the bound on the base variance check a bit looser
We have seen failures, we need proper confidence intervals on these tests
2025-02-26 10:21:41 +01:00
dependabot[bot]
1b48c09742 chore(deps): bump actions/cache from 4.2.0 to 4.2.1
Bumps [actions/cache](https://github.com/actions/cache) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](1bd1e32a3b...0c907a75c2)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-26 10:21:40 +01:00
dependabot[bot]
0d56c051d6 chore(deps): bump actions/upload-artifact from 4.6.0 to 4.6.1
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.6.0 to 4.6.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](65c4c4a1dd...4cec3d8aa0)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-26 10:21:40 +01:00
Agnes Leroy
80b6f1a4f9 chore(gpu): update backend readme 2025-02-26 10:21:40 +01:00
Mayeul@Zama
fca7ef732c chore(docs): add HL strings documentation 2025-02-26 10:21:40 +01:00
Yuxi Zhao
b60a4d9b30 chore(docs): improve nagivation 2025-02-26 10:21:39 +01:00
Arthur Meyre
2077f48c35 chore(ci): make md doctest checker a bit more versatile on user errors 2025-02-26 10:21:39 +01:00
David Testé
abe9868899 chore(ci): fix release workflow for tfhe-versionable
tfhe-versionable crate depends on tfhe-versionable-derive.
Workflow, now ensure that derive crate is published before
attempting to package tfhe-versionable.

Dry-run option is removed since it cannot be use correctly due
the reason aforementioned.
2025-02-26 10:21:34 +01:00
176 changed files with 5556 additions and 2145 deletions

View File

@@ -11,6 +11,8 @@ env:
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACKIFY_MARKDOWN: true
PULL_REQUEST_MD_LINK: ""
CHECKOUT_TOKEN: ${{ secrets.REPO_CHECKOUT_TOKEN || secrets.GITHUB_TOKEN }}
# Secrets will be available only to zama-ai organization members
SECRETS_AVAILABLE: ${{ secrets.JOB_SECRET != '' }}
@@ -51,7 +53,7 @@ jobs:
name: Backward compatibility tests
needs: [ setup-instance ]
concurrency:
group: ${{ github.workflow }}_${{ github.head_ref || github.ref }}
group: ${{ github.workflow_ref }}
cancel-in-progress: true
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
steps:
@@ -62,18 +64,14 @@ jobs:
token: ${{ env.CHECKOUT_TOKEN }}
- name: Install latest stable
uses: dtolnay/rust-toolchain@a54c7afa936fefeb4456b2dd8068152669aa8203
uses: dtolnay/rust-toolchain@888c2e1ea69ab0d4330cbf0af1ecc7b68f368cc1
with:
toolchain: stable
- name: Install git-lfs
run: |
sudo apt update && sudo apt -y install git-lfs
- name: Use specific data branch
if: ${{ contains(github.event.pull_request.labels.*.name, 'data_PR') }}
env:
PR_BRANCH: ${{ github.head_ref || github.ref_name }}
PR_BRANCH: ${{ github.ref_name }}
run: |
echo "BACKWARD_COMPAT_DATA_BRANCH=${PR_BRANCH}" >> "${GITHUB_ENV}"
@@ -83,7 +81,23 @@ jobs:
BRANCH="$(make backward_compat_branch)"
echo "branch=${BRANCH}" >> "${GITHUB_OUTPUT}"
- name: Get backward compat branch head SHA
id: backward_compat_sha
env:
REPO_URL: "https://github.com/zama-ai/tfhe-backward-compat-data"
run: |
SHA=$(git ls-remote ${{ env.REPO_URL }} refs/heads/${{ steps.backward_compat_branch.outputs.branch }} | awk '{print $1}')
echo "sha=${SHA}" >> "${GITHUB_OUTPUT}"
- name: Retrieve data from cache
id: retrieve-data-cache
uses: actions/cache/restore@d4323d4df104b026a6aa633fdb11d772146be0bf #v4.2.2
with:
path: tests/tfhe-backward-compat-data
key: ${{ steps.backward_compat_branch.outputs.branch }}_${{ steps.backward_compat_sha.outputs.sha }}
- name: Clone test data
if: steps.retrieve-data-cache.outputs.cache-hit != 'true'
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
@@ -96,13 +110,26 @@ jobs:
run: |
make test_backward_compatibility_ci
- name: Store data in cache
if: steps.retrieve-data-cache.outputs.cache-hit != 'true'
continue-on-error: true
uses: actions/cache/save@d4323d4df104b026a6aa633fdb11d772146be0bf #v4.2.2
with:
path: tests/tfhe-backward-compat-data
key: ${{ steps.backward_compat_branch.outputs.branch }}_${{ steps.backward_compat_sha.outputs.sha }}
- name: Set pull-request URL
if: ${{ failure() && github.event_name == 'pull_request' }}
run: |
echo "PULL_REQUEST_MD_LINK=[pull-request](${{ vars.PR_BASE_URL }}${{ github.event.pull_request.number }}), " >> "${GITHUB_ENV}"
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Backward compatibility tests finished with status: ${{ job.status }} on '${{ env.BRANCH }}'. (${{ env.ACTION_RUN_URL }})"
SLACK_MESSAGE: "Backward compatibility tests finished with status: ${{ job.status }}. (${{ env.PULL_REQUEST_MD_LINK }}[action run](${{ env.ACTION_RUN_URL }}))"
teardown-instance:
name: Teardown instance (backward-compat-tests)
@@ -127,4 +154,4 @@ jobs:
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (backward-compat-tests) finished with status: ${{ job.status }} on '${{ env.BRANCH }}'. (${{ env.ACTION_RUN_URL }})"
SLACK_MESSAGE: "Instance teardown (backward-compat-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -209,7 +209,7 @@ jobs:
- name: Node cache restoration
id: node-cache
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 #v4.2.0
uses: actions/cache/restore@0c907a75c2c80ebcb7f088228285e798b750cf8f #v4.2.1
with:
path: |
~/.nvm
@@ -222,7 +222,7 @@ jobs:
make install_node
- name: Node cache save
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 #v4.2.0
uses: actions/cache/save@0c907a75c2c80ebcb7f088228285e798b750cf8f #v4.2.1
if: steps.node-cache.outputs.cache-hit != 'true'
with:
path: |

View File

@@ -73,7 +73,7 @@ jobs:
- name: Node cache restoration
id: node-cache
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 #v4.2.0
uses: actions/cache/restore@0c907a75c2c80ebcb7f088228285e798b750cf8f #v4.2.1
with:
path: |
~/.nvm
@@ -86,7 +86,7 @@ jobs:
make install_node
- name: Node cache save
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 #v4.2.0
uses: actions/cache/save@0c907a75c2c80ebcb7f088228285e798b750cf8f #v4.2.1
if: steps.node-cache.outputs.cache-hit != 'true'
with:
path: |

View File

@@ -94,7 +94,7 @@ jobs:
--append-results
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_boolean
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -68,6 +68,7 @@ jobs:
- name: Run benchmarks with AVX512
run: |
make bench_ks_pbs
make bench_pbs
make bench_pbs128
make bench_ks
@@ -85,7 +86,7 @@ jobs:
--walk-subdirs
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_core_crypto
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -99,7 +99,7 @@ jobs:
--append-results
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_erc20
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -80,7 +80,7 @@ jobs:
--walk-subdirs
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_integer_multi_bit_gpu_default
path: ${{ env.RESULTS_FILENAME }}
@@ -157,7 +157,7 @@ jobs:
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_core_crypto
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -77,6 +77,7 @@ jobs:
- name: Run benchmarks with AVX512
run: |
make bench_ks_pbs_gpu
make bench_pbs_gpu
make bench_ks_gpu
@@ -94,7 +95,7 @@ jobs:
--walk-subdirs
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_core_crypto
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -120,7 +120,7 @@ jobs:
--name-suffix avx512
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_erc20_${{ inputs.profile }}
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -196,7 +196,7 @@ jobs:
--bench-type ${{ matrix.bench_type }}
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_${{ matrix.command }}_${{ matrix.op_flavor }}_${{ inputs.profile }}
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -172,7 +172,7 @@ jobs:
--bench-type ${{ matrix.bench_type }}
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_${{ matrix.command }}_${{ matrix.op_flavor }}_${{ matrix.bench_type }}
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -138,7 +138,7 @@ jobs:
--append-results
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_shortint_${{ matrix.op_flavor }}
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -166,7 +166,7 @@ jobs:
--bench-type ${{ matrix.bench_type }}
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_${{ matrix.command }}_${{ matrix.op_flavor }}_${{ matrix.bench_type }}
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -84,7 +84,7 @@ jobs:
--name-suffix avx512
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_fft
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -84,7 +84,7 @@ jobs:
--name-suffix avx512
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_ntt
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -132,7 +132,7 @@ jobs:
--bench-type ${{ env.BENCH_TYPE }}
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_tfhe_zk_pok
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -110,7 +110,7 @@ jobs:
- name: Node cache restoration
id: node-cache
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57 #v4.2.0
uses: actions/cache/restore@0c907a75c2c80ebcb7f088228285e798b750cf8f #v4.2.1
with:
path: |
~/.nvm
@@ -123,7 +123,7 @@ jobs:
make install_node
- name: Node cache save
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57 #v4.2.0
uses: actions/cache/save@0c907a75c2c80ebcb7f088228285e798b750cf8f #v4.2.1
if: steps.node-cache.outputs.cache-hit != 'true'
with:
path: |
@@ -167,7 +167,7 @@ jobs:
--append-results
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_wasm_${{ matrix.browser }}
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -179,7 +179,7 @@ jobs:
--append-results
- name: Upload parsed results artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1
with:
name: ${{ github.sha }}_integer_zk
path: ${{ env.RESULTS_FILENAME }}

View File

@@ -3,16 +3,46 @@ name: Cargo Test tfhe-fft
on:
pull_request:
push:
branches:
- main
env:
CARGO_TERM_COLOR: always
IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }}
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true
jobs:
should-run:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
fft_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.fft_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
persist-credentials: 'false'
- name: Check for file changes
id: changed-files
uses: tj-actions/changed-files@dcc7a0cba800f454d79fff4b993e8c3555bcc0a8
with:
files_yaml: |
fft:
- tfhe/Cargo.toml
- Makefile
- tfhe-fft/**
- '.github/workflows/cargo_test_fft.yml'
cargo-tests-fft:
needs: should-run
if: needs.should-run.outputs.fft_test == 'true'
runs-on: ${{ matrix.runner_type }}
strategy:
matrix:
@@ -39,6 +69,8 @@ jobs:
make test_fft_no_std
cargo-tests-fft-nightly:
needs: should-run
if: needs.should-run.outputs.fft_test == 'true'
runs-on: ${{ matrix.runner_type }}
strategy:
matrix:
@@ -61,7 +93,9 @@ jobs:
make test_fft_no_std_nightly
cargo-tests-fft-node-js:
runs-on: "ubuntu-latest"
needs: should-run
if: needs.should-run.outputs.fft_test == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
@@ -69,3 +103,30 @@ jobs:
run: |
make install_node
make test_fft_node_js_ci
cargo-tests-fft-successful:
needs: [ should-run, cargo-tests-fft, cargo-tests-fft-nightly, cargo-tests-fft-node-js ]
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Tests do not need to run
if: needs.should-run.outputs.fft_test == 'false'
run: |
echo "tfhe-fft files haven't changed tests don't need to run"
- name: Check all tests passed
if: needs.should-run.outputs.fft_test == 'true' &&
needs.cargo-tests-fft.result == 'success' &&
needs.cargo-tests-fft-nightly.result == 'success' &&
needs.cargo-tests-fft-node-js.result == 'success'
run: |
echo "All tfhe-fft test passed"
- name: Check tests failure
if: needs.should-run.outputs.fft_test == 'true' &&
(needs.cargo-tests-fft.result != 'success' ||
needs.cargo-tests-fft-nightly.result != 'success' ||
needs.cargo-tests-fft-node-js.result != 'success')
run: |
echo "Some tfhe-fft tests failed"
exit 1

View File

@@ -3,16 +3,46 @@ name: Cargo Test tfhe-ntt
on:
pull_request:
push:
branches:
- main
env:
CARGO_TERM_COLOR: always
IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }}
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref }}
cancel-in-progress: true
jobs:
jobs:
should-run:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
ntt_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.ntt_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
persist-credentials: 'false'
- name: Check for file changes
id: changed-files
uses: tj-actions/changed-files@dcc7a0cba800f454d79fff4b993e8c3555bcc0a8
with:
files_yaml: |
ntt:
- tfhe/Cargo.toml
- Makefile
- tfhe-ntt/**
- '.github/workflows/cargo_test_ntt.yml'
cargo-tests-ntt:
needs: should-run
if: needs.should-run.outputs.ntt_test == 'true'
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -34,6 +64,8 @@ jobs:
run: make test_ntt_no_std
cargo-tests-ntt-nightly:
needs: should-run
if: needs.should-run.outputs.ntt_test == 'true'
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -52,3 +84,28 @@ jobs:
- name: Test no-std nightly
run: make test_ntt_no_std_nightly
cargo-tests-ntt-successful:
needs: [ should-run, cargo-tests-ntt, cargo-tests-ntt-nightly ]
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Tests do not need to run
if: needs.should-run.outputs.ntt_test == 'false'
run: |
echo "tfhe-ntt files haven't changed tests don't need to run"
- name: Check all tests success
if: needs.should-run.outputs.ntt_test == 'true' &&
needs.cargo-tests-ntt.result == 'success' &&
needs.cargo-tests-ntt-nightly.result == 'success'
run: |
echo "All tfhe-ntt tests passed"
- name: Check tests failure
if: needs.should-run.outputs.ntt_test == 'true' &&
(needs.cargo-tests-ntt.result != 'success' ||
needs.cargo-tests-ntt-nightly.result != 'success')
run: |
echo "Some tfhe-ntt tests failed"
exit 1

View File

@@ -51,7 +51,7 @@ jobs:
- name: Prepare package
run: |
cargo package -p tfhe
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: crate
path: target/package/*.crate
@@ -81,7 +81,7 @@ jobs:
# For provenance of npmjs publish
permissions:
contents: read
id-token: write
id-token: write # also needed for OIDC token exchange on crates.io
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -98,13 +98,16 @@ jobs:
with:
name: crate
path: target/package
- name: Authenticate on registry
uses: rust-lang/crates-io-auth-action@e919bc7605cde86df457cf5b93c5e103838bd879 # v1.0.1
id: auth
- name: Publish crate.io package
if: ${{ inputs.push_to_crates }}
env:
CRATES_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
DRY_RUN: ${{ inputs.dry_run && '--dry-run' || '' }}
run: |
cargo publish -p tfhe --token ${{ env.CRATES_TOKEN }} ${{ env.DRY_RUN }}
cargo publish -p tfhe ${{ env.DRY_RUN }}
- name: Generate hash
id: published_hash

View File

@@ -115,6 +115,9 @@ jobs:
name: Publish CUDA Release
needs: [setup-instance, package] # for comparing hashes
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
permissions:
# Needed for OIDC token exchange on crates.io
id-token: write
strategy:
fail-fast: false
# explicit include-based build matrix, of known valid options
@@ -152,12 +155,16 @@ jobs:
echo "HOME=/home/ubuntu";
} >> "${GITHUB_ENV}"
- name: Authenticate on registry
uses: rust-lang/crates-io-auth-action@e919bc7605cde86df457cf5b93c5e103838bd879 # v1.0.1
id: auth
- name: Publish crate.io package
env:
CRATES_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
DRY_RUN: ${{ inputs.dry_run && '--dry-run' || '' }}
run: |
cargo publish -p tfhe-cuda-backend --token ${{ env.CRATES_TOKEN }} ${{ env.DRY_RUN }}
cargo publish -p tfhe-cuda-backend ${{ env.DRY_RUN }}
- name: Generate hash
id: published_hash

View File

@@ -30,7 +30,7 @@ jobs:
- name: Prepare package
run: |
cargo package -p tfhe-csprng
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: crate-tfhe-csprng
path: target/package/*.crate
@@ -59,6 +59,9 @@ jobs:
name: Publish tfhe-csprng Release
needs: [verify_tag, package]
runs-on: ubuntu-latest
permissions:
# Needed for OIDC token exchange on crates.io
id-token: write
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -70,12 +73,15 @@ jobs:
with:
name: crate-tfhe-csprng
path: target/package
- name: Authenticate on registry
uses: rust-lang/crates-io-auth-action@e919bc7605cde86df457cf5b93c5e103838bd879 # v1.0.1
id: auth
- name: Publish crate.io package
env:
CRATES_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
DRY_RUN: ${{ inputs.dry_run && '--dry-run' || '' }}
run: |
cargo publish -p tfhe-csprng --token ${{ env.CRATES_TOKEN }} ${{ env.DRY_RUN }}
cargo publish -p tfhe-csprng ${{ env.DRY_RUN }}
- name: Generate hash
id: published_hash
run: cd target/package && echo "pub_hash=$(sha256sum ./*.crate | base64 -w0)" >> "${GITHUB_OUTPUT}"

View File

@@ -33,7 +33,7 @@ jobs:
- name: Prepare package
run: |
cargo package -p tfhe-fft
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: crate
path: target/package/*.crate
@@ -60,6 +60,9 @@ jobs:
name: Publish tfhe-fft Release
runs-on: ubuntu-latest
needs: [verify_tag, package] # for comparing hashes
permissions:
# Needed for OIDC token exchange on crates.io
id-token: write
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -67,12 +70,16 @@ jobs:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
- name: Authenticate on registry
uses: rust-lang/crates-io-auth-action@e919bc7605cde86df457cf5b93c5e103838bd879 # v1.0.1
id: auth
- name: Publish crate.io package
env:
CRATES_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
DRY_RUN: ${{ inputs.dry_run && '--dry-run' || '' }}
run: |
cargo publish -p tfhe-fft --token ${{ env.CRATES_TOKEN }} ${{ env.DRY_RUN }}
cargo publish -p tfhe-fft ${{ env.DRY_RUN }}
- name: Generate hash
id: published_hash

View File

@@ -33,7 +33,7 @@ jobs:
- name: Prepare package
run: |
cargo package -p tfhe-ntt
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: crate
path: target/package/*.crate
@@ -60,18 +60,25 @@ jobs:
name: Publish tfhe-ntt Release
runs-on: ubuntu-latest
needs: [verify_tag, package] # for comparing hashes
permissions:
# Needed for OIDC token exchange on crates.io
id-token: write
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- name: Authenticate on registry
uses: rust-lang/crates-io-auth-action@e919bc7605cde86df457cf5b93c5e103838bd879 # v1.0.1
id: auth
- name: Publish crate.io package
env:
CRATES_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
DRY_RUN: ${{ inputs.dry_run && '--dry-run' || '' }}
run: |
cargo publish -p tfhe-ntt --token ${{ env.CRATES_TOKEN }} ${{ env.DRY_RUN }}
cargo publish -p tfhe-ntt ${{ env.DRY_RUN }}
- name: Generate hash
id: published_hash

View File

@@ -2,14 +2,13 @@ name: Publish tfhe-versionable release
on:
workflow_dispatch:
inputs:
dry_run:
description: "Dry-run"
type: boolean
default: true
env:
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
jobs:
verify_tag:
@@ -19,6 +18,7 @@ jobs:
READ_ORG_TOKEN: ${{ secrets.READ_ORG_TOKEN }}
package-derive:
name: Package tfhe-versionable-derive Release
runs-on: ubuntu-latest
outputs:
hash: ${{ steps.hash.outputs.hash }}
@@ -30,7 +30,7 @@ jobs:
- name: Prepare package
run: |
cargo package -p tfhe-versionable-derive
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: crate-tfhe-versionable-derive
path: target/package/*.crate
@@ -53,9 +53,12 @@ jobs:
base64-subjects: ${{ needs.package-derive.outputs.hash }}
publish_release-derive:
name: Publish tfhe-versionable Release
needs: [verify_tag, package-derive] # for comparing hashes
name: Publish tfhe-versionable-derive Release
needs: [ verify_tag, package-derive ] # for comparing hashes
runs-on: ubuntu-latest
permissions:
# Needed for OIDC token exchange on crates.io
id-token: write
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -68,11 +71,14 @@ jobs:
with:
name: crate-tfhe-versionable-derive
path: target/package
- name: Authenticate on registry
uses: rust-lang/crates-io-auth-action@e919bc7605cde86df457cf5b93c5e103838bd879 # v1.0.1
id: auth
- name: Publish crate.io package
env:
CRATES_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: |
cargo publish -p tfhe-versionable-derive --token ${{ env.CRATES_TOKEN }} ${{ env.DRY_RUN }}
cargo publish -p tfhe-versionable-derive
- name: Generate hash
id: published_hash
run: cd target/package && echo "pub_hash=$(sha256sum ./*.crate | base64 -w0)" >> "${GITHUB_OUTPUT}"
@@ -82,24 +88,18 @@ jobs:
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990 # v2.3.2
env:
SLACK_COLOR: failure
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
SLACK_MESSAGE: "SLSA tfhe-versionable-derive - hash comparison failure: (${{ env.ACTION_RUN_URL }})"
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990 # v2.3.2
env:
SLACK_COLOR: ${{ job.status }}
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
SLACK_MESSAGE: "tfhe-versionable-derive release finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
package:
name: Package tfhe-versionable Release
needs: publish_release-derive
runs-on: ubuntu-latest
outputs:
hash: ${{ steps.hash.outputs.hash }}
@@ -111,7 +111,7 @@ jobs:
- name: Prepare package
run: |
cargo package -p tfhe-versionable
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: crate-tfhe-versionable
path: target/package/*.crate
@@ -120,7 +120,7 @@ jobs:
run: cd target/package && echo "hash=$(sha256sum ./*.crate | base64 -w0)" >> "${GITHUB_OUTPUT}"
provenance:
needs: [package]
needs: package
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
permissions:
# Needed to detect the GitHub Actions environment
@@ -135,7 +135,7 @@ jobs:
publish_release:
name: Publish tfhe-versionable Release
needs: [package] # for comparing hashes
needs: package # for comparing hashes
runs-on: ubuntu-latest
steps:
- name: Checkout
@@ -147,36 +147,28 @@ jobs:
with:
name: crate-tfhe-versionable
path: target/package
- name: Authenticate on registry
uses: rust-lang/crates-io-auth-action@e919bc7605cde86df457cf5b93c5e103838bd879 # v1.0.1
id: auth
- name: Publish crate.io package
env:
CRATES_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
run: |
cargo publish -p tfhe-versionable --token ${{ env.CRATES_TOKEN }} ${{ env.DRY_RUN }}
cargo publish -p tfhe-versionable
- name: Generate hash
id: published_hash
run: cd target/package && echo "pub_hash=$(sha256sum ./*.crate | base64 -w0)" >> "${GITHUB_OUTPUT}"
- name: Slack notification (hashes comparison)
if: ${{ needs.package.outputs.hash != steps.published_hash.outputs.pub_hash }}
continue-on-error: true
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990 # v2.3.2
env:
SLACK_COLOR: failure
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
SLACK_MESSAGE: "SLSA tfhe-versionable - hash comparison failure: (${{ env.ACTION_RUN_URL }})"
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990 # v2.3.2
env:
SLACK_COLOR: ${{ job.status }}
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
SLACK_ICON: https://pbs.twimg.com/profile_images/1274014582265298945/OjBKP9kn_400x400.png
SLACK_MESSAGE: "tfhe-versionable release finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
SLACK_USERNAME: ${{ secrets.BOT_USERNAME }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}

View File

@@ -24,7 +24,7 @@ jobs:
- name: Prepare package
run: |
cargo package -p tfhe-zk-pok
- uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
- uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
name: crate-zk-pok
path: target/package/*.crate
@@ -56,6 +56,9 @@ jobs:
name: Publish tfhe-zk-pok Release
needs: [verify_tag, package] # for comparing hashes
runs-on: ubuntu-latest
permissions:
# Needed for OIDC token exchange on crates.io
id-token: write
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
@@ -68,12 +71,15 @@ jobs:
with:
name: crate-zk-pok
path: target/package
- name: Authenticate on registry
uses: rust-lang/crates-io-auth-action@e919bc7605cde86df457cf5b93c5e103838bd879 # v1.0.1
id: auth
- name: Publish crate.io package
env:
CRATES_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
DRY_RUN: ${{ inputs.dry_run && '--dry-run' || '' }}
run: |
cargo publish -p tfhe-zk-pok --token ${{ env.CRATES_TOKEN }} ${{ env.DRY_RUN }}
cargo publish -p tfhe-zk-pok ${{ env.DRY_RUN }}
- name: Verify hash
id: published_hash
run: cd target/package && echo "pub_hash=$(sha256sum ./*.crate | base64 -w0)" >> "${GITHUB_OUTPUT}"

1
.gitignore vendored
View File

@@ -37,3 +37,4 @@ package-lock.json
# Dir used for backward compatibility test data
tests/tfhe-backward-compat-data/
ci/

233
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,233 @@
# Contributing to TFHE-rs
This document provides guidance on how to contribute to **TFHE-rs**.
There are two ways to contribute:
- **Report issues:** Open issues on GitHub to report bugs, suggest improvements, or note typos.
- **Submit codes**: To become an official contributor, you must sign our Contributor License Agreement (CLA). Our CLA-bot will guide you through this process when you open your first pull request.
## 1. Setting up the project
Start by [forking](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo) the **TFHE-rs** repository.
{% hint style="info" %}
- **Rust version**: Ensure that you use a Rust version >= 1.81 to compile **TFHE-rs**.
- **Incompatibility**: AArch64-based machines are not yet supported for Windows as it's currently missing an entropy source to be able to seed the [CSPRNGs](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator) used in **TFHE-rs**.
- **Performance**: For optimal performance, it is highly recommended to run **TFHE-rs** code in release mode with cargo's `--release` flag.
{% endhint %}
To get more details about the library, please refer to the [documentation](https://docs.zama.ai/tfhe-rs).
## 2. Creating a new branch
When creating your branch, make sure to use the following format :
```
git checkout -b {feat|fix|docs|chore…}/short_description
```
For example:
```
git checkout -b feat/new_feature_X
```
## 3. Before committing
### 3.1 Linting
Each commit to **TFHE-rs** should conform to the standards of the project. In particular, every source code, docker or workflows files should be linted to prevent programmatic and stylistic errors.
- Rust source code linters: `clippy`
- Typescript/Javascript source code linters: `eslint`, `prettier`
To apply automatic code formatting, run:
```
make fmt
```
You can perform linting of all Cargo targets with:
```
make clippy_all_targets
```
### 3.2 Testing
Your contributions must include comprehensive documentation and tests without breaking existing tests. To run pre-commit checks, execute:
```
make pcc
```
This command ensure that all the targets in the library are building correctly.
For a faster check, use:
```
make fpcc
```
If you're contributing to GPU code, run also:
```
make pcc_gpu
```
Unit testing suites are heavy and can require a lot of computing power and RAM availability.
Whilst tests are run automatically in continuous integration pipeline, you can run tests locally.
All unit tests have a command formatted as:
```
make test_*
```
Run `make help` to display a list of all the commands available.
To quickly test your changes locally, follow these steps:
1. Locate where the code has changed.
2. Add (or modify) a Cargo test filter to the corresponding `make` target in Makefile.
3. Run the target.
{% hint style="success" %}
`make test_<something>` will print the underlying cargo command in STDOUT. You can quickly test your changes by copy/pasting the command and then modify it to suit your needs.
{% endhint %}
For example, if you made changes in `tfhe/src/integer/*`, you can test them with the following steps:
1. In `test_integer` target, replace the filter `-- integer::` by `-- my_new_test`.
2. Run `make test_integer`.
## 4. Committing
**TFHE-rs** follows the conventional commit specification to maintain a consistent commit history, essential for Semantic Versioning ([semver.org](https://semver.org/)).
Commit messages are automatically checked in CI and will be rejected if they do not comply, so make sure that you follow the commit conventions detailed on [this page]
(https://www.conventionalcommits.org/en/v1.0.0/).
## 5. Rebasing
Before creating a pull request, rebase your branch on the repository's `main` branch. Merge commits are not permitted, thus rebasing ensures fewer conflicts and a smoother PR review process.
## 6. Opening a Pull Request
Once your changes are ready, open a pull request.
For instructions on creating a PR from a fork, refer to GitHub's [official documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork).
## 7. Continuous integration
Before a pull request can be merged, several test suites run automatically. Below is an overview of the CI process:
```mermaid
---
title: Continuous Integration Process
---
sequenceDiagram
autonumber
participant Contributor
participant GitHub
participant Reviewer
participant CI-pipeline
Contributor ->> GitHub: Open pull-request
GitHub -->> Contributor: Ask for CLA signing (once)
loop
Reviewer ->> GitHub: Review code
Reviewer ->> CI-pipeline: Approve workflows (short-run)
CI-pipeline -->> GitHub: Send checks results
Contributor ->> GitHub: Make changes
end
Reviewer ->> GitHub: Pull-request approval
Reviewer ->> CI-pipeline: Approve workflows (long-run)
CI-pipeline -->> GitHub: Send checks results
Reviewer -->> GitHub: Merge if pipeline green
```
> [!Note]
>Useful details:
>* pipeline is triggered by humans
>* review team is located in Paris timezone, pipeline launch will most likely happen during office hours
>* direct changes to CI related files are not allowed for external contributors
>* run `make pcc` to fix any build errors before pushing commits
## 8. Data versioning
Data serialized with TFHE-rs must remain backward compatible. This is done using the [tfhe-versionable](https://crates.io/crates/tfhe-versionable) crate.
If you modify a type that derives `Versionize` in a backward-incompatible way, an upgrade implementation must be provided.
For example, these changes are data breaking:
* Adding a field to a struct.
* Changing the order of the fields within a struct or the variants within an enum.
* Renaming a field of a struct or a variant of an enum.
* Changing the type of field in a struct or a variant in an enum.
On the contrary, these changes are *not* data breaking:
* Renaming a type (unless it implements the `Named` trait).
* Adding a variant to the end of an enum.
## Example: adding a field
Suppose you want to add an i32 field to a type named `MyType`. The original type is defined as:
```rust
#[derive(Serialize, Deserialize, Versionize)]
#[versionize(MyTypeVersions)]
struct MyType {
val: u64,
}
```
And you want to change it to:
```rust
#[derive(Serialize, Deserialize, Versionize)]
#[versionize(MyTypeVersions)]
struct MyType {
val: u64,
other_val: i32
}
```
Follow these steps:
1. Navigate to the definition of the dispatch enum of this type. This is the type inside the `#[versionize(MyTypeVersions)]` macro attribute. In general, this type has the same name as the base type with a `Versions` suffix. You should find something like
```rust
#[derive(VersionsDispatch)]
enum MyTypeVersions {
V0(MyTypeV0),
V1(MyType)
}
```
2. Add a new variant to the enum to preserve the previous version of the type. You can simply copy and paste the previous definition of the type and add a version suffix:
```rust
#[derive(Version)]
struct MyTypeV1 {
val: u64,
}
#[derive(VersionsDispatch)]
enum MyTypeVersions {
V0(MyTypeV0),
V1(MyTypeV1),
V2(MyType) // Here this points to your modified type
}
```
3. Implement the `Upgrade` trait to define how we should go from the previous version to the current version:
```rust
impl Upgrade<MyType> for MyTypeV1 {
type Error = Infallible;
fn upgrade(self) -> Result<MyType, Self::Error> {
Ok(MyType {
val: self.val,
other_val: 0
})
}
}
```
4. Fix the upgrade target of the previous version. In this example, `impl Upgrade<MyType> for MyTypeV0 {` should simply be changed to `impl Upgrade<MyTypeV1> for MyTypeV0 {`

View File

@@ -21,9 +21,9 @@ bytemuck = "1.14.3"
dyn-stack = { version = "0.11", default-features = false }
itertools = "0.14"
num-complex = "0.4"
pulp = { version = "0.20", default-features = false }
pulp = { version = ">=0.21, <0.21.5", default-features = false }
rand = "0.8"
rayon = "1"
rayon = "1.11"
serde = { version = "1.0", default-features = false }
wasm-bindgen = "0.2.100"

View File

@@ -18,6 +18,8 @@ FAST_BENCH?=FALSE
NIGHTLY_TESTS?=FALSE
BENCH_OP_FLAVOR?=DEFAULT
BENCH_TYPE?=latency
BENCH_PARAM_TYPE?=classical
BENCH_PARAMS_SET?=default
NODE_VERSION=22.6
BACKWARD_COMPAT_DATA_URL=https://github.com/zama-ai/tfhe-backward-compat-data.git
BACKWARD_COMPAT_DATA_BRANCH?=$(shell ./scripts/backward_compat_data_version.py)
@@ -431,6 +433,7 @@ clippy_versionable: install_rs_check_toolchain
.PHONY: clippy_tfhe_lints # Run clippy lints on tfhe-lints
clippy_tfhe_lints: install_cargo_dylint # the toolchain is selected with toolchain.toml
cd utils/tfhe-lints && \
rustup toolchain install && \
cargo clippy --all-targets -- --no-deps -D warnings
.PHONY: clippy_all # Run all clippy targets
@@ -907,6 +910,7 @@ test_versionable: install_rs_build_toolchain
.PHONY: test_tfhe_lints # Run test on tfhe-lints
test_tfhe_lints: install_cargo_dylint
cd utils/tfhe-lints && \
rustup toolchain install && \
cargo test
# The backward compat data repo holds historical binary data but also rust code to generate and load them.
@@ -1171,10 +1175,24 @@ bench_boolean: install_rs_check_toolchain
.PHONY: bench_pbs # Run benchmarks for PBS
bench_pbs: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_PARAMS_SET=$(BENCH_PARAMS_SET) cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
--bench pbs-bench \
--features=boolean,shortint,internal-keycache,nightly-avx512 -p $(TFHE_SPEC)
.PHONY: bench_ks_pbs # Run benchmarks for KS-PBS
bench_ks_pbs: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_PARAM_TYPE=$(BENCH_PARAM_TYPE) __TFHE_RS_PARAMS_SET=$(BENCH_PARAMS_SET) \
cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
--bench ks-pbs-bench \
--features=boolean,shortint,internal-keycache,nightly-avx512 -p $(TFHE_SPEC)
.PHONY: bench_ks_pbs_gpu # Run benchmarks for KS-PBS on GPU backend
bench_ks_pbs_gpu: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_PARAM_TYPE=$(BENCH_PARAM_TYPE) __TFHE_RS_PARAMS_SET=$(BENCH_PARAMS_SET) \
cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
--bench ks-pbs-bench \
--features=boolean,shortint,gpu,internal-keycache,nightly-avx512 -p $(TFHE_SPEC)
.PHONY: bench_pbs128 # Run benchmarks for PBS using FFT 128 bits
bench_pbs128: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
@@ -1183,19 +1201,20 @@ bench_pbs128: install_rs_check_toolchain
.PHONY: bench_pbs_gpu # Run benchmarks for PBS on GPU backend
bench_pbs_gpu: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_FAST_BENCH=$(FAST_BENCH) cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_FAST_BENCH=$(FAST_BENCH) __TFHE_RS_PARAMS_SET=$(BENCH_PARAMS_SET) \
cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
--bench pbs-bench \
--features=boolean,shortint,gpu,internal-keycache,nightly-avx512 -p $(TFHE_SPEC)
.PHONY: bench_ks # Run benchmarks for keyswitch
bench_ks: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_PARAMS_SET=$(BENCH_PARAMS_SET) cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
--bench ks-bench \
--features=boolean,shortint,internal-keycache,nightly-avx512 -p $(TFHE_SPEC)
.PHONY: bench_ks_gpu # Run benchmarks for PBS on GPU backend
bench_ks_gpu: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
RUSTFLAGS="$(RUSTFLAGS)" __TFHE_RS_PARAMS_SET=$(BENCH_PARAMS_SET) cargo $(CARGO_RS_CHECK_TOOLCHAIN) bench \
--bench ks-bench \
--features=boolean,shortint,gpu,internal-keycache,nightly-avx512 -p $(TFHE_SPEC)

View File

@@ -10,7 +10,7 @@
<hr/>
<p align="center">
<a href="https://docs.zama.ai/tfhe-rs"> 📒 Documentation</a> | <a href="https://zama.ai/community"> 💛 Community support</a> | <a href="https://github.com/zama-ai/awesome-zama"> 📚 FHE resources by Zama</a>
<a href="https://github.com/zama-ai/tfhe-rs-handbook/blob/main/tfhe-rs-handbook.pdf"> 📃 Read Handbook</a> |<a href="https://docs.zama.ai/tfhe-rs"> 📒 Documentation</a> | <a href="https://zama.ai/community"> 💛 Community support</a> | <a href="https://github.com/zama-ai/awesome-zama"> 📚 FHE resources by Zama</a>
</p>
@@ -67,6 +67,9 @@ production-ready library for all the advanced features of TFHE.
## Getting started
> [!Important]
> **TFHE-rs** released its first stable version v1.0.0 in February 2025, stabilizing the high-level API for the x86 CPU backend.
### Cargo.toml configuration
To use the latest version of `TFHE-rs` in your project, you first need to add it as a dependency in your `Cargo.toml`:
@@ -75,13 +78,13 @@ tfhe = { version = "*", features = ["boolean", "shortint", "integer"] }
```
> [!Note]
> Note: You need to use a Rust version >= 1.81 to compile TFHE-rs.
> Note: You need to use Rust version >= 1.84 to compile TFHE-rs.
> [!Note]
> Note: aarch64-based machines are not yet supported for Windows as it's currently missing an entropy source to be able to seed the [CSPRNGs](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator) used in TFHE-rs.
> Note: AArch64-based machines are not supported for Windows as it's currently missing an entropy source to be able to seed the [CSPRNGs](https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator) used in TFHE-rs.
<p align="right">
<a href="#about" > ↑ Back to top </a>
<a href="#about" > ↑ Back to top </a>
</p>
### A simple example
@@ -138,7 +141,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}
```
To run this code, use the following command:
To run this code, use the following command:
<p align="center"> <code> cargo run --release </code> </p>
> [!Note]
@@ -148,12 +151,15 @@ to run in release mode with cargo's `--release` flag to have the best performanc
*Find an example with more explanations in [this part of the documentation](https://docs.zama.ai/tfhe-rs/get-started/quick_start)*
<p align="right">
<a href="#about" > ↑ Back to top </a>
<a href="#about" > ↑ Back to top </a>
</p>
## Resources
## Resources
### TFHE-rs Handbook
A document containing scientific and technical details about algorithms implemented into the library is available here: [TFHE-rs: A (Practical) Handbook](https://github.com/zama-ai/tfhe-rs-handbook/blob/main/tfhe-rs-handbook.pdf).
### TFHE deep dive
- [TFHE Deep Dive - Part I - Ciphertext types](https://www.zama.ai/post/tfhe-deep-dive-part-1)
@@ -176,7 +182,7 @@ to run in release mode with cargo's `--release` flag to have the best performanc
Full, comprehensive documentation is available here: [https://docs.zama.ai/tfhe-rs](https://docs.zama.ai/tfhe-rs).
<p align="right">
<a href="#about" > ↑ Back to top </a>
<a href="#about" > ↑ Back to top </a>
</p>
@@ -194,9 +200,13 @@ When a new update is published in the Lattice Estimator, we update parameters ac
### Security model
The default parameters for the TFHE-rs library are chosen considering the IND-CPA security model, and are selected with a bootstrapping failure probability fixed at p_error = $2^{-64}$. In particular, it is assumed that the results of decrypted computations are not shared by the secret key owner with any third parties, as such an action can lead to leakage of the secret encryption key. If you are designing an application where decryptions must be shared, you will need to craft custom encryption parameters which are chosen in consideration of the IND-CPA^D security model [1].
By default, the parameter sets used in the High-Level API with the x86 CPU backend have a failure probability $\le 2^{128}$ to securely work in the IND-CPA^D model using the algorithmic techniques provided in our code base [1].
If you want to work within the IND-CPA security model, which is less strict than the IND-CPA-D model, the parameter sets can easily be changed and would have slightly better performance. More details can be found in the [TFHE-rs documentation](https://docs.zama.ai/tfhe-rs).
[1] Li, Baiyu, et al. "Securing approximate homomorphic encryption using differential privacy." Annual International Cryptology Conference. Cham: Springer Nature Switzerland, 2022. https://eprint.iacr.org/2022/816.pdf
The default parameters used in the High-Level API with the GPU backend are chosen considering the IND-CPA security model, and are selected with a bootstrapping failure probability fixed at $p_{error} \le 2^{-64}$. In particular, it is assumed that the results of decrypted computations are not shared by the secret key owner with any third parties, as such an action can lead to leakage of the secret encryption key. If you are designing an application where decryptions must be shared, you will need to craft custom encryption parameters which are chosen in consideration of the IND-CPA^D security model [2].
[1] Bernard, Olivier, et al. "Drifting Towards Better Error Probabilities in Fully Homomorphic Encryption Schemes". https://eprint.iacr.org/2024/1718.pdf
[2] Li, Baiyu, et al. "Securing approximate homomorphic encryption using differential privacy." Annual International Cryptology Conference. Cham: Springer Nature Switzerland, 2022. https://eprint.iacr.org/2022/816.pdf
#### Side-channel attacks
@@ -245,7 +255,7 @@ This software is distributed under the **BSD-3-Clause-Clear** license. Read [thi
>We are open to collaborating and advancing the FHE space with our partners. If you have specific needs, please email us at hello@zama.ai.
<p align="right">
<a href="#about" > ↑ Back to top </a>
<a href="#about" > ↑ Back to top </a>
</p>
@@ -259,8 +269,8 @@ This software is distributed under the **BSD-3-Clause-Clear** license. Read [thi
</picture>
</a>
🌟 If you find this project helpful or interesting, please consider giving it a star on GitHub! Your support helps to grow the community and motivates further development.
🌟 If you find this project helpful or interesting, please consider giving it a star on GitHub! Your support helps to grow the community and motivates further development.
<p align="right">
<a href="#about" > ↑ Back to top </a>
<a href="#about" > ↑ Back to top </a>
</p>

View File

@@ -48,6 +48,8 @@ fn transcipher_from_1_1_stream(
) -> FheUint64 {
assert_eq!(stream.len(), 64);
let id_lut = internal_server_key.generate_lookup_table(|x| x);
let pairs = (0..32)
.into_par_iter()
.map(|i| {
@@ -57,10 +59,11 @@ fn transcipher_from_1_1_stream(
let b0 = &stream[8 * byte_idx + 2 * pair_idx];
let b1 = &stream[8 * byte_idx + 2 * pair_idx + 1];
casting_key.cast(
&internal_server_key
.unchecked_add(b0, &internal_server_key.unchecked_scalar_mul(b1, 2)),
)
let mut combined = internal_server_key
.unchecked_add(b0, &internal_server_key.unchecked_scalar_mul(b1, 2));
internal_server_key.apply_lookup_table_assign(&mut combined, &id_lut);
casting_key.cast(&combined)
})
.collect::<Vec<_>>();

View File

@@ -1,6 +1,6 @@
[package]
name = "tfhe-cuda-backend"
version = "0.8.0"
version = "0.8.1"
edition = "2021"
authors = ["Zama team"]
license = "BSD-3-Clause-Clear"

View File

@@ -13,24 +13,26 @@ and forth between the CPU and the GPU, to create and destroy Cuda streams, etc.:
- `cuda_get_number_of_gpus`
- `cuda_synchronize_device`
The cryptographic operations it provides are:
- an amortized implementation of the TFHE programmable bootstrap: `cuda_bootstrap_amortized_lwe_ciphertext_vector_32` and `cuda_bootstrap_amortized_lwe_ciphertext_vector_64`
- a low latency implementation of the TFHE programmable bootstrap: `cuda_bootstrap_low latency_lwe_ciphertext_vector_32` and `cuda_bootstrap_low_latency_lwe_ciphertext_vector_64`
- the keyswitch: `cuda_keyswitch_lwe_ciphertext_vector_32` and `cuda_keyswitch_lwe_ciphertext_vector_64`
- the larger precision programmable bootstrap (wop PBS, which supports up to 16 bits of message while the classical PBS only supports up to 8 bits of message) and its sub-components: `cuda_wop_pbs_64`, `cuda_extract_bits_64`, `cuda_circuit_bootstrap_64`, `cuda_cmux_tree_64`, `cuda_blind_rotation_sample_extraction_64`
- acceleration for leveled operations: `cuda_negate_lwe_ciphertext_vector_64`, `cuda_add_lwe_ciphertext_vector_64`, `cuda_add_lwe_ciphertext_vector_plaintext_vector_64`, `cuda_mult_lwe_ciphertext_vector_cleartext_vector`.
- an implementation of the classical TFHE programmable bootstrap,
- an implementation of the multi-bit TFHE programmable bootstrap,
- the keyswitch,
- acceleration for leveled operations,
- acceleration for arithmetics over encrypted integers of arbitrary size,
- acceleration for integer compression/decompression.
## Dependencies
**Disclaimer**: Compilation on Windows/Mac is not supported yet. Only Nvidia GPUs are supported.
- nvidia driver - for example, if you're running Ubuntu 20.04 check this [page](https://linuxconfig.org/how-to-install-the-nvidia-drivers-on-ubuntu-20-04-focal-fossa-linux) for installation
- nvidia driver - for example, if you're running Ubuntu 20.04 check this [page](https://linuxconfig.org/how-to-install-the-nvidia-drivers-on-ubuntu-20-04-focal-fossa-linux) for installation. You need an Nvidia GPU with Compute Capability >= 3.0
- [nvcc](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html) >= 10.0
- [gcc](https://gcc.gnu.org/) >= 8.0 - check this [page](https://gist.github.com/ax3l/9489132) for more details about nvcc/gcc compatible versions
- [cmake](https://cmake.org/) >= 3.24
- libclang, to match Rust bingen [requirements](https://rust-lang.github.io/rust-bindgen/requirements.html) >= 9.0
## Build
The Cuda project held in `tfhe-cuda-backend` can be compiled independently from TFHE-rs in the following way:
The Cuda project held in `tfhe-cuda-backend` can be compiled independently of TFHE-rs in the following way:
```
git clone git@github.com:zama-ai/tfhe-rs
cd backends/tfhe-cuda-backend/cuda

View File

@@ -18,7 +18,7 @@ void cuda_convert_lwe_ciphertext_vector_to_cpu_64(void *stream,
void cuda_glwe_sample_extract_64(void *stream, uint32_t gpu_index,
void *lwe_array_out, void const *glwe_array_in,
uint32_t const *nth_array, uint32_t num_nths,
uint32_t glwe_dimension,
uint32_t lwe_per_glwe, uint32_t glwe_dimension,
uint32_t polynomial_size);
}
#endif

View File

@@ -102,9 +102,7 @@ template <typename Torus> struct int_decompression {
// Example: in the 2_2 case we are mapping a 2 bits message onto a 4 bits
// space, we want to keep the original 2 bits value in the 4 bits space,
// so we apply the identity and the encoding will rescale it for us.
auto decompression_rescale_f = [encryption_params](Torus x) -> Torus {
return x;
};
auto decompression_rescale_f = [](Torus x) -> Torus { return x; };
auto effective_compression_message_modulus =
encryption_params.carry_modulus;

View File

@@ -4728,4 +4728,5 @@ void update_degrees_after_scalar_bitxor(uint64_t *output_degrees,
uint64_t *clear_degrees,
uint64_t *input_degrees,
uint32_t num_clear_blocks);
std::pair<bool, bool> get_invert_flags(COMPARISON_TYPE compare);
#endif // CUDA_INTEGER_UTILITIES_H

View File

@@ -24,7 +24,7 @@ void cuda_convert_lwe_ciphertext_vector_to_cpu_64(void *stream,
void cuda_glwe_sample_extract_64(void *stream, uint32_t gpu_index,
void *lwe_array_out, void const *glwe_array_in,
uint32_t const *nth_array, uint32_t num_nths,
uint32_t glwe_dimension,
uint32_t lwe_per_glwe, uint32_t glwe_dimension,
uint32_t polynomial_size) {
switch (polynomial_size) {
@@ -32,43 +32,43 @@ void cuda_glwe_sample_extract_64(void *stream, uint32_t gpu_index,
host_sample_extract<uint64_t, AmortizedDegree<256>>(
static_cast<cudaStream_t>(stream), gpu_index, (uint64_t *)lwe_array_out,
(uint64_t const *)glwe_array_in, (uint32_t const *)nth_array, num_nths,
glwe_dimension);
lwe_per_glwe, glwe_dimension);
break;
case 512:
host_sample_extract<uint64_t, AmortizedDegree<512>>(
static_cast<cudaStream_t>(stream), gpu_index, (uint64_t *)lwe_array_out,
(uint64_t const *)glwe_array_in, (uint32_t const *)nth_array, num_nths,
glwe_dimension);
lwe_per_glwe, glwe_dimension);
break;
case 1024:
host_sample_extract<uint64_t, AmortizedDegree<1024>>(
static_cast<cudaStream_t>(stream), gpu_index, (uint64_t *)lwe_array_out,
(uint64_t const *)glwe_array_in, (uint32_t const *)nth_array, num_nths,
glwe_dimension);
lwe_per_glwe, glwe_dimension);
break;
case 2048:
host_sample_extract<uint64_t, AmortizedDegree<2048>>(
static_cast<cudaStream_t>(stream), gpu_index, (uint64_t *)lwe_array_out,
(uint64_t const *)glwe_array_in, (uint32_t const *)nth_array, num_nths,
glwe_dimension);
lwe_per_glwe, glwe_dimension);
break;
case 4096:
host_sample_extract<uint64_t, AmortizedDegree<4096>>(
static_cast<cudaStream_t>(stream), gpu_index, (uint64_t *)lwe_array_out,
(uint64_t const *)glwe_array_in, (uint32_t const *)nth_array, num_nths,
glwe_dimension);
lwe_per_glwe, glwe_dimension);
break;
case 8192:
host_sample_extract<uint64_t, AmortizedDegree<8192>>(
static_cast<cudaStream_t>(stream), gpu_index, (uint64_t *)lwe_array_out,
(uint64_t const *)glwe_array_in, (uint32_t const *)nth_array, num_nths,
glwe_dimension);
lwe_per_glwe, glwe_dimension);
break;
case 16384:
host_sample_extract<uint64_t, AmortizedDegree<16384>>(
static_cast<cudaStream_t>(stream), gpu_index, (uint64_t *)lwe_array_out,
(uint64_t const *)glwe_array_in, (uint32_t const *)nth_array, num_nths,
glwe_dimension);
lwe_per_glwe, glwe_dimension);
break;
default:
PANIC("Cuda error: unsupported polynomial size. Supported "

View File

@@ -28,7 +28,7 @@ void cuda_convert_lwe_ciphertext_vector_to_cpu(cudaStream_t stream,
template <typename Torus, class params>
__global__ void sample_extract(Torus *lwe_array_out, Torus const *glwe_array_in,
uint32_t const *nth_array,
uint32_t const *nth_array, uint32_t lwe_per_glwe,
uint32_t glwe_dimension) {
const int input_id = blockIdx.x;
@@ -39,28 +39,28 @@ __global__ void sample_extract(Torus *lwe_array_out, Torus const *glwe_array_in,
auto lwe_out = lwe_array_out + input_id * lwe_output_size;
// We assume each GLWE will store the first polynomial_size inputs
uint32_t lwe_per_glwe = params::degree;
auto glwe_in = glwe_array_in + (input_id / lwe_per_glwe) * glwe_input_size;
// nth is ensured to be in [0, lwe_per_glwe)
auto nth = nth_array[input_id] % lwe_per_glwe;
// nth is ensured to be in [0, params::degree)
auto nth = nth_array[input_id] % params::degree;
sample_extract_mask<Torus, params>(lwe_out, glwe_in, glwe_dimension, nth);
sample_extract_body<Torus, params>(lwe_out, glwe_in, glwe_dimension, nth);
}
// lwe_per_glwe LWEs will be extracted per GLWE ciphertext, thus we need to have
// enough indexes
template <typename Torus, class params>
__host__ void host_sample_extract(cudaStream_t stream, uint32_t gpu_index,
Torus *lwe_array_out,
Torus const *glwe_array_in,
uint32_t const *nth_array, uint32_t num_nths,
uint32_t glwe_dimension) {
__host__ void
host_sample_extract(cudaStream_t stream, uint32_t gpu_index,
Torus *lwe_array_out, Torus const *glwe_array_in,
uint32_t const *nth_array, uint32_t num_nths,
uint32_t lwe_per_glwe, uint32_t glwe_dimension) {
cuda_set_device(gpu_index);
dim3 grid(num_nths);
dim3 thds(params::degree / params::opt);
sample_extract<Torus, params><<<grid, thds, 0, stream>>>(
lwe_array_out, glwe_array_in, nth_array, glwe_dimension);
lwe_array_out, glwe_array_in, nth_array, lwe_per_glwe, glwe_dimension);
check_cuda_error(cudaGetLastError());
}

View File

@@ -43,6 +43,9 @@ __global__ void pack(Torus *array_out, Torus *array_in, uint32_t log_modulus,
}
}
/// Packs `num_lwes` LWE-ciphertext contained in `num_glwes` GLWE-ciphertext in
/// a compressed array This function follows the naming used in the CPU
/// implementation
template <typename Torus>
__host__ void host_pack(cudaStream_t stream, uint32_t gpu_index,
Torus *array_out, Torus *array_in, uint32_t num_glwes,
@@ -55,26 +58,23 @@ __host__ void host_pack(cudaStream_t stream, uint32_t gpu_index,
auto log_modulus = mem_ptr->storage_log_modulus;
// [0..num_glwes-1) GLWEs
auto in_len = (compression_params.glwe_dimension + 1) *
compression_params.polynomial_size;
auto in_len = num_glwes * compression_params.glwe_dimension *
compression_params.polynomial_size +
num_lwes;
auto number_bits_to_pack = in_len * log_modulus;
auto nbits = sizeof(Torus) * 8;
// number_bits_to_pack.div_ceil(Scalar::BITS)
auto nbits = sizeof(Torus) * 8;
auto out_len = (number_bits_to_pack + nbits - 1) / nbits;
// Last GLWE
number_bits_to_pack = in_len * log_modulus;
auto last_out_len = (number_bits_to_pack + nbits - 1) / nbits;
auto num_coeffs = (num_glwes - 1) * out_len + last_out_len;
int num_blocks = 0, num_threads = 0;
getNumBlocksAndThreads(num_coeffs, 1024, num_blocks, num_threads);
getNumBlocksAndThreads(out_len, 1024, num_blocks, num_threads);
dim3 grid(num_blocks);
dim3 threads(num_threads);
pack<Torus><<<grid, threads, 0, stream>>>(array_out, array_in, log_modulus,
num_coeffs, in_len, out_len);
out_len, in_len, out_len);
check_cuda_error(cudaGetLastError());
}
@@ -99,14 +99,13 @@ host_integer_compress(cudaStream_t const *streams, uint32_t const *gpu_indexes,
uint32_t lwe_in_size = input_lwe_dimension + 1;
uint32_t glwe_out_size = (compression_params.glwe_dimension + 1) *
compression_params.polynomial_size;
uint32_t num_glwes_for_compression =
num_radix_blocks / mem_ptr->lwe_per_glwe + 1;
uint32_t num_glwes =
(num_radix_blocks + mem_ptr->lwe_per_glwe - 1) / mem_ptr->lwe_per_glwe;
// Keyswitch LWEs to GLWE
auto tmp_glwe_array_out = mem_ptr->tmp_glwe_array_out;
cuda_memset_async(tmp_glwe_array_out, 0,
num_glwes_for_compression *
(compression_params.glwe_dimension + 1) *
num_glwes * (compression_params.glwe_dimension + 1) *
compression_params.polynomial_size * sizeof(Torus),
streams[0], gpu_indexes[0]);
auto fp_ks_buffer = mem_ptr->fp_ks_buffer;
@@ -131,23 +130,21 @@ host_integer_compress(cudaStream_t const *streams, uint32_t const *gpu_indexes,
// Modulus switch
host_modulus_switch_inplace<Torus>(
streams[0], gpu_indexes[0], tmp_glwe_array_out,
num_glwes_for_compression * (compression_params.glwe_dimension + 1) *
compression_params.polynomial_size,
num_glwes * compression_params.glwe_dimension *
compression_params.polynomial_size +
num_radix_blocks,
mem_ptr->storage_log_modulus);
host_pack<Torus>(streams[0], gpu_indexes[0], glwe_array_out,
tmp_glwe_array_out, num_glwes_for_compression,
num_radix_blocks, mem_ptr);
tmp_glwe_array_out, num_glwes, num_radix_blocks, mem_ptr);
}
template <typename Torus>
__global__ void extract(Torus *glwe_array_out, Torus const *array_in,
uint32_t index, uint32_t log_modulus,
uint32_t input_len, uint32_t initial_out_len) {
uint32_t log_modulus, uint32_t initial_out_len) {
auto nbits = sizeof(Torus) * 8;
auto i = threadIdx.x + blockIdx.x * blockDim.x;
auto chunk_array_in = array_in + index * input_len;
if (i < initial_out_len) {
// Unpack
Torus mask = ((Torus)1 << log_modulus) - 1;
@@ -161,12 +158,11 @@ __global__ void extract(Torus *glwe_array_out, Torus const *array_in,
Torus unpacked_i;
if (start_block == end_block_inclusive) {
auto single_part = chunk_array_in[start_block] >> start_remainder;
auto single_part = array_in[start_block] >> start_remainder;
unpacked_i = single_part & mask;
} else {
auto first_part = chunk_array_in[start_block] >> start_remainder;
auto second_part = chunk_array_in[start_block + 1]
<< (nbits - start_remainder);
auto first_part = array_in[start_block] >> start_remainder;
auto second_part = array_in[start_block + 1] << (nbits - start_remainder);
unpacked_i = (first_part | second_part) & mask;
}
@@ -177,6 +173,7 @@ __global__ void extract(Torus *glwe_array_out, Torus const *array_in,
}
/// Extracts the glwe_index-nth GLWE ciphertext
/// This function follows the naming used in the CPU implementation
template <typename Torus>
__host__ void host_extract(cudaStream_t stream, uint32_t gpu_index,
Torus *glwe_array_out, Torus const *array_in,
@@ -188,36 +185,51 @@ __host__ void host_extract(cudaStream_t stream, uint32_t gpu_index,
cuda_set_device(gpu_index);
auto compression_params = mem_ptr->compression_params;
auto log_modulus = mem_ptr->storage_log_modulus;
auto glwe_ciphertext_size = (compression_params.glwe_dimension + 1) *
compression_params.polynomial_size;
uint32_t body_count = mem_ptr->body_count;
auto num_glwes = (body_count + compression_params.polynomial_size - 1) /
compression_params.polynomial_size;
// Compressed length of the compressed GLWE we want to extract
if (mem_ptr->body_count % compression_params.polynomial_size == 0)
body_count = compression_params.polynomial_size;
else if (glwe_index == num_glwes - 1)
body_count = mem_ptr->body_count % compression_params.polynomial_size;
else
body_count = compression_params.polynomial_size;
uint32_t body_count =
std::min(mem_ptr->body_count, compression_params.polynomial_size);
auto initial_out_len =
compression_params.glwe_dimension * compression_params.polynomial_size +
body_count;
auto compressed_glwe_accumulator_size =
(compression_params.glwe_dimension + 1) *
compression_params.polynomial_size;
auto number_bits_to_unpack = compressed_glwe_accumulator_size * log_modulus;
// Calculates how many bits this particular GLWE shall use
auto number_bits_to_unpack = initial_out_len * log_modulus;
auto nbits = sizeof(Torus) * 8;
// number_bits_to_unpack.div_ceil(Scalar::BITS)
auto input_len = (number_bits_to_unpack + nbits - 1) / nbits;
// We assure the tail of the glwe is zeroed
auto zeroed_slice = glwe_array_out + initial_out_len;
cuda_memset_async(zeroed_slice, 0,
(compression_params.polynomial_size - body_count) *
sizeof(Torus),
stream, gpu_index);
// Calculates how many bits a full-packed GLWE shall use
number_bits_to_unpack = glwe_ciphertext_size * log_modulus;
auto len = (number_bits_to_unpack + nbits - 1) / nbits;
// Uses that length to set the input pointer
auto chunk_array_in = array_in + glwe_index * len;
// Ensure the tail of the GLWE is zeroed
if (initial_out_len < glwe_ciphertext_size) {
auto zeroed_slice = glwe_array_out + initial_out_len;
cuda_memset_async(glwe_array_out, 0,
(glwe_ciphertext_size - initial_out_len) * sizeof(Torus),
stream, gpu_index);
}
int num_blocks = 0, num_threads = 0;
getNumBlocksAndThreads(initial_out_len, 128, num_blocks, num_threads);
dim3 grid(num_blocks);
dim3 threads(num_threads);
extract<Torus><<<grid, threads, 0, stream>>>(glwe_array_out, array_in,
glwe_index, log_modulus,
input_len, initial_out_len);
extract<Torus><<<grid, threads, 0, stream>>>(glwe_array_out, chunk_array_in,
log_modulus, initial_out_len);
check_cuda_error(cudaGetLastError());
}
@@ -235,18 +247,13 @@ __host__ void host_integer_decompress(
auto compression_params = h_mem_ptr->compression_params;
auto lwe_per_glwe = compression_params.polynomial_size;
if (indexes_array_size > lwe_per_glwe)
PANIC("Cuda error: too many LWEs to decompress. The number of LWEs should "
"be smaller than "
"polynomial_size.")
auto num_radix_blocks = h_mem_ptr->num_radix_blocks;
if (num_radix_blocks != indexes_array_size)
PANIC("Cuda error: wrong number of LWEs in decompress: the number of LWEs "
"should be the same as indexes_array_size.")
// the first element is the last index in h_indexes_array that lies in the
// related GLWE
// the first element is the number of LWEs that lies in the related GLWE
std::vector<std::pair<int, Torus *>> glwe_vec;
// Extract all GLWEs
@@ -257,7 +264,7 @@ __host__ void host_integer_decompress(
auto extracted_glwe = h_mem_ptr->tmp_extracted_glwe;
host_extract<Torus>(streams[0], gpu_indexes[0], extracted_glwe,
d_packed_glwe_in, current_glwe_index, h_mem_ptr);
glwe_vec.push_back(std::make_pair(0, extracted_glwe));
glwe_vec.push_back(std::make_pair(1, extracted_glwe));
for (int i = 1; i < indexes_array_size; i++) {
auto glwe_index = h_indexes_array[i] / lwe_per_glwe;
if (glwe_index != current_glwe_index) {
@@ -266,10 +273,10 @@ __host__ void host_integer_decompress(
// Extracts a new GLWE
host_extract<Torus>(streams[0], gpu_indexes[0], extracted_glwe,
d_packed_glwe_in, glwe_index, h_mem_ptr);
glwe_vec.push_back(std::make_pair(i, extracted_glwe));
glwe_vec.push_back(std::make_pair(1, extracted_glwe));
} else {
// Updates the index
glwe_vec.back().first++;
// Updates the quantity
++glwe_vec.back().first;
}
}
// Sample extract all LWEs
@@ -279,17 +286,16 @@ __host__ void host_integer_decompress(
uint32_t current_idx = 0;
auto d_indexes_array_chunk = d_indexes_array;
for (const auto &max_idx_and_glwe : glwe_vec) {
uint32_t last_idx = max_idx_and_glwe.first;
const auto num_lwes = max_idx_and_glwe.first;
extracted_glwe = max_idx_and_glwe.second;
auto num_lwes = last_idx + 1 - current_idx;
cuda_glwe_sample_extract_64(streams[0], gpu_indexes[0], extracted_lwe,
extracted_glwe, d_indexes_array_chunk, num_lwes,
compression_params.glwe_dimension,
compression_params.polynomial_size);
cuda_glwe_sample_extract_64(
streams[0], gpu_indexes[0], extracted_lwe, extracted_glwe,
d_indexes_array_chunk, num_lwes, compression_params.polynomial_size,
compression_params.glwe_dimension, compression_params.polynomial_size);
d_indexes_array_chunk += num_lwes;
extracted_lwe += num_lwes * lwe_accumulator_size;
current_idx = last_idx;
current_idx += num_lwes;
}
// Reset

View File

@@ -575,8 +575,8 @@ __host__ void host_unsigned_integer_div_rem_kb(
cuda_synchronize_stream(mem_ptr->sub_streams_3[j], gpu_indexes[j]);
}
assert(first_trivial_block - 1 == cleaned_merged_interesting_remainder.len);
assert(first_trivial_block - 1 == new_remainder.len);
assert(first_trivial_block == cleaned_merged_interesting_remainder.len);
assert(first_trivial_block == new_remainder.len);
remainder1.copy_from(cleaned_merged_interesting_remainder, 0,
first_trivial_block - 1, streams[0], gpu_indexes[0]);

View File

@@ -1,5 +1,36 @@
#include "integer/scalar_comparison.cuh"
#include <iostream>
#include <utility> // for std::pair
std::pair<bool, bool> get_invert_flags(COMPARISON_TYPE compare) {
bool invert_operands;
bool invert_subtraction_result;
switch (compare) {
case COMPARISON_TYPE::LT:
invert_operands = false;
invert_subtraction_result = false;
break;
case COMPARISON_TYPE::LE:
invert_operands = true;
invert_subtraction_result = true;
break;
case COMPARISON_TYPE::GT:
invert_operands = true;
invert_subtraction_result = false;
break;
case COMPARISON_TYPE::GE:
invert_operands = false;
invert_subtraction_result = true;
break;
default:
PANIC("Cuda error: invalid comparison type")
}
return {invert_operands, invert_subtraction_result};
}
void cuda_scalar_comparison_integer_radix_ciphertext_kb_64(
void *const *streams, uint32_t const *gpu_indexes, uint32_t gpu_count,
void *lwe_array_out, void const *lwe_array_in, void const *scalar_blocks,
@@ -22,9 +53,9 @@ void cuda_scalar_comparison_integer_radix_ciphertext_kb_64(
case GE:
case LT:
case LE:
if (lwe_ciphertext_count % 2 != 0)
if (lwe_ciphertext_count % 2 != 0 && lwe_ciphertext_count != 1)
PANIC("Cuda error (scalar comparisons): the number of radix blocks has "
"to be even.")
"to be even or equal to 1.")
host_integer_radix_scalar_difference_check_kb<uint64_t>(
(cudaStream_t *)(streams), gpu_indexes, gpu_count,
static_cast<uint64_t *>(lwe_array_out),

View File

@@ -2,6 +2,27 @@
#define CUDA_INTEGER_SCALAR_COMPARISON_OPS_CUH
#include "integer/comparison.cuh"
template <typename Torus>
Torus is_x_less_than_y_given_input_borrow(Torus last_x_block,
Torus last_y_block, Torus borrow,
uint32_t message_modulus) {
Torus last_bit_pos = log2_int(message_modulus) - 1;
Torus mask = (1 << last_bit_pos) - 1;
Torus x_without_last_bit = last_x_block & mask;
Torus y_without_last_bit = last_y_block & mask;
bool input_borrow_to_last_bit =
x_without_last_bit < (y_without_last_bit + borrow);
Torus result = last_x_block - (last_y_block + borrow);
Torus output_sign_bit = (result >> last_bit_pos) & 1;
bool output_borrow = last_x_block < (last_y_block + borrow);
Torus overflow_flag = (Torus)(input_borrow_to_last_bit ^ output_borrow);
return output_sign_bit ^ overflow_flag;
}
template <typename Torus>
__host__ void scalar_compare_radix_blocks_kb(
@@ -205,42 +226,79 @@ __host__ void integer_radix_unsigned_scalar_difference_check_kb(
lwe_array_msb_out, bsks, ksks, 1, lut, lut->params.message_modulus);
} else {
// We only have to do the regular comparison
// And not the part where we compare most significant blocks with zeros
// total_num_radix_blocks == total_num_scalar_blocks
uint32_t num_lsb_radix_blocks = total_num_radix_blocks;
uint32_t num_scalar_blocks = total_num_scalar_blocks;
if (total_num_radix_blocks == 1) {
std::pair<bool, bool> invert_flags = get_invert_flags(mem_ptr->op);
Torus scalar = 0;
cuda_memcpy_async_to_cpu(&scalar, scalar_blocks, sizeof(Torus),
streams[0], gpu_indexes[0]);
cuda_synchronize_stream(streams[0], gpu_indexes[0]);
auto one_block_lut_f = [invert_flags, scalar](Torus x) -> Torus {
Torus x_0;
Torus x_1;
if (invert_flags.first) {
x_0 = scalar;
x_1 = x;
} else {
x_0 = x;
x_1 = scalar;
}
auto overflowed = x_0 < x_1;
return (Torus)(invert_flags.second ^ overflowed);
};
int_radix_lut<Torus> *one_block_lut = new int_radix_lut<Torus>(
streams, gpu_indexes, gpu_count, params, 1, 1, true);
Torus *lhs = diff_buffer->tmp_packed;
Torus *rhs =
diff_buffer->tmp_packed + total_num_radix_blocks / 2 * big_lwe_size;
generate_device_accumulator<Torus>(
streams[0], gpu_indexes[0], one_block_lut->get_lut(0, 0),
one_block_lut->get_degree(0), one_block_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, one_block_lut_f);
pack_blocks<Torus>(streams[0], gpu_indexes[0], lhs, lwe_array_in,
big_lwe_dimension, num_lsb_radix_blocks,
message_modulus);
pack_blocks<Torus>(streams[0], gpu_indexes[0], rhs, scalar_blocks, 0,
num_scalar_blocks, message_modulus);
one_block_lut->broadcast_lut(streams, gpu_indexes, 0);
// From this point we have half number of blocks
num_lsb_radix_blocks /= 2;
num_scalar_blocks /= 2;
legacy_integer_radix_apply_univariate_lookup_table_kb<Torus>(
streams, gpu_indexes, gpu_count, lwe_array_out, lwe_array_in, bsks,
ksks, 1, one_block_lut);
one_block_lut->release(streams, gpu_indexes, gpu_count);
delete one_block_lut;
} else {
// We only have to do the regular comparison
// And not the part where we compare most significant blocks with zeros
// total_num_radix_blocks == total_num_scalar_blocks
uint32_t num_lsb_radix_blocks = total_num_radix_blocks;
uint32_t num_scalar_blocks = total_num_scalar_blocks;
// comparisons will be assigned
// - 0 if lhs < rhs
// - 1 if lhs == rhs
// - 2 if lhs > rhs
auto comparisons = mem_ptr->tmp_lwe_array_out;
scalar_compare_radix_blocks_kb<Torus>(streams, gpu_indexes, gpu_count,
comparisons, lhs, rhs, mem_ptr, bsks,
ksks, num_lsb_radix_blocks);
Torus *lhs = diff_buffer->tmp_packed;
Torus *rhs =
diff_buffer->tmp_packed + total_num_radix_blocks / 2 * big_lwe_size;
// Reduces a vec containing radix blocks that encrypts a sign
// (inferior, equal, superior) to one single radix block containing the
// final sign
tree_sign_reduction<Torus>(streams, gpu_indexes, gpu_count, lwe_array_out,
comparisons, mem_ptr->diff_buffer->tree_buffer,
sign_handler_f, bsks, ksks,
num_lsb_radix_blocks);
pack_blocks<Torus>(streams[0], gpu_indexes[0], lhs, lwe_array_in,
big_lwe_dimension, num_lsb_radix_blocks,
message_modulus);
pack_blocks<Torus>(streams[0], gpu_indexes[0], rhs, scalar_blocks, 0,
num_scalar_blocks, message_modulus);
// From this point we have half number of blocks
num_lsb_radix_blocks /= 2;
num_scalar_blocks /= 2;
// comparisons will be assigned
// - 0 if lhs < rhs
// - 1 if lhs == rhs
// - 2 if lhs > rhs
auto comparisons = mem_ptr->tmp_lwe_array_out;
scalar_compare_radix_blocks_kb<Torus>(streams, gpu_indexes, gpu_count,
comparisons, lhs, rhs, mem_ptr,
bsks, ksks, num_lsb_radix_blocks);
// Reduces a vec containing radix blocks that encrypts a sign
// (inferior, equal, superior) to one single radix block containing the
// final sign
tree_sign_reduction<Torus>(streams, gpu_indexes, gpu_count, lwe_array_out,
comparisons, mem_ptr->diff_buffer->tree_buffer,
sign_handler_f, bsks, ksks,
num_lsb_radix_blocks);
}
}
}
@@ -448,65 +506,104 @@ __host__ void integer_radix_signed_scalar_difference_check_kb(
2);
} else {
// We only have to do the regular comparison
// And not the part where we compare most significant blocks with zeros
// total_num_radix_blocks == total_num_scalar_blocks
uint32_t num_lsb_radix_blocks = total_num_radix_blocks;
if (total_num_radix_blocks == 1) {
std::pair<bool, bool> invert_flags = get_invert_flags(mem_ptr->op);
Torus scalar = 0;
cuda_memcpy_async_to_cpu(&scalar, scalar_blocks, sizeof(Torus),
streams[0], gpu_indexes[0]);
cuda_synchronize_stream(streams[0], gpu_indexes[0]);
auto one_block_lut_f = [invert_flags, scalar,
message_modulus](Torus x) -> Torus {
Torus x_0;
Torus x_1;
if (invert_flags.first) {
x_0 = scalar;
x_1 = x;
} else {
x_0 = x;
x_1 = scalar;
}
return (Torus)(invert_flags.second) ^
is_x_less_than_y_given_input_borrow<Torus>(x_0, x_1, 0,
message_modulus);
};
int_radix_lut<Torus> *one_block_lut = new int_radix_lut<Torus>(
streams, gpu_indexes, gpu_count, params, 1, 1, true);
for (uint j = 0; j < gpu_count; j++) {
cuda_synchronize_stream(streams[j], gpu_indexes[j]);
generate_device_accumulator<Torus>(
streams[0], gpu_indexes[0], one_block_lut->get_lut(0, 0),
one_block_lut->get_degree(0), one_block_lut->get_max_degree(0),
params.glwe_dimension, params.polynomial_size, params.message_modulus,
params.carry_modulus, one_block_lut_f);
one_block_lut->broadcast_lut(streams, gpu_indexes, 0);
legacy_integer_radix_apply_univariate_lookup_table_kb<Torus>(
streams, gpu_indexes, gpu_count, lwe_array_out, lwe_array_in, bsks,
ksks, 1, one_block_lut);
one_block_lut->release(streams, gpu_indexes, gpu_count);
delete one_block_lut;
} else {
// We only have to do the regular comparison
// And not the part where we compare most significant blocks with zeros
// total_num_radix_blocks == total_num_scalar_blocks
uint32_t num_lsb_radix_blocks = total_num_radix_blocks;
for (uint j = 0; j < gpu_count; j++) {
cuda_synchronize_stream(streams[j], gpu_indexes[j]);
}
auto lsb_streams = mem_ptr->lsb_streams;
auto msb_streams = mem_ptr->msb_streams;
auto lwe_array_ct_out = mem_ptr->tmp_lwe_array_out;
auto lwe_array_sign_out =
lwe_array_ct_out + (num_lsb_radix_blocks / 2) * big_lwe_size;
Torus *lhs = diff_buffer->tmp_packed;
Torus *rhs =
diff_buffer->tmp_packed + total_num_radix_blocks / 2 * big_lwe_size;
pack_blocks<Torus>(lsb_streams[0], gpu_indexes[0], lhs, lwe_array_in,
big_lwe_dimension, num_lsb_radix_blocks - 1,
message_modulus);
pack_blocks<Torus>(lsb_streams[0], gpu_indexes[0], rhs, scalar_blocks, 0,
num_lsb_radix_blocks - 1, message_modulus);
// From this point we have half number of blocks
num_lsb_radix_blocks /= 2;
// comparisons will be assigned
// - 0 if lhs < rhs
// - 1 if lhs == rhs
// - 2 if lhs > rhs
scalar_compare_radix_blocks_kb<Torus>(lsb_streams, gpu_indexes, gpu_count,
lwe_array_ct_out, lhs, rhs, mem_ptr,
bsks, ksks, num_lsb_radix_blocks);
Torus const *encrypted_sign_block =
lwe_array_in + (total_num_radix_blocks - 1) * big_lwe_size;
Torus const *scalar_sign_block =
scalar_blocks + (total_num_scalar_blocks - 1);
auto trivial_sign_block = mem_ptr->tmp_trivial_sign_block;
create_trivial_radix<Torus>(
msb_streams[0], gpu_indexes[0], trivial_sign_block, scalar_sign_block,
big_lwe_dimension, 1, 1, message_modulus, carry_modulus);
legacy_integer_radix_apply_bivariate_lookup_table_kb<Torus>(
msb_streams, gpu_indexes, gpu_count, lwe_array_sign_out,
encrypted_sign_block, trivial_sign_block, bsks, ksks, 1,
mem_ptr->signed_lut, mem_ptr->signed_lut->params.message_modulus);
for (uint j = 0; j < mem_ptr->active_gpu_count; j++) {
cuda_synchronize_stream(lsb_streams[j], gpu_indexes[j]);
cuda_synchronize_stream(msb_streams[j], gpu_indexes[j]);
}
// Reduces a vec containing radix blocks that encrypts a sign
// (inferior, equal, superior) to one single radix block containing the
// final sign
reduce_signs<Torus>(streams, gpu_indexes, gpu_count, lwe_array_out,
lwe_array_ct_out, mem_ptr, sign_handler_f, bsks, ksks,
num_lsb_radix_blocks + 1);
}
auto lsb_streams = mem_ptr->lsb_streams;
auto msb_streams = mem_ptr->msb_streams;
auto lwe_array_ct_out = mem_ptr->tmp_lwe_array_out;
auto lwe_array_sign_out =
lwe_array_ct_out + (num_lsb_radix_blocks / 2) * big_lwe_size;
Torus *lhs = diff_buffer->tmp_packed;
Torus *rhs =
diff_buffer->tmp_packed + total_num_radix_blocks / 2 * big_lwe_size;
pack_blocks<Torus>(lsb_streams[0], gpu_indexes[0], lhs, lwe_array_in,
big_lwe_dimension, num_lsb_radix_blocks - 1,
message_modulus);
pack_blocks<Torus>(lsb_streams[0], gpu_indexes[0], rhs, scalar_blocks, 0,
num_lsb_radix_blocks - 1, message_modulus);
// From this point we have half number of blocks
num_lsb_radix_blocks /= 2;
// comparisons will be assigned
// - 0 if lhs < rhs
// - 1 if lhs == rhs
// - 2 if lhs > rhs
scalar_compare_radix_blocks_kb<Torus>(lsb_streams, gpu_indexes, gpu_count,
lwe_array_ct_out, lhs, rhs, mem_ptr,
bsks, ksks, num_lsb_radix_blocks);
Torus const *encrypted_sign_block =
lwe_array_in + (total_num_radix_blocks - 1) * big_lwe_size;
Torus const *scalar_sign_block =
scalar_blocks + (total_num_scalar_blocks - 1);
auto trivial_sign_block = mem_ptr->tmp_trivial_sign_block;
create_trivial_radix<Torus>(
msb_streams[0], gpu_indexes[0], trivial_sign_block, scalar_sign_block,
big_lwe_dimension, 1, 1, message_modulus, carry_modulus);
legacy_integer_radix_apply_bivariate_lookup_table_kb<Torus>(
msb_streams, gpu_indexes, gpu_count, lwe_array_sign_out,
encrypted_sign_block, trivial_sign_block, bsks, ksks, 1,
mem_ptr->signed_lut, mem_ptr->signed_lut->params.message_modulus);
for (uint j = 0; j < mem_ptr->active_gpu_count; j++) {
cuda_synchronize_stream(lsb_streams[j], gpu_indexes[j]);
cuda_synchronize_stream(msb_streams[j], gpu_indexes[j]);
}
// Reduces a vec containing radix blocks that encrypts a sign
// (inferior, equal, superior) to one single radix block containing the
// final sign
reduce_signs<Torus>(streams, gpu_indexes, gpu_count, lwe_array_out,
lwe_array_ct_out, mem_ptr, sign_handler_f, bsks, ksks,
num_lsb_radix_blocks + 1);
}
}

View File

@@ -26,7 +26,7 @@ get_join_buffer_element(int level_id, int glwe_id, G &group,
* Both operands should be at fourier domain
*
* This function assumes:
* - Thread blocks at dimension x relates to the decomposition level.
* - Thread blocks at dimension z relates to the decomposition level.
* - Thread blocks at dimension y relates to the glwe dimension.
* - polynomial_size / params::opt threads are available per block
*/
@@ -38,55 +38,6 @@ mul_ggsw_glwe_in_fourier_domain(double2 *fft, double2 *join_buffer,
bool support_dsm = false) {
const uint32_t polynomial_size = params::degree;
const uint32_t glwe_dimension = gridDim.y - 1;
const uint32_t level_count = gridDim.x;
// The first product is used to initialize level_join_buffer
auto this_block_rank = get_this_block_rank<G>(group, support_dsm);
// Continues multiplying fft by every polynomial in that particular bsk level
// Each y-block accumulates in a different polynomial at each iteration
auto bsk_slice = get_ith_mask_kth_block(
bootstrapping_key, iteration, blockIdx.y, blockIdx.x, polynomial_size,
glwe_dimension, level_count);
for (int j = 0; j < glwe_dimension + 1; j++) {
int idx = (j + this_block_rank) % (glwe_dimension + 1);
auto bsk_poly = bsk_slice + idx * polynomial_size / 2;
auto buffer_slice = get_join_buffer_element<G>(blockIdx.x, idx, group,
join_buffer, polynomial_size,
glwe_dimension, support_dsm);
polynomial_product_accumulate_in_fourier_domain<params, double2>(
buffer_slice, fft, bsk_poly, j == 0);
group.sync();
}
// -----------------------------------------------------------------
// All blocks are synchronized here; after this sync, level_join_buffer has
// the values needed from every other block
// accumulate rest of the products into fft buffer
for (int l = 0; l < level_count; l++) {
auto cur_src_acc = get_join_buffer_element<G>(l, blockIdx.y, group,
join_buffer, polynomial_size,
glwe_dimension, support_dsm);
polynomial_accumulate_in_fourier_domain<params>(fft, cur_src_acc, l == 0);
}
synchronize_threads_in_block();
}
// This is a temporary function to have a working version of the tbc-PBS
// with large integers.
// TO DO: we should erase this function when the other flavors of the PBS also
// work with the number of samples in the first block dimension.
template <typename G, class params>
__device__ void mul_ggsw_glwe_in_fourier_domain_tbc(
double2 *fft, double2 *join_buffer,
const double2 *__restrict__ bootstrapping_key, int iteration, G &group,
bool support_dsm = false) {
const uint32_t polynomial_size = params::degree;
const uint32_t glwe_dimension = gridDim.y - 1;
const uint32_t level_count = gridDim.z;
// The first product is used to initialize level_join_buffer

View File

@@ -60,8 +60,8 @@ __global__ void device_programmable_bootstrap_cg(
if constexpr (SMD == FULLSM) {
selected_memory = sharedmem;
} else {
int block_index = blockIdx.x + blockIdx.y * gridDim.x +
blockIdx.z * gridDim.x * gridDim.y;
int block_index = blockIdx.z + blockIdx.y * gridDim.z +
blockIdx.x * gridDim.z * gridDim.y;
selected_memory = &device_mem[block_index * device_memory_size_per_block];
}
@@ -80,14 +80,14 @@ __global__ void device_programmable_bootstrap_cg(
// The third dimension of the block is used to determine on which ciphertext
// this block is operating, in the case of batch bootstraps
const Torus *block_lwe_array_in =
&lwe_array_in[lwe_input_indexes[blockIdx.z] * (lwe_dimension + 1)];
&lwe_array_in[lwe_input_indexes[blockIdx.x] * (lwe_dimension + 1)];
const Torus *block_lut_vector =
&lut_vector[lut_vector_indexes[blockIdx.z] * params::degree *
&lut_vector[lut_vector_indexes[blockIdx.x] * params::degree *
(glwe_dimension + 1)];
double2 *block_join_buffer =
&join_buffer[blockIdx.z * level_count * (glwe_dimension + 1) *
&join_buffer[blockIdx.x * level_count * (glwe_dimension + 1) *
params::degree / 2];
// Since the space is L1 cache is small, we use the same memory location for
// the rotated accumulator and the fft accumulator, since we know that the
@@ -128,7 +128,7 @@ __global__ void device_programmable_bootstrap_cg(
// accumulator decomposed at level 0, 1 at 1, etc.)
GadgetMatrix<Torus, params> gadget_acc(base_log, level_count,
accumulator_rotated);
gadget_acc.decompose_and_compress_level(accumulator_fft, blockIdx.x);
gadget_acc.decompose_and_compress_level(accumulator_fft, blockIdx.z);
NSMFFT_direct<HalfDegree<params>>(accumulator_fft);
synchronize_threads_in_block();
@@ -142,11 +142,11 @@ __global__ void device_programmable_bootstrap_cg(
}
auto block_lwe_array_out =
&lwe_array_out[lwe_output_indexes[blockIdx.z] *
&lwe_array_out[lwe_output_indexes[blockIdx.x] *
(glwe_dimension * polynomial_size + 1) +
blockIdx.y * polynomial_size];
if (blockIdx.x == 0) {
if (blockIdx.z == 0) {
if (blockIdx.y < glwe_dimension) {
// Perform a sample extract. At this point, all blocks have the result,
// but we do the computation at block 0 to avoid waiting for extra blocks,
@@ -156,9 +156,9 @@ __global__ void device_programmable_bootstrap_cg(
for (int i = 1; i < num_many_lut; i++) {
auto next_lwe_array_out =
lwe_array_out +
(i * gridDim.z * (glwe_dimension * polynomial_size + 1));
(i * gridDim.x * (glwe_dimension * polynomial_size + 1));
auto next_block_lwe_array_out =
&next_lwe_array_out[lwe_output_indexes[blockIdx.z] *
&next_lwe_array_out[lwe_output_indexes[blockIdx.x] *
(glwe_dimension * polynomial_size + 1) +
blockIdx.y * polynomial_size];
@@ -173,9 +173,9 @@ __global__ void device_programmable_bootstrap_cg(
auto next_lwe_array_out =
lwe_array_out +
(i * gridDim.z * (glwe_dimension * polynomial_size + 1));
(i * gridDim.x * (glwe_dimension * polynomial_size + 1));
auto next_block_lwe_array_out =
&next_lwe_array_out[lwe_output_indexes[blockIdx.z] *
&next_lwe_array_out[lwe_output_indexes[blockIdx.x] *
(glwe_dimension * polynomial_size + 1) +
blockIdx.y * polynomial_size];
@@ -257,7 +257,7 @@ __host__ void host_programmable_bootstrap_cg(
double2 *buffer_fft = buffer->global_join_buffer;
int thds = polynomial_size / params::opt;
dim3 grid(level_count, glwe_dimension + 1, input_lwe_ciphertext_count);
dim3 grid(input_lwe_ciphertext_count, glwe_dimension + 1, level_count);
void *kernel_args[16];
kernel_args[0] = &lwe_array_out;

View File

@@ -45,8 +45,8 @@ __global__ void __launch_bounds__(params::degree / params::opt)
if constexpr (SMD == FULLSM) {
selected_memory = sharedmem;
} else {
int block_index = blockIdx.x + blockIdx.y * gridDim.x +
blockIdx.z * gridDim.x * gridDim.y;
int block_index = blockIdx.z + blockIdx.y * gridDim.z +
blockIdx.x * gridDim.z * gridDim.y;
selected_memory = &device_mem[block_index * device_memory_size_per_block];
}
@@ -61,22 +61,22 @@ __global__ void __launch_bounds__(params::degree / params::opt)
// The third dimension of the block is used to determine on which ciphertext
// this block is operating, in the case of batch bootstraps
const Torus *block_lwe_array_in =
&lwe_array_in[lwe_input_indexes[blockIdx.z] * (lwe_dimension + 1)];
&lwe_array_in[lwe_input_indexes[blockIdx.x] * (lwe_dimension + 1)];
const Torus *block_lut_vector =
&lut_vector[lut_vector_indexes[blockIdx.z] * params::degree *
&lut_vector[lut_vector_indexes[blockIdx.x] * params::degree *
(glwe_dimension + 1)];
double2 *block_join_buffer =
&join_buffer[blockIdx.z * level_count * (glwe_dimension + 1) *
&join_buffer[blockIdx.x * level_count * (glwe_dimension + 1) *
params::degree / 2];
Torus *global_accumulator_slice =
&global_accumulator[(blockIdx.y + blockIdx.z * (glwe_dimension + 1)) *
&global_accumulator[(blockIdx.y + blockIdx.x * (glwe_dimension + 1)) *
params::degree];
const double2 *keybundle =
&keybundle_array[blockIdx.z * keybundle_size_per_input];
&keybundle_array[blockIdx.x * keybundle_size_per_input];
if (lwe_offset == 0) {
// Put "b" in [0, 2N[
@@ -106,7 +106,7 @@ __global__ void __launch_bounds__(params::degree / params::opt)
// accumulator_rotated decomposed at level 0, 1 at 1, etc.)
GadgetMatrix<Torus, params> gadget_acc(base_log, level_count,
accumulator_rotated);
gadget_acc.decompose_and_compress_level(accumulator_fft, blockIdx.x);
gadget_acc.decompose_and_compress_level(accumulator_fft, blockIdx.z);
NSMFFT_direct<HalfDegree<params>>(accumulator_fft);
synchronize_threads_in_block();
@@ -121,10 +121,10 @@ __global__ void __launch_bounds__(params::degree / params::opt)
auto accumulator = accumulator_rotated;
if (blockIdx.x == 0) {
if (blockIdx.z == 0) {
if (lwe_offset + lwe_chunk_size >= (lwe_dimension / grouping_factor)) {
auto block_lwe_array_out =
&lwe_array_out[lwe_output_indexes[blockIdx.z] *
&lwe_array_out[lwe_output_indexes[blockIdx.x] *
(glwe_dimension * polynomial_size + 1) +
blockIdx.y * polynomial_size];
@@ -139,9 +139,9 @@ __global__ void __launch_bounds__(params::degree / params::opt)
for (int i = 1; i < num_many_lut; i++) {
auto next_lwe_array_out =
lwe_array_out +
(i * gridDim.z * (glwe_dimension * polynomial_size + 1));
(i * gridDim.x * (glwe_dimension * polynomial_size + 1));
auto next_block_lwe_array_out =
&next_lwe_array_out[lwe_output_indexes[blockIdx.z] *
&next_lwe_array_out[lwe_output_indexes[blockIdx.x] *
(glwe_dimension * polynomial_size + 1) +
blockIdx.y * polynomial_size];
@@ -159,9 +159,9 @@ __global__ void __launch_bounds__(params::degree / params::opt)
auto next_lwe_array_out =
lwe_array_out +
(i * gridDim.z * (glwe_dimension * polynomial_size + 1));
(i * gridDim.x * (glwe_dimension * polynomial_size + 1));
auto next_block_lwe_array_out =
&next_lwe_array_out[lwe_output_indexes[blockIdx.z] *
&next_lwe_array_out[lwe_output_indexes[blockIdx.x] *
(glwe_dimension * polynomial_size + 1) +
blockIdx.y * polynomial_size];
@@ -349,7 +349,7 @@ __host__ void execute_cg_external_product_loop(
kernel_args[20] = &num_many_lut;
kernel_args[21] = &lut_stride;
dim3 grid_accumulate(level_count, glwe_dimension + 1, num_samples);
dim3 grid_accumulate(num_samples, glwe_dimension + 1, level_count);
dim3 thds(polynomial_size / params::opt, 1, 1);
if (max_shared_memory < partial_dm) {

View File

@@ -40,8 +40,8 @@ __global__ void __launch_bounds__(params::degree / params::opt)
if constexpr (SMD == FULLSM) {
selected_memory = sharedmem;
} else {
int block_index = blockIdx.x + blockIdx.y * gridDim.x +
blockIdx.z * gridDim.x * gridDim.y;
int block_index = blockIdx.z + blockIdx.y * gridDim.z +
blockIdx.x * gridDim.z * gridDim.y;
selected_memory = &device_mem[block_index * device_memory_size_per_block];
}
@@ -56,19 +56,19 @@ __global__ void __launch_bounds__(params::degree / params::opt)
// The third dimension of the block is used to determine on which ciphertext
// this block is operating, in the case of batch bootstraps
const Torus *block_lwe_array_in =
&lwe_array_in[lwe_input_indexes[blockIdx.z] * (lwe_dimension + 1)];
&lwe_array_in[lwe_input_indexes[blockIdx.x] * (lwe_dimension + 1)];
const Torus *block_lut_vector =
&lut_vector[lut_vector_indexes[blockIdx.z] * params::degree *
&lut_vector[lut_vector_indexes[blockIdx.x] * params::degree *
(glwe_dimension + 1)];
Torus *global_slice =
global_accumulator +
(blockIdx.y + blockIdx.z * (glwe_dimension + 1)) * params::degree;
(blockIdx.y + blockIdx.x * (glwe_dimension + 1)) * params::degree;
double2 *global_fft_slice =
global_join_buffer + (blockIdx.y + blockIdx.x * (glwe_dimension + 1) +
blockIdx.z * level_count * (glwe_dimension + 1)) *
global_join_buffer + (blockIdx.y + blockIdx.z * (glwe_dimension + 1) +
blockIdx.x * level_count * (glwe_dimension + 1)) *
(polynomial_size / 2);
if (lwe_iteration == 0) {
@@ -116,7 +116,7 @@ __global__ void __launch_bounds__(params::degree / params::opt)
// decomposition, for the mask and the body (so block 0 will have the
// accumulator decomposed at level 0, 1 at 1, etc.)
GadgetMatrix<Torus, params> gadget_acc(base_log, level_count, accumulator);
gadget_acc.decompose_and_compress_level(accumulator_fft, blockIdx.x);
gadget_acc.decompose_and_compress_level(accumulator_fft, blockIdx.z);
// We are using the same memory space for accumulator_fft and
// accumulator_rotated, so we need to synchronize here to make sure they
@@ -375,7 +375,7 @@ __host__ void execute_step_one(
int max_shared_memory = cuda_get_max_shared_memory(gpu_index);
cuda_set_device(gpu_index);
int thds = polynomial_size / params::opt;
dim3 grid(level_count, glwe_dimension + 1, input_lwe_ciphertext_count);
dim3 grid(input_lwe_ciphertext_count, glwe_dimension + 1, level_count);
if (max_shared_memory < partial_sm) {
device_programmable_bootstrap_step_one<Torus, params, NOSM>

View File

@@ -169,8 +169,8 @@ __global__ void __launch_bounds__(params::degree / params::opt)
if constexpr (SMD == FULLSM) {
selected_memory = sharedmem;
} else {
int block_index = blockIdx.x + blockIdx.y * gridDim.x +
blockIdx.z * gridDim.x * gridDim.y;
int block_index = blockIdx.z + blockIdx.y * gridDim.z +
blockIdx.x * gridDim.z * gridDim.y;
selected_memory = &device_mem[block_index * device_memory_size_per_block];
}
@@ -183,19 +183,19 @@ __global__ void __launch_bounds__(params::degree / params::opt)
accumulator_fft = (double2 *)sharedmem;
const Torus *block_lwe_array_in =
&lwe_array_in[lwe_input_indexes[blockIdx.z] * (lwe_dimension + 1)];
&lwe_array_in[lwe_input_indexes[blockIdx.x] * (lwe_dimension + 1)];
const Torus *block_lut_vector =
&lut_vector[lut_vector_indexes[blockIdx.z] * params::degree *
&lut_vector[lut_vector_indexes[blockIdx.x] * params::degree *
(glwe_dimension + 1)];
Torus *global_slice =
&global_accumulator[(blockIdx.y + blockIdx.z * (glwe_dimension + 1)) *
&global_accumulator[(blockIdx.y + blockIdx.x * (glwe_dimension + 1)) *
params::degree];
double2 *global_fft_slice =
&global_accumulator_fft[(blockIdx.y + blockIdx.x * (glwe_dimension + 1) +
blockIdx.z * level_count *
&global_accumulator_fft[(blockIdx.y + blockIdx.z * (glwe_dimension + 1) +
blockIdx.x * level_count *
(glwe_dimension + 1)) *
(polynomial_size / 2)];
@@ -232,7 +232,7 @@ __global__ void __launch_bounds__(params::degree / params::opt)
// decomposition, for the mask and the body (so block 0 will have the
// accumulator decomposed at level 0, 1 at 1, etc.)
GadgetMatrix<Torus, params> gadget_acc(base_log, level_count, accumulator);
gadget_acc.decompose_and_compress_level(accumulator_fft, blockIdx.x);
gadget_acc.decompose_and_compress_level(accumulator_fft, blockIdx.z);
// We are using the same memory space for accumulator_fft and
// accumulator_rotated, so we need to synchronize here to make sure they
@@ -560,7 +560,7 @@ execute_step_one(cudaStream_t stream, uint32_t gpu_index,
auto global_accumulator = buffer->global_accumulator;
auto global_accumulator_fft = buffer->global_join_buffer;
dim3 grid_accumulate_step_one(level_count, glwe_dimension + 1, num_samples);
dim3 grid_accumulate_step_one(num_samples, glwe_dimension + 1, level_count);
dim3 thds(polynomial_size / params::opt, 1, 1);
if (max_shared_memory < partial_sm_accumulate_step_one)

View File

@@ -62,8 +62,8 @@ __global__ void device_programmable_bootstrap_tbc(
if (support_dsm)
selected_memory += sizeof(Torus) * polynomial_size;
} else {
int block_index = blockIdx.x + blockIdx.y * gridDim.x +
blockIdx.z * gridDim.x * gridDim.y;
int block_index = blockIdx.z + blockIdx.y * gridDim.z +
blockIdx.x * gridDim.z * gridDim.y;
selected_memory = &device_mem[block_index * device_memory_size_per_block];
}
@@ -83,14 +83,14 @@ __global__ void device_programmable_bootstrap_tbc(
// The third dimension of the block is used to determine on which ciphertext
// this block is operating, in the case of batch bootstraps
const Torus *block_lwe_array_in =
&lwe_array_in[lwe_input_indexes[blockIdx.z] * (lwe_dimension + 1)];
&lwe_array_in[lwe_input_indexes[blockIdx.x] * (lwe_dimension + 1)];
const Torus *block_lut_vector =
&lut_vector[lut_vector_indexes[blockIdx.z] * params::degree *
&lut_vector[lut_vector_indexes[blockIdx.x] * params::degree *
(glwe_dimension + 1)];
double2 *block_join_buffer =
&join_buffer[blockIdx.z * level_count * (glwe_dimension + 1) *
&join_buffer[blockIdx.x * level_count * (glwe_dimension + 1) *
params::degree / 2];
// Since the space is L1 cache is small, we use the same memory location for
// the rotated accumulator and the fft accumulator, since we know that the
@@ -132,7 +132,7 @@ __global__ void device_programmable_bootstrap_tbc(
// accumulator decomposed at level 0, 1 at 1, etc.)
GadgetMatrix<Torus, params> gadget_acc(base_log, level_count,
accumulator_rotated);
gadget_acc.decompose_and_compress_level(accumulator_fft, blockIdx.x);
gadget_acc.decompose_and_compress_level(accumulator_fft, blockIdx.z);
NSMFFT_direct<HalfDegree<params>>(accumulator_fft);
synchronize_threads_in_block();
@@ -147,11 +147,11 @@ __global__ void device_programmable_bootstrap_tbc(
}
auto block_lwe_array_out =
&lwe_array_out[lwe_output_indexes[blockIdx.z] *
&lwe_array_out[lwe_output_indexes[blockIdx.x] *
(glwe_dimension * polynomial_size + 1) +
blockIdx.y * polynomial_size];
if (blockIdx.x == 0) {
if (blockIdx.z == 0) {
if (blockIdx.y < glwe_dimension) {
// Perform a sample extract. At this point, all blocks have the result,
// but we do the computation at block 0 to avoid waiting for extra blocks,
@@ -162,9 +162,9 @@ __global__ void device_programmable_bootstrap_tbc(
for (int i = 1; i < num_many_lut; i++) {
auto next_lwe_array_out =
lwe_array_out +
(i * gridDim.z * (glwe_dimension * polynomial_size + 1));
(i * gridDim.x * (glwe_dimension * polynomial_size + 1));
auto next_block_lwe_array_out =
&next_lwe_array_out[lwe_output_indexes[blockIdx.z] *
&next_lwe_array_out[lwe_output_indexes[blockIdx.x] *
(glwe_dimension * polynomial_size + 1) +
blockIdx.y * polynomial_size];
@@ -180,9 +180,9 @@ __global__ void device_programmable_bootstrap_tbc(
auto next_lwe_array_out =
lwe_array_out +
(i * gridDim.z * (glwe_dimension * polynomial_size + 1));
(i * gridDim.x * (glwe_dimension * polynomial_size + 1));
auto next_block_lwe_array_out =
&next_lwe_array_out[lwe_output_indexes[blockIdx.z] *
&next_lwe_array_out[lwe_output_indexes[blockIdx.x] *
(glwe_dimension * polynomial_size + 1) +
blockIdx.y * polynomial_size];
@@ -292,7 +292,7 @@ __host__ void host_programmable_bootstrap_tbc(
double2 *buffer_fft = buffer->global_join_buffer;
int thds = polynomial_size / params::opt;
dim3 grid(level_count, glwe_dimension + 1, input_lwe_ciphertext_count);
dim3 grid(input_lwe_ciphertext_count, glwe_dimension + 1, level_count);
cudaLaunchConfig_t config = {0};
// The grid dimension is not affected by cluster launch, and is still
@@ -303,9 +303,9 @@ __host__ void host_programmable_bootstrap_tbc(
cudaLaunchAttribute attribute[1];
attribute[0].id = cudaLaunchAttributeClusterDimension;
attribute[0].val.clusterDim.x = level_count; // Cluster size in X-dimension
attribute[0].val.clusterDim.x = 1;
attribute[0].val.clusterDim.y = (glwe_dimension + 1);
attribute[0].val.clusterDim.z = 1;
attribute[0].val.clusterDim.z = level_count; // Cluster size in Z-dimension
config.attrs = attribute;
config.numAttrs = 1;
config.stream = stream;
@@ -424,7 +424,7 @@ __host__ bool supports_thread_block_clusters_on_classic_programmable_bootstrap(
int cluster_size;
dim3 grid_accumulate(level_count, glwe_dimension + 1, num_samples);
dim3 grid_accumulate(num_samples, glwe_dimension + 1, level_count);
dim3 thds(polynomial_size / params::opt, 1, 1);
cudaLaunchConfig_t config = {0};

View File

@@ -118,7 +118,7 @@ __global__ void __launch_bounds__(params::degree / params::opt)
synchronize_threads_in_block();
// Perform G^-1(ACC) * GGSW -> GLWE
mul_ggsw_glwe_in_fourier_domain_tbc<cluster_group, params>(
mul_ggsw_glwe_in_fourier_domain<cluster_group, params>(
accumulator_fft, block_join_buffer, keybundle, i, cluster, support_dsm);
NSMFFT_inverse<HalfDegree<params>>(accumulator_fft);
synchronize_threads_in_block();

View File

@@ -30,6 +30,7 @@ unsafe extern "C" {
glwe_array_in: *const ffi::c_void,
nth_array: *const u32,
num_nths: u32,
lwe_per_glwe: u32,
glwe_dimension: u32,
polynomial_size: u32,
);

View File

@@ -1,18 +1,18 @@
[backend.aws.cpu-big]
region = "eu-west-3"
image_id = "ami-0cd5012d17ae64070"
image_id = "ami-0449b775abf884686"
instance_type = "m6i.32xlarge"
user = "ubuntu"
[backend.aws.cpu-big_fallback]
region = "us-east-1"
image_id = "ami-04e3bb9aebb6786df"
image_id = "ami-0c6e54f3be8d03234"
instance_type = "m6i.32xlarge"
user = "ubuntu"
[backend.aws.cpu-small]
region = "eu-west-3"
image_id = "ami-0cd5012d17ae64070"
image_id = "ami-0449b775abf884686"
instance_type = "m6i.4xlarge"
user = "ubuntu"

View File

@@ -10,7 +10,7 @@ const DIR_TO_IGNORE: [&str; 3] = [
"tests/tfhe-backward-compat-data",
];
const FILES_TO_IGNORE: [&str; 6] = [
const FILES_TO_IGNORE: [&str; 7] = [
// This contains fragments of code that are unrelated to TFHE-rs
"tfhe/docs/tutorials/sha256_bool.md",
// TODO: This contains code that could be executed as a trivium docstring
@@ -22,6 +22,7 @@ const FILES_TO_IGNORE: [&str; 6] = [
// TODO: find a way to test the tfhe-ntt readme
"tfhe-ntt/README.md",
"utils/tfhe-lints/README.md",
"CONTRIBUTING.md",
];
pub fn check_tfhe_docs_are_tested() -> Result<(), Error> {
@@ -126,10 +127,18 @@ pub fn check_tfhe_docs_are_tested() -> Result<(), Error> {
}
let difference = doc_files.difference(&tested_files);
let files_that_may_not_exist = tested_files.difference(&doc_files);
let files_that_dont_exist: Vec<_> = files_that_may_not_exist
.into_iter()
.filter(|p| !p.exists())
.collect();
let debug_format = format!("missing file from user doc tests: {difference:#?}");
let debug_format = format!(
"missing file from user doc tests: {difference:#?}\n\
files that are tested but don't exist: {files_that_dont_exist:#?}"
);
if difference.count() != 0 {
if difference.count() != 0 || !files_that_dont_exist.is_empty() {
return Err(Error::new(ErrorKind::NotFound, debug_format));
}

View File

@@ -43,7 +43,7 @@ impl<BlockCipher: AesBlockCipher> AesCtrGenerator<BlockCipher> {
let first_index = self.state.table_index().incremented();
let output = (0..n_children.0)
.into_par_iter()
.zip(rayon::iter::repeatn(
.zip(rayon::iter::repeat_n(
(self.block_cipher.clone(), first_index, n_bytes),
n_children.0,
))

View File

@@ -1,6 +1,6 @@
[package]
name = "tfhe"
version = "1.0.0"
version = "1.0.1"
edition = "2021"
readme = "../README.md"
keywords = ["fully", "homomorphic", "encryption", "fhe", "cryptography"]
@@ -60,7 +60,7 @@ tfhe-fft = { version = "0.8.0", path = "../tfhe-fft", features = [
] }
tfhe-ntt = { version = "0.5.0", path = "../tfhe-ntt" }
pulp = { workspace = true, features = ["default"] }
tfhe-cuda-backend = { version = "0.8.0", path = "../backends/tfhe-cuda-backend", optional = true }
tfhe-cuda-backend = { version = "0.8.1", path = "../backends/tfhe-cuda-backend", optional = true }
aligned-vec = { workspace = true, features = ["default", "serde"] }
dyn-stack = { workspace = true, features = ["default"] }
paste = "1.0.7"
@@ -162,6 +162,12 @@ path = "benches/core_crypto/pbs_bench.rs"
harness = false
required-features = ["boolean", "shortint", "internal-keycache"]
[[bench]]
name = "ks-pbs-bench"
path = "benches/core_crypto/ks_pbs_bench.rs"
harness = false
required-features = ["shortint", "internal-keycache"]
[[bench]]
name = "dev-bench"
path = "benches/core_crypto/dev_bench.rs"

View File

@@ -1,8 +1,11 @@
#[path = "../utilities.rs"]
mod utilities;
use crate::utilities::{write_to_json, CryptoParametersRecord, OperatorType};
use criterion::{black_box, criterion_main, Criterion};
use crate::utilities::{
filter_parameters, init_parameters_set, write_to_json, CryptoParametersRecord, DesiredBackend,
DesiredNoiseDistribution, OperatorType, ParametersSet, PARAMETERS_SET,
};
use criterion::{black_box, Criterion};
use serde::Serialize;
use tfhe::boolean::prelude::*;
use tfhe::core_crypto::prelude::*;
@@ -10,7 +13,7 @@ use tfhe::keycache::NamedParam;
use tfhe::shortint::parameters::current_params::{
V1_0_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128, VEC_ALL_MULTI_BIT_PBS_PARAMETERS,
};
#[cfg(not(feature = "gpu"))]
use tfhe::shortint::parameters::current_params::{
@@ -29,9 +32,11 @@ use tfhe::shortint::parameters::{
#[cfg(feature = "gpu")]
use tfhe::shortint::parameters::{
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64,
};
use tfhe::shortint::prelude::*;
use tfhe::shortint::{MultiBitPBSParameters, PBSParameters};
@@ -64,8 +69,10 @@ const SHORTINT_MULTI_BIT_BENCH_PARAMS: [MultiBitPBSParameters; 6] = [
];
#[cfg(feature = "gpu")]
const SHORTINT_MULTI_BIT_BENCH_PARAMS: [MultiBitPBSParameters; 4] = [
const SHORTINT_MULTI_BIT_BENCH_PARAMS: [MultiBitPBSParameters; 6] = [
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
@@ -80,28 +87,78 @@ const BOOLEAN_BENCH_PARAMS: [(&str, BooleanParameters); 2] = [
];
fn benchmark_parameters_64bits() -> Vec<(String, CryptoParametersRecord<u64>)> {
let classic = SHORTINT_BENCH_PARAMS
.iter()
.map(|params| {
(
params.name(),
<ClassicPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
let (classic, multi_bit) = match PARAMETERS_SET.get().unwrap() {
ParametersSet::Default => {
let classic = SHORTINT_BENCH_PARAMS
.iter()
.map(|params| {
(
params.name(),
<ClassicPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
)
})
.collect::<Vec<(String, CryptoParametersRecord<u64>)>>();
let multi_bit = SHORTINT_MULTI_BIT_BENCH_PARAMS
.iter()
.map(|params| {
(
params.name(),
<MultiBitPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
)
})
.collect();
(classic, multi_bit)
}
ParametersSet::All => {
let desired_noise = DesiredNoiseDistribution::Both;
let desired_backend = if cfg!(feature = "gpu") {
DesiredBackend::Gpu
} else {
DesiredBackend::Cpu
};
let classic = filter_parameters(
&VEC_ALL_CLASSIC_PBS_PARAMETERS,
desired_noise,
DesiredBackend::Cpu, // No parameters set are specific to GPU in this vector
)
})
.collect::<Vec<(String, CryptoParametersRecord<u64>)>>();
let multi_bit = SHORTINT_MULTI_BIT_BENCH_PARAMS
.iter()
.map(|params| {
(
params.name(),
<MultiBitPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
.into_iter()
.map(|(params, name)| {
(
name.to_string(),
<ClassicPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
)
})
.collect::<Vec<(String, CryptoParametersRecord<u64>)>>();
let multi_bit = filter_parameters(
&VEC_ALL_MULTI_BIT_PBS_PARAMETERS,
desired_noise,
desired_backend,
)
})
.collect();
.into_iter()
.map(|(params, name)| {
(
name.to_string(),
<MultiBitPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
)
})
.collect();
(classic, multi_bit)
}
};
[classic, multi_bit].concat()
}
@@ -526,6 +583,7 @@ mod cuda {
#[cfg(feature = "gpu")]
use cuda::cuda_keyswitch_group;
use tfhe::shortint::parameters::v1_0::VEC_ALL_CLASSIC_PBS_PARAMETERS;
pub fn keyswitch_group() {
let mut criterion: Criterion<_> = (Criterion::default()
@@ -555,7 +613,24 @@ pub fn packing_keyswitch_group() {
);
}
#[cfg(not(feature = "gpu"))]
criterion_main!(keyswitch_group, packing_keyswitch_group);
#[cfg(feature = "gpu")]
criterion_main!(cuda_keyswitch_group);
fn go_through_gpu_bench_groups() {
cuda_keyswitch_group();
}
#[cfg(not(feature = "gpu"))]
fn go_through_cpu_bench_groups() {
keyswitch_group();
packing_keyswitch_group();
}
fn main() {
init_parameters_set();
#[cfg(feature = "gpu")]
go_through_gpu_bench_groups();
#[cfg(not(feature = "gpu"))]
go_through_cpu_bench_groups();
Criterion::default().configure_from_args().final_summary();
}

View File

@@ -0,0 +1,760 @@
#[path = "../utilities.rs"]
mod utilities;
use crate::utilities::{
filter_parameters, init_parameters_set, multi_bit_num_threads, write_to_json,
CryptoParametersRecord, DesiredBackend, DesiredNoiseDistribution, OperatorType, ParametersSet,
PARAMETERS_SET,
};
use criterion::{black_box, Criterion};
use serde::Serialize;
use std::env;
use tfhe::core_crypto::prelude::*;
use tfhe::keycache::NamedParam;
use tfhe::shortint::parameters::current_params::*;
use tfhe::shortint::parameters::*;
const SHORTINT_BENCH_PARAMS_TUNIFORM: [ClassicPBSParameters; 4] = [
V1_0_PARAM_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128,
V1_0_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
V1_0_PARAM_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128,
V1_0_PARAM_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128,
];
const SHORTINT_BENCH_PARAMS_GAUSSIAN: [ClassicPBSParameters; 4] = [
V1_0_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M128,
];
#[cfg(feature = "gpu")]
const SHORTINT_MULTI_BIT_BENCH_PARAMS: [MultiBitPBSParameters; 6] = [
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
];
#[cfg(not(feature = "gpu"))]
const SHORTINT_MULTI_BIT_BENCH_PARAMS: [MultiBitPBSParameters; 6] = [
V1_0_PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
];
fn benchmark_parameters() -> Vec<(String, CryptoParametersRecord<u64>)> {
match PARAMETERS_SET.get().unwrap() {
ParametersSet::Default => SHORTINT_BENCH_PARAMS_TUNIFORM
.iter()
.chain(SHORTINT_BENCH_PARAMS_GAUSSIAN.iter())
.map(|params| {
(
params.name(),
<ClassicPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
)
})
.collect(),
ParametersSet::All => {
filter_parameters(
&VEC_ALL_CLASSIC_PBS_PARAMETERS,
DesiredNoiseDistribution::Both,
DesiredBackend::Cpu, // No parameters set are specific to GPU in this vector
)
.into_iter()
.map(|(params, name)| {
(
name.to_string(),
<ClassicPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
)
})
.collect()
}
}
}
fn multi_bit_benchmark_parameters(
) -> Vec<(String, CryptoParametersRecord<u64>, LweBskGroupingFactor)> {
match PARAMETERS_SET.get().unwrap() {
ParametersSet::Default => SHORTINT_MULTI_BIT_BENCH_PARAMS
.iter()
.map(|params| {
(
params.name(),
<MultiBitPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
params.grouping_factor,
)
})
.collect(),
ParametersSet::All => {
let desired_backend = if cfg!(feature = "gpu") {
DesiredBackend::Gpu
} else {
DesiredBackend::Cpu
};
filter_parameters(
&VEC_ALL_MULTI_BIT_PBS_PARAMETERS,
DesiredNoiseDistribution::Both,
desired_backend,
)
.into_iter()
.map(|(params, name)| {
(
name.to_string(),
<MultiBitPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
params.grouping_factor,
)
})
.collect()
}
}
}
fn ks_pbs<Scalar: UnsignedTorus + CastInto<usize> + Serialize>(
c: &mut Criterion,
parameters: &[(String, CryptoParametersRecord<Scalar>)],
) {
let bench_name = "core_crypto::ks_pbs";
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
let seeder = seeder.as_mut();
let mut encryption_generator =
EncryptionRandomGenerator::<DefaultRandomGenerator>::new(seeder.seed(), seeder);
let mut secret_generator = SecretRandomGenerator::<DefaultRandomGenerator>::new(seeder.seed());
for (name, params) in parameters.iter() {
// Create the LweSecretKey
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
params.lwe_dimension.unwrap(),
&mut secret_generator,
);
let output_glwe_secret_key: GlweSecretKeyOwned<Scalar> =
allocate_and_generate_new_binary_glwe_secret_key(
params.glwe_dimension.unwrap(),
params.polynomial_size.unwrap(),
&mut secret_generator,
);
let output_lwe_secret_key = output_glwe_secret_key.into_lwe_secret_key();
let ksk_big_to_small = allocate_and_generate_new_lwe_keyswitch_key(
&output_lwe_secret_key,
&input_lwe_secret_key,
params.ks_base_log.unwrap(),
params.ks_level.unwrap(),
params.lwe_noise_distribution.unwrap(),
params.ciphertext_modulus.unwrap(),
&mut encryption_generator,
);
// Create the empty bootstrapping key in the Fourier domain
let fourier_bsk = FourierLweBootstrapKey::new(
params.lwe_dimension.unwrap(),
params.glwe_dimension.unwrap().to_glwe_size(),
params.polynomial_size.unwrap(),
params.pbs_base_log.unwrap(),
params.pbs_level.unwrap(),
);
// Allocate a new LweCiphertext and encrypt our plaintext
let input_ks_ct: LweCiphertextOwned<Scalar> = allocate_and_encrypt_new_lwe_ciphertext(
&output_lwe_secret_key,
Plaintext(Scalar::ONE),
params.lwe_noise_distribution.unwrap(),
params.ciphertext_modulus.unwrap(),
&mut encryption_generator,
);
let mut output_ks_ct: LweCiphertextOwned<Scalar> = LweCiphertext::new(
Scalar::ZERO,
input_lwe_secret_key.lwe_dimension().to_lwe_size(),
params.ciphertext_modulus.unwrap(),
);
let accumulator = GlweCiphertext::new(
Scalar::ZERO,
params.glwe_dimension.unwrap().to_glwe_size(),
params.polynomial_size.unwrap(),
params.ciphertext_modulus.unwrap(),
);
// Allocate the LweCiphertext to store the result of the PBS
let mut output_pbs_ct = LweCiphertext::new(
Scalar::ZERO,
output_lwe_secret_key.lwe_dimension().to_lwe_size(),
params.ciphertext_modulus.unwrap(),
);
let mut buffers = ComputationBuffers::new();
let fft = Fft::new(fourier_bsk.polynomial_size());
let fft = fft.as_view();
buffers.resize(
programmable_bootstrap_lwe_ciphertext_mem_optimized_requirement::<Scalar>(
fourier_bsk.glwe_size(),
fourier_bsk.polynomial_size(),
fft,
)
.unwrap()
.unaligned_bytes_required(),
);
let id = format!("{bench_name}::{name}");
{
bench_group.bench_function(&id, |b| {
b.iter(|| {
keyswitch_lwe_ciphertext(&ksk_big_to_small, &input_ks_ct, &mut output_ks_ct);
programmable_bootstrap_lwe_ciphertext_mem_optimized(
&output_ks_ct,
&mut output_pbs_ct,
&accumulator.as_view(),
&fourier_bsk,
fft,
buffers.stack(),
);
black_box(&mut output_pbs_ct);
})
});
}
let bit_size = (params.message_modulus.unwrap_or(2) as u32).ilog2();
write_to_json(
&id,
*params,
name,
"ks-pbs",
&OperatorType::Atomic,
bit_size,
vec![bit_size],
);
}
}
fn multi_bit_ks_pbs<
Scalar: UnsignedTorus + CastInto<usize> + CastFrom<usize> + Default + Sync + Serialize,
>(
c: &mut Criterion,
parameters: &[(String, CryptoParametersRecord<Scalar>, LweBskGroupingFactor)],
deterministic_pbs: bool,
) {
let bench_name = if deterministic_pbs {
"core_crypto::multi_bit_deterministic_ks_pbs"
} else {
"core_crypto::multi_bit_ks_pbs"
};
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
let seeder = seeder.as_mut();
let mut encryption_generator =
EncryptionRandomGenerator::<DefaultRandomGenerator>::new(seeder.seed(), seeder);
let mut secret_generator = SecretRandomGenerator::<DefaultRandomGenerator>::new(seeder.seed());
for (name, params, grouping_factor) in parameters.iter() {
// Create the LweSecretKey
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
params.lwe_dimension.unwrap(),
&mut secret_generator,
);
let output_glwe_secret_key: GlweSecretKeyOwned<Scalar> =
allocate_and_generate_new_binary_glwe_secret_key(
params.glwe_dimension.unwrap(),
params.polynomial_size.unwrap(),
&mut secret_generator,
);
let output_lwe_secret_key = output_glwe_secret_key.into_lwe_secret_key();
let ksk_big_to_small = allocate_and_generate_new_lwe_keyswitch_key(
&output_lwe_secret_key,
&input_lwe_secret_key,
params.ks_base_log.unwrap(),
params.ks_level.unwrap(),
params.lwe_noise_distribution.unwrap(),
params.ciphertext_modulus.unwrap(),
&mut encryption_generator,
);
let multi_bit_bsk = FourierLweMultiBitBootstrapKey::new(
params.lwe_dimension.unwrap(),
params.glwe_dimension.unwrap().to_glwe_size(),
params.polynomial_size.unwrap(),
params.pbs_base_log.unwrap(),
params.pbs_level.unwrap(),
*grouping_factor,
);
// Allocate a new LweCiphertext and encrypt our plaintext
let input_ks_ct: LweCiphertextOwned<Scalar> = allocate_and_encrypt_new_lwe_ciphertext(
&output_lwe_secret_key,
Plaintext(Scalar::ONE),
params.lwe_noise_distribution.unwrap(),
params.ciphertext_modulus.unwrap(),
&mut encryption_generator,
);
let mut output_ks_ct: LweCiphertextOwned<Scalar> = LweCiphertext::new(
Scalar::ZERO,
input_lwe_secret_key.lwe_dimension().to_lwe_size(),
params.ciphertext_modulus.unwrap(),
);
let accumulator = GlweCiphertext::new(
Scalar::ZERO,
params.glwe_dimension.unwrap().to_glwe_size(),
params.polynomial_size.unwrap(),
params.ciphertext_modulus.unwrap(),
);
// Allocate the LweCiphertext to store the result of the PBS
let mut output_pbs_ct = LweCiphertext::new(
Scalar::ZERO,
output_lwe_secret_key.lwe_dimension().to_lwe_size(),
params.ciphertext_modulus.unwrap(),
);
let thread_count = multi_bit_num_threads(
params.message_modulus.unwrap(),
params.carry_modulus.unwrap(),
grouping_factor.0,
)
.unwrap() as usize;
let id = format!("{bench_name}::{name}::parallelized");
bench_group.bench_function(&id, |b| {
b.iter(|| {
keyswitch_lwe_ciphertext(&ksk_big_to_small, &input_ks_ct, &mut output_ks_ct);
multi_bit_programmable_bootstrap_lwe_ciphertext(
&output_ks_ct,
&mut output_pbs_ct,
&accumulator.as_view(),
&multi_bit_bsk,
ThreadCount(thread_count),
deterministic_pbs,
);
black_box(&mut output_pbs_ct);
})
});
let bit_size = params.message_modulus.unwrap().ilog2();
write_to_json(
&id,
*params,
name,
"ks-pbs",
&OperatorType::Atomic,
bit_size,
vec![bit_size],
);
}
}
#[cfg(feature = "gpu")]
mod cuda {
use super::{benchmark_parameters, multi_bit_benchmark_parameters};
use crate::utilities::{
write_to_json, CryptoParametersRecord, OperatorType, GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE,
};
use criterion::{black_box, Criterion};
use serde::Serialize;
use tfhe::core_crypto::gpu::glwe_ciphertext_list::CudaGlweCiphertextList;
use tfhe::core_crypto::gpu::lwe_bootstrap_key::CudaLweBootstrapKey;
use tfhe::core_crypto::gpu::lwe_ciphertext_list::CudaLweCiphertextList;
use tfhe::core_crypto::gpu::lwe_keyswitch_key::CudaLweKeyswitchKey;
use tfhe::core_crypto::gpu::lwe_multi_bit_bootstrap_key::CudaLweMultiBitBootstrapKey;
use tfhe::core_crypto::gpu::vec::{CudaVec, GpuIndex};
use tfhe::core_crypto::gpu::{
cuda_keyswitch_lwe_ciphertext, cuda_multi_bit_programmable_bootstrap_lwe_ciphertext,
cuda_programmable_bootstrap_lwe_ciphertext, CudaStreams,
};
use tfhe::core_crypto::prelude::*;
fn cuda_ks_pbs<Scalar: UnsignedTorus + CastInto<usize> + Serialize>(
c: &mut Criterion,
parameters: &[(String, CryptoParametersRecord<Scalar>)],
) {
let bench_name = "core_crypto::cuda::ks_pbs";
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
let seeder = seeder.as_mut();
let mut encryption_generator =
EncryptionRandomGenerator::<DefaultRandomGenerator>::new(seeder.seed(), seeder);
let mut secret_generator =
SecretRandomGenerator::<DefaultRandomGenerator>::new(seeder.seed());
let gpu_index = 0;
let stream = CudaStreams::new_single_gpu(GpuIndex::new(gpu_index));
for (name, params) in parameters.iter() {
if params.polynomial_size.unwrap().0 > GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE {
println!("[WARNING] polynomial size is too large for parameters set '{}' (max: {}, got: {})", name, GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE, params.polynomial_size.unwrap().0);
continue;
}
// Create the LweSecretKey
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
params.lwe_dimension.unwrap(),
&mut secret_generator,
);
let output_glwe_secret_key: GlweSecretKeyOwned<Scalar> =
allocate_and_generate_new_binary_glwe_secret_key(
params.glwe_dimension.unwrap(),
params.polynomial_size.unwrap(),
&mut secret_generator,
);
let output_lwe_secret_key = output_glwe_secret_key.into_lwe_secret_key();
let ksk_big_to_small = allocate_and_generate_new_lwe_keyswitch_key(
&output_lwe_secret_key,
&input_lwe_secret_key,
params.ks_base_log.unwrap(),
params.ks_level.unwrap(),
params.lwe_noise_distribution.unwrap(),
CiphertextModulus::new_native(),
&mut encryption_generator,
);
let ksk_big_to_small_gpu =
CudaLweKeyswitchKey::from_lwe_keyswitch_key(&ksk_big_to_small, &stream);
let bsk = LweBootstrapKey::new(
Scalar::ZERO,
params.glwe_dimension.unwrap().to_glwe_size(),
params.polynomial_size.unwrap(),
params.pbs_base_log.unwrap(),
params.pbs_level.unwrap(),
params.lwe_dimension.unwrap(),
params.ciphertext_modulus.unwrap(),
);
let bsk_gpu = CudaLweBootstrapKey::from_lwe_bootstrap_key(&bsk, &stream);
// Allocate a new LweCiphertext and encrypt our plaintext
let input_ks_ct = allocate_and_encrypt_new_lwe_ciphertext(
&input_lwe_secret_key,
Plaintext(Scalar::ZERO),
params.lwe_noise_distribution.unwrap(),
params.ciphertext_modulus.unwrap(),
&mut encryption_generator,
);
let input_ks_ct_gpu = CudaLweCiphertextList::from_lwe_ciphertext(&input_ks_ct, &stream);
let output_ks_ct: LweCiphertextOwned<Scalar> = LweCiphertext::new(
Scalar::ZERO,
input_lwe_secret_key.lwe_dimension().to_lwe_size(),
params.ciphertext_modulus.unwrap(),
);
let mut output_ks_ct_gpu =
CudaLweCiphertextList::from_lwe_ciphertext(&output_ks_ct, &stream);
let accumulator = GlweCiphertext::new(
Scalar::ZERO,
params.glwe_dimension.unwrap().to_glwe_size(),
params.polynomial_size.unwrap(),
params.ciphertext_modulus.unwrap(),
);
let accumulator_gpu =
CudaGlweCiphertextList::from_glwe_ciphertext(&accumulator, &stream);
// Allocate the LweCiphertext to store the result of the PBS
let output_pbs_ct = LweCiphertext::new(
Scalar::ZERO,
output_lwe_secret_key.lwe_dimension().to_lwe_size(),
params.ciphertext_modulus.unwrap(),
);
let mut output_pbs_ct_gpu =
CudaLweCiphertextList::from_lwe_ciphertext(&output_pbs_ct, &stream);
let h_indexes = &[Scalar::ZERO];
stream.synchronize();
let mut d_input_indexes = unsafe { CudaVec::<Scalar>::new_async(1, &stream, 0) };
let mut d_output_indexes = unsafe { CudaVec::<Scalar>::new_async(1, &stream, 0) };
let mut d_lut_indexes = unsafe { CudaVec::<Scalar>::new_async(1, &stream, 0) };
unsafe {
d_input_indexes.copy_from_cpu_async(h_indexes.as_ref(), &stream, 0);
d_output_indexes.copy_from_cpu_async(h_indexes.as_ref(), &stream, 0);
d_lut_indexes.copy_from_cpu_async(h_indexes.as_ref(), &stream, 0);
}
stream.synchronize();
let id = format!("{bench_name}::{name}");
{
bench_group.bench_function(&id, |b| {
b.iter(|| {
cuda_keyswitch_lwe_ciphertext(
&ksk_big_to_small_gpu,
&input_ks_ct_gpu,
&mut output_ks_ct_gpu,
&d_input_indexes,
&d_output_indexes,
&stream,
);
cuda_programmable_bootstrap_lwe_ciphertext(
&output_ks_ct_gpu,
&mut output_pbs_ct_gpu,
&accumulator_gpu,
&d_lut_indexes,
&d_output_indexes,
&d_input_indexes,
LweCiphertextCount(1),
&bsk_gpu,
&stream,
);
black_box(&mut output_pbs_ct_gpu);
})
});
}
let bit_size = (params.message_modulus.unwrap_or(2) as u32).ilog2();
write_to_json(
&id,
*params,
name,
"ks-pbs",
&OperatorType::Atomic,
bit_size,
vec![bit_size],
);
}
}
fn cuda_multi_bit_ks_pbs<
Scalar: UnsignedTorus + CastInto<usize> + CastFrom<usize> + Default + Serialize + Sync,
>(
c: &mut Criterion,
parameters: &[(String, CryptoParametersRecord<Scalar>, LweBskGroupingFactor)],
) {
let bench_name = "core_crypto::cuda::multi_bit_ks_pbs";
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
let seeder = seeder.as_mut();
let mut encryption_generator =
EncryptionRandomGenerator::<DefaultRandomGenerator>::new(seeder.seed(), seeder);
let mut secret_generator =
SecretRandomGenerator::<DefaultRandomGenerator>::new(seeder.seed());
let gpu_index = 0;
let stream = CudaStreams::new_single_gpu(GpuIndex::new(gpu_index));
for (name, params, grouping_factor) in parameters.iter() {
if params.polynomial_size.unwrap().0 > GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE {
println!("[WARNING] polynomial size is too large for parameters set '{}' (max: {}, got: {})", name, GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE, params.polynomial_size.unwrap().0);
continue;
}
// Create the LweSecretKey
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
params.lwe_dimension.unwrap(),
&mut secret_generator,
);
let output_glwe_secret_key: GlweSecretKeyOwned<Scalar> =
allocate_and_generate_new_binary_glwe_secret_key(
params.glwe_dimension.unwrap(),
params.polynomial_size.unwrap(),
&mut secret_generator,
);
let output_lwe_secret_key = output_glwe_secret_key.into_lwe_secret_key();
let ksk_big_to_small = allocate_and_generate_new_lwe_keyswitch_key(
&output_lwe_secret_key,
&input_lwe_secret_key,
params.ks_base_log.unwrap(),
params.ks_level.unwrap(),
params.lwe_noise_distribution.unwrap(),
CiphertextModulus::new_native(),
&mut encryption_generator,
);
let ksk_big_to_small_gpu =
CudaLweKeyswitchKey::from_lwe_keyswitch_key(&ksk_big_to_small, &stream);
let multi_bit_bsk = LweMultiBitBootstrapKey::new(
Scalar::ZERO,
params.glwe_dimension.unwrap().to_glwe_size(),
params.polynomial_size.unwrap(),
params.pbs_base_log.unwrap(),
params.pbs_level.unwrap(),
params.lwe_dimension.unwrap(),
*grouping_factor,
params.ciphertext_modulus.unwrap(),
);
let multi_bit_bsk_gpu = CudaLweMultiBitBootstrapKey::from_lwe_multi_bit_bootstrap_key(
&multi_bit_bsk,
&stream,
);
// Allocate a new LweCiphertext and encrypt our plaintext
let input_ks_ct = allocate_and_encrypt_new_lwe_ciphertext(
&input_lwe_secret_key,
Plaintext(Scalar::ZERO),
params.lwe_noise_distribution.unwrap(),
params.ciphertext_modulus.unwrap(),
&mut encryption_generator,
);
let input_ks_ct_gpu = CudaLweCiphertextList::from_lwe_ciphertext(&input_ks_ct, &stream);
let output_ks_ct: LweCiphertextOwned<Scalar> = LweCiphertext::new(
Scalar::ZERO,
input_lwe_secret_key.lwe_dimension().to_lwe_size(),
params.ciphertext_modulus.unwrap(),
);
let mut output_ks_ct_gpu =
CudaLweCiphertextList::from_lwe_ciphertext(&output_ks_ct, &stream);
let accumulator = GlweCiphertext::new(
Scalar::ZERO,
params.glwe_dimension.unwrap().to_glwe_size(),
params.polynomial_size.unwrap(),
params.ciphertext_modulus.unwrap(),
);
let accumulator_gpu =
CudaGlweCiphertextList::from_glwe_ciphertext(&accumulator, &stream);
// Allocate the LweCiphertext to store the result of the PBS
let output_pbs_ct = LweCiphertext::new(
Scalar::ZERO,
output_lwe_secret_key.lwe_dimension().to_lwe_size(),
params.ciphertext_modulus.unwrap(),
);
let mut output_pbs_ct_gpu =
CudaLweCiphertextList::from_lwe_ciphertext(&output_pbs_ct, &stream);
let h_indexes = &[Scalar::ZERO];
stream.synchronize();
let mut d_input_indexes = unsafe { CudaVec::<Scalar>::new_async(1, &stream, 0) };
let mut d_output_indexes = unsafe { CudaVec::<Scalar>::new_async(1, &stream, 0) };
let mut d_lut_indexes = unsafe { CudaVec::<Scalar>::new_async(1, &stream, 0) };
unsafe {
d_input_indexes.copy_from_cpu_async(h_indexes.as_ref(), &stream, 0);
d_output_indexes.copy_from_cpu_async(h_indexes.as_ref(), &stream, 0);
d_lut_indexes.copy_from_cpu_async(h_indexes.as_ref(), &stream, 0);
}
stream.synchronize();
let id = format!("{bench_name}::{name}");
bench_group.bench_function(&id, |b| {
b.iter(|| {
cuda_keyswitch_lwe_ciphertext(
&ksk_big_to_small_gpu,
&input_ks_ct_gpu,
&mut output_ks_ct_gpu,
&d_input_indexes,
&d_output_indexes,
&stream,
);
cuda_multi_bit_programmable_bootstrap_lwe_ciphertext(
&output_ks_ct_gpu,
&mut output_pbs_ct_gpu,
&accumulator_gpu,
&d_lut_indexes,
&d_output_indexes,
&d_input_indexes,
&multi_bit_bsk_gpu,
&stream,
);
black_box(&mut output_ks_ct_gpu);
})
});
let bit_size = params.message_modulus.unwrap().ilog2();
write_to_json(
&id,
*params,
name,
"ks-pbs",
&OperatorType::Atomic,
bit_size,
vec![bit_size],
);
}
}
pub fn cuda_ks_pbs_group() {
let mut criterion: Criterion<_> = (Criterion::default()).configure_from_args();
cuda_ks_pbs(&mut criterion, &benchmark_parameters());
}
pub fn cuda_multi_bit_ks_pbs_group() {
let mut criterion: Criterion<_> = (Criterion::default()).configure_from_args();
cuda_multi_bit_ks_pbs(&mut criterion, &multi_bit_benchmark_parameters());
}
}
#[cfg(feature = "gpu")]
use cuda::{cuda_ks_pbs_group, cuda_multi_bit_ks_pbs_group};
pub fn ks_pbs_group() {
let mut criterion: Criterion<_> = (Criterion::default()).configure_from_args();
ks_pbs(&mut criterion, &benchmark_parameters());
}
pub fn multi_bit_ks_pbs_group() {
let mut criterion: Criterion<_> = (Criterion::default()).configure_from_args();
multi_bit_ks_pbs(&mut criterion, &multi_bit_benchmark_parameters(), false);
multi_bit_ks_pbs(&mut criterion, &multi_bit_benchmark_parameters(), true);
}
#[cfg(feature = "gpu")]
fn go_through_gpu_bench_groups(val: &str) {
match val.to_lowercase().as_str() {
"classical" => cuda_ks_pbs_group(),
"multi_bit" => cuda_multi_bit_ks_pbs_group(),
_ => panic!("unknown benchmark operations flavor"),
};
}
#[cfg(not(feature = "gpu"))]
fn go_through_cpu_bench_groups(val: &str) {
match val.to_lowercase().as_str() {
"classical" => ks_pbs_group(),
"multi_bit" => multi_bit_ks_pbs_group(),
_ => panic!("unknown benchmark operations flavor"),
}
}
fn main() {
init_parameters_set();
match env::var("__TFHE_RS_PARAM_TYPE") {
Ok(val) => {
#[cfg(feature = "gpu")]
go_through_gpu_bench_groups(&val);
#[cfg(not(feature = "gpu"))]
go_through_cpu_bench_groups(&val);
}
Err(_) => {
ks_pbs_group();
multi_bit_ks_pbs_group()
}
};
Criterion::default().configure_from_args().final_summary();
}

View File

@@ -1,8 +1,12 @@
#[path = "../utilities.rs"]
mod utilities;
use crate::utilities::{write_to_json, CryptoParametersRecord, OperatorType};
use criterion::{black_box, criterion_main, Criterion};
use crate::utilities::{
filter_parameters, init_parameters_set, multi_bit_num_threads, write_to_json,
CryptoParametersRecord, DesiredBackend, DesiredNoiseDistribution, OperatorType, ParametersSet,
PARAMETERS_SET,
};
use criterion::{black_box, Criterion};
use rayon::prelude::*;
use serde::Serialize;
use tfhe::boolean::parameters::{
@@ -14,8 +18,12 @@ use tfhe::keycache::NamedParam;
use tfhe::shortint::parameters::current_params::*;
use tfhe::shortint::parameters::*;
const SHORTINT_BENCH_PARAMS_TUNIFORM: [ClassicPBSParameters; 1] =
[PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128];
const SHORTINT_BENCH_PARAMS_TUNIFORM: [ClassicPBSParameters; 4] = [
V1_0_PARAM_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M128,
V1_0_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
V1_0_PARAM_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M128,
V1_0_PARAM_MESSAGE_4_CARRY_4_KS_PBS_TUNIFORM_2M128,
];
const SHORTINT_BENCH_PARAMS_GAUSSIAN: [ClassicPBSParameters; 4] = [
V1_0_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
@@ -24,6 +32,26 @@ const SHORTINT_BENCH_PARAMS_GAUSSIAN: [ClassicPBSParameters; 4] = [
V1_0_PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M128,
];
#[cfg(feature = "gpu")]
const SHORTINT_MULTI_BIT_BENCH_PARAMS: [MultiBitPBSParameters; 6] = [
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
];
#[cfg(not(feature = "gpu"))]
const SHORTINT_MULTI_BIT_BENCH_PARAMS: [MultiBitPBSParameters; 6] = [
V1_0_PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
];
const BOOLEAN_BENCH_PARAMS: [(&str, BooleanParameters); 2] = [
("BOOLEAN_DEFAULT_PARAMS", DEFAULT_PARAMETERS),
(
@@ -33,18 +61,35 @@ const BOOLEAN_BENCH_PARAMS: [(&str, BooleanParameters); 2] = [
];
fn benchmark_parameters_64bits() -> Vec<(String, CryptoParametersRecord<u64>)> {
SHORTINT_BENCH_PARAMS_TUNIFORM
.iter()
.chain(SHORTINT_BENCH_PARAMS_GAUSSIAN.iter())
.map(|params| {
match PARAMETERS_SET.get().unwrap() {
ParametersSet::Default => SHORTINT_BENCH_PARAMS_TUNIFORM
.iter()
.chain(SHORTINT_BENCH_PARAMS_GAUSSIAN.iter())
.map(|params| {
(
params.name(),
<ClassicPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
)
})
.collect(),
ParametersSet::All => filter_parameters(
&VEC_ALL_CLASSIC_PBS_PARAMETERS,
DesiredNoiseDistribution::Both,
DesiredBackend::Cpu, // No parameters set are specific to GPU in this vector
)
.into_iter()
.map(|(params, name)| {
(
params.name(),
name.to_string(),
<ClassicPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
)
})
.collect()
.collect(),
}
}
fn benchmark_parameters_32bits() -> Vec<(String, CryptoParametersRecord<u32>)> {
@@ -94,36 +139,43 @@ fn throughput_benchmark_parameters_32bits() -> Vec<(String, CryptoParametersReco
fn multi_bit_benchmark_parameters_64bits(
) -> Vec<(String, CryptoParametersRecord<u64>, LweBskGroupingFactor)> {
let parameters = if cfg!(feature = "gpu") {
vec![
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
]
} else {
vec![
V1_0_PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
V1_0_PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
]
};
parameters
.iter()
.map(|params| {
(
params.name(),
<MultiBitPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
params.grouping_factor,
match PARAMETERS_SET.get().unwrap() {
ParametersSet::Default => SHORTINT_MULTI_BIT_BENCH_PARAMS
.iter()
.map(|params| {
(
params.name(),
<MultiBitPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
params.grouping_factor,
)
})
.collect(),
ParametersSet::All => {
let desired_backend = if cfg!(feature = "gpu") {
DesiredBackend::Gpu
} else {
DesiredBackend::Cpu
};
filter_parameters(
&VEC_ALL_MULTI_BIT_PBS_PARAMETERS,
DesiredNoiseDistribution::Both,
desired_backend,
)
})
.collect()
.into_iter()
.map(|(params, name)| {
(
name.to_string(),
<MultiBitPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
params.grouping_factor,
)
})
.collect()
}
}
}
fn mem_optimized_pbs<Scalar: UnsignedTorus + CastInto<usize> + Serialize>(
@@ -133,8 +185,8 @@ fn mem_optimized_pbs<Scalar: UnsignedTorus + CastInto<usize> + Serialize>(
let bench_name = "core_crypto::pbs_mem_optimized";
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(15)
.measurement_time(std::time::Duration::from_secs(60));
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
@@ -359,12 +411,17 @@ fn multi_bit_pbs<
>(
c: &mut Criterion,
parameters: &[(String, CryptoParametersRecord<Scalar>, LweBskGroupingFactor)],
deterministic_pbs: bool,
) {
let bench_name = "core_crypto::multi_bit_pbs";
let bench_name = if deterministic_pbs {
"core_crypto::multi_bit_deterministic_pbs"
} else {
"core_crypto::multi_bit_pbs"
};
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(15)
.measurement_time(std::time::Duration::from_secs(60));
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
@@ -419,98 +476,12 @@ fn multi_bit_pbs<
params.ciphertext_modulus.unwrap(),
);
let id = format!("{bench_name}::{name}::parallelized");
bench_group.bench_function(&id, |b| {
b.iter(|| {
multi_bit_programmable_bootstrap_lwe_ciphertext(
&lwe_ciphertext_in,
&mut out_pbs_ct,
&accumulator.as_view(),
&multi_bit_bsk,
ThreadCount(10),
false,
);
black_box(&mut out_pbs_ct);
})
});
let bit_size = params.message_modulus.unwrap().ilog2();
write_to_json(
&id,
*params,
name,
"pbs",
&OperatorType::Atomic,
bit_size,
vec![bit_size],
);
}
}
fn multi_bit_deterministic_pbs<
Scalar: UnsignedTorus + CastInto<usize> + CastFrom<usize> + Default + Serialize + Sync,
>(
c: &mut Criterion,
parameters: &[(String, CryptoParametersRecord<Scalar>, LweBskGroupingFactor)],
) {
let bench_name = "core_crypto::multi_bit_deterministic_pbs";
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(15)
.measurement_time(std::time::Duration::from_secs(60));
// Create the PRNG
let mut seeder = new_seeder();
let seeder = seeder.as_mut();
let mut encryption_generator =
EncryptionRandomGenerator::<DefaultRandomGenerator>::new(seeder.seed(), seeder);
let mut secret_generator = SecretRandomGenerator::<DefaultRandomGenerator>::new(seeder.seed());
for (name, params, grouping_factor) in parameters.iter() {
// Create the LweSecretKey
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
params.lwe_dimension.unwrap(),
&mut secret_generator,
);
let output_glwe_secret_key: GlweSecretKeyOwned<Scalar> =
allocate_and_generate_new_binary_glwe_secret_key(
params.glwe_dimension.unwrap(),
params.polynomial_size.unwrap(),
&mut secret_generator,
);
let output_lwe_secret_key = output_glwe_secret_key.into_lwe_secret_key();
let multi_bit_bsk = FourierLweMultiBitBootstrapKey::new(
params.lwe_dimension.unwrap(),
params.glwe_dimension.unwrap().to_glwe_size(),
params.polynomial_size.unwrap(),
params.pbs_base_log.unwrap(),
params.pbs_level.unwrap(),
*grouping_factor,
);
// Allocate a new LweCiphertext and encrypt our plaintext
let lwe_ciphertext_in = allocate_and_encrypt_new_lwe_ciphertext(
&input_lwe_secret_key,
Plaintext(Scalar::ZERO),
params.lwe_noise_distribution.unwrap(),
params.ciphertext_modulus.unwrap(),
&mut encryption_generator,
);
let accumulator = GlweCiphertext::new(
Scalar::ZERO,
params.glwe_dimension.unwrap().to_glwe_size(),
params.polynomial_size.unwrap(),
params.ciphertext_modulus.unwrap(),
);
// Allocate the LweCiphertext to store the result of the PBS
let mut out_pbs_ct = LweCiphertext::new(
Scalar::ZERO,
output_lwe_secret_key.lwe_dimension().to_lwe_size(),
params.ciphertext_modulus.unwrap(),
);
let thread_count = multi_bit_num_threads(
params.message_modulus.unwrap(),
params.carry_modulus.unwrap(),
grouping_factor.0,
)
.unwrap() as usize;
let id = format!("{bench_name}::{name}::parallelized");
bench_group.bench_function(&id, |b| {
@@ -520,8 +491,8 @@ fn multi_bit_deterministic_pbs<
&mut out_pbs_ct,
&accumulator.as_view(),
&multi_bit_bsk,
ThreadCount(10),
true,
ThreadCount(thread_count),
deterministic_pbs,
);
black_box(&mut out_pbs_ct);
})
@@ -544,8 +515,8 @@ fn mem_optimized_pbs_ntt(c: &mut Criterion) {
let bench_name = "core_crypto::pbs_ntt";
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(15)
.measurement_time(std::time::Duration::from_secs(60));
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
@@ -698,8 +669,8 @@ fn pbs_throughput<Scalar: UnsignedTorus + CastInto<usize> + Sync + Send + Serial
let bench_name = "core_crypto::pbs_throughput";
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(15)
.measurement_time(std::time::Duration::from_secs(60));
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
@@ -817,8 +788,14 @@ fn pbs_throughput<Scalar: UnsignedTorus + CastInto<usize> + Sync + Send + Serial
#[cfg(feature = "gpu")]
mod cuda {
use super::{multi_bit_benchmark_parameters_64bits, throughput_benchmark_parameters_64bits};
use crate::utilities::{write_to_json, CryptoParametersRecord, EnvConfig, OperatorType};
use super::{
benchmark_parameters_64bits, multi_bit_benchmark_parameters_64bits,
throughput_benchmark_parameters_64bits,
};
use crate::utilities::{
write_to_json, CryptoParametersRecord, EnvConfig, OperatorType,
GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE,
};
use criterion::{black_box, Criterion};
use serde::Serialize;
use tfhe::core_crypto::gpu::glwe_ciphertext_list::CudaGlweCiphertextList;
@@ -831,43 +808,6 @@ mod cuda {
cuda_programmable_bootstrap_lwe_ciphertext, CudaStreams,
};
use tfhe::core_crypto::prelude::*;
use tfhe::keycache::NamedParam;
use tfhe::shortint::parameters::current_params::*;
use tfhe::shortint::parameters::*;
use tfhe::shortint::{ClassicPBSParameters, PBSParameters};
const SHORTINT_CUDA_BENCH_PARAMS: [ClassicPBSParameters; 14] = [
// TUniform
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
// Gaussian
V1_0_PARAM_MESSAGE_1_CARRY_0_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_2_CARRY_0_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_2_CARRY_1_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_3_CARRY_0_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_3_CARRY_2_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_4_CARRY_0_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_4_CARRY_3_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_5_CARRY_0_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_6_CARRY_0_KS_PBS_GAUSSIAN_2M128,
V1_0_PARAM_MESSAGE_7_CARRY_0_KS_PBS_GAUSSIAN_2M128,
];
fn cuda_benchmark_parameters_64bits() -> Vec<(String, CryptoParametersRecord<u64>)> {
SHORTINT_CUDA_BENCH_PARAMS
.iter()
.map(|params| {
(
params.name(),
<ClassicPBSParameters as Into<PBSParameters>>::into(*params)
.to_owned()
.into(),
)
})
.collect()
}
fn cuda_pbs<Scalar: UnsignedTorus + CastInto<usize> + Serialize>(
c: &mut Criterion,
@@ -876,8 +816,8 @@ mod cuda {
let bench_name = "core_crypto::cuda::pbs";
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(15)
.measurement_time(std::time::Duration::from_secs(60));
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
@@ -891,6 +831,11 @@ mod cuda {
let stream = CudaStreams::new_single_gpu(GpuIndex::new(gpu_index));
for (name, params) in parameters.iter() {
if params.polynomial_size.unwrap().0 > GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE {
println!("[WARNING] polynomial size is too large for parameters set '{}' (max: {}, got: {})", name, GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE, params.polynomial_size.unwrap().0);
continue;
}
// Create the LweSecretKey
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
params.lwe_dimension.unwrap(),
@@ -997,8 +942,8 @@ mod cuda {
let bench_name = "core_crypto::cuda::multi_bit_pbs";
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(15)
.measurement_time(std::time::Duration::from_secs(60));
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
@@ -1012,6 +957,11 @@ mod cuda {
let stream = CudaStreams::new_single_gpu(GpuIndex::new(gpu_index));
for (name, params, grouping_factor) in parameters.iter() {
if params.polynomial_size.unwrap().0 > GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE {
println!("[WARNING] polynomial size is too large for parameters set '{}' (max: {}, got: {})", name, GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE, params.polynomial_size.unwrap().0);
continue;
}
// Create the LweSecretKey
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
params.lwe_dimension.unwrap(),
@@ -1119,8 +1069,8 @@ mod cuda {
let bench_name = "core_crypto::cuda::pbs_throughput";
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(15)
.measurement_time(std::time::Duration::from_secs(60));
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
@@ -1134,6 +1084,11 @@ mod cuda {
let stream = CudaStreams::new_single_gpu(GpuIndex::new(gpu_index));
for (name, params) in parameters.iter() {
if params.polynomial_size.unwrap().0 > GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE {
println!("[WARNING] polynomial size is too large for parameters set '{}' (max: {}, got: {})", name, GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE, params.polynomial_size.unwrap().0);
continue;
}
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
params.lwe_dimension.unwrap(),
&mut secret_generator,
@@ -1259,8 +1214,8 @@ mod cuda {
let bench_name = "core_crypto::cuda::multi_bit_pbs_throughput";
let mut bench_group = c.benchmark_group(bench_name);
bench_group
.sample_size(15)
.measurement_time(std::time::Duration::from_secs(60));
.sample_size(10)
.measurement_time(std::time::Duration::from_secs(30));
// Create the PRNG
let mut seeder = new_seeder();
@@ -1274,6 +1229,11 @@ mod cuda {
let stream = CudaStreams::new_single_gpu(GpuIndex::new(gpu_index));
for (name, params, grouping_factor) in parameters.iter() {
if params.polynomial_size.unwrap().0 > GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE {
println!("[WARNING] polynomial size is too large for parameters set '{}' (max: {}, got: {})", name, GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE, params.polynomial_size.unwrap().0);
continue;
}
let input_lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
params.lwe_dimension.unwrap(),
&mut secret_generator,
@@ -1399,7 +1359,7 @@ mod cuda {
pub fn cuda_pbs_group() {
let mut criterion: Criterion<_> = (Criterion::default()).configure_from_args();
cuda_pbs(&mut criterion, &cuda_benchmark_parameters_64bits());
cuda_pbs(&mut criterion, &benchmark_parameters_64bits());
}
pub fn cuda_pbs_throughput_group() {
@@ -1434,8 +1394,16 @@ pub fn pbs_group() {
pub fn multi_bit_pbs_group() {
let mut criterion: Criterion<_> = (Criterion::default()).configure_from_args();
multi_bit_pbs(&mut criterion, &multi_bit_benchmark_parameters_64bits());
multi_bit_deterministic_pbs(&mut criterion, &multi_bit_benchmark_parameters_64bits());
multi_bit_pbs(
&mut criterion,
&multi_bit_benchmark_parameters_64bits(),
false,
);
multi_bit_pbs(
&mut criterion,
&multi_bit_benchmark_parameters_64bits(),
true,
);
}
pub fn pbs_throughput_group() {
@@ -1444,12 +1412,28 @@ pub fn pbs_throughput_group() {
pbs_throughput(&mut criterion, &throughput_benchmark_parameters_32bits());
}
#[cfg(not(feature = "gpu"))]
criterion_main!(pbs_group, multi_bit_pbs_group, pbs_throughput_group);
#[cfg(feature = "gpu")]
criterion_main!(
cuda_pbs_group,
cuda_multi_bit_pbs_group,
cuda_pbs_throughput_group,
cuda_multi_bit_pbs_throughput_group
);
fn go_through_gpu_bench_groups() {
cuda_pbs_group();
cuda_multi_bit_pbs_group();
cuda_pbs_throughput_group();
cuda_multi_bit_pbs_throughput_group();
}
#[cfg(not(feature = "gpu"))]
fn go_through_cpu_bench_groups() {
pbs_group();
multi_bit_pbs_group();
pbs_throughput_group();
}
fn main() {
init_parameters_set();
#[cfg(feature = "gpu")]
go_through_gpu_bench_groups();
#[cfg(not(feature = "gpu"))]
go_through_cpu_bench_groups();
Criterion::default().configure_from_args().final_summary();
}

View File

@@ -1,5 +1,7 @@
use serde::Serialize;
use std::collections::HashMap;
use std::path::PathBuf;
use std::sync::OnceLock;
use std::{env, fs};
use tfhe::core_crypto::prelude::*;
@@ -46,7 +48,8 @@ pub mod shortint_utils {
ShortintKeySwitchingParameters, PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128,
};
use tfhe::shortint::{
ClassicPBSParameters, MultiBitPBSParameters, PBSParameters, ShortintParameterSet,
CarryModulus, ClassicPBSParameters, MessageModulus, MultiBitPBSParameters, PBSParameters,
ShortintParameterSet,
};
/// An iterator that yields a succession of combinations
@@ -185,6 +188,181 @@ pub mod shortint_utils {
}
}
}
// This array has been built according to performance benchmarks measuring latency over a
// matrix of 4 parameters set, 3 grouping factor and a wide range of threads values.
// The values available here as u64 are the optimal number of threads to use for a given triplet
// representing one or more parameters set.
const MULTI_BIT_THREADS_ARRAY: [((MessageModulus, CarryModulus, LweBskGroupingFactor), u64);
12] = [
(
(MessageModulus(2), CarryModulus(2), LweBskGroupingFactor(2)),
5,
),
(
(MessageModulus(4), CarryModulus(4), LweBskGroupingFactor(2)),
5,
),
(
(MessageModulus(8), CarryModulus(8), LweBskGroupingFactor(2)),
5,
),
(
(
MessageModulus(16),
CarryModulus(16),
LweBskGroupingFactor(2),
),
5,
),
(
(MessageModulus(2), CarryModulus(2), LweBskGroupingFactor(3)),
7,
),
(
(MessageModulus(4), CarryModulus(4), LweBskGroupingFactor(3)),
9,
),
(
(MessageModulus(8), CarryModulus(8), LweBskGroupingFactor(3)),
10,
),
(
(
MessageModulus(16),
CarryModulus(16),
LweBskGroupingFactor(3),
),
10,
),
(
(MessageModulus(2), CarryModulus(2), LweBskGroupingFactor(4)),
11,
),
(
(MessageModulus(4), CarryModulus(4), LweBskGroupingFactor(4)),
13,
),
(
(MessageModulus(8), CarryModulus(8), LweBskGroupingFactor(4)),
11,
),
(
(
MessageModulus(16),
CarryModulus(16),
LweBskGroupingFactor(4),
),
11,
),
];
/// Define the number of threads to use for parameters doing multithreaded programmable
/// bootstrapping.
///
/// Parameters must have the same values between message and carry modulus.
/// Grouping factor 2, 3 and 4 are the only ones that are supported.
#[allow(dead_code)]
pub fn multi_bit_num_threads(
message_modulus: u64,
carry_modulus: u64,
grouping_factor: usize,
) -> Option<u64> {
// TODO Implement an interpolation mechanism for X_Y parameters set
if message_modulus != carry_modulus || [2, 3, 4].contains(&(grouping_factor as i32)) {
return None;
}
let thread_map: HashMap<(MessageModulus, CarryModulus, LweBskGroupingFactor), u64> =
HashMap::from_iter(MULTI_BIT_THREADS_ARRAY);
thread_map
.get(&(
MessageModulus(message_modulus),
CarryModulus(carry_modulus),
LweBskGroupingFactor(grouping_factor),
))
.copied()
}
#[allow(dead_code)]
pub static PARAMETERS_SET: OnceLock<ParametersSet> = OnceLock::new();
pub enum ParametersSet {
Default,
All,
}
#[allow(dead_code)]
impl ParametersSet {
pub fn from_env() -> Result<Self, String> {
let raw_value = env::var("__TFHE_RS_PARAMS_SET").unwrap_or("default".to_string());
match raw_value.to_lowercase().as_str() {
"default" => Ok(ParametersSet::Default),
"all" => Ok(ParametersSet::All),
_ => Err(format!("parameters set '{raw_value}' is not supported")),
}
}
}
#[allow(dead_code)]
pub fn init_parameters_set() {
PARAMETERS_SET.get_or_init(|| ParametersSet::from_env().unwrap());
}
#[allow(dead_code)]
#[derive(Clone, Copy, Debug)]
pub enum DesiredNoiseDistribution {
Gaussian,
TUniform,
Both,
}
#[allow(dead_code)]
#[derive(Clone, Copy, Debug)]
pub enum DesiredBackend {
Cpu,
Gpu,
}
#[allow(dead_code)]
impl DesiredBackend {
fn matches_parameter_name_backend(&self, param_name: &str) -> bool {
matches!(
(self, param_name.to_lowercase().contains("gpu")),
(DesiredBackend::Cpu, false) | (DesiredBackend::Gpu, true)
)
}
}
#[allow(dead_code)]
pub fn filter_parameters<'a, P: Copy + Into<PBSParameters>>(
params: &[(&'a P, &'a str)],
desired_noise_distribution: DesiredNoiseDistribution,
desired_backend: DesiredBackend,
) -> Vec<(&'a P, &'a str)> {
params
.iter()
.filter_map(|(p, name)| {
let temp_param: PBSParameters = (**p).into();
match (
temp_param.lwe_noise_distribution(),
desired_noise_distribution,
) {
// If it's one of the pairs, we continue the process.
(DynamicDistribution::Gaussian(_), DesiredNoiseDistribution::Gaussian)
| (DynamicDistribution::TUniform(_), DesiredNoiseDistribution::TUniform)
| (_, DesiredNoiseDistribution::Both) => (),
_ => return None,
}
if !desired_backend.matches_parameter_name_backend(name) {
return None;
};
Some((*p, *name))
})
.collect()
}
}
#[allow(unused_imports)]
@@ -357,6 +535,10 @@ pub fn write_to_json<
fs::write(params_directory, serde_json::to_string(&record).unwrap()).unwrap();
}
#[allow(dead_code)]
#[cfg(feature = "gpu")]
pub const GPU_MAX_SUPPORTED_POLYNOMIAL_SIZE: usize = 16384;
const FAST_BENCH_BIT_SIZES: [usize; 1] = [64];
const BENCH_BIT_SIZES: [usize; 8] = [4, 8, 16, 32, 40, 64, 128, 256];
const MULTI_BIT_CPU_SIZES: [usize; 6] = [4, 8, 16, 32, 40, 64];

View File

@@ -22,18 +22,27 @@ layout:
Learn the basics of TFHE-rs, set it up, and make it run with ease.
<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>What is TFHE-rs?</strong></td><td>Understand TFHE-rs library and basic cryptographic concepts</td><td><a href="getting_started/readme.md">getting_started.md</a></td><td><a href=".gitbook/assets/start1.png">start1.png</a></td></tr><tr><td><strong>Installation</strong></td><td>Follow the step by step guide to import TFHE-rs in your project</td><td><a href="getting_started/installation.md">installation.md</a></td><td><a href=".gitbook/assets/start2.png">start2.png</a></td></tr><tr><td><strong>Quick start</strong></td><td>See a full example of using TFHE-rs to compute on encrypted data</td><td><a href="getting_started/quick_start.md">quick_start.md</a></td><td><a href=".gitbook/assets/start3.png">start3.png</a></td></tr></tbody></table>
<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>What is TFHE-rs?</strong></td><td>Understand TFHE-rs library and basic cryptographic concepts</td><td><a href="getting_started/README.md">getting_started</a></td><td><a href=".gitbook/assets/start1.png">start1.png</a></td></tr><tr><td><strong>Installation</strong></td><td>Follow the step by step guide to import TFHE-rs in your project</td><td><a href="getting_started/installation.md">installation.md</a></td><td><a href=".gitbook/assets/start2.png">start2.png</a></td></tr><tr><td><strong>Quick start</strong></td><td>See a full example of using TFHE-rs to compute on encrypted data</td><td><a href="getting_started/quick_start.md">quick_start.md</a></td><td><a href=".gitbook/assets/start3.png">start3.png</a></td></tr></tbody></table>
## Build with TFHE-rs
Start building with TFHE-rs by exploring its core features, discovering essential guides, and learning more with user-friendly tutorials.
<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>Fundamentals</strong></td><td>Explore the core features.</td><td><ul><li><a href="fundamentals/configure-and-generate-keys.md">Configure</a></li><li><a href="fundamentals/encrypt-data.md">Encrypt data</a></li></ul></td><td><a href=".gitbook/assets/build1.png">build1.png</a></td></tr><tr><td><strong>Guides</strong></td><td>Deploy your project.</td><td><ul><li><a href="guides/run_on_gpu.md">Run on GPU</a></li><li><a href="guides/rust_configuration.md">Configure Rust</a></li></ul></td><td><a href=".gitbook/assets/build2.png">build2.png</a></td></tr><tr><td><strong>Tutorials</strong></td><td>Learn more with tutorials.</td><td><ul><li><a href="tutorials/see-all-tutorials.md#start-here">Start here</a></li><li><a href="tutorials/see-all-tutorials.md#go-further">Go further</a></li></ul></td><td><a href=".gitbook/assets/build3.png">build3.png</a></td></tr></tbody></table>
<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><strong>FHE Computations</strong></td><td>Run FHE computation on encrypted data.</td><td><ul><li><a href="fhe-computation/types/">Types </a></li><li><a href="fhe-computation/operations/">Operations</a></li></ul></td><td><a href=".gitbook/assets/build1.png">build1.png</a></td></tr><tr><td><strong>Configuration</strong></td><td>Advanced configuration for better performance.</td><td><ul><li><a href="configuration/rust_configuration.md">Advanced Rust </a></li><li><a href="configuration/run_on_gpu.md">GPU acceleration</a></li></ul></td><td><a href=".gitbook/assets/build2.png">build2.png</a></td></tr><tr><td><strong>Integration</strong></td><td>Use TFHE-rs in different contexts or platforms..</td><td><ul><li><a href="integration/c_api.md">C API</a></li><li><a href="integration/js_on_wasm_api.md">JS on WASM API</a></li></ul></td><td><a href=".gitbook/assets/build3.png">build3.png</a></td></tr></tbody></table>
## Explore more
Access to additional resources and join the Zama community.
### Tutorials
Explore step-by-step guides that walk you through real-world uses of TFHE-rs.&#x20;
* [Homomorphic parity bit](tutorials/parity_bit.md): Learn how to implement a parity bit calculation over encrypted data
* [Homomorphic case changing on ASCII string](tutorials/ascii_fhe_string.md): See how to process string data securely by changing cases while keeping the data encrypted.
* [SHA256 with Boolean API](tutorials/sha256_bool.md): Delve into a more complex example: implementing the SHA256 hash function entirely on encrypted boolean values.
* [All tutorials](tutorials/see-all-tutorials.md): A complete list of all available tutorials in one place.tutorials: A complete list of all available tutorials in one place.
### References & Explanations
Take a deep dive into TFHE-rs, exploring APIs from the highest to the lowest level of abstraction and accessing additional resources for in-depth explanations.
@@ -54,10 +63,10 @@ Ask technical questions and discuss with the community. Our team of experts usua
Collaborate with us to advance the FHE spaces and drive innovation together.
* [Contribute to TFHE-rs](dev/contributing.md)
* [Contribute to TFHE-rs](../../CONTRIBUTING.md)
* [Check the latest release note](https://github.com/zama-ai/tfhe-rs/releases)
* [Request a feature](https://github.com/zama-ai/tfhe-rs/issues/new?assignees=\&labels=feature\_request\&projects=\&template=feature\_request.md\&title=)
* [Report a bug](https://github.com/zama-ai/tfhe-rs/issues/new?assignees=\&labels=triage\_required\&projects=\&template=bug\_report.md\&title=)
* [Request a feature](https://github.com/zama-ai/tfhe-rs/issues/new?assignees=\&labels=feature_request\&projects=\&template=feature_request.md\&title=)
* [Report a bug](https://github.com/zama-ai/tfhe-rs/issues/new?assignees=\&labels=triage_required\&projects=\&template=bug_report.md\&title=)
***

View File

@@ -4,58 +4,79 @@
## Get Started
* [What is TFHE-rs?](getting\_started/readme.md)
* [Installation](getting\_started/installation.md)
* [Quick start](getting\_started/quick\_start.md)
* [Types & Operations](getting\_started/operations.md)
* [Benchmarks](getting\_started/benchmarks/summary.md)
* [CPU Benchmarks](getting\_started/benchmarks/cpu\_benchmarks.md)
* [GPU Benchmarks](getting\_started/benchmarks/gpu\_benchmarks.md)
* [What is TFHE-rs?](getting_started/README.md)
* [Installation](getting_started/installation.md)
* [Quick start](getting_started/quick_start.md)
* [Benchmarks](getting_started/benchmarks/README.md)
* [CPU Benchmarks](getting_started/benchmarks/cpu/README.md)
* [Integer](getting_started/benchmarks/cpu/cpu_integer_operations.md)
* [Programmable bootstrapping](getting_started/benchmarks/cpu/cpu_programmable_bootstrapping.md)
* [GPU Benchmarks](getting_started/benchmarks/gpu/README.md)
* [Integer](getting_started/benchmarks/gpu/gpu_integer_operations.md)
* [Programmable bootstrapping](getting_started/benchmarks/gpu/gpu_programmable_bootstrapping.md)
* [Zero-knowledge proof benchmarks](getting_started/benchmarks/zk_proof_benchmarks.md)
* [Security and cryptography](getting\_started/security\_and\_cryptography.md)
* [Security and cryptography](getting_started/security_and_cryptography.md)
## Fundamentals
## FHE Computation
* [Configuration and key generation](fundamentals/configure-and-generate-keys.md)
* [Server key](fundamentals/set-the-server-key.md)
* [Encryption](fundamentals/encrypt-data.md)
* [Computation on encrypted data](fundamentals/compute.md)
* [Decryption](fundamentals/decrypt-data.md)
* [Encrypted pseudo random values](fundamentals/encrypted-prf.md)
* [Serialization/deserialization](fundamentals/serialization.md)
* [Compressing ciphertexts/keys](fundamentals/compress.md)
* [Debugging](fundamentals/debug.md)
* [Types](fhe-computation/types/README.md)
* [Integer](fhe-computation/types/integer.md)
* [Strings](fhe-computation/types/strings.md)
* [Array](fhe-computation/types/array.md)
* [Operations](fhe-computation/operations/README.md)
* [Arithmetic operations](fhe-computation/operations/arithmetic-operations.md)
* [Bitwise operations](fhe-computation/operations/bitwise-operations.md)
* [Comparison operations](fhe-computation/operations/comparison-operations.md)
* [Min/Max operations](fhe-computation/operations/min-max-operations.md)
* [Ternary conditional operations](fhe-computation/operations/ternary-conditional-operations.md)
* [Casting operations](fhe-computation/operations/casting-operations.md)
* [Boolean Operations](fhe-computation/operations/boolean-operations.md)
* [String Operations](fhe-computation/operations/string-operations.md)
* [Core workflow](fhe-computation/compute/README.md)
* [Configuration and key generation](fhe-computation/compute/configure-and-generate-keys.md)
* [Server key](fhe-computation/compute/set-the-server-key.md)
* [Encryption](fhe-computation/compute/encrypt-data.md)
* [Decryption](fhe-computation/compute/decrypt-data.md)
* [Parameters](fhe-computation/compute/parameters.md)
* [Data handling](fhe-computation/data-handling/README.md)
* [Compressing ciphertexts/keys](fhe-computation/data-handling/compress.md)
* [Serialization/deserialization](fhe-computation/data-handling/serialization.md)
* [Data versioning](fhe-computation/data-handling/data_versioning.md)
* [Advanced features](fhe-computation/advanced-features/README.md)
* [Encrypted pseudo random values](fhe-computation/advanced-features/encrypted-prf.md)
* [Overflow detection](fhe-computation/advanced-features/overflow_operations.md)
* [Public key encryption](fhe-computation/advanced-features/public_key.md)
* [Trivial ciphertexts](fhe-computation/advanced-features/trivial_ciphertext.md)
* [Zero-knowledge proofs](fhe-computation/advanced-features/zk-pok.md)
* [Multi-threading with Rayon crate](fhe-computation/advanced-features/rayon_crate.md)
* [Tooling](fhe-computation/tooling/README.md)
* [PBS statistics](fhe-computation/tooling/pbs-stats.md)
* [Generic trait bounds](fhe-computation/tooling/trait_bounds.md)
* [Debugging](fhe-computation/tooling/debug.md)
## Guides
## Configuration
* [Rust configuration](guides/rust\_configuration.md)
* [GPU acceleration](guides/run\_on\_gpu.md)
* [Overflow detection](guides/overflow\_operations.md)
* [Data versioning](guides/data\_versioning.md)
* [Public key encryption](guides/public\_key.md)
* [Zero-knowledge proofs](guides/zk-pok.md)
* [Generic trait bounds](guides/trait\_bounds.md)
* [Parallelized PBS](guides/parallelized\_pbs.md)
* [High-level API in C](guides/c\_api.md)
* [JS on WASM API](guides/js\_on\_wasm\_api.md)
* [Multi-threading with Rayon crate](guides/rayon\_crate.md)
* [Trivial ciphertexts](guides/trivial\_ciphertext.md)
* [PBS statistics](guides/pbs-stats.md)
* [Array](guides/array.md)
* [Strings](guides/strings.md)
* [Advanced Rust setup](configuration/rust_configuration.md)
* [GPU acceleration](configuration/run_on_gpu.md)
* [Parallelized PBS](configuration/parallelized_pbs.md)
## Integration
* [JS on WASM API](integration/js_on_wasm_api.md)
* [High-level API in C](integration/c_api.md)
## Tutorials
* [Homomorphic parity bit](tutorials/parity_bit.md)
* [Homomorphic case changing on Ascii string](tutorials/ascii_fhe_string.md)
* [SHA256 with Boolean API](tutorials/sha256_bool.md)
* [All tutorials](tutorials/see-all-tutorials.md)
* [Homomorphic parity bit](tutorials/parity\_bit.md)
* [Homomorphic case changing on Ascii string](tutorials/ascii\_fhe\_string.md)
* [SHA256 with Boolean API](tutorials/sha256\_bool.md)
## References
* [API references](https://docs.rs/tfhe/latest/tfhe/)
* [Fine-grained APIs](references/fine-grained-apis/README.md)
* [Quick start](references/fine-grained-apis/quick\_start.md)
* [Quick start](references/fine-grained-apis/quick_start.md)
* [Boolean](references/fine-grained-apis/boolean/README.md)
* [Operations](references/fine-grained-apis/boolean/operations.md)
* [Cryptographic parameters](references/fine-grained-apis/boolean/parameters.md)
@@ -78,7 +99,7 @@
## Developers
* [Contributing](dev/contributing.md)
* [Contributing](../../CONTRIBUTING.md)
* [Release note](https://github.com/zama-ai/tfhe-rs/releases)
* [Feature request](https://github.com/zama-ai/tfhe-rs/issues/new?assignees=\&labels=feature\_request\&projects=\&template=feature\_request.md\&title=)
* [Bug report](https://github.com/zama-ai/tfhe-rs/issues/new?assignees=\&labels=triage\_required\&projects=\&template=bug\_report.md\&title=)
* [Feature request](https://github.com/zama-ai/tfhe-rs/issues/new?assignees=\&labels=feature_request\&projects=\&template=feature_request.md\&title=)
* [Bug report](https://github.com/zama-ai/tfhe-rs/issues/new?assignees=\&labels=triage_required\&projects=\&template=bug_report.md\&title=)

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 560" preserveAspectRatio="meet" width="100%" height="560">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Size</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="405.0" y="20.0">CPU</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="615.0" y="20.0">GPU</text>
<rect x="0" y="40" width="300" height="520" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="520" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">Negation (-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="60.0">106 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="60.0">25.2 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">Add / Sub (+,-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="100.0">105 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="100.0">25.2 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="140.0">Mul (x)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="140.0">401 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="140.0">237 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="180.0">Equal / Not Equal (eq, ne)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="180.0">81.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="180.0">17.7 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="220.0">Comparisons (ge, gt, le, lt)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="220.0">102 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="220.0">26.2 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="260.0">Max / Min (max, min)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="260.0">145 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="260.0">43.6 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="300.0">Bitwise operations (&amp;, |, ^)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="300.0">20.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="300.0">5.97 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="340.0">Div / Rem (/, %)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="340.0">8.22 s</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="340.0">2.05 s</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="380.0">Left / Right Shifts (&lt;&lt;, &gt;&gt;)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="380.0">134 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="380.0">86.7 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="420.0">Left / Right Rotations (left_rotate, right_rotate)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="420.0">133 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="420.0">86.8 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="460.0">Leading / Trailing zeros/ones</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="460.0">247 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="460.0">62.3 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="500.0">Log2</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="500.0">267 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="500.0">73.9 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="540.0">Select</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="405.0" y="540.0">32.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="615.0" y="540.0">17.5 ms</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="120" x2="720" y2="120"/>
<line stroke="white" stroke-width="2" x1="0" y1="160" x2="720" y2="160"/>
<line stroke="white" stroke-width="2" x1="0" y1="200" x2="720" y2="200"/>
<line stroke="white" stroke-width="2" x1="0" y1="240" x2="720" y2="240"/>
<line stroke="white" stroke-width="2" x1="0" y1="280" x2="720" y2="280"/>
<line stroke="white" stroke-width="2" x1="0" y1="320" x2="720" y2="320"/>
<line stroke="white" stroke-width="2" x1="0" y1="360" x2="720" y2="360"/>
<line stroke="white" stroke-width="2" x1="0" y1="400" x2="720" y2="400"/>
<line stroke="white" stroke-width="2" x1="0" y1="440" x2="720" y2="440"/>
<line stroke="white" stroke-width="2" x1="0" y1="480" x2="720" y2="480"/>
<line stroke="white" stroke-width="2" x1="0" y1="520" x2="720" y2="520"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="560"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="510.0" y1="0" x2="510.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="560"/>
</svg>

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 560" preserveAspectRatio="meet" width="100%" height="560">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Size</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="29.666666666666668">8</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="29.666666666666668">16</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="29.666666666666668">32</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="29.666666666666668">64</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="29.666666666666668">128</text>
<rect x="0" y="40" width="300" height="520" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="520" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">Negation (-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="60.0">48.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="60.0">57.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="60.0">79.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="60.0">105 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="60.0">159 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">Add / Sub (+,-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="100.0">53.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="100.0">59.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="100.0">82.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="100.0">109 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="100.0">165 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="140.0">Mul (x)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="140.0">97.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="140.0">141 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="140.0">213 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="140.0">400 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="140.0">1.14 s</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="180.0">Equal / Not Equal (eq, ne)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="180.0">36.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="180.0">56.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="180.0">56.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="180.0">81.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="180.0">82.0 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="220.0">Comparisons (ge, gt, le, lt)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="220.0">37.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="220.0">54.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="220.0">76.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="220.0">99.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="220.0">145 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="260.0">Max / Min (max, min)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="260.0">76.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="260.0">97.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="260.0">121 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="260.0">148 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="260.0">194 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="300.0">Bitwise operations (&amp;, |, ^)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="300.0">18.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="300.0">19.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="300.0">20.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="300.0">22.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="300.0">23.8 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="340.0">Div / Rem (/, %)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="340.0">644 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="340.0">1.49 s</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="340.0">3.44 s</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="340.0">8.49 s</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="340.0">20.9 s</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="380.0">Left / Right Shifts (&lt;&lt;, &gt;&gt;)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="380.0">58.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="380.0">81.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="380.0">107 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="380.0">142 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="380.0">178 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="420.0">Left / Right Rotations (left_rotate, right_rotate)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="420.0">59.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="420.0">81.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="420.0">107 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="420.0">142 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="420.0">186 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="460.0">Leading / Trailing zeros/ones</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="460.0">95.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="460.0">159 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="460.0">182 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="460.0">255 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="460.0">304 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="500.0">Log2</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="500.0">114 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="500.0">173 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="500.0">199 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="500.0">280 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="500.0">327 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="540.0">Select</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="540.0">29.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="540.0">32.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="540.0">33.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="540.0">36.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="540.0">37.2 ms</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="120" x2="720" y2="120"/>
<line stroke="white" stroke-width="2" x1="0" y1="160" x2="720" y2="160"/>
<line stroke="white" stroke-width="2" x1="0" y1="200" x2="720" y2="200"/>
<line stroke="white" stroke-width="2" x1="0" y1="240" x2="720" y2="240"/>
<line stroke="white" stroke-width="2" x1="0" y1="280" x2="720" y2="280"/>
<line stroke="white" stroke-width="2" x1="0" y1="320" x2="720" y2="320"/>
<line stroke="white" stroke-width="2" x1="0" y1="360" x2="720" y2="360"/>
<line stroke="white" stroke-width="2" x1="0" y1="400" x2="720" y2="400"/>
<line stroke="white" stroke-width="2" x1="0" y1="440" x2="720" y2="440"/>
<line stroke="white" stroke-width="2" x1="0" y1="480" x2="720" y2="480"/>
<line stroke="white" stroke-width="2" x1="0" y1="520" x2="720" y2="520"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="560"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="384.0" y1="0" x2="384.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="468.0" y1="0" x2="468.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="552.0" y1="0" x2="552.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="636.0" y1="0" x2="636.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="560"/>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 440" preserveAspectRatio="meet" width="100%" height="440">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Size</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="29.666666666666668">8</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="29.666666666666668">16</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="29.666666666666668">32</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="29.666666666666668">64</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="29.666666666666668">128</text>
<rect x="0" y="40" width="300" height="400" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="400" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">Add / Sub (+,-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="60.0">52.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="60.0">60.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="60.0">64.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="60.0">89.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="60.0">111 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">Mul (x)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="100.0">74.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="100.0">125 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="100.0">175 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="100.0">242 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="100.0">453 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="140.0">Equal / Not Equal (eq, ne)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="140.0">32.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="140.0">35.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="140.0">55.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="140.0">58.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="140.0">79.0 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="180.0">Comparisons (ge, gt, le, lt)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="180.0">37.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="180.0">36.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="180.0">56.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="180.0">78.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="180.0">101 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="220.0">Max / Min (max, min)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="220.0">52.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="220.0">57.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="220.0">78.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="220.0">103 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="220.0">123 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="260.0">Bitwise operations (&amp;, |, ^)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="260.0">18.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="260.0">19.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="260.0">21.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="260.0">23.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="260.0">24.1 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="300.0">Div (/)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="300.0">139 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="300.0">202 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="300.0">280 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="300.0">456 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="300.0">912 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="340.0">Rem (%)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="340.0">275 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="340.0">366 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="340.0">536 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="340.0">778 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="340.0">1.37 s</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="380.0">Left / Right Shifts (&lt;&lt;, &gt;&gt;)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="380.0">20.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="380.0">20.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="380.0">21.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="380.0">23.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="380.0">24.2 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="420.0">Left / Right Rotations (left_rotate, right_rotate)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="420.0">19.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="420.0">20.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="420.0">21.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="420.0">23.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="420.0">24.1 ms</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="120" x2="720" y2="120"/>
<line stroke="white" stroke-width="2" x1="0" y1="160" x2="720" y2="160"/>
<line stroke="white" stroke-width="2" x1="0" y1="200" x2="720" y2="200"/>
<line stroke="white" stroke-width="2" x1="0" y1="240" x2="720" y2="240"/>
<line stroke="white" stroke-width="2" x1="0" y1="280" x2="720" y2="280"/>
<line stroke="white" stroke-width="2" x1="0" y1="320" x2="720" y2="320"/>
<line stroke="white" stroke-width="2" x1="0" y1="360" x2="720" y2="360"/>
<line stroke="white" stroke-width="2" x1="0" y1="400" x2="720" y2="400"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="440"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="384.0" y1="0" x2="384.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="468.0" y1="0" x2="468.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="552.0" y1="0" x2="552.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="636.0" y1="0" x2="636.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="440"/>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 560" preserveAspectRatio="meet" width="100%" height="560">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Size</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="29.666666666666668">8</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="29.666666666666668">16</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="29.666666666666668">32</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="29.666666666666668">64</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="29.666666666666668">128</text>
<rect x="0" y="40" width="300" height="520" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="520" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">Negation (-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="60.0">48.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="60.0">57.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="60.0">78.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="60.0">103 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="60.0">162 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">Add / Sub (+,-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="100.0">52.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="100.0">58.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="100.0">79.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="100.0">101 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="100.0">161 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="140.0">Mul (x)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="140.0">94.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="140.0">136 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="140.0">210 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="140.0">381 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="140.0">1.1 s</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="180.0">Equal / Not Equal (eq, ne)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="180.0">36.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="180.0">55.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="180.0">55.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="180.0">76.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="180.0">77.6 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="220.0">Comparisons (ge, gt, le, lt)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="220.0">36.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="220.0">54.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="220.0">73.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="220.0">94.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="220.0">136 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="260.0">Max / Min (max, min)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="260.0">74.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="260.0">94.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="260.0">115 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="260.0">138 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="260.0">183 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="300.0">Bitwise operations (&amp;, |, ^)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="300.0">18.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="300.0">19.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="300.0">19.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="300.0">20.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="300.0">22.0 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="340.0">Div / Rem (/, %)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="340.0">667 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="340.0">1.49 s</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="340.0">3.39 s</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="340.0">7.87 s</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="340.0">19.6 s</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="380.0">Left / Right Shifts (&lt;&lt;, &gt;&gt;)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="380.0">59.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="380.0">79.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="380.0">100 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="380.0">128 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="380.0">169 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="420.0">Left / Right Rotations (left_rotate, right_rotate)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="420.0">57.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="420.0">77.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="420.0">98.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="420.0">128 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="420.0">178 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="460.0">Leading / Trailing zeros/ones</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="460.0">96.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="460.0">153 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="460.0">172 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="460.0">234 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="460.0">291 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="500.0">Log2</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="500.0">114 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="500.0">170 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="500.0">195 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="500.0">256 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="500.0">312 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="540.0">Select</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="540.0">28.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="540.0">29.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="540.0">31.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="540.0">31.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="540.0">34.3 ms</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="120" x2="720" y2="120"/>
<line stroke="white" stroke-width="2" x1="0" y1="160" x2="720" y2="160"/>
<line stroke="white" stroke-width="2" x1="0" y1="200" x2="720" y2="200"/>
<line stroke="white" stroke-width="2" x1="0" y1="240" x2="720" y2="240"/>
<line stroke="white" stroke-width="2" x1="0" y1="280" x2="720" y2="280"/>
<line stroke="white" stroke-width="2" x1="0" y1="320" x2="720" y2="320"/>
<line stroke="white" stroke-width="2" x1="0" y1="360" x2="720" y2="360"/>
<line stroke="white" stroke-width="2" x1="0" y1="400" x2="720" y2="400"/>
<line stroke="white" stroke-width="2" x1="0" y1="440" x2="720" y2="440"/>
<line stroke="white" stroke-width="2" x1="0" y1="480" x2="720" y2="480"/>
<line stroke="white" stroke-width="2" x1="0" y1="520" x2="720" y2="520"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="560"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="384.0" y1="0" x2="384.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="468.0" y1="0" x2="468.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="552.0" y1="0" x2="552.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="636.0" y1="0" x2="636.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="560"/>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 440" preserveAspectRatio="meet" width="100%" height="440">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Size</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="29.666666666666668">8</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="29.666666666666668">16</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="29.666666666666668">32</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="29.666666666666668">64</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="29.666666666666668">128</text>
<rect x="0" y="40" width="300" height="400" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="400" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">Add / Sub (+,-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="60.0">51.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="60.0">56.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="60.0">57.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="60.0">78.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="60.0">104 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">Mul (x)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="100.0">75.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="100.0">118 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="100.0">161 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="100.0">222 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="100.0">419 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="140.0">Equal / Not Equal (eq, ne)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="140.0">34.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="140.0">35.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="140.0">56.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="140.0">54.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="140.0">75.8 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="180.0">Comparisons (ge, gt, le, lt)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="180.0">36.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="180.0">35.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="180.0">53.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="180.0">73.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="180.0">94.5 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="220.0">Max / Min (max, min)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="220.0">55.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="220.0">55.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="220.0">74.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="220.0">95.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="220.0">117 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="260.0">Bitwise operations (&amp;, |, ^)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="260.0">19.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="260.0">19.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="260.0">19.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="260.0">21.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="260.0">22.7 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="300.0">Div (/)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="300.0">137 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="300.0">189 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="300.0">269 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="300.0">451 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="300.0">833 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="340.0">Rem (%)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="340.0">268 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="340.0">344 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="340.0">492 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="340.0">719 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="340.0">1.27 s</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="380.0">Left / Right Shifts (&lt;&lt;, &gt;&gt;)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="380.0">18.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="380.0">19.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="380.0">19.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="380.0">20.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="380.0">21.9 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="420.0">Left / Right Rotations (left_rotate, right_rotate)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="420.0">19.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="420.0">19.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="420.0">19.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="420.0">21.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="420.0">22.7 ms</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="120" x2="720" y2="120"/>
<line stroke="white" stroke-width="2" x1="0" y1="160" x2="720" y2="160"/>
<line stroke="white" stroke-width="2" x1="0" y1="200" x2="720" y2="200"/>
<line stroke="white" stroke-width="2" x1="0" y1="240" x2="720" y2="240"/>
<line stroke="white" stroke-width="2" x1="0" y1="280" x2="720" y2="280"/>
<line stroke="white" stroke-width="2" x1="0" y1="320" x2="720" y2="320"/>
<line stroke="white" stroke-width="2" x1="0" y1="360" x2="720" y2="360"/>
<line stroke="white" stroke-width="2" x1="0" y1="400" x2="720" y2="400"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="440"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="384.0" y1="0" x2="384.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="468.0" y1="0" x2="468.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="552.0" y1="0" x2="552.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="636.0" y1="0" x2="636.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="440"/>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 120" preserveAspectRatio="meet" width="100%" height="120">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Precision (bits)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="352.5" y="20.0">2</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="457.5" y="20.0">4</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="562.5" y="20.0">6</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="667.5" y="20.0">8</text>
<rect x="0" y="40" width="300" height="80" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="80" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="60.0">9.61 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="60.0">12.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="60.0">111 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="60.0">1.5 s</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">KS - PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="100.0">10.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="100.0">14.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="100.0">129 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="100.0">1.44 s</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="120"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="405.0" y1="0" x2="405.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="510.0" y1="0" x2="510.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="615.0" y1="0" x2="615.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="120"/>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 200" preserveAspectRatio="meet" width="100%" height="200">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Precision (bits)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="352.5" y="20.0">2</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="457.5" y="20.0">4</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="562.5" y="20.0">6</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="667.5" y="20.0">8</text>
<rect x="0" y="40" width="300" height="160" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="160" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="60.0">6.04 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="60.0">11.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="60.0">98.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="60.0">458 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">MB-PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="100.0">3.41 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="100.0">4.58 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="100.0">37.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="100.0">156 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="140.0">KS-PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="140.0">7.79 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="140.0">14.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="140.0">114 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="140.0">536 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="180.0">KS-MB-PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="180.0">5.53 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="180.0">7.51 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="180.0">47.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="180.0">244 ms</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="120" x2="720" y2="120"/>
<line stroke="white" stroke-width="2" x1="0" y1="160" x2="720" y2="160"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="200"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="200"/>
<line stroke="white" stroke-width="2" x1="405.0" y1="0" x2="405.0" y2="200"/>
<line stroke="white" stroke-width="2" x1="510.0" y1="0" x2="510.0" y2="200"/>
<line stroke="white" stroke-width="2" x1="615.0" y1="0" x2="615.0" y2="200"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="200"/>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 200" preserveAspectRatio="meet" width="100%" height="200">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Precision (bits)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="352.5" y="20.0">2</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="457.5" y="20.0">4</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="562.5" y="20.0">6</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="667.5" y="20.0">8</text>
<rect x="0" y="40" width="300" height="160" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="160" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="60.0">8.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="60.0">11.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="60.0">102 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="60.0">649 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">MB-PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="100.0">4.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="100.0">4.43 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="100.0">27.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="100.0">248 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="140.0">KS-PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="140.0">11.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="140.0">14.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="140.0">118 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="140.0">873 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="180.0">KS-MB-PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="180.0">5.97 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="180.0">7.55 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="180.0">44.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="180.0">453 ms</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="120" x2="720" y2="120"/>
<line stroke="white" stroke-width="2" x1="0" y1="160" x2="720" y2="160"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="200"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="200"/>
<line stroke="white" stroke-width="2" x1="405.0" y1="0" x2="405.0" y2="200"/>
<line stroke="white" stroke-width="2" x1="510.0" y1="0" x2="510.0" y2="200"/>
<line stroke="white" stroke-width="2" x1="615.0" y1="0" x2="615.0" y2="200"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="200"/>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 560" preserveAspectRatio="meet" width="100%" height="560">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Size</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="29.666666666666668">8</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="29.666666666666668">16</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="29.666666666666668">32</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="29.666666666666668">64</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="29.666666666666668">128</text>
<rect x="0" y="40" width="300" height="520" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="520" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">Negation (-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="60.0">11.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="60.0">12.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="60.0">17.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="60.0">25.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="60.0">51.1 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">Add / Sub (+,-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="100.0">11.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="100.0">12.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="100.0">17.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="100.0">25.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="100.0">51.2 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="140.0">Mul (x)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="140.0">23.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="140.0">37.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="140.0">76.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="140.0">237 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="140.0">830 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="180.0">Equal / Not Equal (eq, ne)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="180.0">7.65 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="180.0">11.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="180.0">12.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="180.0">17.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="180.0">24.1 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="220.0">Comparisons (ge, gt, le, lt)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="220.0">11.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="220.0">15.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="220.0">20.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="220.0">26.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="220.0">38.0 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="260.0">Max / Min (max, min)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="260.0">18.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="260.0">24.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="260.0">30.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="260.0">43.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="260.0">68.5 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="300.0">Bitwise operations (&amp;, |, ^)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="300.0">3.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="300.0">4.01 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="300.0">4.58 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="300.0">5.97 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="300.0">11.2 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="340.0">Div / Rem (/, %)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="340.0">154 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="340.0">318 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="340.0">763 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="340.0">2.05 s</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="340.0">6.35 s</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="380.0">Left / Right Shifts (&lt;&lt;, &gt;&gt;)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="380.0">22.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="380.0">30.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="380.0">43.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="380.0">86.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="380.0">162 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="420.0">Left / Right Rotations (left_rotate, right_rotate)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="420.0">22.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="420.0">30.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="420.0">43.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="420.0">86.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="420.0">162 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="460.0">Leading / Trailing zeros/ones</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="460.0">25.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="460.0">33.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="460.0">44.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="460.0">62.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="460.0">105 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="500.0">Log2</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="500.0">35.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="500.0">48.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="500.0">55.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="500.0">73.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="500.0">113 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="540.0">Select</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="540.0">7.76 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="540.0">8.72 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="540.0">10.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="540.0">17.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="540.0">30.5 ms</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="120" x2="720" y2="120"/>
<line stroke="white" stroke-width="2" x1="0" y1="160" x2="720" y2="160"/>
<line stroke="white" stroke-width="2" x1="0" y1="200" x2="720" y2="200"/>
<line stroke="white" stroke-width="2" x1="0" y1="240" x2="720" y2="240"/>
<line stroke="white" stroke-width="2" x1="0" y1="280" x2="720" y2="280"/>
<line stroke="white" stroke-width="2" x1="0" y1="320" x2="720" y2="320"/>
<line stroke="white" stroke-width="2" x1="0" y1="360" x2="720" y2="360"/>
<line stroke="white" stroke-width="2" x1="0" y1="400" x2="720" y2="400"/>
<line stroke="white" stroke-width="2" x1="0" y1="440" x2="720" y2="440"/>
<line stroke="white" stroke-width="2" x1="0" y1="480" x2="720" y2="480"/>
<line stroke="white" stroke-width="2" x1="0" y1="520" x2="720" y2="520"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="560"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="384.0" y1="0" x2="384.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="468.0" y1="0" x2="468.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="552.0" y1="0" x2="552.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="636.0" y1="0" x2="636.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="560"/>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 440" preserveAspectRatio="meet" width="100%" height="440">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Size</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="29.666666666666668">8</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="29.666666666666668">16</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="29.666666666666668">32</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="29.666666666666668">64</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="29.666666666666668">128</text>
<rect x="0" y="40" width="300" height="400" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="400" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">Add / Sub (+,-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="60.0">11.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="60.0">12.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="60.0">17.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="60.0">25.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="60.0">51.4 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">Mul (x)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="100.0">18.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="100.0">26.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="100.0">46.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="100.0">109 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="100.0">330 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="140.0">Equal / Not Equal (eq, ne)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="140.0">7.81 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="140.0">8.08 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="140.0">12.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="140.0">13.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="140.0">18.8 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="180.0">Comparisons (ge, gt, le, lt)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="180.0">9.61 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="180.0">13.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="180.0">17.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="180.0">22.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="180.0">29.0 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="220.0">Max / Min (max, min)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="220.0">17.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="220.0">21.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="220.0">28.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="220.0">39.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="220.0">59.4 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="260.0">Bitwise operations (&amp;, |, ^)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="260.0">3.63 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="260.0">4.11 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="260.0">4.65 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="260.0">6.03 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="260.0">11.2 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="300.0">Div (/)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="300.0">28.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="300.0">41.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="300.0">83.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="300.0">214 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="300.0">664 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="340.0">Rem (%)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="340.0">56.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="340.0">80.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="340.0">149 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="340.0">351 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="340.0">1.04 s</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="380.0">Left / Right Shifts (&lt;&lt;, &gt;&gt;)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="380.0">3.63 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="380.0">4.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="380.0">4.63 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="380.0">6.03 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="380.0">11.2 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="420.0">Left / Right Rotations (left_rotate, right_rotate)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="420.0">3.63 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="420.0">4.11 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="420.0">4.64 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="420.0">6.03 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="420.0">11.3 ms</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="120" x2="720" y2="120"/>
<line stroke="white" stroke-width="2" x1="0" y1="160" x2="720" y2="160"/>
<line stroke="white" stroke-width="2" x1="0" y1="200" x2="720" y2="200"/>
<line stroke="white" stroke-width="2" x1="0" y1="240" x2="720" y2="240"/>
<line stroke="white" stroke-width="2" x1="0" y1="280" x2="720" y2="280"/>
<line stroke="white" stroke-width="2" x1="0" y1="320" x2="720" y2="320"/>
<line stroke="white" stroke-width="2" x1="0" y1="360" x2="720" y2="360"/>
<line stroke="white" stroke-width="2" x1="0" y1="400" x2="720" y2="400"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="440"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="384.0" y1="0" x2="384.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="468.0" y1="0" x2="468.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="552.0" y1="0" x2="552.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="636.0" y1="0" x2="636.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="440"/>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 560" preserveAspectRatio="meet" width="100%" height="560">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Size</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="29.666666666666668">8</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="29.666666666666668">16</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="29.666666666666668">32</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="29.666666666666668">64</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="29.666666666666668">128</text>
<rect x="0" y="40" width="300" height="520" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="520" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">Negation (-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="60.0">11.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="60.0">11.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="60.0">16.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="60.0">21.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="60.0">36.7 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">Add / Sub (+,-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="100.0">11.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="100.0">11.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="100.0">16.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="100.0">21.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="100.0">36.7 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="140.0">Mul (x)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="140.0">22.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="140.0">31.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="140.0">63.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="140.0">164 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="140.0">545 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="180.0">Equal / Not Equal (eq, ne)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="180.0">7.95 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="180.0">11.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="180.0">12.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="180.0">16.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="180.0">19.2 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="220.0">Comparisons (ge, gt, le, lt)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="220.0">11.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="220.0">15.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="220.0">19.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="220.0">24.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="220.0">31.6 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="260.0">Max / Min (max, min)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="260.0">18.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="260.0">23.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="260.0">28.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="260.0">35.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="260.0">50.0 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="300.0">Bitwise operations (&amp;, |, ^)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="300.0">3.54 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="300.0">3.66 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="300.0">4.24 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="300.0">4.82 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="300.0">6.43 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="340.0">Div / Rem (/, %)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="340.0">273 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="340.0">580 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="340.0">1.28 s</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="340.0">2.97 s</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="340.0">7.41 s</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="380.0">Left / Right Shifts (&lt;&lt;, &gt;&gt;)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="380.0">21.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="380.0">27.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="380.0">36.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="380.0">53.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="380.0">106 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="420.0">Left / Right Rotations (left_rotate, right_rotate)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="420.0">21.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="420.0">27.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="420.0">36.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="420.0">53.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="420.0">106 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="460.0">Leading / Trailing zeros/ones</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="460.0">25.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="460.0">32.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="460.0">42.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="460.0">56.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="460.0">78.5 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="500.0">Log2</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="500.0">43.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="500.0">57.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="500.0">99.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="500.0">280 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="500.0">962 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="540.0">Select</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="540.0">7.38 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="540.0">7.98 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="540.0">9.02 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="540.0">11.3 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="540.0">18.6 ms</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="120" x2="720" y2="120"/>
<line stroke="white" stroke-width="2" x1="0" y1="160" x2="720" y2="160"/>
<line stroke="white" stroke-width="2" x1="0" y1="200" x2="720" y2="200"/>
<line stroke="white" stroke-width="2" x1="0" y1="240" x2="720" y2="240"/>
<line stroke="white" stroke-width="2" x1="0" y1="280" x2="720" y2="280"/>
<line stroke="white" stroke-width="2" x1="0" y1="320" x2="720" y2="320"/>
<line stroke="white" stroke-width="2" x1="0" y1="360" x2="720" y2="360"/>
<line stroke="white" stroke-width="2" x1="0" y1="400" x2="720" y2="400"/>
<line stroke="white" stroke-width="2" x1="0" y1="440" x2="720" y2="440"/>
<line stroke="white" stroke-width="2" x1="0" y1="480" x2="720" y2="480"/>
<line stroke="white" stroke-width="2" x1="0" y1="520" x2="720" y2="520"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="560"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="384.0" y1="0" x2="384.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="468.0" y1="0" x2="468.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="552.0" y1="0" x2="552.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="636.0" y1="0" x2="636.0" y2="560"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="560"/>
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 440" preserveAspectRatio="meet" width="100%" height="440">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Size</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="342.0" y="29.666666666666668">8</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="426.0" y="29.666666666666668">16</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="510.0" y="29.666666666666668">32</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="594.0" y="29.666666666666668">64</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="13.333333333333334">FheUint</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="678.0" y="29.666666666666668">128</text>
<rect x="0" y="40" width="300" height="400" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="400" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">Add / Sub (+,-)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="60.0">11.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="60.0">11.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="60.0">16.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="60.0">22.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="60.0">36.8 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">Mul (x)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="100.0">18.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="100.0">24.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="100.0">41.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="100.0">93.5 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="100.0">271 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="140.0">Equal / Not Equal (eq, ne)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="140.0">8.26 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="140.0">8.53 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="140.0">12.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="140.0">13.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="140.0">18.0 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="180.0">Comparisons (ge, gt, le, lt)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="180.0">9.95 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="180.0">13.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="180.0">17.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="180.0">21.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="180.0">27.4 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="220.0">Max / Min (max, min)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="220.0">17.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="220.0">21.6 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="220.0">26.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="220.0">33.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="220.0">46.2 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="260.0">Bitwise operations (&amp;, |, ^)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="260.0">3.64 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="260.0">3.79 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="260.0">4.36 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="260.0">4.91 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="260.0">6.54 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="300.0">Div (/)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="300.0">26.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="300.0">39.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="300.0">71.8 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="300.0">176 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="300.0">544 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="340.0">Rem (%)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="340.0">56.9 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="340.0">77.4 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="340.0">131 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="340.0">292 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="340.0">839 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="380.0">Left / Right Shifts (&lt;&lt;, &gt;&gt;)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="380.0">3.55 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="380.0">3.7 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="380.0">4.28 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="380.0">4.82 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="380.0">6.45 ms</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="420.0">Left / Right Rotations (left_rotate, right_rotate)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="342.0" y="420.0">3.55 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="426.0" y="420.0">3.71 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="510.0" y="420.0">4.28 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="594.0" y="420.0">4.82 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="678.0" y="420.0">6.46 ms</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="120" x2="720" y2="120"/>
<line stroke="white" stroke-width="2" x1="0" y1="160" x2="720" y2="160"/>
<line stroke="white" stroke-width="2" x1="0" y1="200" x2="720" y2="200"/>
<line stroke="white" stroke-width="2" x1="0" y1="240" x2="720" y2="240"/>
<line stroke="white" stroke-width="2" x1="0" y1="280" x2="720" y2="280"/>
<line stroke="white" stroke-width="2" x1="0" y1="320" x2="720" y2="320"/>
<line stroke="white" stroke-width="2" x1="0" y1="360" x2="720" y2="360"/>
<line stroke="white" stroke-width="2" x1="0" y1="400" x2="720" y2="400"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="440"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="384.0" y1="0" x2="384.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="468.0" y1="0" x2="468.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="552.0" y1="0" x2="552.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="636.0" y1="0" x2="636.0" y2="440"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="440"/>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 120" preserveAspectRatio="meet" width="100%" height="120">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Precision (bits)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="352.5" y="20.0">2</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="457.5" y="20.0">4</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="562.5" y="20.0">6</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="667.5" y="20.0">8</text>
<rect x="0" y="40" width="300" height="80" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="80" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">MB-PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="60.0">3.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="60.0">4.03 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="60.0">22.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="60.0">N/A</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">KS - MB-PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="100.0">3.22 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="100.0">4.02 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="100.0">22.2 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="100.0">N/A</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="120"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="405.0" y1="0" x2="405.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="510.0" y1="0" x2="510.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="615.0" y1="0" x2="615.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="120"/>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 120" preserveAspectRatio="meet" width="100%" height="120">
<rect x="0" y="0" width="720" height="40" fill="black"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="6" y="20.0">Operation \ Precision (bits)</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="352.5" y="20.0">2</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="457.5" y="20.0">4</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="562.5" y="20.0">6</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="bold" fill="white" x="667.5" y="20.0">8</text>
<rect x="0" y="40" width="300" height="80" fill="#fbbc04"/>
<rect x="300" y="40" width="420" height="80" fill="#f3f3f3"/>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="60.0">MB-PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="60.0">3.38 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="60.0">4.22 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="60.0">23.0 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="60.0">N/A</text>
<text dominant-baseline="middle" text-anchor="start" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="6" y="100.0">KS - MB-PBS</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="352.5" y="100.0">3.38 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="457.5" y="100.0">4.22 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="562.5" y="100.0">23.1 ms</text>
<text dominant-baseline="middle" text-anchor="middle" font-family="Arial" font-size="14" font-weight="normal" fill="black" x="667.5" y="100.0">N/A</text>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="720" y2="0"/>
<line stroke="white" stroke-width="2" x1="0" y1="40" x2="720" y2="40"/>
<line stroke="white" stroke-width="2" x1="0" y1="80" x2="720" y2="80"/>
<line stroke="white" stroke-width="2" x1="0" y1="0" x2="0" y2="120"/>
<line stroke="white" stroke-width="2" x1="300.0" y1="0" x2="300.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="405.0" y1="0" x2="405.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="510.0" y1="0" x2="510.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="615.0" y1="0" x2="615.0" y2="120"/>
<line stroke="white" stroke-width="2" x1="720.0" y1="0" x2="720.0" y2="120"/>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -1,6 +1,6 @@
# Parallelized PBS
This document describes the implementation and benefits of parallelized [Programmable Bootstrapping](../getting\_started/security\_and\_cryptography.md) (PBS) in **TFHE-rs**, including code examples for using multi-bit PBS parameters and ensuring deterministic execution.
This document describes the implementation and benefits of parallelized [Programmable Bootstrapping](../getting_started/security_and_cryptography.md) (PBS) in **TFHE-rs**, including code examples for using multi-bit PBS parameters and ensuring deterministic execution.
## Parallelized Programmable Bootstrapping

View File

@@ -11,15 +11,14 @@ This guide explains how to update your existing program to leverage GPU accelera
* [gcc](https://gcc.gnu.org/) >= 8.0 - check this [page](https://gist.github.com/ax3l/9489132) for more details about nvcc/gcc compatible versions
* [cmake](https://cmake.org/) >= 3.24
* libclang, to match Rust bingen [requirements](https://rust-lang.github.io/rust-bindgen/requirements.html) >= 9.0
* Rust version - check this [page](rust\_configuration.md)
* Rust version - check this [page](rust_configuration.md)
## Importing to your project
To use the **TFHE-rs** GPU backend in your project, add the following dependency in your `Cargo.toml`.
```toml
tfhe = { version = "1.0.0", features = ["boolean", "shortint", "integer", "gpu"] }
tfhe = { version = "~1.0.1", features = ["boolean", "shortint", "integer", "gpu"] }
```
{% hint style="success" %}
@@ -31,7 +30,7 @@ For optimal performance when using **TFHE-rs**, run your code in release mode wi
**TFHE-rs** GPU backend is supported on Linux (x86, aarch64).
| OS | x86 | aarch64 |
|---------|-------------|---------------|
| ------- | ----------- | ------------- |
| Linux | Supported | Supported\* |
| macOS | Unsupported | Unsupported\* |
| Windows | Unsupported | Unsupported |
@@ -40,7 +39,7 @@ For optimal performance when using **TFHE-rs**, run your code in release mode wi
### Configuring and creating keys.
Comparing to the [CPU example](../getting\_started/quick\_start.md), GPU set up differs in the key creation, as detailed [here](run\_on\_gpu.md#Setting-the-keys)
Comparing to the [CPU example](../getting_started/quick_start.md), GPU set up differs in the key creation, as detailed [here](run\_on\_gpu.md#setting-the-keys)
Here is a full example (combining the client and server parts):
@@ -77,9 +76,7 @@ fn main() {
}
```
Beware that when the GPU feature is activated, when calling: `let config = ConfigBuilder::default().build();`,
the cryptographic parameters differ from the CPU ones, used when the GPU feature is not activated.
Indeed, TFHE-rs uses dedicated parameters for the GPU in order to achieve better performance.
Beware that when the GPU feature is activated, when calling: `let config = ConfigBuilder::default().build();`, the cryptographic parameters differ from the CPU ones, used when the GPU feature is not activated. Indeed, TFHE-rs uses dedicated parameters for the GPU in order to achieve better performance.
### Setting the keys
@@ -103,7 +100,7 @@ On the client-side, the method to encrypt the data is exactly the same than the
The server first need to set up its keys with `set_server_key(gpu_key)`.
Then, homomorphic computations are performed using the same approach as the [CPU operations](../getting\_started/operations.md).
Then, homomorphic computations are performed using the same approach as the [CPU operations](../fhe-computation/operations/README.md).
```Rust
//Server-side
@@ -131,7 +128,7 @@ Finally, the client decrypts the results using:
The GPU backend includes the following operations for both signed and unsigned encrypted integers:
| name | symbol | `Enc`/`Enc` | `Enc`/ `Int` |
|-----------------------|----------------|----------------------------|----------------------------|
| --------------------- | -------------- | -------------------------- | -------------------------- |
| Neg | `-` | :heavy\_check\_mark: | N/A |
| Add | `+` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Sub | `-` | :heavy\_check\_mark: | :heavy\_check\_mark: |
@@ -157,31 +154,32 @@ The GPU backend includes the following operations for both signed and unsigned e
| Cast (from src type) | `cast_from` | :heavy\_multiplication\_x: | N/A |
| Ternary operator | `select` | :heavy\_check\_mark: | :heavy\_multiplication\_x: |
{% hint style="info" %}
All operations follow the same syntax than the one described in [here](../getting\_started/operations.md).
All operations follow the same syntax than the one described in [here](../fhe-computation/operations/README.md).
{% endhint %}
## Multi-GPU support
TFHE-rs supports platforms with multiple GPUs. There is **nothing to change in the code to execute on such platforms**. To keep the API as user-friendly as possible, the configuration is automatically set, i.e., the user has no fine-grained control over the number of GPUs to be used.
## Benchmark
Please refer to the [GPU benchmarks](../getting_started/benchmarks/gpu_benchmarks.md) for detailed performance benchmark results.
## Benchmark
Please refer to the [GPU benchmarks](../getting_started/benchmarks/gpu/README.md) for detailed performance benchmark results.
## Warning
When measuring GPU times on your own on Linux, set the environment variable `CUDA_MODULE_LOADING=EAGER` to avoid CUDA API overheads during the first kernel execution.
## Compressing ciphertexts after some homomorphic computation on the GPU
You can compress ciphertexts using the GPU, even after computations, just like on the [CPU](../fundamentals/compress.md#compression-ciphertexts-after-some-homomorphic-computation).
You can compress ciphertexts using the GPU, even after computations, just like on the [CPU](../fhe-computation/data-handling/compress.md#compression-ciphertexts-after-some-homomorphic-computation).
The way to do it is very similar to how it's done on the CPU.
The following example shows how to compress and decompress a list containing 4 messages:
- One 32-bits integer
- One 64-bit integer
- One Boolean
- One 2-bit integer
The way to do it is very similar to how it's done on the CPU. The following example shows how to compress and decompress a list containing 4 messages:
* One 32-bits integer
* One 64-bit integer
* One Boolean
* One 2-bit integer
```rust
use tfhe::prelude::*;
@@ -246,7 +244,8 @@ fn main() {
## Array types
It is possible to use array types on GPU, just as [on CPU](array.md). Here is an example showing how to do it:
It is possible to use array types on GPU, just as [on CPU](../fhe-computation/types/array.md). Here is an example showing how to do it:
```rust
use tfhe::{ConfigBuilder, set_server_key, ClearArray, ClientKey, CompressedServerKey};
use tfhe::array::GpuFheUint32Array;

View File

@@ -64,7 +64,7 @@ This crate provides 3 kinds of data types. Each kind is enabled by activating th
### AVX-512
While the library generally selects automatically the best instruction sets available by the host, in the case of 'AVX-512', you have to choose it explicitly. This requires to use a [nightly toolchain](rust\_configuration.md#using-tfhe-rs-with-nightly-toolchain) with the feature `nightly-avx512`.
While the library generally selects automatically the best instruction sets available by the host, in the case of 'AVX-512', you have to choose it explicitly. This requires to use a nightly toolchain with the feature `nightly-avx512`.
```shell
cargo +nightly build --release --features=nightly-avx512

View File

@@ -1,6 +0,0 @@
# Contributing
There are two ways to contribute to `TFHE-rs`. You can:
* open issues to report bugs and typos and to suggest ideas;
* ask to become an official contributor by emailing hello@zama.ai. Only approved contributors can send pull requests, so get in touch before you do.

View File

@@ -0,0 +1 @@
# Advanced features

View File

@@ -17,10 +17,10 @@ Here's the list of operations supported along with their symbol:
The usage of these operations is similar to the standard ones. The key difference is in the decryption process, as shown in following example:
```rust
/// Adds two [FheUint] and returns a boolean indicating overflow.
///
/// * The operation is modular, i.e on overflow the result wraps around.
/// * On overflow the [FheBool] is true, otherwise false
// Adds two [FheUint] and returns a boolean indicating overflow.
//
// * The operation is modular, i.e on overflow the result wraps around.
// * On overflow the [FheBool] is true, otherwise false
use tfhe::prelude::*;
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint16};
@@ -40,21 +40,3 @@ assert_eq!(
);
assert!(overflowed.decrypt(&client_key));
```
The following tables show the current benchmarks result.
Unsigned homomorphic integers:
| Operation\Size | FheUint8 | FheUint16 | FheUint32 | FheUint64 | FheUint128 | FheUint256 |
| -------------------------- | --------- | --------- | --------- | --------- | ---------- | ---------- |
| unsigned\_overflowing\_add | 63.67 ms | 84.11 ms | 107.95 ms | 120.8 ms | 147.38 ms | 191.28 ms |
| unsigned\_overflowing\_sub | 68.89 ms | 81.83 ms | 107.63 ms | 120.38 ms | 150.21 ms | 190.39 ms |
| unsigned\_overflowing\_mul | 140.76 ms | 191.85 ms | 272.65 ms | 510.61 ms | 1.34 s | 4.51 s |
Signed homomorphic integers:
| Operation\Size | FheInt8 | FheInt16 | FheInt32 | FheInt64 | FheInt128 | FheInt256 |
| ------------------------ | --------- | --------- | --------- | --------- | --------- | --------- |
| signed\_overflowing\_add | 76.54 ms | 84.78 ms | 104.23 ms | 134.38 ms | 162.99 ms | 202.56 ms |
| signed\_overflowing\_sub | 82.46 ms | 86.92 ms | 104.41 ms | 132.21 ms | 168.06 ms | 201.17 ms |
| signed\_overflowing\_mul | 277.91 ms | 365.67 ms | 571.22 ms | 1.21 s | 3.57 s | 12.84 s |

View File

@@ -7,7 +7,7 @@ Public key encryption refers to the cryptographic paradigm where the encryption
* **Classical public key**: the first method involves the public key containing many encryptions of zero, as detailed in [Guide to Fully Homomorphic Encryption over the \[Discretized\] Torus, Appendix A.](https://eprint.iacr.org/2021/1402)
* **Compact public key**: the second method is based on the paper [TFHE Public-Key Encryption Revisited](https://eprint.iacr.org/2023/603), allowing for significantly smaller key sizes compared to the first method.
Public keys can also be [compressed](../fundamentals/compress.md) to reduce size.
Public keys can also be [compressed](../data-handling/compress.md) to reduce size.
## Classical public key

View File

@@ -74,25 +74,29 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
```
Performance can be improved by setting `lto="fat"` in `Cargo.toml`
```toml
[profile.release]
lto = "fat"
```
and by building the code for the native CPU architecture and in release mode, e.g. by calling `RUSTFLAGS="-C target-cpu=native" cargo run --release`.
{% hint style="info" %}
You can choose a more costly proof with `ZkComputeLoad::Proof`, which has a faster verification time. Alternatively, you can select `ZkComputeLoad::Verify` for a faster proof and slower verification.
You can choose a more costly proof with `ZkComputeLoad::Proof`, which has a faster verification time. Alternatively, you can select `ZkComputeLoad::Verify` for a faster proof and slower verification.
{% endhint %}
## Scheme version
The ZK scheme used to generate and verify proofs is available in two versions:
- ZKV1: This version is close to the original paper from [Libert](https://eprint.iacr.org/2023/800).
- ZKV2: Differing from the paper, this version provides better performance for provers and verifiers.
* ZKV1: This version is close to the original paper from [Libert](https://eprint.iacr.org/2023/800).
* ZKV2: Differing from the paper, this version provides better performance for provers and verifiers.
**TFHE-rs** selects automatically the scheme to use based on the encryption parameters during the CRS generation. With default parameters, ZKV2 is selected.
The following example shows how to generate a CRS and proofs for ZKV1. Compared to the previous example, only the parameters are changed:
```rust
use rand::prelude::*;
use tfhe::prelude::*;
@@ -150,5 +154,6 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
}
```
## Benchmark
Please refer to the [Zero-knowledge proof benchmarks](../getting_started/benchmarks/zk_proof_benchmarks.md) for detailed performance benchmark results.
## Benchmark
Please refer to the [Zero-knowledge proof benchmarks](../../getting_started/benchmarks/zk_proof_benchmarks.md) for detailed performance benchmark results.

View File

@@ -4,7 +4,7 @@ This document explains how to initialize the configuration and generate keys.
The configuration specifies the selected data types and their custom crypto-parameters. You should only use custom parameters for advanced usage and/or testing.
To create a configuration, use the `ConfigBuilder` type. The following example shows the setup using 8-bit unsigned integers with default parameters. Additionally, ensure the `integers` feature is enabled, as indicated in the table on [this page](../guides/rust\_configuration.md#homomorphic-types).
To create a configuration, use the `ConfigBuilder` type. The following example shows the setup using 8-bit unsigned integers with default parameters. Additionally, ensure the `integers` feature is enabled, as indicated in the table on [this page](../../configuration/rust_configuration.md#homomorphic-types).
The configuration is initialized by creating a builder with all types deactivated. Then, the integer types with default parameters are activated, for using `FheUint8` values.

View File

@@ -0,0 +1,66 @@
# Cryptographic Parameters
This document explains how the choice of cryptographic parameters impacts both the security and efficiency of FHE algorithms. The chosen parameters determine the error probability (sometimes referred to failure probability) and overall performance of computations using fully homomorphic encryption. This error probability is due to the noisy nature of FHE computations (see [here](../../getting\_started/security\_and\_cryptography.md) for more details about the encryption process).
All parameter sets provide at least 128-bits of security according to the [Lattice-Estimator](https://github.com/malb/lattice-estimator).
## Default parameters
Currently, the default parameters use blocks that contain 2 bits of message and 2 bits of carry - a tweaked uniform (TUniform, defined [here](../../getting_started/security_and_cryptography.md#noise)) noise distribution, and have a bootstrapping failure probability $$p_{error} \le 2^{-128}$$.
These are particularly suitable for applications that need to be secure in the IND-CPA^D model (see [here](../../getting_started/security_and_cryptography.md) for more details).
The GPU backend still uses an error probability smaller than $$2^{-64}$$ by default. Those will be updated soon.
When using the high-level API of **TFHE-rs**, you can create a key pair using the default recommended set of parameters. For example:
```rust
use tfhe::{ConfigBuilder, generate_keys};
fn main() {
let config = ConfigBuilder::default().build();
// Client-side
let (client_key, server_key) = generate_keys(config);
// encryption and FHE operations
}
```
{% hint style="info" %}
These default parameters may be updated with in future releases of **TFHE-rs**, potentially causing incompatibilities between versions. For production systems, it is therefore recommended to specify a fixed parameter set.
{% endhint %}
## Parameters versioning and naming scheme
Parameter sets are versioned for backward compatibility. This means that each set of parameters can be tied to a specific version of **TFHE-rs**, so that they remain unchanged and compatible after an upgrade.
All parameter sets are stored as variables inside the `tfhe::shortint::parameters` module, with submodules named after the versions of **TFHE-rs** in which these parameters where added. For example, parameters added in **TFHE-rs** v1.0 can be found inside `tfhe::shortint::parameters::v1_0`.
The naming convention of these parameters indicates their capabilities. Taking `tfhe::parameters::v1_0::V1_0_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M128` as an example:
- `V1_0`: these parameters were introduced in **TFHE-rs** v1.0
- `MESSAGE_2`: LWE blocks include 2 bits of message
- `CARRY_2`: LWE blocks include 2 bits of carry
- `KS_PBS`: the keyswitch is computed before the bootstrap
- `TUNIFORM`: the tweaked uniform noise distribution is used
- `2M128`: the probability of failure for the bootstrap is $$2^{-128}$$
For convenience, aliases are provided for the most used sets of parameters and stored in the module `tfhe::shortint::parameters::aliases`. Note, however, that these parameters are not stable over time and are always updated to the latest **TFHE-rs** version. For this reason, they should only be used for prototyping and are not suitable for production use cases.
## How to choose the parameter sets
You can override the default parameters with the `with_custom_parameters(block_parameters)` method of the `Config` object. For example, to use a Gaussian distribution instead of the TUniform one, you can modify your configuration as follows:
```rust
use tfhe::{ConfigBuilder, generate_keys};
use tfhe::shortint::parameters::v1_0::V1_0_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128;
fn main() {
let config =
ConfigBuilder::with_custom_parameters(V1_0_PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M128)
.build();
// Client-side
let (client_key, server_key) = generate_keys(config);
// encryption and FHE operations
}
```

View File

@@ -0,0 +1 @@
# Data handling

View File

@@ -16,8 +16,8 @@ You can load serialized data with the `unversionize` function, even in newer ver
[dependencies]
# ...
tfhe = { version = "1.0.0", features = ["integer"] }
tfhe-versionable = "0.4.0"
tfhe = { version = "~1.0.1", features = ["integer"] }
tfhe-versionable = "0.5.0"
bincode = "1.3.3"
```

View File

@@ -7,6 +7,7 @@ This document explains the `serialization` and `deserialization` features that a
When dealing with sensitive types, it's important to implement safe serialization and safe deserialization functions to prevent runtime errors and enhance security. **TFHE-rs** provide easy to use functions for this purpose, such as `safe_serialize`, `safe_deserialize` and `safe_deserialize_conformant`.
Here is a basic example on how to use it:
```rust
// main.rs
@@ -35,7 +36,7 @@ fn main() {
The safe deserialization must take the output of a safe-serialization as input. During the process, the following validation occurs:
* **Type match**: deserializing `type A` from a serialized `type B` raises an error indicating "On deserialization, expected type A, got type B".
* **Version compatibility**: data serialized in previous versions of **TFHE-rs** are automatically upgraded to the latest version using the [data versioning](../guides/data\_versioning.md) feature.
* **Version compatibility**: data serialized in previous versions of **TFHE-rs** are automatically upgraded to the latest version using the [data versioning](data_versioning.md) feature.
* **Parameter compatibility**: deserializing an object of `type A` with one set of crypto parameters from an object of `type A` with another set of crypto parameters raises an error indicating "Deserialized object of type A not conformant with given parameter set"
* If both parameter sets have the same LWE dimension for ciphertexts, a ciphertext from param 1 may not fail this deserialization check with param 2.
* This check can't distinguish ciphertexts/server keys from independent client keys with the same parameters.
@@ -120,8 +121,7 @@ fn main() {
The safe serialization and deserialization use `bincode` internally.
To selectively disable some of the features of the safe serialization, you can use `SerializationConfig`/`DeserializationConfig` builders.
For example, it is possible to disable the data versioning:
To selectively disable some of the features of the safe serialization, you can use `SerializationConfig`/`DeserializationConfig` builders. For example, it is possible to disable the data versioning:
```rust
// main.rs
@@ -152,8 +152,7 @@ fn main() {
**TFHE-rs** uses the [Serde](https://crates.io/crates/serde) framework and implements Serde's `Serialize` and `Deserialize` traits.
This allows you to serialize into any [data format](https://serde.rs/#data-formats) supported by serde.
However, this is a more bare bone approach as none of the checks described in the previous section will be performed for you.
This allows you to serialize into any [data format](https://serde.rs/#data-formats) supported by serde. However, this is a more bare bone approach as none of the checks described in the previous section will be performed for you.
In the following example, we use [bincode](https://crates.io/crates/bincode) for its binary format:
@@ -162,7 +161,7 @@ In the following example, we use [bincode](https://crates.io/crates/bincode) for
[dependencies]
# ...
tfhe = { version = "1.0.0", features = ["integer"] }
tfhe = { version = "~1.0.1", features = ["integer"] }
bincode = "1.3.3"
```

View File

@@ -0,0 +1,30 @@
# Operations
This document gives a high-level overview of various operations on encrypted integers supported by **TFHE-rs.**
**TFHE-rs** supports various operations on encrypted integers (`Enc`) of any size between 1 and 256 bits. These operations can also work between encrypted integers and clear integers (`Int`).
| name | symbol | `Enc`/`Enc` | `Enc`/ `Int` |
| --------------------- | ----------- | -------------------- | -------------------------- |
| Neg | `-` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Add | `+` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Sub | `-` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Mul | `*` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Div | `/` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Rem | `%` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Not | `!` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| BitAnd | `&` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| BitOr | `\|` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| BitXor | `^` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Shr | `>>` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Shl | `<<` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Min | `min` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Max | `max` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Greater than | `gt` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Greater or equal than | `ge` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Less than | `lt` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Less or equal than | `le` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Equal | `eq` | :heavy\_check\_mark: | :heavy\_check\_mark: |
| Cast (into dest type) | `cast_into` | :heavy\_check\_mark: | :heavy\_multiplication\_x: |
| Cast (from src type) | `cast_from` | :heavy\_check\_mark: | :heavy\_multiplication\_x: |
| Ternary operator | `select` | :heavy\_check\_mark: | :heavy\_multiplication\_x: |

View File

@@ -0,0 +1,60 @@
# Arithmetic operations
This document details the arithmetic operations supported by **TFHE-rs**.
Homomorphic integer types (`FheUint` and `FheInt`) support the following arithmetic operations:
| name | symbol | type |
| --------------------------------------------------------- | ------ | ------ |
| [Neg](https://doc.rust-lang.org/std/ops/trait.Neg.html) | `-` | Unary |
| [Add](https://doc.rust-lang.org/std/ops/trait.Add.html) | `+` | Binary |
| [Sub](https://doc.rust-lang.org/std/ops/trait.Sub.html) | `-` | Binary |
| [Mul](https://doc.rust-lang.org/std/ops/trait.Mul.html) | `*` | Binary |
| [Div](https://doc.rust-lang.org/std/ops/trait.Div.html)\* | `/` | Binary |
| [Rem](https://doc.rust-lang.org/std/ops/trait.Rem.html)\* | `%` | Binary |
Specifications for operations with zero:
* **Division by zero**: returns modulus - 1.
* Example: for FheUint8 (modulus = $$2^8=256$$), dividing by zero returns an encryption of 255.
* **Remainder operator**: returns the first input unchanged.
* Example: if `ct1 = FheUint8(63)` and `ct2 = FheUint8(0)`, then ct1 % ct2 returns FheUint8(63).
The following example shows how to perform arithmetic operations:
```rust
use tfhe::prelude::*;
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheInt8, FheUint8};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConfigBuilder::default().build();
let (keys, server_keys) = generate_keys(config);
set_server_key(server_keys);
let clear_a = 15_u64;
let clear_b = 27_u64;
let clear_c = 43_u64;
let clear_d = -87_i64;
let mut a = FheUint8::try_encrypt(clear_a, &keys)?;
let mut b = FheUint8::try_encrypt(clear_b, &keys)?;
let c = FheUint8::try_encrypt(clear_c, &keys)?;
let mut d = FheInt8::try_encrypt(clear_d, &keys)?;
a *= &b; // Clear equivalent computations: 15 * 27 mod 256 = 149
b = &b + &c; // Clear equivalent computations: 27 + 43 mod 256 = 70
b -= 76u8; // Clear equivalent computations: 70 - 76 mod 256 = 250
d -= 13i8; // Clear equivalent computations: -87 - 13 = 100 in [-128, 128[
let dec_a: u8 = a.decrypt(&keys);
let dec_b: u8 = b.decrypt(&keys);
let dec_d: i8 = d.decrypt(&keys);
assert_eq!(dec_a, ((clear_a * clear_b) % 256_u64) as u8);
assert_eq!(dec_b, (((clear_b + clear_c).wrapping_sub(76_u64)) % 256_u64) as u8);
assert_eq!(dec_d, (clear_d - 13) as i8);
Ok(())
}
```

View File

@@ -0,0 +1,39 @@
# Bitwise operations
This document details the bitwise operations supported by **TFHE-rs**.
Homomorphic integer types support the following bitwise operations:
<table><thead><tr><th width="242">name</th><th>symbol</th><th>type</th></tr></thead><tbody><tr><td><a href="https://doc.rust-lang.org/std/ops/trait.Not.html">Not</a></td><td><code>!</code></td><td>Unary</td></tr><tr><td><a href="https://doc.rust-lang.org/std/ops/trait.BitAnd.html">BitAnd</a></td><td><code>&#x26;</code></td><td>Binary</td></tr><tr><td><a href="https://doc.rust-lang.org/std/ops/trait.BitOr.html">BitOr</a></td><td><code>|</code></td><td>Binary</td></tr><tr><td><a href="https://doc.rust-lang.org/std/ops/trait.BitXor.html">BitXor</a></td><td><code>^</code></td><td>Binary</td></tr><tr><td><a href="https://doc.rust-lang.org/std/ops/trait.Shr.html">Shr</a></td><td><code>>></code></td><td>Binary</td></tr><tr><td><a href="https://doc.rust-lang.org/std/ops/trait.Shl.html">Shl</a></td><td><code>&#x3C;&#x3C;</code></td><td>Binary</td></tr><tr><td><a href="https://doc.rust-lang.org/std/primitive.u32.html#method.rotate_right">Rotate Right</a></td><td><code>rotate_right</code></td><td>Binary</td></tr><tr><td><a href="https://doc.rust-lang.org/std/primitive.u32.html#method.rotate_left">Rotate Left</a></td><td><code>rotate_left</code></td><td>Binary</td></tr></tbody></table>
The following example shows how to perform bitwise operations:
```rust
use tfhe::prelude::*;
use tfhe::{generate_keys, set_server_key, ConfigBuilder, FheUint8};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = ConfigBuilder::default().build();
let (keys, server_keys) = generate_keys(config);
set_server_key(server_keys);
let clear_a = 164;
let clear_b = 212;
let mut a = FheUint8::try_encrypt(clear_a, &keys)?;
let mut b = FheUint8::try_encrypt(clear_b, &keys)?;
a ^= &b;
b ^= &a;
a ^= &b;
let dec_a: u8 = a.decrypt(&keys);
let dec_b: u8 = b.decrypt(&keys);
// We homomorphically swapped values using bitwise operations
assert_eq!(dec_a, clear_b);
assert_eq!(dec_b, clear_a);
Ok(())
}
```

Some files were not shown because too many files have changed in this diff Show More