Compare commits

..

43 Commits

Author SHA1 Message Date
Arthur Meyre
615ed3d5db refactor(tfhe)!: update key level order for better performance
- use natural order for decomposition levels in bsk

co-authored-by: Agnes Leroy <agnes.leroy@zama.ai>
2024-11-05 17:23:57 +01:00
Arthur Meyre
dda93889da chore: update data backward compatibility branch 2024-11-05 17:23:57 +01:00
Arthur Meyre
748b88e905 chore(tfhe): update version to 0.10.0 2024-11-05 17:23:57 +01:00
Arthur Meyre
612657260f chore: bump CUDA backend version to 0.6.0 2024-11-05 17:23:57 +01:00
Nicolas Sarlin
6ee3eb17b9 chore(zk): add a proof compat test between x86_64 and wasm 2024-11-05 17:07:04 +01:00
Agnes Leroy
c1374a0e10 chore(gpu): increase sm for rtxa6000 2024-11-05 12:11:36 +01:00
Agnes Leroy
a9601fc47d chore(gpu): remove decompressed ct comparison btw cpu and gpu
The results are not expected to match bitwise
2024-11-04 15:01:53 -03:00
Agnes Leroy
bd255cd958 chore(gpu): rework ci to adapt to the shortage of h100 2024-11-04 15:23:43 +01:00
Arthur Meyre
6fe36799fd chore(ci): fix clippy issue for M1 build 2024-11-04 12:53:58 +01:00
dependabot[bot]
02419d6852 chore(deps): bump zgosalvez/github-actions-ensure-sha-pinned-actions
Bumps [zgosalvez/github-actions-ensure-sha-pinned-actions](https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions) from 3.0.15 to 3.0.16.
- [Release notes](https://github.com/zgosalvez/github-actions-ensure-sha-pinned-actions/releases)
- [Commits](ed00f72a3c...38608ef4fb)

---
updated-dependencies:
- dependency-name: zgosalvez/github-actions-ensure-sha-pinned-actions
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-04 12:53:09 +01:00
David Testé
8d53fa124d chore(ci): cache node build in workflows
Building Node is failing often due to network error.
Caching a successful build will allow more reliable workflows.
2024-11-04 09:19:46 +01:00
tmontaigu
e8a3da9bb3 chore(csprng): no longer check macOS version
We checked the macOS version to be sure that the
SecRandomCopyBytes was available.

Since rust 1.74 (which is older than our current msrv)
rust only supports macOS >= 10.12, thus we can expect
SecRandomCopyBytes to always be available and can remove the check
2024-10-31 18:29:01 +01:00
Agnes Leroy
8643b06857 fix(gpu): fix memory error in cg classical PBS 2024-10-31 15:19:45 +01:00
yuxizama
3611dece11 chore(docs): fix the survey format 2024-10-31 11:23:28 +01:00
Agnes Leroy
3bd7cf789c chore(gpu): restrict bindings generation 2024-10-31 11:16:08 +01:00
Agnes Leroy
fc26f2abb7 chore(gpu): restrict should run 2024-10-31 11:14:03 +01:00
David Testé
083e973fb2 chore(ci): update version of selenium to 4.26.0
This reduces console verbosity.
2024-10-31 09:30:41 +01:00
Nicolas Sarlin
e91f3d3ba3 chore(zk): bump version to 0.3.1 2024-10-30 14:54:48 +01:00
Nicolas Sarlin
96360cfef9 fix(zk): proof compatiblity between 32/64b platforms 2024-10-30 14:54:48 +01:00
David Testé
93ddb6b084 chore(ci): verify commit on release
Enforce commit being associated to a tag.
The tag must be committed by a member of the release team.
In addition, the tag needs to be verified. Finally, triggering
actor must also be a member of the release team.
2024-10-30 14:40:04 +01:00
David Testé
4ce8b5e2d9 chore(bench): skip tuniform parameters for pbs with ntt 2024-10-29 15:19:41 +01:00
Mayeul@Zama
df9fd6cd19 chore(zk): regroup compute load proof optionals 2024-10-29 09:55:22 +01:00
dependabot[bot]
69482dec9b chore(deps): bump actions/checkout from 4.2.1 to 4.2.2
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.1 to 4.2.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](eef61447b9...11bd71901b)

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

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-28 15:01:14 +01:00
dependabot[bot]
2d341f8506 chore(deps): bump rtCamp/action-slack-notify from 2.3.1 to 2.3.2
Bumps [rtCamp/action-slack-notify](https://github.com/rtcamp/action-slack-notify) from 2.3.1 to 2.3.2.
- [Release notes](https://github.com/rtcamp/action-slack-notify/releases)
- [Commits](65e6fc1ce6...c33737706d)

---
updated-dependencies:
- dependency-name: rtCamp/action-slack-notify
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-28 15:01:05 +01:00
Arthur Meyre
776c95c16e chore(ci): update chrome version 2024-10-28 09:38:40 +01:00
Arthur Meyre
f497bf09a3 chore(ci): fix wasm bench parameter names 2024-10-25 16:52:22 +02:00
Arthur Meyre
a6fd9553b8 chore(ci): fix odd clippy import issue for ks bench 2024-10-25 16:52:22 +02:00
dependabot[bot]
6628717077 chore(deps): update zama-ai/slab-github-runner requirement to 801df0b8db5ea2b06128b7476c652f5ed5f193a8
Updates the requirements on [zama-ai/slab-github-runner](https://github.com/zama-ai/slab-github-runner) to permit the latest version.
- [Release notes](https://github.com/zama-ai/slab-github-runner/releases)
- [Commits](801df0b8db)

---
updated-dependencies:
- dependency-name: zama-ai/slab-github-runner
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-25 16:31:23 +02:00
Mayeul@Zama
fdbe0404c1 refactor(fhe_strings): CharIter is a Vec, cleanups 2024-10-25 16:16:37 +02:00
Mayeul@Zama
1262106652 chore(fhe_strings): remove some par_bridge 2024-10-25 16:16:37 +02:00
Mayeul@Zama
d74372657e refactor(fhe_strings): add is_empty method to FheString 2024-10-25 16:16:37 +02:00
Mayeul@Zama
27e34a835c refactor(fhe_strings): add len function 2024-10-25 16:16:37 +02:00
Mayeul@Zama
aebc2619b2 refactor(fhe_strings): add padded param to from_uint 2024-10-25 16:16:37 +02:00
Mayeul@Zama
5056e06380 chore(fhe_strings): add encryption-decryption test 2024-10-25 16:16:37 +02:00
Mayeul@Zama
b90b20f31e chore(fhe_strings): remove EncryptOutput 2024-10-25 16:16:37 +02:00
Mayeul@Zama
2369d02025 chore(fhe_strings): remove TrivialEncryptOutput 2024-10-25 16:16:37 +02:00
David Testé
e9af460d3e feat(core): add batched programmable boostraping 2024-10-25 15:19:44 +02:00
Arthur Meyre
a88597b183 chore(wop): fix test for bivariate CRT
- insane degrees generated randomly required insane amounts of memory to
supposedly run the test, now just pretend we did an addition to have higher
degree and keep the spirit of the test
2024-10-25 14:54:16 +02:00
Arthur Meyre
1417925a6c chore(ci): generate wopbs keys to avoid test crashes 2024-10-25 14:54:16 +02:00
Arthur Meyre
199cb6714a chore(all): remove default big/small configurations 2024-10-25 14:54:16 +02:00
Arthur Meyre
33c21b97ad chore(c_api): remove the get parameters function from shortint
- always use parameter names to get parameters
2024-10-25 14:54:16 +02:00
Arthur Meyre
b585ca226d chore(js): remove functions to get shortint parameters, always use names 2024-10-25 14:54:16 +02:00
Agnes Leroy
92523d236c chore(all): add TUniform params for GPU, make TUniform params default
- also remove some aliases for parameters
- stop using aliases for parameters in shortint and integer
- update test filtering
2024-10-25 14:54:16 +02:00
358 changed files with 5031 additions and 25869 deletions

View File

@@ -26,7 +26,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -44,7 +44,7 @@ jobs:
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -72,7 +72,7 @@ jobs:
echo "branch=${BRANCH}" >> "${GITHUB_OUTPUT}"
- name: Clone test data
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
repository: zama-ai/tfhe-backward-compat-data
@@ -87,7 +87,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Backward compatibility tests finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -100,7 +100,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -111,7 +111,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (backward-compat-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -51,7 +51,7 @@ jobs:
any_file_changed: ${{ env.IS_PULL_REQUEST == 'false' || steps.aggregated-changes.outputs.any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -131,7 +131,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -151,7 +151,7 @@ jobs:
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -191,10 +191,36 @@ jobs:
run: |
make test_user_doc
- name: Get Node version
run: |
echo "NODE_VERSION=$(make node_version)" >> "${GITHUB_ENV}"
- name: Node cache restoration
id: node-cache
uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a #v4.1.2
with:
path: |
~/.nvm
~/.npm
key: node-${{ env.NODE_VERSION }}
- name: Install Node
if: steps.node-cache.outputs.cache-hit != 'true'
run: |
make install_node
- name: Node cache save
uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a #v4.1.2
if: steps.node-cache.outputs.cache-hit != 'true'
with:
path: |
~/.nvm
~/.npm
key: node-${{ env.NODE_VERSION }}
- name: Run js on wasm API tests
if: needs.should-run.outputs.wasm_test == 'true'
run: |
make install_node
make test_nodejs_wasm_api_ci
- name: Gen Keys if required
@@ -225,7 +251,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Fast AWS tests finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -238,7 +264,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -249,7 +275,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (fast-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -39,7 +39,7 @@ jobs:
steps.changed-files.outputs.integer_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
persist-credentials: "false"
@@ -72,7 +72,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -90,7 +90,7 @@ jobs:
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: "false"
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -124,7 +124,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Unsigned Integer tests finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -137,7 +137,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -148,7 +148,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (unsigned-integer-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -39,7 +39,7 @@ jobs:
steps.changed-files.outputs.integer_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
persist-credentials: "false"
@@ -72,7 +72,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -90,7 +90,7 @@ jobs:
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: "false"
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -128,7 +128,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Signed Integer tests finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -141,7 +141,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -152,7 +152,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (signed-integer-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -57,7 +57,7 @@ jobs:
any_file_changed: ${{ env.IS_PULL_REQUEST == 'false' || steps.aggregated-changes.outputs.any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -131,7 +131,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -151,7 +151,7 @@ jobs:
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -221,7 +221,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "CPU tests finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -234,7 +234,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -245,7 +245,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cpu-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -27,7 +27,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -45,7 +45,7 @@ jobs:
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -55,9 +55,35 @@ jobs:
with:
toolchain: stable
- name: Install web resources
- name: Get Node version
run: |
echo "NODE_VERSION=$(make node_version)" >> "${GITHUB_ENV}"
- name: Node cache restoration
id: node-cache
uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a #v4.1.2
with:
path: |
~/.nvm
~/.npm
key: node-${{ env.NODE_VERSION }}
- name: Install Node
if: steps.node-cache.outputs.cache-hit != 'true'
run: |
make install_node
- name: Node cache save
uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a #v4.1.2
if: steps.node-cache.outputs.cache-hit != 'true'
with:
path: |
~/.nvm
~/.npm
key: node-${{ env.NODE_VERSION }}
- name: Install web resources
run: |
make install_chrome_browser
make install_chrome_web_driver
@@ -73,10 +99,14 @@ jobs:
run: |
make test_web_js_api_parallel_chrome_ci
- name: Run x86_64/wasm zk compatibility tests
run: |
make test_zk_wasm_x86_compat_ci
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "WASM tests finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -89,7 +119,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -100,7 +130,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (wasm-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -29,7 +29,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -48,7 +48,7 @@ jobs:
continue-on-error: true
steps:
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -105,7 +105,7 @@ jobs:
path: ${{ env.RESULTS_FILENAME }}
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -120,7 +120,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Boolean benchmarks finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -133,7 +133,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -144,7 +144,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (boolean-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -26,7 +26,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -44,7 +44,7 @@ jobs:
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
steps:
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -93,7 +93,7 @@ jobs:
path: ${{ env.RESULTS_FILENAME }}
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -108,7 +108,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "PBS benchmarks finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -121,7 +121,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -132,7 +132,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (core-crypto-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -29,7 +29,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -49,7 +49,7 @@ jobs:
timeout-minutes: 720 # 12 hours
steps:
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -73,7 +73,7 @@ jobs:
toolchain: nightly
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -116,7 +116,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "ERC20 benchmarks finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -129,7 +129,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -140,7 +140,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (erc20-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -39,7 +39,7 @@ jobs:
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -59,7 +59,7 @@ jobs:
toolchain: nightly
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -97,7 +97,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Integer RTX 4090 full benchmarks finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -114,7 +114,7 @@ jobs:
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -132,7 +132,7 @@ jobs:
toolchain: nightly
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -179,7 +179,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Core crypto RTX 4090 full benchmarks finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -27,7 +27,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -66,7 +66,7 @@ jobs:
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -136,7 +136,7 @@ jobs:
path: ${{ env.RESULTS_FILENAME }}
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -156,7 +156,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-core-crypto-benchmarks.result }}
SLACK_MESSAGE: "PBS GPU benchmarks finished with status: ${{ needs.cuda-core-crypto-benchmarks.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -169,7 +169,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -180,7 +180,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-core-crypto-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -30,7 +30,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -68,7 +68,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -145,7 +145,7 @@ jobs:
path: ${{ env.RESULTS_FILENAME }}
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -165,7 +165,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-erc20-benchmarks.result }}
SLACK_MESSAGE: "Integer GPU benchmarks finished with status: ${{ needs.cuda-erc20-benchmarks.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -178,7 +178,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -189,7 +189,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-erc20-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -30,7 +30,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -68,7 +68,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -151,7 +151,7 @@ jobs:
path: ${{ env.RESULTS_FILENAME }}
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -171,7 +171,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-integer-benchmarks.result }}
SLACK_MESSAGE: "Integer GPU benchmarks finished with status: ${{ needs.cuda-integer-benchmarks.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -184,7 +184,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -195,7 +195,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-integer-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -29,7 +29,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -72,7 +72,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -116,7 +116,7 @@ jobs:
} >> "${GITHUB_ENV}"
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -164,7 +164,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-integer-full-2-gpu-benchmarks.result }}
SLACK_MESSAGE: "Integer GPU 2xH100 benchmarks finished with status: ${{ needs.cuda-integer-full-2-gpu-benchmarks.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -177,7 +177,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -188,7 +188,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-integer-full-2-gpu-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -29,7 +29,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -72,7 +72,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -116,7 +116,7 @@ jobs:
} >> "${GITHUB_ENV}"
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -170,7 +170,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-integer-full-benchmarks.result }}
SLACK_MESSAGE: "Integer GPU full benchmarks finished with status: ${{ needs.cuda-integer-full-benchmarks.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -183,7 +183,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -194,7 +194,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-integer-full-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -42,7 +42,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -81,7 +81,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -174,7 +174,7 @@ jobs:
path: ${{ env.RESULTS_FILENAME }}
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -194,7 +194,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-integer-multi-bit-benchmarks.result }}
SLACK_MESSAGE: "Integer GPU multi-bit benchmarks finished with status: ${{ needs.cuda-integer-multi-bit-benchmarks.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -207,7 +207,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -218,7 +218,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-integer-multi-bit-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -42,7 +42,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -82,7 +82,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -126,7 +126,7 @@ jobs:
} >> "${GITHUB_ENV}"
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -184,7 +184,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-integer-multi-bit-multi-gpu-benchmarks.result }}
SLACK_MESSAGE: "Integer multi GPU multi-bit benchmarks finished with status: ${{ needs.cuda-integer-multi-bit-multi-gpu-benchmarks.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -197,7 +197,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -208,7 +208,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-integer-multi-bit-multi-gpu-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -29,7 +29,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -72,7 +72,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -116,7 +116,7 @@ jobs:
} >> "${GITHUB_ENV}"
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -164,7 +164,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-integer-full-multi-gpu-benchmarks.result }}
SLACK_MESSAGE: "Integer GPU full benchmarks finished with status: ${{ needs.cuda-integer-full-multi-gpu-benchmarks.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -177,7 +177,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -188,7 +188,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-integer-full-multi-gpu-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -29,7 +29,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -72,7 +72,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -116,7 +116,7 @@ jobs:
} >> "${GITHUB_ENV}"
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -176,7 +176,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-l40-benchmarks.result }}
SLACK_MESSAGE: "Cuda benchmarks (L40) finished with status: ${{ needs.cuda-l40-benchmarks.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -189,7 +189,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -200,7 +200,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-l40-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -62,7 +62,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -87,7 +87,7 @@ jobs:
op_flavor: ${{ fromJson(needs.prepare-matrix.outputs.op_flavor) }}
steps:
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -111,7 +111,7 @@ jobs:
toolchain: nightly
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -160,7 +160,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Integer full benchmarks finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -173,7 +173,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -184,7 +184,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (integer-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -56,7 +56,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -79,7 +79,7 @@ jobs:
op_flavor: ${{ fromJson(needs.prepare-matrix.outputs.op_flavor) }}
steps:
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -103,7 +103,7 @@ jobs:
toolchain: nightly
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -156,7 +156,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Shortint full benchmarks finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -169,7 +169,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -180,7 +180,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (shortint-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -62,7 +62,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -87,7 +87,7 @@ jobs:
op_flavor: [ default, unchecked ]
steps:
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -111,7 +111,7 @@ jobs:
toolchain: nightly
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -154,7 +154,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Signed integer full benchmarks finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -167,7 +167,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -178,7 +178,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (signed-integer-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -33,7 +33,7 @@ jobs:
wasm_bench: ${{ steps.changed-files.outputs.wasm_bench_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -64,7 +64,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -84,7 +84,7 @@ jobs:
browser: [ chrome, firefox ]
steps:
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -102,9 +102,35 @@ jobs:
with:
toolchain: nightly
- name: Install web resources
- name: Get Node version
run: |
echo "NODE_VERSION=$(make node_version)" >> "${GITHUB_ENV}"
- name: Node cache restoration
id: node-cache
uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a #v4.1.2
with:
path: |
~/.nvm
~/.npm
key: node-${{ env.NODE_VERSION }}
- name: Install Node
if: steps.node-cache.outputs.cache-hit != 'true'
run: |
make install_node
- name: Node cache save
uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a #v4.1.2
if: steps.node-cache.outputs.cache-hit != 'true'
with:
path: |
~/.nvm
~/.npm
key: node-${{ env.NODE_VERSION }}
- name: Install web resources
run: |
make install_${{ matrix.browser }}_browser
make install_${{ matrix.browser }}_web_driver
@@ -145,7 +171,7 @@ jobs:
path: ${{ env.RESULTS_FILENAME }}
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -160,7 +186,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "WASM benchmarks (${{ matrix.browser }}) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -173,7 +199,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -184,7 +210,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (wasm-client-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -30,7 +30,7 @@ jobs:
zk_pok_changed: ${{ steps.changed-files.outputs.zk_pok_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -65,7 +65,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -84,7 +84,7 @@ jobs:
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
steps:
- name: Checkout tfhe-rs repo with tags
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -108,7 +108,7 @@ jobs:
toolchain: nightly
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -145,7 +145,7 @@ jobs:
path: ${{ env.RESULTS_FILENAME }}
- name: Checkout Slab repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: zama-ai/slab
path: slab
@@ -160,7 +160,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "PKE ZK benchmarks finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -173,7 +173,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -184,7 +184,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (pke-zk-benchmarks) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -25,7 +25,7 @@ jobs:
fail-fast: false
steps:
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Install latest stable
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Get actionlint
run: |
@@ -27,7 +27,7 @@ jobs:
make lint_workflow
- name: Ensure SHA pinned actions
uses: zgosalvez/github-actions-ensure-sha-pinned-actions@ed00f72a3ca5b6eff8ad4d3ffdcacedb67a21db1 # v3.0.15
uses: zgosalvez/github-actions-ensure-sha-pinned-actions@38608ef4fb69adae7f1eac6eeb88e67b7d083bfd # v3.0.16
with:
allowlist: |
slsa-framework/slsa-github-generator

View File

@@ -25,7 +25,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -44,7 +44,7 @@ jobs:
timeout-minutes: 5760 # 4 days
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Install latest stable
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a
@@ -108,7 +108,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Code coverage finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -121,7 +121,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -132,7 +132,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (code-coverage) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -27,7 +27,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -45,7 +45,7 @@ jobs:
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -62,7 +62,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "concrete-csprng randomness check finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -75,7 +75,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -86,7 +86,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (csprng-randomness-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -117,7 +117,7 @@ jobs:
- name: Slack Notification
if: ${{ always() && job.status == 'failure' }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Failed to auto-${{ env.CLOSE_TYPE }} PR on data repo: ${{ fromJson(env.GH_API_RES || env.TARGET_REPO_PR).message }}"

View File

@@ -34,7 +34,7 @@ jobs:
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -77,7 +77,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "CUDA RTX 4090 tests finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -28,7 +28,7 @@ jobs:
gpu_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.gpu_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -48,10 +48,9 @@ jobs:
- tfhe/src/high_level_api/**
- tfhe/src/c_api/**
- 'tfhe/docs/**.md'
- Makefile
- '.github/workflows/gpu_fast_h100_tests.yml'
- scripts/**
- ci/**
- scripts/integer-tests.sh
- ci/slab.toml
setup-instance:
name: Setup instance (cuda-h100-tests)
@@ -65,7 +64,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -108,7 +107,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -171,7 +170,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-tests-linux.result }}
SLACK_MESSAGE: "Fast H100 tests finished with status: ${{ needs.cuda-tests-linux.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -184,7 +183,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -195,7 +194,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-h100-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -27,7 +27,7 @@ jobs:
gpu_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.gpu_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -48,9 +48,8 @@ jobs:
- tfhe/src/c_api/**
- 'tfhe/docs/**.md'
- '.github/workflows/gpu_fast_tests.yml'
- Makefile
- scripts/**
- ci/**
- scripts/integer-tests.sh
- ci/slab.toml
setup-instance:
name: Setup instance (cuda-tests)
@@ -63,7 +62,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -106,7 +105,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -169,7 +168,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-tests-linux.result }}
SLACK_MESSAGE: "Base GPU tests finished with status: ${{ needs.cuda-tests-linux.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -182,7 +181,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -193,7 +192,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -25,7 +25,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@447a2d0fd2d1a9d647aa0d0723a6e9255372f261
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -66,7 +66,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -127,7 +127,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-tests-linux.result }}
SLACK_MESSAGE: "Full H100 tests finished with status: ${{ needs.cuda-tests-linux.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -139,7 +139,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@447a2d0fd2d1a9d647aa0d0723a6e9255372f261
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -150,7 +150,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-h100-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -28,7 +28,7 @@ jobs:
gpu_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.gpu_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -48,10 +48,9 @@ jobs:
- tfhe/src/high_level_api/**
- tfhe/src/c_api/**
- 'tfhe/docs/**.md'
- Makefile
- '.github/workflows/**_multi_gpu_tests.yml'
- scripts/**
- ci/**
- scripts/integer-tests.sh
- ci/slab.toml
setup-instance:
name: Setup instance (cuda-tests-multi-gpu)
@@ -65,7 +64,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -108,7 +107,7 @@ jobs:
sudo make install
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -174,7 +173,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-tests-linux.result }}
SLACK_MESSAGE: "Multi-GPU tests finished with status: ${{ needs.cuda-tests-linux.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -187,7 +186,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -198,7 +197,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-tests-multi-gpu) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -24,7 +24,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -53,7 +53,7 @@ jobs:
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -97,7 +97,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "CUDA AWS post-commit checks finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -110,7 +110,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -121,7 +121,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-pcc) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -0,0 +1,185 @@
# Signed integer GPU tests on an RTXA6000 VM on hyperstack with classical PBS
name: TFHE Cuda Backend - Signed integer tests with classical PBS
env:
CARGO_TERM_COLOR: always
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
RUSTFLAGS: "-C target-cpu=native"
RUST_BACKTRACE: "full"
RUST_MIN_STACK: "8388608"
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 }}
IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }}
on:
# Allows you to run this workflow manually from the Actions tab as an alternative.
workflow_dispatch:
pull_request:
types: [ labeled ]
jobs:
should-run:
runs-on: ubuntu-latest
permissions:
pull-requests: write
outputs:
gpu_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.gpu_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
- name: Check for file changes
id: changed-files
uses: tj-actions/changed-files@c3a1bb2c992d77180ae65be6ae6c166cf40f857c
with:
since_last_remote_commit: true
files_yaml: |
gpu:
- tfhe/Cargo.toml
- tfhe/build.rs
- backends/tfhe-cuda-backend/**
- tfhe/src/core_crypto/gpu/**
- tfhe/src/integer/gpu/**
- tfhe/src/shortint/parameters/**
- tfhe/src/high_level_api/**
- tfhe/src/c_api/**
- 'tfhe/docs/**.md'
- '.github/workflows/gpu_signed_integer_classic_tests.yml'
- scripts/integer-tests.sh
- ci/slab.toml
setup-instance:
name: Setup instance (cuda-signed-classic-tests)
needs: should-run
if: github.event_name != 'pull_request' ||
(github.event.action != 'labeled' && needs.should-run.outputs.gpu_test == 'true') ||
(github.event.action == 'labeled' && github.event.label.name == 'approved' && needs.should-run.outputs.gpu_test == 'true')
runs-on: ubuntu-latest
outputs:
runner-name: ${{ steps.start-instance.outputs.label }}
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
slab-url: ${{ secrets.SLAB_BASE_URL }}
job-secret: ${{ secrets.JOB_SECRET }}
backend: hyperstack
profile: gpu-test
cuda-tests-linux:
name: CUDA signed integer tests with classical PBS
needs: [ should-run, setup-instance ]
if: github.event_name != 'pull_request' ||
(github.event_name == 'pull_request' && needs.setup-instance.result != 'skipped')
concurrency:
group: ${{ github.workflow }}_${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
strategy:
fail-fast: false
# explicit include-based build matrix, of known valid options
matrix:
include:
- os: ubuntu-22.04
cuda: "12.2"
gcc: 11
env:
CUDA_PATH: /usr/local/cuda-${{ matrix.cuda }}
CMAKE_VERSION: 3.29.6
steps:
# Mandatory on hyperstack since a bootable volume is not re-usable yet.
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y checkinstall zlib1g-dev libssl-dev libclang-dev
wget https://github.com/Kitware/CMake/releases/download/v${{ env.CMAKE_VERSION }}/cmake-${{ env.CMAKE_VERSION }}.tar.gz
tar -zxvf cmake-${{ env.CMAKE_VERSION }}.tar.gz
cd cmake-${{ env.CMAKE_VERSION }}
./bootstrap
make -j"$(nproc)"
sudo make install
- name: Checkout tfhe-rs
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Set up home
run: |
echo "HOME=/home/ubuntu" >> "${GITHUB_ENV}"
- name: Install latest stable
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a
with:
toolchain: stable
- name: Export CUDA variables
if: ${{ !cancelled() }}
run: |
echo "CUDA_PATH=$CUDA_PATH" >> "${GITHUB_ENV}"
echo "$CUDA_PATH/bin" >> "${GITHUB_PATH}"
echo "LD_LIBRARY_PATH=$CUDA_PATH/lib:$LD_LIBRARY_PATH" >> "${GITHUB_ENV}"
echo "CUDACXX=/usr/local/cuda-${{ matrix.cuda }}/bin/nvcc" >> "${GITHUB_ENV}"
# Specify the correct host compilers
- name: Export gcc and g++ variables
if: ${{ !cancelled() }}
run: |
{
echo "CC=/usr/bin/gcc-${{ matrix.gcc }}";
echo "CXX=/usr/bin/g++-${{ matrix.gcc }}";
echo "CUDAHOSTCXX=/usr/bin/g++-${{ matrix.gcc }}";
echo "HOME=/home/ubuntu";
} >> "${GITHUB_ENV}"
- name: Check device is detected
if: ${{ !cancelled() }}
run: nvidia-smi
- name: Run signed integer tests
run: |
BIG_TESTS_INSTANCE=TRUE make test_signed_integer_gpu_ci
slack-notify:
name: Slack Notification
needs: [ setup-instance, cuda-tests-linux ]
runs-on: ubuntu-latest
if: ${{ always() && needs.cuda-tests-linux.result != 'skipped' && failure() }}
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-tests-linux.result }}
SLACK_MESSAGE: "Integer GPU signed integer tests with classical PBS finished with status: ${{ needs.cuda-tests-linux.result }}. (${{ env.ACTION_RUN_URL }})"
teardown-instance:
name: Teardown instance (cuda-signed-classic-tests)
if: ${{ always() && needs.setup-instance.result != 'skipped' }}
needs: [ setup-instance, cuda-tests-linux ]
runs-on: ubuntu-latest
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
slab-url: ${{ secrets.SLAB_BASE_URL }}
job-secret: ${{ secrets.JOB_SECRET }}
label: ${{ needs.setup-instance.outputs.runner-name }}
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-signed-classic-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -28,7 +28,7 @@ jobs:
gpu_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.gpu_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -49,10 +49,9 @@ jobs:
- tfhe/src/high_level_api/**
- tfhe/src/c_api/**
- 'tfhe/docs/**.md'
- Makefile
- '.github/workflows/gpu_signed_integer_h100_tests.yml'
- scripts/**
- ci/**
- scripts/integer-tests.sh
- ci/slab.toml
setup-instance:
name: Setup instance (cuda-h100-tests)
@@ -66,7 +65,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -110,7 +109,7 @@ jobs:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Set up home
run: |
@@ -144,10 +143,6 @@ jobs:
if: ${{ !cancelled() }}
run: nvidia-smi
- name: Run signed integer tests
run: |
BIG_TESTS_INSTANCE=TRUE make test_signed_integer_gpu_ci
- name: Run signed integer multi-bit tests
run: |
BIG_TESTS_INSTANCE=TRUE make test_signed_integer_multi_bit_gpu_ci
@@ -160,7 +155,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-tests-linux.result }}
SLACK_MESSAGE: "Integer GPU H100 tests finished with status: ${{ needs.cuda-tests-linux.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -173,7 +168,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -184,7 +179,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-h100-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -22,7 +22,6 @@ on:
types:
- opened
- synchronize
- labeled
schedule:
# Nightly tests @ 1AM after each work day
- cron: "0 1 * * MON-FRI"
@@ -36,7 +35,7 @@ jobs:
gpu_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.gpu_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -57,9 +56,8 @@ jobs:
- tfhe/src/c_api/**
- 'tfhe/docs/**.md'
- '.github/workflows/gpu_signed_integer_tests.yml'
- Makefile
- scripts/**
- ci/**
- scripts/integer-tests.sh
- ci/slab.toml
setup-instance:
name: Setup instance (cuda-signed-integer-tests)
@@ -67,13 +65,13 @@ jobs:
needs: should-run
if: (github.event_name == 'schedule' && github.repository == 'zama-ai/tfhe-rs') ||
github.event_name == 'workflow_dispatch' ||
(github.event.action != 'labeled' && needs.should-run.outputs.gpu_test == 'true')
needs.should-run.outputs.gpu_test == 'true'
outputs:
runner-name: ${{ steps.start-instance.outputs.label }}
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -117,7 +115,7 @@ jobs:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -174,7 +172,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-signed-integer-tests.result }}
SLACK_MESSAGE: "Base GPU tests finished with status: ${{ needs.cuda-signed-integer-tests.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -187,7 +185,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -198,7 +196,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-signed-integer-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -0,0 +1,185 @@
# Test unsigned integers on an RTXA6000 VM on hyperstack with the classical PBS
name: TFHE Cuda Backend - Unsigned integer tests with classical PBS
env:
CARGO_TERM_COLOR: always
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
RUSTFLAGS: "-C target-cpu=native"
RUST_BACKTRACE: "full"
RUST_MIN_STACK: "8388608"
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 }}
IS_PULL_REQUEST: ${{ github.event_name == 'pull_request' }}
on:
# Allows you to run this workflow manually from the Actions tab as an alternative.
workflow_dispatch:
pull_request:
types: [ labeled ]
jobs:
should-run:
runs-on: ubuntu-latest
permissions:
pull-requests: write
outputs:
gpu_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.gpu_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
- name: Check for file changes
id: changed-files
uses: tj-actions/changed-files@c3a1bb2c992d77180ae65be6ae6c166cf40f857c
with:
since_last_remote_commit: true
files_yaml: |
gpu:
- tfhe/Cargo.toml
- tfhe/build.rs
- backends/tfhe-cuda-backend/**
- tfhe/src/core_crypto/gpu/**
- tfhe/src/integer/gpu/**
- tfhe/src/shortint/parameters/**
- tfhe/src/high_level_api/**
- tfhe/src/c_api/**
- 'tfhe/docs/**.md'
- '.github/workflows/gpu_unsigned_integer_classic_tests.yml'
- scripts/integer-tests.sh
- ci/slab.toml
setup-instance:
name: Setup instance (cuda-unsigned-classic-tests)
needs: should-run
if: github.event_name != 'pull_request' ||
(github.event.action != 'labeled' && needs.should-run.outputs.gpu_test == 'true') ||
(github.event.action == 'labeled' && github.event.label.name == 'approved' && needs.should-run.outputs.gpu_test == 'true')
runs-on: ubuntu-latest
outputs:
runner-name: ${{ steps.start-instance.outputs.label }}
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
slab-url: ${{ secrets.SLAB_BASE_URL }}
job-secret: ${{ secrets.JOB_SECRET }}
backend: hyperstack
profile: gpu-test
cuda-tests-linux:
name: CUDA unsigned integer tests with classical PBS
needs: [ should-run, setup-instance ]
if: github.event_name != 'pull_request' ||
(github.event_name == 'pull_request' && needs.setup-instance.result != 'skipped')
concurrency:
group: ${{ github.workflow }}_${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
runs-on: ${{ needs.setup-instance.outputs.runner-name }}
strategy:
fail-fast: false
# explicit include-based build matrix, of known valid options
matrix:
include:
- os: ubuntu-22.04
cuda: "12.2"
gcc: 11
env:
CUDA_PATH: /usr/local/cuda-${{ matrix.cuda }}
CMAKE_VERSION: 3.29.6
steps:
# Mandatory on hyperstack since a bootable volume is not re-usable yet.
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y checkinstall zlib1g-dev libssl-dev libclang-dev
wget https://github.com/Kitware/CMake/releases/download/v${{ env.CMAKE_VERSION }}/cmake-${{ env.CMAKE_VERSION }}.tar.gz
tar -zxvf cmake-${{ env.CMAKE_VERSION }}.tar.gz
cd cmake-${{ env.CMAKE_VERSION }}
./bootstrap
make -j"$(nproc)"
sudo make install
- name: Checkout tfhe-rs
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Set up home
run: |
echo "HOME=/home/ubuntu" >> "${GITHUB_ENV}"
- name: Install latest stable
uses: dtolnay/rust-toolchain@7b1c307e0dcbda6122208f10795a713336a9b35a
with:
toolchain: stable
- name: Export CUDA variables
if: ${{ !cancelled() }}
run: |
echo "CUDA_PATH=$CUDA_PATH" >> "${GITHUB_ENV}"
echo "$CUDA_PATH/bin" >> "${GITHUB_PATH}"
echo "LD_LIBRARY_PATH=$CUDA_PATH/lib:$LD_LIBRARY_PATH" >> "${GITHUB_ENV}"
echo "CUDACXX=/usr/local/cuda-${{ matrix.cuda }}/bin/nvcc" >> "${GITHUB_ENV}"
# Specify the correct host compilers
- name: Export gcc and g++ variables
if: ${{ !cancelled() }}
run: |
{
echo "CC=/usr/bin/gcc-${{ matrix.gcc }}";
echo "CXX=/usr/bin/g++-${{ matrix.gcc }}";
echo "CUDAHOSTCXX=/usr/bin/g++-${{ matrix.gcc }}";
echo "HOME=/home/ubuntu";
} >> "${GITHUB_ENV}"
- name: Check device is detected
if: ${{ !cancelled() }}
run: nvidia-smi
- name: Run unsigned integer tests
run: |
BIG_TESTS_INSTANCE=TRUE make test_unsigned_integer_gpu_ci
slack-notify:
name: Slack Notification
needs: [ setup-instance, cuda-tests-linux ]
runs-on: ubuntu-latest
if: ${{ always() && needs.cuda-tests-linux.result != 'skipped' && failure() }}
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-tests-linux.result }}
SLACK_MESSAGE: "Unsigned integer GPU classic tests finished with status: ${{ needs.cuda-tests-linux.result }}. (${{ env.ACTION_RUN_URL }})"
teardown-instance:
name: Teardown instance (cuda-unsigned-classic-tests)
if: ${{ always() && needs.setup-instance.result != 'skipped' }}
needs: [ setup-instance, cuda-tests-linux ]
runs-on: ubuntu-latest
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
slab-url: ${{ secrets.SLAB_BASE_URL }}
job-secret: ${{ secrets.JOB_SECRET }}
label: ${{ needs.setup-instance.outputs.runner-name }}
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-unsigned-classic-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -28,7 +28,7 @@ jobs:
gpu_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.gpu_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -49,10 +49,9 @@ jobs:
- tfhe/src/high_level_api/**
- tfhe/src/c_api/**
- 'tfhe/docs/**.md'
- Makefile
- '.github/workflows/gpu_unsigned_integer_tests.yml'
- scripts/**
- ci/**
- '.github/workflows/gpu_unsigned_integer_h100_tests.yml'
- scripts/integer-tests.sh
- ci/slab.toml
setup-instance:
name: Setup instance (cuda-h100-tests)
@@ -66,7 +65,7 @@ jobs:
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -110,7 +109,7 @@ jobs:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Set up home
run: |
@@ -144,10 +143,6 @@ jobs:
if: ${{ !cancelled() }}
run: nvidia-smi
- name: Run unsigned integer tests
run: |
BIG_TESTS_INSTANCE=TRUE make test_unsigned_integer_gpu_ci
- name: Run unsigned integer multi-bit tests
run: |
BIG_TESTS_INSTANCE=TRUE make test_unsigned_integer_multi_bit_gpu_ci
@@ -160,7 +155,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-tests-linux.result }}
SLACK_MESSAGE: "Unsigned integer GPU H100 tests finished with status: ${{ needs.cuda-tests-linux.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -173,7 +168,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -184,7 +179,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-h100-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -21,7 +21,6 @@ on:
types:
- opened
- synchronize
- labeled
schedule:
# Nightly tests @ 1AM after each work day
- cron: "0 1 * * MON-FRI"
@@ -35,7 +34,7 @@ jobs:
gpu_test: ${{ env.IS_PULL_REQUEST == 'false' || steps.changed-files.outputs.gpu_any_changed }}
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
token: ${{ secrets.FHE_ACTIONS_TOKEN }}
@@ -57,23 +56,22 @@ jobs:
- tfhe/src/c_api/**
- 'tfhe/docs/**.md'
- '.github/workflows/gpu_unsigned_integer_tests.yml'
- Makefile
- scripts/**
- ci/**
- scripts/integer-tests.sh
- ci/slab.toml
setup-instance:
name: Setup instance (cuda-unsigned-integer-tests)
needs: should-run
if: (github.event_name == 'schedule' && github.repository == 'zama-ai/tfhe-rs') ||
github.event_name == 'workflow_dispatch' ||
(github.event.action != 'labeled' && needs.should-run.outputs.gpu_test == 'true')
needs.should-run.outputs.gpu_test == 'true'
runs-on: ubuntu-latest
outputs:
runner-name: ${{ steps.start-instance.outputs.label }}
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -117,7 +115,7 @@ jobs:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Set up home
run: |
@@ -171,7 +169,7 @@ jobs:
continue-on-error: true
steps:
- name: Send message
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cuda-unsigned-integer-tests.result }}
SLACK_MESSAGE: "Unsigned integer GPU tests finished with status: ${{ needs.cuda-unsigned-integer-tests.result }}. (${{ env.ACTION_RUN_URL }})"
@@ -184,7 +182,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -195,7 +193,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (cuda-unsigned-integer-tests) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -34,7 +34,7 @@ jobs:
timeout-minutes: 720
steps:
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
persist-credentials: 'false'
@@ -149,7 +149,7 @@ jobs:
- name: Slack Notification
if: ${{ needs.cargo-builds.result != 'skipped' }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ needs.cargo-builds.result }}
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}

View File

@@ -30,13 +30,20 @@ env:
NPM_TAG: ""
jobs:
verify_tag:
uses: ./.github/workflows/verify_tagged_commit.yml
secrets:
RELEASE_TEAM: ${{ secrets.RELEASE_TEAM }}
READ_ORG_TOKEN: ${{ secrets.READ_ORG_TOKEN }}
package:
runs-on: ubuntu-latest
needs: verify_tag
outputs:
hash: ${{ steps.hash.outputs.hash }}
steps:
- name: Checkout
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- name: Prepare package
@@ -74,7 +81,7 @@ jobs:
id-token: write
steps:
- name: Checkout
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- name: Create NPM version tag
@@ -101,7 +108,7 @@ jobs:
- 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@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: failure
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}
@@ -146,7 +153,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}

View File

@@ -12,12 +12,19 @@ env:
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
jobs:
verify_tag:
uses: ./.github/workflows/verify_tagged_commit.yml
secrets:
RELEASE_TEAM: ${{ secrets.RELEASE_TEAM }}
READ_ORG_TOKEN: ${{ secrets.READ_ORG_TOKEN }}
publish_release:
name: Publish concrete-csprng Release
needs: verify_tag
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -31,7 +38,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}

View File

@@ -21,15 +21,22 @@ env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
jobs:
verify_tag:
uses: ./.github/workflows/verify_tagged_commit.yml
secrets:
RELEASE_TEAM: ${{ secrets.RELEASE_TEAM }}
READ_ORG_TOKEN: ${{ secrets.READ_ORG_TOKEN }}
setup-instance:
name: Setup instance (publish-cuda-release)
needs: verify_tag
runs-on: ubuntu-latest
outputs:
runner-name: ${{ steps.start-instance.outputs.label }}
steps:
- name: Start instance
id: start-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: start
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -54,7 +61,7 @@ jobs:
CUDA_PATH: /usr/local/cuda-${{ matrix.cuda }}
steps:
- name: Checkout
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -99,7 +106,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "tfhe-cuda-backend release finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"
@@ -112,7 +119,7 @@ jobs:
steps:
- name: Stop instance
id: stop-instance
uses: zama-ai/slab-github-runner@c0e7168795bd78f61f61146951ed9d0c73c9b701
uses: zama-ai/slab-github-runner@801df0b8db5ea2b06128b7476c652f5ed5f193a8
with:
mode: stop
github-token: ${{ secrets.SLAB_ACTION_TOKEN }}
@@ -123,7 +130,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_MESSAGE: "Instance teardown (publish-cuda-release) finished with status: ${{ job.status }}. (${{ env.ACTION_RUN_URL }})"

View File

@@ -12,12 +12,19 @@ env:
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
jobs:
verify_tag:
uses: ./.github/workflows/verify_tagged_commit.yml
secrets:
RELEASE_TEAM: ${{ secrets.RELEASE_TEAM }}
READ_ORG_TOKEN: ${{ secrets.READ_ORG_TOKEN }}
publish_release:
name: Publish tfhe-versionable Release
needs: verify_tag
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -38,7 +45,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}

View File

@@ -13,12 +13,19 @@ env:
ACTION_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
jobs:
verify_tag:
uses: ./.github/workflows/verify_tagged_commit.yml
secrets:
RELEASE_TEAM: ${{ secrets.RELEASE_TEAM }}
READ_ORG_TOKEN: ${{ secrets.READ_ORG_TOKEN }}
publish_release:
name: Publish tfhe-zk-pok Release
needs: verify_tag
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
@@ -32,7 +39,7 @@ jobs:
- name: Slack Notification
if: ${{ failure() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}

View File

@@ -17,10 +17,10 @@ jobs:
runs-on: large_ubuntu_16
steps:
- name: Checkout tfhe-rs
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- name: Checkout lattice-estimator
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
repository: malb/lattice-estimator
path: lattice_estimator
@@ -42,7 +42,7 @@ jobs:
- name: Slack Notification
if: ${{ always() }}
continue-on-error: true
uses: rtCamp/action-slack-notify@65e6fc1ce697e2df8149d9ae9909acc5ec5599ce
uses: rtCamp/action-slack-notify@c33737706dea87cd7784c687dadc9adf1be59990
env:
SLACK_COLOR: ${{ job.status }}
SLACK_CHANNEL: ${{ secrets.SLACK_CHANNEL }}

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 0
- name: git-sync

View File

@@ -0,0 +1,32 @@
# Verify a tagged commit
name: Verify tagged commit
on:
workflow_call:
secrets:
RELEASE_TEAM:
required: true
READ_ORG_TOKEN:
required: true
jobs:
checks:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
# Check triggering actor membership
- name: Actor verification
id: actor_check
uses: morfien101/actions-authorized-user@4a3cfbf0bcb3cafe4a71710a278920c5d94bb38b
with:
username: ${{ github.triggering_actor }}
org: ${{ github.repository_owner }}
team: ${{ secrets.RELEASE_TEAM }}
github_token: ${{ secrets.READ_ORG_TOKEN }}
- name: Actor authorized
run: |
if [ "${{ steps.actor_check.outputs.authorized }}" == "false" ]; then
echo "Actor '${{ github.triggering_actor }}' is not authorized to perform release"
exit 1
fi

6
.gitignore vendored
View File

@@ -28,10 +28,8 @@ backends/tfhe-cuda-backend/cuda/cmake-build-debug/
tfhe/web_wasm_parallel_tests/server.PID
venv/
web-test-runner/
node_modules/
package-lock.json
# Dir used for backward compatibility test data
tfhe/tfhe-backward-compat-data/
# Sampling tool stuff
/venv/
**/*.algo_sample_acquistion

View File

@@ -9,9 +9,13 @@ members = [
"backends/tfhe-cuda-backend",
"utils/tfhe-versionable",
"utils/tfhe-versionable-derive",
"tfhe-rs-cost-model"
]
exclude = ["tfhe/backward_compatibility_tests"]
exclude = [
"tfhe/backward_compatibility_tests",
"utils/cargo-tfhe-lints-inner",
"utils/cargo-tfhe-lints"
]
[profile.bench]
lto = "fat"

View File

@@ -21,7 +21,7 @@ BENCH_OP_FLAVOR?=DEFAULT
NODE_VERSION=22.6
FORWARD_COMPAT?=OFF
BACKWARD_COMPAT_DATA_URL=https://github.com/zama-ai/tfhe-backward-compat-data.git
BACKWARD_COMPAT_DATA_BRANCH?=v0.3
BACKWARD_COMPAT_DATA_BRANCH?=v0.4
BACKWARD_COMPAT_DATA_PROJECT=tfhe-backward-compat-data
BACKWARD_COMPAT_DATA_DIR=$(BACKWARD_COMPAT_DATA_PROJECT)
TFHE_SPEC:=tfhe
@@ -122,6 +122,10 @@ install_node:
$(SHELL) -i -c 'nvm install $(NODE_VERSION)' || \
( echo "Unable to install node, unknown error." && exit 1 )
.PHONY: node_version # Return Node version that will be installed
node_version:
@echo "$(NODE_VERSION)"
.PHONY: install_dieharder # Install dieharder for apt distributions or macOS
install_dieharder:
@dieharder -h > /dev/null 2>&1 || \
@@ -163,8 +167,8 @@ install_web_resource:
rm checksum && \
$(decompress_cmd) $(filename)
install_chrome_browser: url = "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/linux64/chrome-linux64.zip"
install_chrome_browser: checksum = "c5d7da679f3a353ae4e4420ab113de06d4bd459152f5b17558390c02d9520566"
install_chrome_browser: url = "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.69/linux64/chrome-linux64.zip"
install_chrome_browser: checksum = "f789d53911a50cfa4a2bc1f09cde57567247f52515436d92b1aa9de93c2787d0"
install_chrome_browser: dest = "$(WEB_RUNNER_DIR)/chrome"
install_chrome_browser: filename = "chrome-linux64.zip"
install_chrome_browser: decompress_cmd = unzip
@@ -172,8 +176,8 @@ install_chrome_browser: decompress_cmd = unzip
.PHONY: install_chrome_browser # Install Chrome browser for Linux
install_chrome_browser: install_web_resource
install_chrome_web_driver: url = "https://storage.googleapis.com/chrome-for-testing-public/128.0.6613.137/linux64/chromedriver-linux64.zip"
install_chrome_web_driver: checksum = "f041092f403fb7455a6da2871070b6587c32814a3e3c2b0a794d3d4aa4739151"
install_chrome_web_driver: url = "https://storage.googleapis.com/chrome-for-testing-public/130.0.6723.69/linux64/chromedriver-linux64.zip"
install_chrome_web_driver: checksum = "90fe8dedf33eefe4b72704f626fa9f5834427c042235cfeb4251f18c9f0336ea"
install_chrome_web_driver: dest = "$(WEB_RUNNER_DIR)/chrome"
install_chrome_web_driver: filename = "chromedriver-linux64.zip"
install_chrome_web_driver: decompress_cmd = unzip
@@ -401,7 +405,7 @@ clippy_versionable: install_rs_check_toolchain
.PHONY: clippy_all # Run all clippy targets
clippy_all: clippy_rustdoc clippy clippy_boolean clippy_shortint clippy_integer clippy_all_targets \
clippy_c_api clippy_js_wasm_api clippy_tasks clippy_core clippy_concrete_csprng clippy_zk_pok clippy_trivium \
clippy_versionable clippy_noise_measurement
clippy_versionable
.PHONY: clippy_fast # Run main clippy targets
clippy_fast: clippy_rustdoc clippy clippy_all_targets clippy_c_api clippy_js_wasm_api clippy_tasks \
@@ -829,6 +833,19 @@ test_zk_pok: install_rs_build_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
-p tfhe-zk-pok
.PHONY: test_zk_wasm_x86_compat_ci
test_zk_wasm_x86_compat_ci: check_nvm_installed
source ~/.nvm/nvm.sh && \
nvm install $(NODE_VERSION) && \
nvm use $(NODE_VERSION) && \
$(MAKE) test_zk_wasm_x86_compat
.PHONY: test_zk_wasm_x86_compat # Check compatibility between wasm and x86_64 proofs
test_zk_wasm_x86_compat: install_rs_build_toolchain build_node_js_api
cd tfhe/tests/zk_wasm_x86_test && npm install
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
-p tfhe --test zk_wasm_x86_test --features=$(TARGET_ARCH_FEATURE),integer,zk-pok
.PHONY: test_versionable # Run tests for tfhe-versionable subcrate
test_versionable: install_rs_build_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo $(CARGO_RS_BUILD_TOOLCHAIN) test --profile $(CARGO_PROFILE) \
@@ -1168,8 +1185,8 @@ bench_hlapi_erc20_gpu: install_rs_check_toolchain
gen_key_cache: install_rs_build_toolchain
RUSTFLAGS="$(RUSTFLAGS) --cfg tarpaulin" cargo $(CARGO_RS_BUILD_TOOLCHAIN) run --profile $(CARGO_PROFILE) \
--example generates_test_keys \
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,internal-keycache -- \
$(MULTI_BIT_ONLY) $(COVERAGE_ONLY)
--features=$(TARGET_ARCH_FEATURE),boolean,shortint,experimental,internal-keycache -p $(TFHE_SPEC) \
-- $(MULTI_BIT_ONLY) $(COVERAGE_ONLY)
.PHONY: gen_key_cache_core_crypto # Run function to generate keys and cache them for core_crypto tests
gen_key_cache_core_crypto: install_rs_build_toolchain
@@ -1244,38 +1261,6 @@ sha256_bool: install_rs_check_toolchain
--example sha256_bool \
--features=$(TARGET_ARCH_FEATURE),boolean
.PHONY: external_product_noise_measurement # Run scripts to run noise measurement for external_product
external_product_noise_measurement: setup_venv_noise_measurement install_rs_check_toolchain
source venv/bin/activate && \
cd tfhe-rs-cost-model/src/ && \
python3 external_product_correction.py \
--rust-toolchain $(CARGO_RS_CHECK_TOOLCHAIN) \
--chunks "$$(nproc)" -- \
--algorithm multi-bit-ext-prod \
--multi-bit-grouping-factor 2
.PHONY: external_product_noise_measurement_classic # Run scripts to run noise measurement for external_product
external_product_noise_measurement_classic: setup_venv_noise_measurement install_rs_check_toolchain
source venv/bin/activate && \
cd tfhe-rs-cost-model/src/ && \
python3 external_product_correction.py \
--rust-toolchain $(CARGO_RS_CHECK_TOOLCHAIN) \
--chunks "$$(nproc)" -- \
--algorithm ext-prod
.PHONY: clippy_noise_measurement # Run clippy lints on noise measurement tool
clippy_noise_measurement: install_rs_check_toolchain
RUSTFLAGS="$(RUSTFLAGS)" cargo "$(CARGO_RS_CHECK_TOOLCHAIN)" clippy --all-targets \
-p tfhe-rs-cost-model -- --no-deps -D warnings
.PHONY: setup_venv_noise_measurement
setup_venv_noise_measurement:
python3 -m venv venv
source venv/bin/activate && \
pip install -U pip wheel setuptools && \
pip install -r tfhe-rs-cost-model/src/requirements.txt
.PHONY: pcc # pcc stands for pre commit checks (except GPU)
pcc: no_tfhe_typo no_dbg_log check_fmt check_typos lint_doc check_md_docs_are_tested check_intra_md_links \
clippy_all tfhe_lints check_compile_tests

View File

@@ -1,5 +1,6 @@
use criterion::Criterion;
use tfhe::prelude::*;
use tfhe::shortint::parameters::PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64;
use tfhe::shortint::prelude::*;
use tfhe::{generate_keys, ConfigBuilder, FheUint64};
use tfhe_trivium::{KreyviumStreamShortint, TransCiphering};
@@ -10,7 +11,8 @@ pub fn kreyvium_shortint_warmup(c: &mut Criterion) {
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) = gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS);
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
@@ -60,7 +62,8 @@ pub fn kreyvium_shortint_gen(c: &mut Criterion) {
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) = gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS);
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
@@ -105,7 +108,8 @@ pub fn kreyvium_shortint_trans(c: &mut Criterion) {
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) = gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS);
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),

View File

@@ -1,5 +1,6 @@
use criterion::Criterion;
use tfhe::prelude::*;
use tfhe::shortint::parameters::PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64;
use tfhe::shortint::prelude::*;
use tfhe::{generate_keys, ConfigBuilder, FheUint64};
use tfhe_trivium::{TransCiphering, TriviumStreamShortint};
@@ -10,7 +11,8 @@ pub fn trivium_shortint_warmup(c: &mut Criterion) {
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) = gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS);
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
@@ -60,7 +62,8 @@ pub fn trivium_shortint_gen(c: &mut Criterion) {
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) = gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS);
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),
@@ -105,7 +108,8 @@ pub fn trivium_shortint_trans(c: &mut Criterion) {
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) = gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS);
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),

View File

@@ -1,7 +1,7 @@
use crate::{KreyviumStream, KreyviumStreamByte, KreyviumStreamShortint, TransCiphering};
use tfhe::prelude::*;
use tfhe::shortint::parameters::PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64;
use tfhe::{generate_keys, ConfigBuilder, FheBool, FheUint64, FheUint8};
// Values for these tests come from the github repo renaud1239/Kreyvium,
// commit fd6828f68711276c25f55e605935028f5e843f43
@@ -221,7 +221,8 @@ fn kreyvium_test_shortint_long() {
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) = gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS);
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),

View File

@@ -1,7 +1,7 @@
use crate::{TransCiphering, TriviumStream, TriviumStreamByte, TriviumStreamShortint};
use tfhe::prelude::*;
use tfhe::shortint::parameters::PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64;
use tfhe::{generate_keys, ConfigBuilder, FheBool, FheUint64, FheUint8};
// Values for these tests come from the github repo cantora/avr-crypto-lib, commit 2a5b018,
// file testvectors/trivium-80.80.test-vectors
@@ -357,7 +357,8 @@ fn trivium_test_shortint_long() {
let underlying_ck: tfhe::shortint::ClientKey = (*hl_client_key.as_ref()).clone().into();
let underlying_sk: tfhe::shortint::ServerKey = (*hl_server_key.as_ref()).clone().into();
let (client_key, server_key): (ClientKey, ServerKey) = gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS);
let (client_key, server_key): (ClientKey, ServerKey) =
gen_keys(PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64);
let ksk = KeySwitchingKey::new(
(&client_key, Some(&server_key)),

View File

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

View File

@@ -1,9 +1,8 @@
use std::env;
use std::path::PathBuf;
use std::process::Command;
fn main() {
if let Ok(val) = env::var("DOCS_RS") {
if let Ok(val) = std::env::var("DOCS_RS") {
if val.parse::<u32>() == Ok(1) {
return;
}
@@ -28,7 +27,7 @@ fn main() {
println!("cargo::rerun-if-changed=cuda/CMakeLists.txt");
println!("cargo::rerun-if-changed=src");
if env::consts::OS == "linux" {
if std::env::consts::OS == "linux" {
let output = Command::new("./get_os_name.sh").output().unwrap();
let distribution = String::from_utf8(output.stdout).unwrap();
if distribution != "Ubuntu\n" {
@@ -56,30 +55,55 @@ fn main() {
println!("cargo:rustc-link-lib=stdc++");
let header_path = "wrapper.h";
println!("cargo:rerun-if-changed={}", header_path);
let headers = vec![
"wrapper.h",
"cuda/include/ciphertext.h",
"cuda/include/integer/compression/compression.h",
"cuda/include/integer/integer.h",
"cuda/include/keyswitch.h",
"cuda/include/linear_algebra.h",
"cuda/include/pbs/programmable_bootstrap.h",
"cuda/include/pbs/programmable_bootstrap_multibit.h",
];
let out_path = PathBuf::from("src").join("bindings.rs");
let bindings_modified = if out_path.exists() {
std::fs::metadata(&out_path).unwrap().modified().unwrap()
} else {
std::time::SystemTime::UNIX_EPOCH // If bindings file doesn't exist, consider it older
};
let mut headers_modified = bindings_modified;
for header in headers {
println!("cargo:rerun-if-changed={}", header);
// Check modification times
let header_modified = std::fs::metadata(header).unwrap().modified().unwrap();
if header_modified > headers_modified {
headers_modified = header_modified;
}
}
let bindings = bindgen::Builder::default()
.header(header_path)
// allow only what we are interested in, the custom types appearing in the interface
.allowlist_type("PBS_TYPE")
.allowlist_type("SHIFT_OR_ROTATE_TYPE")
// and the functions reachable from the headers included in wrapper.h
.allowlist_function(".*")
.clang_arg("-x")
.clang_arg("c++")
.clang_arg("-std=c++17")
.clang_arg("-I/usr/include")
.clang_arg("-I/usr/local/include")
.ctypes_prefix("ffi")
.raw_line("use crate::ffi;")
.generate()
.expect("Unable to generate bindings");
// Regenerate bindings only if header has been modified
if headers_modified > bindings_modified {
let bindings = bindgen::Builder::default()
.header(header_path)
// allow only what we are interested in, the custom types appearing in the interface
.allowlist_type("PBS_TYPE")
.allowlist_type("SHIFT_OR_ROTATE_TYPE")
// and the functions reachable from the headers included in wrapper.h
.allowlist_function(".*")
.clang_arg("-x")
.clang_arg("c++")
.clang_arg("-std=c++17")
.clang_arg("-I/usr/include")
.clang_arg("-I/usr/local/include")
.ctypes_prefix("ffi")
.raw_line("use crate::ffi;")
.generate()
.expect("Unable to generate bindings");
bindings
.write_to_file(&out_path)
.expect("Couldn't write bindings!");
bindings
.write_to_file(&out_path)
.expect("Couldn't write bindings!");
}
} else {
panic!(
"Error: platform not supported, tfhe-cuda-backend not built (only Linux is supported)"

View File

@@ -75,8 +75,7 @@ keyswitch(Torus *lwe_array_out, const Torus *__restrict__ lwe_output_indexes,
level_count);
Torus state = a_i >> (sizeof(Torus) * 8 - base_log * level_count);
for (int j = level_count - 1; j >= 0; j--) {
// Levels are stored in reverse order
for (int j = 0; j < level_count; j++) {
auto ksk_block =
get_ith_block(ksk, i, j, lwe_dimension_out, level_count);
Torus decomposed = decompose_one<Torus>(state, mask_mod_b, base_log);
@@ -209,8 +208,7 @@ __device__ void packing_keyswitch_lwe_ciphertext_into_glwe_ciphertext(
// block of key for current lwe coefficient (cur_input_lwe[i])
auto ksk_block = &fp_ksk[i * ksk_block_size];
for (int j = level_count - 1; j >= 0; j--) {
// Levels are stored in reverse order
for (int j = 0; j < level_count; j++) {
auto ksk_glwe = &ksk_block[j * glwe_size * polynomial_size];
// Iterate through each level and multiply by the ksk piece
auto ksk_glwe_chunk = &ksk_glwe[poly_id * coef_per_block];

View File

@@ -268,17 +268,20 @@ void cuda_drop_async(void *ptr, cudaStream_t stream, uint32_t gpu_index) {
/// Get the maximum size for the shared memory
int cuda_get_max_shared_memory(uint32_t gpu_index) {
int max_shared_memory = 0;
cudaDeviceGetAttribute(&max_shared_memory, cudaDevAttrMaxSharedMemoryPerBlock,
gpu_index);
check_cuda_error(cudaGetLastError());
#if CUDA_ARCH == 900
max_shared_memory = 226000;
#elif CUDA_ARCH == 890
max_shared_memory = 100000;
#elif CUDA_ARCH == 860
max_shared_memory = 100000;
#elif CUDA_ARCH == 800
max_shared_memory = 163000;
#elif CUDA_ARCH == 700
max_shared_memory = 95000;
#else
cudaDeviceGetAttribute(&max_shared_memory, cudaDevAttrMaxSharedMemoryPerBlock,
gpu_index);
check_cuda_error(cudaGetLastError());
#endif
return max_shared_memory;
}

View File

@@ -24,8 +24,8 @@ __device__ const T *get_ith_mask_kth_block(const T *ptr, int i, int k,
uint32_t level_count) {
return &ptr[get_start_ith_ggsw(i, polynomial_size, glwe_dimension,
level_count) +
level * polynomial_size / 2 * (glwe_dimension + 1) *
(glwe_dimension + 1) +
(level_count - level - 1) * polynomial_size / 2 *
(glwe_dimension + 1) * (glwe_dimension + 1) +
k * polynomial_size / 2 * (glwe_dimension + 1)];
}
@@ -35,8 +35,8 @@ __device__ T *get_ith_mask_kth_block(T *ptr, int i, int k, int level,
int glwe_dimension, uint32_t level_count) {
return &ptr[get_start_ith_ggsw(i, polynomial_size, glwe_dimension,
level_count) +
level * polynomial_size / 2 * (glwe_dimension + 1) *
(glwe_dimension + 1) +
(level_count - level - 1) * polynomial_size / 2 *
(glwe_dimension + 1) * (glwe_dimension + 1) +
k * polynomial_size / 2 * (glwe_dimension + 1)];
}
template <typename T>
@@ -45,8 +45,8 @@ __device__ T *get_ith_body_kth_block(T *ptr, int i, int k, int level,
int glwe_dimension, uint32_t level_count) {
return &ptr[get_start_ith_ggsw(i, polynomial_size, glwe_dimension,
level_count) +
level * polynomial_size / 2 * (glwe_dimension + 1) *
(glwe_dimension + 1) +
(level_count - level - 1) * polynomial_size / 2 *
(glwe_dimension + 1) * (glwe_dimension + 1) +
k * polynomial_size / 2 * (glwe_dimension + 1) +
glwe_dimension * polynomial_size / 2];
}

View File

@@ -67,12 +67,12 @@ __global__ void device_programmable_bootstrap_cg(
// We always compute the pointer with most restrictive alignment to avoid
// alignment issues
double2 *accumulator_fft = (double2 *)selected_memory;
Torus *accumulator =
(Torus *)accumulator_fft +
(ptrdiff_t)(sizeof(double2) * polynomial_size / 2 / sizeof(Torus));
Torus *accumulator = (Torus *)selected_memory;
Torus *accumulator_rotated =
(Torus *)accumulator + (ptrdiff_t)polynomial_size;
(Torus *)accumulator + (ptrdiff_t)(polynomial_size);
double2 *accumulator_fft =
(double2 *)(accumulator_rotated) +
(ptrdiff_t)(polynomial_size * sizeof(Torus) / sizeof(double2));
if constexpr (SMD == PARTIALSM)
accumulator_fft = (double2 *)sharedmem;

View File

@@ -162,10 +162,10 @@ __global__ void __launch_bounds__(params::degree / params::opt)
// We always compute the pointer with most restrictive alignment to avoid
// alignment issues
double2 *accumulator_fft = (double2 *)selected_memory;
Torus *accumulator =
(Torus *)accumulator_fft +
(ptrdiff_t)(sizeof(double2) * params::degree / 2 / sizeof(Torus));
Torus *accumulator = (Torus *)selected_memory;
double2 *accumulator_fft =
(double2 *)accumulator +
(ptrdiff_t)(sizeof(Torus) * params::degree / sizeof(double2));
if constexpr (SMD == PARTIALSM)
accumulator_fft = (double2 *)sharedmem;

View File

@@ -1,3 +1,4 @@
// These files must be added to the headers vec in the build.rs to check for file changes
#include "cuda/include/ciphertext.h"
#include "cuda/include/integer/compression/compression.h"
#include "cuda/include/integer/integer.h"

View File

@@ -1,2 +1,2 @@
beautifulsoup4==4.12.3
selenium==4.24.0
selenium==4.26.0

View File

@@ -1,5 +1,4 @@
use crate::seeders::{Seed, Seeder};
use std::cmp::Ordering;
/// There is no `rseed` equivalent in the ARM specification until `ARMv8.5-A`.
/// However it seems that these instructions are not exposed in `core::arch::aarch64`.
@@ -51,8 +50,7 @@ pub struct AppleSecureEnclaveSeeder;
impl Seeder for AppleSecureEnclaveSeeder {
fn seed(&mut self) -> Seed {
// 16 bytes == 128 bits
let mut bytes = [0u8; 16];
let mut bytes = [0u8; std::mem::size_of::<u128>() / std::mem::size_of::<u8>()];
secure_enclave::generate_random_bytes(&mut bytes)
.expect("Failure while using Apple secure enclave: {err:?}");
@@ -60,71 +58,13 @@ impl Seeder for AppleSecureEnclaveSeeder {
}
fn is_available() -> bool {
let os_version_sysctl_name = match std::ffi::CString::new("kern.osproductversion") {
Ok(c_str) => c_str,
_ => return false,
};
// Big enough buffer to get a version output as an ASCII string
const OUTPUT_BUFFER_SIZE: usize = 64;
let mut output_buffer_size = OUTPUT_BUFFER_SIZE;
let mut output_buffer = [0u8; OUTPUT_BUFFER_SIZE];
let res = unsafe {
libc::sysctlbyname(
os_version_sysctl_name.as_ptr() as *const _ as *const _,
&mut output_buffer as *mut _ as *mut _,
&mut output_buffer_size as *mut _ as *mut _,
std::ptr::null_mut(),
0,
)
};
if res != 0 {
return false;
}
let result_c_str =
match std::ffi::CStr::from_bytes_with_nul(&output_buffer[..output_buffer_size]) {
Ok(c_str) => c_str,
_ => return false,
};
let result_string = match result_c_str.to_str() {
Ok(str) => str,
_ => return false,
};
// Normally we get a major version and minor version
let split_string: Vec<&str> = result_string.split('.').collect();
let mut major = -1;
let mut minor = -1;
// Major part of the version string
if !split_string.is_empty() {
major = match split_string[0].parse() {
Ok(major_from_str) => major_from_str,
_ => return false,
};
}
// SecRandomCopyBytes is available starting with mac OS 10.7
// SecRandomCopyBytes is available starting with macOS 10.7
// https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
// This match pattern is recommended by clippy, so we oblige here
match major.cmp(&10) {
Ordering::Greater => true,
Ordering::Equal => {
// Minor part of the version string
if split_string.len() >= 2 {
minor = match split_string[1].parse() {
Ok(minor_from_str) => minor_from_str,
_ => return false,
};
}
minor >= 7
}
Ordering::Less => false,
}
//
// Since Rust 1.74, rust supports macOS >= 10.12
// https://blog.rust-lang.org/2023/09/25/Increasing-Apple-Version-Requirements.html
// Thus SecRandomCopyBytes is always expected to be available
true
}
}

57
exps.sh
View File

@@ -1,57 +0,0 @@
#!/usr/bin/env bash
set -e
toolchain=$(cat toolchain.txt)
source venv/bin/activate
cd tfhe-rs-cost-model/src/
python3 external_product_correction.py \
--rust-toolchain "${toolchain}" \
--chunks "$(nproc)" \
--dir ext_prod_no_fft -- \
--algorithm ext-prod \
--sample-size 100
python3 external_product_correction.py \
--rust-toolchain "${toolchain}" \
--chunks "$(nproc)" \
--dir multi_bit_gf_2_ext_prod_no_fft -- \
--algorithm multi-bit-ext-prod \
--multi-bit-grouping-factor 2 \
--sample-size 100
python3 external_product_correction.py \
--rust-toolchain "${toolchain}" \
--chunks "$(nproc)" \
--dir multi_bit_gf3_ext_prod_no_fft -- \
--algorithm multi-bit-ext-prod \
--multi-bit-grouping-factor 3 \
--sample-size 100
python3 external_product_correction.py \
--rust-toolchain "${toolchain}" \
--chunks "$(nproc)" \
--dir ext_prod_fft -- \
--algorithm ext-prod \
--sample-size 100 \
--use-fft
python3 external_product_correction.py \
--rust-toolchain "${toolchain}" \
--chunks "$(nproc)" \
--dir multi_bit_gf_2_ext_prod_fft -- \
--algorithm multi-bit-ext-prod \
--multi-bit-grouping-factor 2 \
--sample-size 100 \
--use-fft
python3 external_product_correction.py \
--rust-toolchain "${toolchain}" \
--chunks "$(nproc)" \
--dir multi_bit_gf3_ext_prod_fft -- \
--algorithm multi-bit-ext-prod \
--multi-bit-grouping-factor 3 \
--sample-size 100 \
--use-fft

View File

@@ -66,8 +66,8 @@ parser.add_argument(
# block PBS are too slow for high params
# mul_crt_4_4 is extremely flaky (~80% failure)
# test_wopbs_bivariate_crt_wopbs_param_message generate tables that are too big at the moment
# test_integer_smart_mul_param_message_4_carry_4_ks_pbs is too slow
# so is test_integer_default_add_sequence_multi_thread_param_message_4_carry_4_ks_pbs
# test_integer_smart_mul_param_message_4_carry_4_ks_pbs_gaussian_2m64 is too slow
# so is test_integer_default_add_sequence_multi_thread_param_message_4_carry_4_ks_pbs_gaussian_2m64
# skip smart_div, smart_rem which are already covered by the smar_div_rem test
# skip default_div, default_rem which are covered by default_div_rem
EXCLUDED_INTEGER_TESTS = [
@@ -75,28 +75,30 @@ EXCLUDED_INTEGER_TESTS = [
"/.*integer_smart_rem_param/",
"/.*integer_default_div_param/",
"/.*integer_default_rem_param/",
"/.*_block_pbs(_base)?_param_message_[34]_carry_[34]_ks_pbs$/",
"~mul_crt_param_message_4_carry_4_ks_pbs",
"/.*test_wopbs_bivariate_crt_wopbs_param_message_[34]_carry_[34]_ks_pbs$/",
"/.*test_integer_smart_mul_param_message_4_carry_4_ks_pbs$/",
"/.*test_integer_default_add_sequence_multi_thread_param_message_4_carry_4_ks_pbs$/",
"/.*_block_pbs(_base)?_param_message_[34]_carry_[34]_ks_pbs_gaussian_2m64$/",
"~mul_crt_param_message_4_carry_4_ks_pbs_gaussian_2m64",
"/.*test_wopbs_bivariate_crt_wopbs_param_message_[34]_carry_[34]_ks_pbs_gaussian_2m64$/",
"/.*test_integer_smart_mul_param_message_4_carry_4_ks_pbs_gaussian_2m64$/",
"/.*test_integer_default_add_sequence_multi_thread_param_message_4_carry_4_ks_pbs_gaussian_2m64$/",
]
# skip default_div, default_rem which are covered by default_div_rem
EXCLUDED_INTEGER_FAST_TESTS = [
"/.*integer_default_div_param/",
"/.*integer_default_rem_param/",
"/.*_param_message_[14]_carry_[14]_ks_pbs$/",
"/.*default_add_sequence_multi_thread_param_message_3_carry_3_ks_pbs$/",
"/.*_param_message_[14]_carry_[14]_ks_pbs_gaussian_2m64$/",
"/.*default_add_sequence_multi_thread_param_message_3_carry_3_ks_pbs_gaussian_2m64$/",
]
EXCLUDED_BIG_PARAMETERS = [
"/.*_param_message_4_carry_4_ks_pbs$/",
"/.*_param_message_4_carry_4_ks_pbs_gaussian_2m64$/",
]
def filter_integer_tests(input_args):
multi_bit_filter = "_multi_bit" if input_args.multi_bit else ""
(multi_bit_filter, group_filter) = (
("_multi_bit", "_group_[0-9]") if input_args.multi_bit else ("", "")
)
backend_filter = ""
if input_args.backend == "gpu":
backend_filter = "gpu::"
@@ -122,18 +124,18 @@ def filter_integer_tests(input_args):
if input_args.fast_tests and input_args.nightly_tests:
filter_expression.append(
f"test(/.*_default_.*?_param{multi_bit_filter}_message_[2-3]_carry_[2-3]_.*/)"
f"test(/.*_default_.*?_param{multi_bit_filter}{group_filter}_message_[2-3]_carry_[2-3]_.*/)"
)
elif input_args.fast_tests:
# Test only fast default operations with only one set of parameters
filter_expression.append(
f"test(/.*_default_.*?_param{multi_bit_filter}_message_2_carry_2_.*/)"
f"test(/.*_default_.*?_param{multi_bit_filter}{group_filter}_message_2_carry_2_.*/)"
)
elif input_args.nightly_tests:
# Test only fast default operations with only one set of parameters
# This subset would run slower than fast_tests hence the use of nightly_tests
filter_expression.append(
f"test(/.*_default_.*?_param{multi_bit_filter}_message_3_carry_3_.*/)"
f"test(/.*_default_.*?_param{multi_bit_filter}{group_filter}_message_3_carry_3_.*/)"
)
excluded_tests = (
@@ -171,7 +173,7 @@ def filter_shortint_tests(input_args):
msg_carry_pairs.append((4, 4))
filter_expression = [
f"test(/^shortint::.*_param{multi_bit_filter}_message_{msg}_carry_{carry}{group_filter}(_compact_pk)?_ks_pbs/)"
f"test(/^shortint::.*_param{multi_bit_filter}{group_filter}_message_{msg}_carry_{carry}(_compact_pk)?_ks_pbs.*/)"
for msg, carry in msg_carry_pairs
]
filter_expression.append("test(/^shortint::.*_ci_run_filter/)")

View File

@@ -1,26 +0,0 @@
[package]
name = "tfhe-rs-cost-model"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
aligned-vec = { version = "0.5", features = ["serde"] }
clap = { version = "3.1", features = ["derive"] }
itertools = "0.8.0"
indicatif = "0.16.2"
rand = "0.6.5"
rand_chacha = "0.1.1"
rayon = "1.9.0"
[target.'cfg(target_arch = "x86_64")'.dependencies.tfhe]
path = "../tfhe"
features = ["x86_64-unix"]
[target.'cfg(target_arch = "aarch64")'.dependencies.tfhe]
path = "../tfhe"
features = ["aarch64-unix"]
[features]
nightly-avx512 = ["tfhe/nightly-avx512"]

View File

@@ -1,47 +0,0 @@
# Noise Sampling & Assurance Tool
<<<<<<< HEAD
Before a `Makefile` is done (**TODO**?), we run the tool (only analysis of previously gathered samples) in `./src` via
=======
Before a `Makefile` is done (TODO), we run the tool (analysis mode only) in `./src` via
>>>>>>> d62eed0c (readme)
```bash
./bin/python3 external_product_correction.py --chunks 192 --rust-toolchain nightly-2024-08-19 --analysis-only --dir multi-bit-sampling/gf2/ -- --algorithm multi-bit-ext-prod --multi-bit-grouping-factor 2
```
where Python has its local environment and additional lib's installed locally, some of the following commands may help:
```bash
python3 -m venv .
./bin/pip install scipy
./bin/pip install scikit-learn
```
Also, the current Rust toolchain can be found in `/toolchain.txt`
## "Advanced"
The command that is called can be called directly as
```bash
$ RUSTFLAGS="-C target-cpu=native" cargo run --release -- --help
```
which writes down the list of parameters that can also be given to the analyzing tool after `--`.
## How It Works
???
- all is orchestrated by `external_product_correction.py`
- Rust code is compiled & executed ... this generates vector(s) of errors
- samples are analyzed and curves are fitted
## Nice-To-Have
- `Makefile`? part of CI workflow? test report?
- for now, improve output: meaning of printed values, ...
- rework as an assurance tool for all op's (not only for external product)
- make a macro that generates these tests?
- put this macro "near" each tested operation (i.e., greatly simplify adding new op's)
- use noise formulas extracted from the latest optimizer (was there a PR on that?)

View File

@@ -1,3 +0,0 @@
#!/bin/bash
./bin/python3 external_product_correction.py --chunks 192 --rust-toolchain nightly-2024-08-19 --analysis-only --dir multi-bit-sampling/gf2/ -- --algorithm multi-bit-ext-prod --multi-bit-grouping-factor 2 > log-real-to-pred-2.dat

View File

@@ -1,562 +0,0 @@
import argparse
import concurrent.futures
import csv
import dataclasses
import datetime
import json
import pathlib
import subprocess
import functools
from pathlib import Path
import numpy as np
np.set_printoptions(threshold=np.inf)
np.set_printoptions(linewidth=np.inf)
from scipy.optimize import curve_fit
from sklearn.ensemble import IsolationForest
# Command used to run Rust program responsible to perform sampling on external product.
BASE_COMMAND = 'RUSTFLAGS="-C target-cpu=native" cargo {} {} --release --features=nightly-avx512'
# Leave toolchain empty at first
BUILD_COMMAND = BASE_COMMAND.format("{}", "build")
RUN_COMMAND = BASE_COMMAND.format("{}", "run") + " -- --tot {} --id {} {}"
SECS_PER_HOUR = 3600
SECS_PER_MINUTES = 60
parser = argparse.ArgumentParser(description="Compute coefficient correction for external product")
parser.add_argument(
"--chunks",
type=int,
help="Total number of chunks the parameter grid is divided into."
"Each chunk is run in a sub-process, to speed up processing make sure to"
" have at least this number of CPU cores to allocate for this task",
)
parser.add_argument(
"--rust-toolchain",
type=str,
help="The rust toolchain to use",
)
parser.add_argument(
"--output-file",
"-o",
type=str,
dest="output_filename",
default="correction_coefficients.json",
help="Output file containing correction coefficients, formatted as JSON"
" (default: correction_coefficients.json)",
)
parser.add_argument(
"--analysis-only",
"-A",
action="store_true",
dest="analysis_only",
help="If this flag is set, no sampling will be done, it will only try to"
" analyze existing results",
)
parser.add_argument("--dir", type=str, default=".", help="Dir where acquisition files are stored.")
parser.add_argument(
"--worst-case-analysis",
"-W",
dest="worst_case_analysis",
action="store_true",
help="Perform a 1000 analysis pruning different outliers, "
"selecting the wort-case parameter for the fft noise fitting",
)
parser.add_argument(
"sampling_args",
nargs=argparse.REMAINDER,
help="Arguments directly passed to sampling program, to get an exhaustive list"
" of options run command: `cargo run -- --help`",
)
@dataclasses.dataclass(init=False)
class SamplingLine:
"""
Extract output variance parameter from a sampling result string.
:param line: :class:`str` formatted as ``polynomial_size, glwe_dimension,
decomposition_level_count, decomposition_base_log, input_variance, output_variance,
predicted_variance``
"""
parameters: list
input_variance: float
output_variance_exp: float
output_variance_th: float
def __init__(self, line: dict):
self.input_variance = float(line["input_variance"])
self.output_variance_exp = float(line["output_variance"])
self.single_ggsw_variance = float(line["single_ggsw_variance"])
self.output_variance_th = float(line["predicted_variance"])
self.parameters = [
float(line["polynomial_size"]),
float(line["glwe_dimension"]),
float(line["decomposition_level_count"]),
float(line["decomposition_base_log"]),
]
# polynomial_size, glwe_dimension, decomposition_level_count, decomposition_base_log
ggsw_value = int(line["ggsw_encrypted_value"])
if ggsw_value != 1:
raise ValueError(f"GGSW value is not 1, it's: {ggsw_value}")
def concatenate_result_files(dir_):
"""
Concatenate result files into a single one.
:param pattern: filename pattern as :class:`str`
:return: concatenated filename as :class:`Path`
"""
dir_path = Path(dir_)
results_filepath = dir_path / "concatenated_sampling_results"
files = sorted(Path(dir_).glob("*.algo_sample_acquistion"))
if results_filepath.exists():
results_filepath.unlink()
first_file = files[0]
with results_filepath.open("w", encoding="utf-8") as results:
content = first_file.read_text()
(header, sep, _content) = content.partition("\n")
new_hader = (header + sep).replace(" ", "")
results.write(new_hader)
with results_filepath.open("a", encoding="utf-8") as results:
for file in files:
content = file.read_text()
(_header, _sep, content) = content.partition("\n")
results.write(content.replace(" ", ""))
return results_filepath
def extract_from_acquisitions(filename):
"""
Retrieve and parse data from sampling results.
:param filename: sampling results filename as :class:`Path`
:return: :class:`tuple` of :class:`numpy.array`
"""
parameters = []
exp_output_variance = []
th_output_variance = []
single_ggsw_variance = []
input_variance = []
with filename.open() as csvfile:
csv_reader = csv.DictReader(csvfile, delimiter=",")
for line in csv_reader:
try:
sampled_line = SamplingLine(line)
except Exception as err:
# If an exception occurs when parsing a result line, we simply discard this one.
print(f"Exception while parsing line (error: {err}, line: {line})")
continue
exp_output_var = sampled_line.output_variance_exp
th_output_var = sampled_line.output_variance_th
single_ggsw_var = sampled_line.single_ggsw_variance
input_var = sampled_line.input_variance
params = sampled_line.parameters
if exp_output_var < 0.083:
params.append(th_output_var)
parameters.append(params)
exp_output_variance.append(exp_output_var)
th_output_variance.append(th_output_var)
single_ggsw_variance.append(single_ggsw_var)
input_variance.append(input_var)
num_samples = len(parameters)
print(f"There is {num_samples} samples ...")
return (
(
np.array(parameters),
np.array(exp_output_variance),
np.array(th_output_variance),
np.array(single_ggsw_variance),
np.array(input_variance),
)
if num_samples != 0
else None
)
def get_input(filename):
"""
:param filename: result filename as :class:`Path`
:return: :class:`tuple` of X and Y values
"""
acquisition_samples = extract_from_acquisitions(filename)
if acquisition_samples is None:
return None
(
parameters,
exp_output_variance,
_th_output_variance,
_single_ggsw_variance,
input_variance,
) = acquisition_samples
y_values = np.maximum(0.0, (exp_output_variance - input_variance)) #TODO return a NaN if exp_output_variance <= input_variance ??
x_values = parameters
return x_values, y_values
def get_input_without_outlier(filename, bits):
inputs = get_input(filename)
if inputs is None:
return None
return remove_outlier(bits, *inputs)
def remove_outlier(bits, x_values, y_values):
"""
Remove outliers from a dataset using an isolation forest algorithm.
:param x_values: values for the first dimension as :class:`list`
:param y_values: values for the second dimension as :class:`list`
:return: cleaned dataset as :class:`tuple` which element storing values a dimension in a
:class:`list`
"""
# identify outliers in the training dataset
iso = IsolationForest(contamination=0.1) # Contamination value obtained by experience
yhat = iso.fit_predict(x_values)
# select all rows that are not outliers
mask = yhat != -1
previous_size = len(x_values)
# ~ x_values, y_values = x_values[mask, :], y_values[mask]
new_size = len(x_values)
print(f"Removing {previous_size - new_size} outliers ...")
x_values = x_values.astype(np.float64)
# Scale the values from variance to modular variance after the filtering was done to avoid
# overflowing the isolation forest from sklearn
x_values[:, -1] = x_values[:, -1] * np.float64(2 ** (bits * 2))
y_values = y_values.astype(np.float64) * np.float64(2 ** (bits * 2))
return x_values, y_values
def fft_noise(x, a, b, c, log2_q):
"""
Noise formula for FFTW.
"""
# 53 bits of mantissa kept at most
bits_lost_per_conversion = max(0, log2_q - 53)
bit_lost_roundtrip = 2 * bits_lost_per_conversion
N = x[:, 0]
k = x[:, 1]
level = x[:, 2]
logbase = x[:, 3]
theoretical_var = x[:, -1]
# ~ print(x[:,0])
# ~ print(x[:,1])
# ~ print(x[:,-1])
# ~ print("----")
return k * (k + 1) * level * ( # tanh: * 2.**(1.-(1.+a/(2.**logbase))*.5*(np.tanh(b*(level-(N/50.)/logbase))+1.))
# ~ a * 2**bit_lost_roundtrip * 2.0 ** (2 * logbase) * N**1.584962501
# ~ + b * 2**bit_lost_roundtrip * 2.0 ** (2 * logbase) * N**2
a * 2**bit_lost_roundtrip * 2.0 ** (2 * logbase) * N**2 # in theory, not present
+ b * 2**bit_lost_roundtrip * 2.0 ** (2 * logbase) * (N**2)*np.log2(N)
+ c * 2**bit_lost_roundtrip * 2.0 ** (2 * logbase) * (N**2)*(np.log2(N)**2)
) + theoretical_var
def fft_noise_128(x, a, b, c, log2_q):
"""
Noise formula for f128 fft
"""
# 106 bits of mantissa kept at most
bits_lost_per_conversion = max(0, log2_q - 106)
bit_lost_roundtrip = 2 * bits_lost_per_conversion
N = x[:, 0]
k = x[:, 1]
level = x[:, 2]
logbase = x[:, 3]
theoretical_var = x[:, -1]
# we lose 2 * 11 bits of mantissa per conversion 22 * 2 = 44
return k * (k + 1) * level * ( # tanh: * 2.**(1.-(1.+a/(2.**logbase))*.5*(np.tanh(b*(level-(N/50.)/logbase))+1.))
# ~ a * 2**bit_lost_roundtrip * 2.0 ** (2 * logbase) * N**1.584962501
# ~ + b * 2**bit_lost_roundtrip * 2.0 ** (2 * logbase) * N**2
a * 2**bit_lost_roundtrip * 2.0 ** (2 * logbase) * N**2
+ b * 2**bit_lost_roundtrip * 2.0 ** (2 * logbase) * (N**2)*np.log2(N)
+ c * 2**bit_lost_roundtrip * 2.0 ** (2 * logbase) * (N**2)*(np.log2(N)**2)
) + theoretical_var
def log_fft_noise_fun(x, a, b, c, fft_noise_fun):
return np.log2(fft_noise_fun(x, a, b, c))
def train(x_values, y_values, fft_noise_fun):
weights, _ = curve_fit(
#TODO try changing the formula according to paper
lambda x, a, b, c: log_fft_noise_fun(x, a, b, c, fft_noise_fun), x_values, np.log2(y_values)
)
return weights
def get_weights(filename, fft_noise_fun, bits):
"""
Get weights from sampling results.
:param filename: results filename as :class:`Path`
:return: :class:`dict` of weights formatted as ``{"a": <float>, "b": <float>, "c": <float>}``
"""
inputs_without_outlier = get_input_without_outlier(filename, bits)
if inputs_without_outlier is None:
return None
x_values, y_values = inputs_without_outlier
weights = train(x_values, y_values, fft_noise_fun)
test(x_values, y_values, weights, fft_noise_fun)
return {"a": weights[0], "b": weights[1], "c": weights[2]}
def write_to_file(filename, obj):
"""
Write the given ``obj``ect into a file formatted as JSON.
:param filename: filename to write into as :class:`str`
:param obj: object to write as JSON
"""
filepath = Path(filename)
try:
with filepath.open("w", encoding="utf-8") as f:
json.dump(obj, f)
except Exception as err:
print(f"Exception occurred while writing to {filename}: {err}")
else:
print(f"Results written to {filename}")
def build_sampler(rust_toolchain) -> bool:
"""
Build sampling Rust program as a subprocess.
"""
start_time = datetime.datetime.now()
print("Building sampling program")
build_command = BUILD_COMMAND.format(rust_toolchain)
process = subprocess.run(build_command, shell=True, capture_output=True, check=False)
elapsed_time = (datetime.datetime.now() - start_time).total_seconds()
stderr = process.stderr.decode()
stderr_formatted = f"STDERR: {stderr}" if stderr else ""
print(
f"Building failed after {elapsed_time} seconds\n"
f"STDOUT: {process.stdout.decode()}\n"
f"{stderr_formatted}"
)
if process.returncode == 0:
print(f"Building done in {elapsed_time} seconds")
return True
else:
return False
def run_sampling_chunk(rust_toolchain, total_chunks, identity, input_args) -> bool:
"""
Run an external product sampling on a chunk of data as a subprocess.
:param total_chunks: number of chunks the parameter is divided into
:param identity: chunk identifier as :class:`int`
:param input_args: arguments passed to sampling program
"""
cmd = RUN_COMMAND.format(rust_toolchain, total_chunks, identity, input_args)
start_time = datetime.datetime.now()
print(f"External product sampling chunk #{identity} starting")
process = subprocess.run(cmd, shell=True, capture_output=True, check=False)
elapsed_time = (datetime.datetime.now() - start_time).total_seconds()
hours = int(elapsed_time // SECS_PER_HOUR)
minutes = int((elapsed_time % SECS_PER_HOUR) // SECS_PER_MINUTES)
seconds = int(elapsed_time % SECS_PER_HOUR % SECS_PER_MINUTES)
if process.returncode == 0:
print(
f"External product sampling chunk #{identity} successfully done in"
f" {hours}:{minutes}:{seconds}"
)
return True
else:
stderr = process.stderr.decode()
stderr_formatted = f"STDERR: {stderr}" if stderr else ""
print(
f"External product sampling chunk #{identity} failed after"
f" {hours}:{minutes}:{seconds}\n"
f"STDOUT: {process.stdout.decode()}\n"
f"{stderr_formatted}"
)
return False
def log_var(variance):
if variance <= 0:
return np.nan
return np.log2(variance) # was: np.ceil(0.5 * np.log2(variance)) ??
def test(x_values, y_values, weights, fft_noise_fun):
for nu in range(8,15):
big_N = 2.**nu
mse = 0.0
mse_without_correction = 0.0
count = 0
for index in range(len(x_values)):
params = np.array([x_values[index, :]])
real_out = y_values[index]
pred_out = max(fft_noise_fun(params, *list(weights))[0], 0.000001) #TODO make sure this const is OK
if params[0,0] == big_N:
mse += (log_var(real_out) - log_var(pred_out)) ** 2
print(f"{log_var(real_out) - log_var(pred_out)}, {params[0][0]}, {params[0][1]}, {params[0][2]}, {params[0][3]}, {params[0][4]}, {real_out}, {pred_out}") # log_var(real_out) - log_var(pred_out) == log_var(real_out/pred_out)
# print(
# f"th: {log_var(params[0, -1])}, pred_fft: {log_var(pred_out)}, "
# f"real: {log_var(real_out)}"
# )
mse_without_correction += (log_var(real_out) - log_var(params[0, -1])) ** 2
count += 1
# print(log_var(params[0, -1]))
# mse_without_correction += (log_var(real_out) ) ** 2
# print()
count = max(count, 1)
mse /= count # len(x_values)
mse = .5 * mse ** .5
mse_without_correction /= count # len(x_values)
mse_without_correction = .5 * mse_without_correction ** .5
# ~ print(f"½ √mse (N = {big_N}): {mse} .. {2 ** (2*mse)}") # \nMSE without correction: {mse_without_correction}
mse = 0.0
mse_without_correction = 0.0
count = 0
for index in range(len(x_values)):
params = np.array([x_values[index, :]])
real_out = y_values[index]
pred_out = max(fft_noise_fun(params, *list(weights))[0], 0.000001)
mse += (log_var(real_out) - log_var(pred_out)) ** 2
# print(
# f"th: {log_var(params[0, -1])}, pred_fft: {log_var(pred_out)}, "
# f"real: {log_var(real_out)}"
# )
mse_without_correction += (log_var(real_out) - log_var(params[0, -1])) ** 2
count += 1
# print(log_var(params[0, -1]))
# mse_without_correction += (log_var(real_out) ) ** 2
count = max(count, 1)
mse /= count # len(x_values)
mse = .5 * mse ** .5
mse_without_correction /= count # len(x_values)
mse_without_correction = .5 * mse_without_correction ** .5
print(f"½ √mse (all N): {mse} .. {2 ** (2*mse)} \n½ √MSE without correction: {mse_without_correction} .. {2 ** (2*mse_without_correction)}")
return mse, mse_without_correction
def main():
args = parser.parse_args()
rust_toolchain = args.rust_toolchain
if rust_toolchain[0] != "+":
rust_toolchain = f"+{rust_toolchain}"
sampling_args = list(filter(lambda x: x != "--", args.sampling_args))
bits = 64
fft_noise_fun = fft_noise
if any(arg in ["ext-prod-u128-split", "ext-prod-u128"] for arg in sampling_args):
fft_noise_fun = fft_noise_128
bits = 128
for idx, flag_or_value in enumerate(sampling_args):
if flag_or_value in ["-q", "--modulus-log2"]:
bits = int(sampling_args[idx + 1])
break
sampling_args.extend(["--dir", args.dir])
fft_noise_fun = functools.partial(fft_noise_fun, log2_q=bits)
dest_dir = Path(args.dir).resolve()
if not args.analysis_only:
# if dest_dir.exists() and dest_dir.glob(args.output_filename):
# user_input = input(
# f"Warning directory {str(dest_dir)} already exists, "
# "proceed and overwrite existing data? [y/N]\n"
# )
# if user_input.lower() != "y":
# print("Aborting.")
# exit(1)
dest_dir.mkdir(parents=True, exist_ok=True)
if not build_sampler(rust_toolchain):
print("Error while building sampler. Exiting")
exit(1)
with concurrent.futures.ThreadPoolExecutor(max_workers=args.chunks) as executor:
futures = []
for n in range(args.chunks):
futures.append(
executor.submit(
run_sampling_chunk,
rust_toolchain,
args.chunks,
n,
" ".join(sampling_args),
)
)
# Wait for all sampling chunks to be completed.
concurrent.futures.wait(futures)
execution_ok = True
for future in futures:
execution_ok = execution_ok and future.result()
if not execution_ok:
print("Error while running samplings processes. Check logs.")
exit(1)
result_file = concatenate_result_files(args.dir)
output_file = dest_dir / args.output_filename
if args.worst_case_analysis:
weights = get_weights(result_file, fft_noise_fun, bits)
if weights is None:
print("Empty weights after outlier removal, exiting")
return
max_a = weights["a"]
max_b = weights["b"]
max_c = weights["c"]
for _ in range(1000):
weights = get_weights(result_file, fft_noise_fun, bits)
max_a = max(max_a, weights["a"])
max_b = max(max_b, weights["b"])
max_c = max(max_c, weights["c"])
write_to_file(output_file, {"a": max_a, "b": max_b, "c": max_c})
else:
weights = get_weights(result_file, fft_noise_fun, bits)
if weights is None:
print("Empty weights after outlier removal, exiting")
return
write_to_file(output_file, weights)
if __name__ == "__main__":
main()

View File

@@ -1,21 +0,0 @@
#!/usr/bin/env gnuplot
GF = 2
SFX = "-tanh" # -tanh
DATAFILE = "log-real-to-pred-".GF.SFX.".dat"
set term pngcairo size 1200,900 linewidth 2
set out "histogram-".GF.SFX.".png"
set style fill solid 0.5 # fill style
set xrange [-4:4]
set yrange [0:600]
min=-3. # min value
max= 3. # max value
n = 200
width=(max-min)/n # interval width
set boxwidth width*0.8
hist(x,width)=width*floor(x/width)+width/2.0
plot DATAFILE u (hist($1,width)):(1.0) smooth freq w boxes lc rgb "green" notitle

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,706 +0,0 @@
use super::*;
use itertools::Itertools;
use rand::prelude::*;
use rayon::prelude::*;
use std::path::{Path, PathBuf};
use tfhe::core_crypto::commons::noise_formulas::lwe_keyswitch::keyswitch_additive_variance_132_bits_security_gaussian;
use tfhe::core_crypto::commons::noise_formulas::lwe_programmable_bootstrap::pbs_variance_132_bits_security_gaussian;
use tfhe::core_crypto::commons::noise_formulas::secure_noise::{
minimal_glwe_variance_for_132_bits_security_gaussian,
minimal_lwe_variance_for_132_bits_security_gaussian,
};
// pub const SECURITY_LEVEL: u64 = 132;
// Variance of uniform distribution over [0; 1)
pub const UNIFORM_NOISE_VARIANCE: f64 = 1. / 12.;
#[derive(Clone, Copy, Debug)]
struct Params {
lwe_dimension: LweDimension,
glwe_dimension: GlweDimension,
polynomial_size: PolynomialSize,
pbs_base_log: DecompositionBaseLog,
pbs_level: DecompositionLevelCount,
ks_base_log: DecompositionBaseLog,
ks_level: DecompositionLevelCount,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
struct ParamsHash {
lwe_dimension: LweDimension,
glwe_dimension: GlweDimension,
polynomial_size: PolynomialSize,
pbs_level: DecompositionLevelCount,
ks_level: DecompositionLevelCount,
ks_base_log_smaller_than_5: bool,
}
impl std::hash::Hash for ParamsHash {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.lwe_dimension.0.hash(state);
self.glwe_dimension.0.hash(state);
self.polynomial_size.0.hash(state);
self.pbs_level.0.hash(state);
self.ks_level.0.hash(state);
self.ks_base_log_smaller_than_5.hash(state);
}
}
impl From<Params> for ParamsHash {
fn from(value: Params) -> Self {
Self {
lwe_dimension: value.lwe_dimension,
glwe_dimension: value.glwe_dimension,
polynomial_size: value.polynomial_size,
pbs_level: value.pbs_level,
ks_level: value.ks_level,
ks_base_log_smaller_than_5: value.ks_base_log.0 <= 5,
}
}
}
struct NoiseVariances {
lwe_noise_variance: Variance,
glwe_noise_variance: Variance,
estimated_pbs_noise_variance: Variance,
estimated_ks_noise_variance: Variance,
br_to_ms_noise_variance: Variance,
}
impl NoiseVariances {
fn all_noises_are_not_uniformly_random(&self) -> bool {
self.lwe_noise_variance.0 < UNIFORM_NOISE_VARIANCE
&& self.glwe_noise_variance.0 < UNIFORM_NOISE_VARIANCE
&& self.estimated_ks_noise_variance.0 < UNIFORM_NOISE_VARIANCE
&& self.estimated_pbs_noise_variance.0 < UNIFORM_NOISE_VARIANCE
&& self.br_to_ms_noise_variance.0 < UNIFORM_NOISE_VARIANCE
}
}
// TODO
// This needs to be updated with the research optimizer
// This was taken from concrete CPU temporarily
pub fn estimate_modulus_switching_noise_with_binary_key(
internal_ks_output_lwe_dimension: LweDimension,
glwe_polynomial_size: PolynomialSize,
modulus: f64,
) -> Variance {
let ciphertext_modulus_log = modulus.log2() as u32;
fn modular_variance_variance_ratio(ciphertext_modulus_log: u32) -> f64 {
2_f64.powi(2 * ciphertext_modulus_log as i32)
}
fn modular_variance_to_variance(modular_variance: f64, ciphertext_modulus_log: u32) -> f64 {
modular_variance / modular_variance_variance_ratio(ciphertext_modulus_log)
}
let nb_msb = glwe_polynomial_size.0.ilog2() + 1;
let w = 2_f64.powi(nb_msb as i32);
let n = internal_ks_output_lwe_dimension.0 as f64;
Variance(
(1. / 12. + n / 24.) / (w * w)
+ modular_variance_to_variance(-1. / 12. + n / 48., ciphertext_modulus_log),
)
}
fn lwe_glwe_noise_ap_estimate(
Params {
lwe_dimension,
glwe_dimension,
polynomial_size,
pbs_base_log,
pbs_level,
ks_base_log,
ks_level,
}: Params,
ciphertext_modulus_log: u32,
) -> NoiseVariances {
let modulus = 2.0f64.powi(ciphertext_modulus_log as i32);
let lwe_noise_variance =
minimal_lwe_variance_for_132_bits_security_gaussian(lwe_dimension, modulus);
let glwe_noise_variance = minimal_glwe_variance_for_132_bits_security_gaussian(
glwe_dimension,
polynomial_size,
modulus,
);
let estimated_pbs_noise_variance = pbs_variance_132_bits_security_gaussian(
lwe_dimension,
glwe_dimension,
polynomial_size,
pbs_base_log,
pbs_level,
modulus,
);
let estimated_ks_noise_variance = keyswitch_additive_variance_132_bits_security_gaussian(
glwe_dimension.to_equivalent_lwe_dimension(polynomial_size),
lwe_dimension,
ks_base_log,
ks_level,
modulus,
);
let ms_noise_variance =
estimate_modulus_switching_noise_with_binary_key(lwe_dimension, polynomial_size, modulus);
let br_to_ms_noise_variance = Variance(
estimated_pbs_noise_variance.0 + estimated_ks_noise_variance.0 + ms_noise_variance.0,
);
NoiseVariances {
lwe_noise_variance,
glwe_noise_variance,
estimated_pbs_noise_variance,
estimated_ks_noise_variance,
br_to_ms_noise_variance,
}
}
fn write_results_to_file(
params: Params,
perf_metrics_array: &[(usize, ThreadCount, usize, PerfMetrics)],
out_dir: &Path,
) {
let exp_name = format!(
"n={}_k={}_N={}_brl={}_brb={}_ksl={}_ksb={}",
params.lwe_dimension.0,
params.glwe_dimension.0,
params.polynomial_size.0,
params.pbs_level.0,
params.pbs_base_log.0,
params.ks_level.0,
params.ks_base_log.0,
);
let out_file_name = PathBuf::from(format!("{exp_name}.csv"));
let out_path = out_dir.join(out_file_name);
if out_path.exists() {
std::fs::remove_file(&out_path).unwrap();
}
let mut out = std::fs::File::options()
.create(true)
.append(true)
.open(&out_path)
.unwrap();
// per_batch_runtime_s: f64,
// pbs_per_s: f64,
// pbs_per_s_per_thread: f64,
// equivalent_monothread_pbs_runtime_s: f64,
writeln!(
&mut out,
"chunk_size,threads_used,batch_count,overall_runtime_s,\
per_batch_runtime_s,pbs_per_s,pbs_per_s_per_thread,equivalent_monothread_pbs_runtime_s"
)
.unwrap();
for (chunk_size, thread_count, batch_count, perf_metrics) in perf_metrics_array {
let thread_count = thread_count.0;
let PerfMetrics {
overall_runtime_s,
per_batch_runtime_s,
pbs_per_s,
pbs_per_s_per_thread,
equivalent_monothread_pbs_runtime_s,
} = perf_metrics;
writeln!(
&mut out,
"{chunk_size},{thread_count},{batch_count},{overall_runtime_s},\
{per_batch_runtime_s},{pbs_per_s},{pbs_per_s_per_thread},{equivalent_monothread_pbs_runtime_s}"
).unwrap();
}
}
fn filter_b_l_limited(
bases: &[usize],
levels: &[usize],
preserved_mantissa: usize,
) -> Vec<BaseLevel> {
let mut bases_levels = vec![];
for (b, l) in iproduct!(bases, levels) {
if b * l <= preserved_mantissa {
if *b == 1 {
if (b * l) % 5 == 0 {
bases_levels.push(BaseLevel {
base: DecompositionBaseLog(*b),
level: DecompositionLevelCount(*l),
});
}
} else {
bases_levels.push(BaseLevel {
base: DecompositionBaseLog(*b),
level: DecompositionLevelCount(*l),
});
}
}
}
bases_levels
}
// preserved_mantissa = number of bits that are in the mantissa of the floating point numbers used
pub fn timing_experiment(algorithm: &str, preserved_mantissa: usize, modulus: u128) {
assert_eq!(algorithm, EXT_PROD_ALGO);
let out_dir = Path::new("exp");
if !out_dir.exists() {
std::fs::create_dir(out_dir).unwrap();
}
let ciphertext_modulus: CiphertextModulus<u64> = match modulus {
0 => CiphertextModulus::new_native(),
_ => CiphertextModulus::try_new(modulus).unwrap(),
};
assert!(ciphertext_modulus.is_compatible_with_native_modulus());
let lwe_dimension_search_space = (512..=1024).step_by(64).map(LweDimension);
let glwe_dimension_search_space = (1..=5).map(GlweDimension);
let polynomial_size_search_space = (8..=14).map(|poly_log2| PolynomialSize(1 << poly_log2));
let modulus_log2 = if ciphertext_modulus.is_native_modulus() {
64usize
} else {
ciphertext_modulus.get_custom_modulus().ilog2() as usize
};
// TODO: as discussed with Sam, limit to 40
let max_base_level_product = 40;
let preserved_mantissa = preserved_mantissa.min(modulus_log2);
let (potential_base_logs, potential_levels) = (
(1..=modulus_log2).collect::<Vec<_>>(),
(1..=modulus_log2).collect::<Vec<_>>(),
);
let max_base_log_level_prod = preserved_mantissa
.min(modulus_log2)
.min(max_base_level_product);
// let base_log_level_pbs = filter_b_l(
// &potential_base_logs,
// &potential_levels,
// max_base_log_level_prod,
// );
let base_log_level_pbs = filter_b_l_limited(
&potential_base_logs,
&potential_levels,
max_base_log_level_prod,
);
// Same for KS
let base_log_level_ks = base_log_level_pbs.clone();
let hypercube = iproduct!(
lwe_dimension_search_space,
glwe_dimension_search_space,
polynomial_size_search_space,
base_log_level_pbs,
base_log_level_ks
);
let hypercube: Vec<_> = hypercube
.map(
|(
lwe_dimension,
glwe_dimension,
polynomial_size,
pbs_base_log_level,
ks_base_log_level,
)| {
let params = Params {
lwe_dimension,
glwe_dimension,
polynomial_size,
pbs_base_log: pbs_base_log_level.base,
pbs_level: pbs_base_log_level.level,
ks_base_log: ks_base_log_level.base,
ks_level: ks_base_log_level.level,
};
let variances =
lwe_glwe_noise_ap_estimate(params, modulus_log2.try_into().unwrap());
(params, variances)
},
)
.filter(|(_params, variances)| {
// let noise_ok = variances.all_noises_are_not_uniformly_random();
// let base_logs_not_too_small = params.pbs_base_log.0 != 1 && params.ks_base_log.0 !=
// 1;
// noise_ok && base_logs_not_too_small
// let glwe_poly_not_too_big = params.polynomial_size.0 < 2048
// || (params.polynomial_size.0 >= 2048 && params.glwe_dimension.0 == 1);
// noise_ok && glwe_poly_not_too_big
// noise_ok
variances.all_noises_are_not_uniformly_random()
})
.collect();
println!("candidates {}", hypercube.len());
let mut hypercube: Vec<_> = hypercube
.into_iter()
.unique_by(|x| ParamsHash::from(x.0))
.collect();
println!("candidates {}", hypercube.len());
// hypercube.sort_by(|a, b| {
// let a = a.0;
// let b = b.0;
// let cost_a = ks_cost(
// a.lwe_dimension,
// a.glwe_dimension
// .to_equivalent_lwe_dimension(a.polynomial_size),
// a.ks_level,
// ) + pbs_cost(
// a.lwe_dimension,
// a.glwe_dimension,
// a.pbs_level,
// a.polynomial_size,
// );
// let cost_b = ks_cost(
// b.lwe_dimension,
// b.glwe_dimension
// .to_equivalent_lwe_dimension(b.polynomial_size),
// b.ks_level,
// ) + pbs_cost(
// b.lwe_dimension,
// b.glwe_dimension,
// b.pbs_level,
// b.polynomial_size,
// );
// cost_a.cmp(&cost_b)
// });
let seed = [0u8; 8 * 4];
let mut rng = rand_chacha::ChaChaRng::from_seed(seed);
hypercube.shuffle(&mut rng);
// // After the shuffle make the small levels pop first
// hypercube.sort_by(|a, b| {
// let a = a.0;
// let b = b.0;
// let a_level_prod = a.ks_level.0 * a.pbs_level.0;
// let b_level_prod = b.ks_level.0 * b.pbs_level.0;
// a_level_prod.cmp(&b_level_prod)
// // let a_size = a
// // .glwe_dimension
// // .to_equivalent_lwe_dimension(a.polynomial_size)
// // .0
// // * a.ks_level.0
// // * a.lwe_dimension.to_lwe_size().0
// // + a.lwe_dimension.0
// // * (a.glwe_dimension.to_glwe_size().0.pow(2))
// // * a.pbs_level.0
// // * a.polynomial_size.0;
// // let b_size = b
// // .glwe_dimension
// // .to_equivalent_lwe_dimension(b.polynomial_size)
// // .0
// // * b.ks_level.0
// // * b.lwe_dimension.to_lwe_size().0
// // + b.lwe_dimension.0
// // * (b.glwe_dimension.to_glwe_size().0.pow(2))
// // * b.pbs_level.0
// // * b.polynomial_size.0;
// // a_size.cmp(&b_size)
// });
// {
// let mut out = std::fs::File::options()
// .create(true)
// .truncate(true)
// .write(true)
// .open(&out_dir.join(&"params.log"))
// .unwrap();
// for (param, _) in &hypercube {
// writeln!(&mut out, "{param:?}").unwrap();
// }
// panic!("lol");
// }
let start_time = std::time::Instant::now();
for (idx, (params, variances)) in hypercube.into_iter().enumerate() {
let loop_start = std::time::Instant::now();
println!("#{idx} start");
println!("{params:#?}");
let perf_metrics = run_timing_measurements(params, variances, ciphertext_modulus);
println!("{perf_metrics:#?}");
write_results_to_file(params, &perf_metrics, out_dir);
let loop_elapsed = loop_start.elapsed();
println!("#{idx} done in {loop_elapsed:?}");
println!("overall runtime {:?}", start_time.elapsed());
}
}
pub const CHUNK_SIZE: [usize; 5] = [1, 32, 64, 128, 192];
pub const BATCH_COUNT: usize = 100;
#[derive(Clone, Copy, Debug)]
struct PerfMetrics {
overall_runtime_s: f64,
per_batch_runtime_s: f64,
pbs_per_s: f64,
pbs_per_s_per_thread: f64,
equivalent_monothread_pbs_runtime_s: f64,
}
fn compute_perf_metrics(
overall_runtime: std::time::Duration,
batch_count: usize,
pbs_per_batch: usize,
thread_count: usize,
) -> PerfMetrics {
let per_batch_runtime = overall_runtime / batch_count.try_into().unwrap();
let per_batch_runtime_s = per_batch_runtime.as_secs_f64();
let batch_per_s = 1.0 / per_batch_runtime_s;
let pbs_per_s = batch_per_s * pbs_per_batch as f64;
let pbs_per_s_per_thread = pbs_per_s / thread_count as f64;
let equivalent_monothread_pbs_runtime_s = 1.0 / pbs_per_s_per_thread;
PerfMetrics {
overall_runtime_s: overall_runtime.as_secs_f64(),
per_batch_runtime_s,
pbs_per_s,
pbs_per_s_per_thread,
equivalent_monothread_pbs_runtime_s,
}
}
fn run_timing_measurements(
params: Params,
variances: NoiseVariances,
ciphertext_modulus: CiphertextModulus<u64>,
) -> Vec<(usize, ThreadCount, usize, PerfMetrics)> {
// let params = Params {
// lwe_dimension: LweDimension(742),
// glwe_dimension: GlweDimension(1),
// polynomial_size: PolynomialSize(2048),
// pbs_base_log: DecompositionBaseLog(23),
// pbs_level: DecompositionLevelCount(1),
// ks_base_log: DecompositionBaseLog(3),
// ks_level: DecompositionLevelCount(5),
// };
let mut seeder = new_seeder();
let seeder = seeder.as_mut();
let mut secret_random_generator =
SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());
let mut encryption_random_generator =
EncryptionRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed(), seeder);
let lwe_noise_distribution =
Gaussian::from_dispersion_parameter(variances.lwe_noise_variance, 0.0);
let glwe_noise_distribution =
Gaussian::from_dispersion_parameter(variances.glwe_noise_variance, 0.0);
let lwe_secret_key = allocate_and_generate_new_binary_lwe_secret_key(
params.lwe_dimension,
&mut secret_random_generator,
);
let glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
params.glwe_dimension,
params.polynomial_size,
&mut secret_random_generator,
);
let ksk = allocate_and_generate_new_lwe_keyswitch_key(
&glwe_secret_key.as_lwe_secret_key(),
&lwe_secret_key,
params.ks_base_log,
params.ks_level,
lwe_noise_distribution,
ciphertext_modulus,
&mut encryption_random_generator,
);
let fbsk = {
let bsk = allocate_and_generate_new_lwe_bootstrap_key(
&lwe_secret_key,
&glwe_secret_key,
params.pbs_base_log,
params.pbs_level,
glwe_noise_distribution,
ciphertext_modulus,
&mut encryption_random_generator,
);
let mut fbsk = FourierLweBootstrapKey::new(
bsk.input_lwe_dimension(),
bsk.glwe_size(),
bsk.polynomial_size(),
bsk.decomposition_base_log(),
bsk.decomposition_level_count(),
);
par_convert_standard_lwe_bootstrap_key_to_fourier(&bsk, &mut fbsk);
fbsk
};
let inputs: Vec<_> = (0..BATCH_COUNT * CHUNK_SIZE.last().unwrap())
.map(|_| {
allocate_and_encrypt_new_lwe_ciphertext(
&glwe_secret_key.as_lwe_secret_key(),
Plaintext(0),
glwe_noise_distribution,
ciphertext_modulus,
&mut encryption_random_generator,
)
})
.collect();
let mut output = inputs.clone();
let fft = Fft::new(fbsk.polynomial_size());
let fft = fft.as_view();
let mut buffers: Vec<_> = (0..*CHUNK_SIZE.last().unwrap())
.map(|_| {
let buffer_after_ks =
LweCiphertext::new(0u64, ksk.output_lwe_size(), ciphertext_modulus);
let mut computations_buffers = ComputationBuffers::new();
computations_buffers.resize(
programmable_bootstrap_lwe_ciphertext_mem_optimized_requirement::<u64>(
fbsk.glwe_size(),
fbsk.polynomial_size(),
fft,
)
.unwrap()
.try_unaligned_bytes_required()
.unwrap(),
);
(buffer_after_ks, computations_buffers)
})
.collect();
let mut accumulator = GlweCiphertext::new(
0u64,
fbsk.glwe_size(),
fbsk.polynomial_size(),
ciphertext_modulus,
);
let mut rng = thread_rng();
// Random values in the lut
accumulator.as_mut().fill_with(|| rng.gen::<u64>());
let mut timings = vec![];
let current_thread_count = rayon::current_num_threads();
for chunk_size in CHUNK_SIZE {
let effective_thread_count = ThreadCount(chunk_size.min(current_thread_count));
let ciphertext_to_process_count = chunk_size * BATCH_COUNT;
if chunk_size == 1 {
assert_eq!(ciphertext_to_process_count, BATCH_COUNT);
let (after_ks_buffer, fft_buffer) = &mut buffers[0];
let start = std::time::Instant::now();
for (input_lwe, output_lwe) in inputs[..ciphertext_to_process_count]
.iter()
.zip(output[..ciphertext_to_process_count].iter_mut())
{
keyswitch_lwe_ciphertext(&ksk, input_lwe, after_ks_buffer);
programmable_bootstrap_lwe_ciphertext_mem_optimized(
after_ks_buffer,
output_lwe,
&accumulator,
&fbsk,
fft,
fft_buffer.stack(),
);
}
let elapsed = start.elapsed();
let perf_metrics =
compute_perf_metrics(elapsed, BATCH_COUNT, chunk_size, effective_thread_count.0);
timings.push((
chunk_size,
effective_thread_count,
BATCH_COUNT,
perf_metrics,
));
} else {
let mut measurement_count = 0;
let start = std::time::Instant::now();
for (input_lwe_chunk, output_lwe_chunk) in inputs[..ciphertext_to_process_count]
.chunks_exact(chunk_size)
.zip(output[..ciphertext_to_process_count].chunks_exact_mut(chunk_size))
{
measurement_count += 1;
assert_eq!(input_lwe_chunk.len(), chunk_size);
assert_eq!(output_lwe_chunk.len(), chunk_size);
input_lwe_chunk
.par_iter()
.zip(output_lwe_chunk.par_iter_mut())
.zip(buffers.par_iter_mut())
.for_each(|((input_lwe, output_lwe), (after_ks_buffer, fft_buffer))| {
keyswitch_lwe_ciphertext(&ksk, input_lwe, after_ks_buffer);
programmable_bootstrap_lwe_ciphertext_mem_optimized(
after_ks_buffer,
output_lwe,
&accumulator,
&fbsk,
fft,
fft_buffer.stack(),
);
});
}
let elapsed = start.elapsed();
assert_eq!(measurement_count, BATCH_COUNT);
let perf_metrics =
compute_perf_metrics(elapsed, BATCH_COUNT, chunk_size, effective_thread_count.0);
timings.push((
chunk_size,
effective_thread_count,
BATCH_COUNT,
perf_metrics,
));
}
}
timings
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,801 +0,0 @@
mod ks_pbs_timing;
mod operators;
use crate::operators::classic_pbs::{
classic_pbs_external_product, classic_pbs_external_product_u128,
classic_pbs_external_product_u128_split,
};
use crate::operators::multi_bit_pbs::{
multi_bit_pbs_external_product, std_multi_bit_pbs_external_product,
};
use clap::Parser;
use itertools::iproduct;
use std::fs::OpenOptions;
use std::io::Write;
use tfhe::core_crypto::algorithms::misc::torus_modular_diff;
use tfhe::core_crypto::commons::noise_formulas::external_product_no_fft::external_product_no_fft_additive_variance132_bits_security_gaussian;
use tfhe::core_crypto::commons::noise_formulas::multi_bit_external_product_no_fft::multi_bit_external_product_no_fft_additive_variance_132_bits_security_gaussian;
use tfhe::core_crypto::commons::noise_formulas::secure_noise::minimal_glwe_variance_for_132_bits_security_gaussian;
use tfhe::core_crypto::prelude::*;
pub const DEBUG: bool = false;
pub const EXT_PROD_ALGO: &str = "ext-prod";
pub const MULTI_BIT_EXT_PROD_ALGO: &str = "multi-bit-ext-prod";
pub const STD_MULTI_BIT_EXT_PROD_ALGO: &str = "std-multi-bit-ext-prod";
pub const EXT_PROD_U128_SPLIT_ALGO: &str = "ext-prod-u128-split";
pub const EXT_PROD_U128_ALGO: &str = "ext-prod-u128";
#[derive(Debug)]
pub struct GlweCiphertextGgswCiphertextExternalProductParameters<Scalar: UnsignedInteger> {
pub ggsw_noise: Gaussian<f64>,
pub glwe_noise: Gaussian<f64>,
pub glwe_dimension: GlweDimension,
pub ggsw_encrypted_value: Scalar,
pub polynomial_size: PolynomialSize,
pub decomposition_base_log: DecompositionBaseLog,
pub decomposition_level_count: DecompositionLevelCount,
pub ciphertext_modulus: CiphertextModulus<Scalar>,
}
#[derive(Parser, Debug)]
#[clap(author,version,about,long_about = None)]
struct Args {
/// Total number of threads.
#[clap(long, short)]
tot: usize,
/// Current Thread ID
#[clap(long, short)]
id: usize,
/// Number of time a test is repeated for a single set of parameter.
/// This indicates the number of different keys since,at each repetition,we re-sample
/// everything
#[clap(long, short, default_value_t = 10)]
repetitions: usize,
/// The size of the sample per key
#[clap(long, short = 'S', default_value_t = 10)]
sample_size: usize,
/// Step used for testing levels beyond 20in hypercube.
/// Example: with a step of 3,tested levels tested would be: 1 through 20 then 21,24,27,etc
#[clap(long, short = 's', default_value_t = 1)]
steps: usize,
/// Which algorithm to measure fft noise for
#[clap(long,short = 'a',value_parser = [
EXT_PROD_ALGO,
MULTI_BIT_EXT_PROD_ALGO,
STD_MULTI_BIT_EXT_PROD_ALGO,
EXT_PROD_U128_SPLIT_ALGO,
EXT_PROD_U128_ALGO
],default_value = "")]
algorithm: String,
#[clap(long)]
use_fft: bool,
#[clap(long)]
multi_bit_grouping_factor: Option<usize>,
#[clap(long, short = 'q')]
modulus_log2: Option<u32>,
#[clap(long, short = 'd', default_value = ".")]
dir: String,
#[clap(long, action)]
timing_only: bool,
}
fn variance_to_stddev(var: Variance) -> StandardDev {
StandardDev::from_standard_dev(var.get_standard_dev())
}
fn get_analysis_output_file(dir: &str, id: usize) -> std::fs::File {
match OpenOptions::new()
.read(true)
.write(true)
.append(true)
.create(true)
.open(format!("{dir}/{id}.algo_sample_acquistion"))
{
Err(why) => panic!("{why}"),
Ok(file) => file,
}
}
fn prepare_output_file_header(dir: &str, id: usize) {
let mut file = get_analysis_output_file(dir, id);
let header =
"polynomial_size,glwe_dimension,decomposition_level_count,decomposition_base_log,\
ggsw_encrypted_value,input_variance,output_variance,predicted_variance,single_ggsw_variance,mean_runtime_ns,\
prep_time_ns\n";
let _ = file.write(header.as_bytes()).unwrap();
}
#[allow(clippy::too_many_arguments)]
fn write_to_file<Scalar: UnsignedInteger + std::fmt::Display>(
params: &GlweCiphertextGgswCiphertextExternalProductParameters<Scalar>,
input_stddev: StandardDev,
output_stddev: StandardDev,
single_ggsw_stddev: StandardDev,
pred_stddev: StandardDev,
mean_runtime_ns: u128,
mean_prep_time_ns: u128,
dir: &str,
id: usize,
) {
let data_to_save = format!(
"{},{},{},{},{},{},{},{},{},{},{}\n",
params.polynomial_size.0,
params.glwe_dimension.0,
params.decomposition_level_count.0,
params.decomposition_base_log.0,
params.ggsw_encrypted_value,
input_stddev.get_variance(),
output_stddev.get_variance(),
pred_stddev.get_variance(),
single_ggsw_stddev.get_variance(),
mean_runtime_ns,
mean_prep_time_ns,
);
let mut file = get_analysis_output_file(dir, id);
let _ = file.write(data_to_save.as_bytes()).unwrap();
}
fn minimal_variance_for_security(
k: GlweDimension,
size: PolynomialSize,
modulus_log2: u32,
) -> Variance {
let modulus = 2.0f64.powi(modulus_log2 as i32);
minimal_glwe_variance_for_132_bits_security_gaussian(k, size, modulus)
}
fn mean(data: &[f64]) -> Option<f64> {
// adapted from https://rust-lang-nursery.github.io/rust-cookbook/science/mathematics/statistics.html
let sum: f64 = data.iter().sum();
let count = data.len();
match count {
positive if positive > 0 => Some(sum / count as f64),
_ => None,
}
}
fn std_deviation(data: &[f64]) -> Option<StandardDev> {
// from https://rust-lang-nursery.github.io/rust-cookbook/science/mathematics/statistics.html
// replacing the mean by 0. as we theoretically know it
match (mean(data), data.len()) {
(Some(_data_mean), count) if count > 0 => {
let variance = data
.iter()
.map(|&value| {
let diff = 0. - value;
diff * diff
})
.sum::<f64>()
/ count as f64;
Some(StandardDev::from_standard_dev(variance.sqrt()))
}
_ => None,
}
}
fn compute_torus_diff<Scalar: UnsignedInteger>(
errs: &mut [f64],
output: Vec<Scalar>,
input: Vec<Scalar>,
ciphertext_modulus: CiphertextModulus<Scalar>,
bit: Scalar,
) {
if bit == Scalar::ONE {
for (&out, (&inp, err)) in output.iter().zip(input.iter().zip(errs.iter_mut())) {
*err = torus_modular_diff(out, inp, ciphertext_modulus);
}
} else if bit == Scalar::ZERO {
for (&out, err) in output.iter().zip(errs.iter_mut()) {
*err = torus_modular_diff(out, Scalar::ZERO, ciphertext_modulus);
}
} else {
panic!("Not a bit: {:?}", bit);
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct BaseLevel {
base: DecompositionBaseLog,
level: DecompositionLevelCount,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct HyperCubeParams {
glwe_dimension: GlweDimension,
base_level: BaseLevel,
polynomial_size: PolynomialSize,
}
fn filter_b_l(bases: &[usize], levels: &[usize], preserved_mantissa: usize) -> Vec<BaseLevel> {
let mut bases_levels = vec![];
for (b, l) in iproduct!(bases, levels) {
if b * l <= preserved_mantissa {
bases_levels.push(BaseLevel {
base: DecompositionBaseLog(*b),
level: DecompositionLevelCount(*l),
});
}
}
bases_levels
}
fn ggsw_scalar_size(k: GlweDimension, l: DecompositionLevelCount, n: PolynomialSize) -> usize {
let (k, l, n) = (k.0, l.0, n.0);
(k + 1).pow(2) * l * n
}
fn scalar_muls_per_ext_prod(
k: GlweDimension,
l: DecompositionLevelCount,
n: PolynomialSize,
) -> usize {
// Each coefficient of the ggsw is involved once in an fmadd operation
ggsw_scalar_size(k, l, n)
}
fn ext_prod_cost(k: GlweDimension, l: DecompositionLevelCount, n: PolynomialSize) -> usize {
// Conversions going from integer to float and from float to integer
let conversion_cost = 2 * k.to_glwe_size().0 * n.0;
// Fwd and back
let fft_cost = 2 * l.0 * k.to_glwe_size().0 * n.0 * n.0.ilog2() as usize;
scalar_muls_per_ext_prod(k, l, n) + conversion_cost + fft_cost
}
#[allow(dead_code)]
fn ks_cost(
input_lwe_dimenion: LweDimension,
output_lwe_dimension: LweDimension,
ks_level_count: DecompositionLevelCount,
) -> usize {
// times 2 as it's multiply and add
2 * input_lwe_dimenion.0 * ks_level_count.0 * output_lwe_dimension.0
}
#[allow(dead_code)]
fn pbs_cost(
w: LweDimension,
k: GlweDimension,
l: DecompositionLevelCount,
n: PolynomialSize,
) -> usize {
w.0 * ext_prod_cost(k, l, n)
}
fn main() {
let args = Args::parse();
let tot = args.tot;
let id = args.id;
let total_repetitions = args.repetitions;
let base_sample_size = args.sample_size;
let algo = args.algorithm;
let dir = &args.dir;
let timing_only = args.timing_only;
let use_fft = args.use_fft;
if algo.is_empty() {
panic!("No algorithm provided")
}
let grouping_factor = match algo.as_str() {
MULTI_BIT_EXT_PROD_ALGO | STD_MULTI_BIT_EXT_PROD_ALGO => Some(LweBskGroupingFactor(
args.multi_bit_grouping_factor
.expect("Required multi_bit_grouping_factor when sampling multi bit alogrithms"),
)),
_ => None,
};
let modulus: u128 = match args.modulus_log2 {
Some(modulus_log2) => {
if modulus_log2 > 128 {
panic!("Got modulus_log2 > 128,this is not supported");
}
match algo.as_str() {
EXT_PROD_ALGO | MULTI_BIT_EXT_PROD_ALGO | STD_MULTI_BIT_EXT_PROD_ALGO => {
if modulus_log2 > 64 {
panic!("Got modulus_log2 > 64,for 64 bits scalars");
}
1u128 << modulus_log2
}
EXT_PROD_U128_SPLIT_ALGO | EXT_PROD_U128_ALGO => {
if modulus_log2 == 128 {
// native
0
} else {
1u128 << modulus_log2
}
}
_ => unreachable!(),
}
}
// Native
None => 0,
};
// TODO manage moduli < 2^53
let (stepped_levels_cutoff, max_base_log_inclusive, preserved_mantissa) = match algo.as_str() {
EXT_PROD_U128_ALGO | EXT_PROD_U128_SPLIT_ALGO => (41, 128, 106),
_ => (21, 64, 53),
};
if timing_only {
return ks_pbs_timing::timing_experiment(&algo, preserved_mantissa, modulus);
}
assert_ne!(
tot, 0,
"Got tot = 0 for noise sampling experiment,unsupported"
);
// Parameter Grid
let polynomial_sizes = vec![
PolynomialSize(1 << 8),
PolynomialSize(1 << 9),
PolynomialSize(1 << 10),
PolynomialSize(1 << 11),
PolynomialSize(1 << 12),
PolynomialSize(1 << 13),
PolynomialSize(1 << 14),
];
let max_polynomial_size = polynomial_sizes.iter().copied().max().unwrap();
let glwe_dimensions = vec![
GlweDimension(1),
GlweDimension(2),
GlweDimension(3),
GlweDimension(4),
GlweDimension(5),
];
let base_logs: Vec<_> = (1..=max_base_log_inclusive).collect();
let mut levels = (1..stepped_levels_cutoff).collect::<Vec<_>>();
let mut stepped_levels = (stepped_levels_cutoff..=max_base_log_inclusive)
.step_by(args.steps)
.collect::<Vec<_>>();
levels.append(&mut stepped_levels);
let bases_levels = filter_b_l(&base_logs, &levels, preserved_mantissa);
let hypercube = iproduct!(glwe_dimensions, bases_levels, polynomial_sizes);
let mut hypercube: Vec<HyperCubeParams> = hypercube
.map(
|(glwe_dimension, base_level, polynomial_size)| HyperCubeParams {
glwe_dimension,
base_level,
polynomial_size,
},
)
.collect();
hypercube.sort_by(|a, b| {
let k_a = a.glwe_dimension;
let l_a = a.base_level.level;
let n_a = a.polynomial_size;
let k_b = b.glwe_dimension;
let l_b = b.base_level.level;
let n_b = b.polynomial_size;
let muls_a = ext_prod_cost(k_a, l_a, n_a);
let muls_b = ext_prod_cost(k_b, l_b, n_b);
muls_a.cmp(&muls_b)
});
// Pick elements of increasing complexity stepping by the number of threads to balance the
// computation cost among threads
let chunk: Vec<_> = hypercube.iter().skip(id).step_by(tot).collect();
let chunk_size = chunk.len();
println!(
"-> Thread #{id} computing chunk #{id} of length {chunk_size} \
(processing elements #{id} + k * {tot})",
);
prepare_output_file_header(dir, id);
let mut seeder = new_seeder();
let seeder = seeder.as_mut();
let mut secret_random_generator =
SecretRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed());
let mut encryption_random_generator =
EncryptionRandomGenerator::<ActivatedRandomGenerator>::new(seeder.seed(), seeder);
let u64_tool =
|secret_rng: &mut SecretRandomGenerator<ActivatedRandomGenerator>,
encrypt_rng: &mut EncryptionRandomGenerator<ActivatedRandomGenerator>| {
for (
curr_idx,
HyperCubeParams {
glwe_dimension,
base_level:
BaseLevel {
base: decomposition_base_log,
level: decomposition_level_count,
},
polynomial_size,
},
) in chunk.iter().enumerate()
{
let glwe_dimension = *glwe_dimension;
let decomposition_base_log = *decomposition_base_log;
let decomposition_level_count = *decomposition_level_count;
let polynomial_size = *polynomial_size;
let ciphertext_modulus = CiphertextModulus::try_new(modulus).unwrap();
let modulus_log2 = if ciphertext_modulus.is_native_modulus() {
u64::BITS
} else if ciphertext_modulus.is_power_of_two() {
ciphertext_modulus.get_custom_modulus().ilog2()
} else {
todo!("Non power of 2 moduli are currently not supported")
};
println!("Chunk part: {:?}/{chunk_size:?} done", curr_idx + 1);
let sample_size = base_sample_size * max_polynomial_size.0 / polynomial_size.0;
let ggsw_noise = Gaussian::from_dispersion_parameter(
minimal_variance_for_security(glwe_dimension, polynomial_size, modulus_log2),
0.0,
);
// We measure the noise added to a GLWE ciphertext,here we can choose to have no
// input noise
// It also avoid potential cases where the noise is so big it gets decomposed
// during computations,it's an assumption we apparently already make ("small noise
// regime")
let glwe_noise = Gaussian::from_dispersion_parameter(Variance(0.0), 0.0);
// minimal_variance_for_security_64(glwe_dimension, poly_size);
let parameters = GlweCiphertextGgswCiphertextExternalProductParameters::<u64> {
ggsw_noise,
glwe_noise,
glwe_dimension,
ggsw_encrypted_value: 1,
polynomial_size,
decomposition_base_log,
decomposition_level_count,
ciphertext_modulus,
};
println!("params: {parameters:?}");
let noise_prediction = match algo.as_str() {
EXT_PROD_ALGO => {
external_product_no_fft_additive_variance132_bits_security_gaussian(
glwe_dimension,
polynomial_size,
decomposition_base_log,
decomposition_level_count,
2.0f64.powi(modulus_log2 as i32),
)
}
MULTI_BIT_EXT_PROD_ALGO =>multi_bit_external_product_no_fft_additive_variance_132_bits_security_gaussian(
glwe_dimension,
polynomial_size,
decomposition_base_log,
decomposition_level_count,
grouping_factor.unwrap().0 as f64,
2.0f64.powi(modulus_log2 as i32),
),
STD_MULTI_BIT_EXT_PROD_ALGO => multi_bit_external_product_no_fft_additive_variance_132_bits_security_gaussian(
glwe_dimension,
polynomial_size,
decomposition_base_log,
decomposition_level_count,
grouping_factor.unwrap().0 as f64,
2.0f64.powi(modulus_log2 as i32),
),
_ => unreachable!(),
};
let fft = Fft::new(parameters.polynomial_size);
let mut computation_buffers = ComputationBuffers::new();
computation_buffers.resize(
add_external_product_assign_mem_optimized_requirement::<u64>(
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
fft.as_view(),
)
.unwrap()
.unaligned_bytes_required()
.max(
fft.as_view()
.forward_scratch()
.unwrap()
.unaligned_bytes_required(),
),
);
let mut errors = vec![0.; sample_size * polynomial_size.0 * total_repetitions];
if noise_prediction.get_variance() < 1. / 12. {
let mut total_runtime_ns = 0u128;
let mut total_prep_time_ns = 0u128;
for (_, errs) in (0..total_repetitions)
.zip(errors.chunks_mut(sample_size * polynomial_size.0))
{
let mut raw_inputs = Vec::with_capacity(sample_size);
let mut outputs = Vec::with_capacity(sample_size);
let (sample_runtime_ns, prep_time_ns) = match algo.as_str() {
EXT_PROD_ALGO => classic_pbs_external_product(
&parameters,
&mut raw_inputs,
&mut outputs,
sample_size,
secret_rng,
encrypt_rng,
use_fft,
fft.as_view(),
&mut computation_buffers,
),
MULTI_BIT_EXT_PROD_ALGO => multi_bit_pbs_external_product(
&parameters,
&mut raw_inputs,
&mut outputs,
sample_size,
secret_rng,
encrypt_rng,
use_fft,
fft.as_view(),
&mut computation_buffers,
grouping_factor.unwrap(),
),
STD_MULTI_BIT_EXT_PROD_ALGO => std_multi_bit_pbs_external_product(
&parameters,
&mut raw_inputs,
&mut outputs,
sample_size,
secret_rng,
encrypt_rng,
use_fft,
fft.as_view(),
&mut computation_buffers,
grouping_factor.unwrap(),
),
_ => unreachable!(),
};
total_runtime_ns += sample_runtime_ns;
total_prep_time_ns += prep_time_ns;
let raw_input_plaintext_vector =
raw_inputs.into_iter().flatten().collect::<Vec<_>>();
let output_plaintext_vector =
outputs.into_iter().flatten().collect::<Vec<_>>();
compute_torus_diff(
errs,
output_plaintext_vector,
raw_input_plaintext_vector,
parameters.ciphertext_modulus,
parameters.ggsw_encrypted_value,
);
}
let _mean_err = mean(&errors).unwrap();
let std_err = std_deviation(&errors).unwrap();
let mean_runtime_ns =
total_runtime_ns / ((total_repetitions * sample_size) as u128);
// GGSW is prepared only once per sample
let mean_prep_time_ns = total_prep_time_ns / (total_repetitions as u128);
write_to_file(
&parameters,
parameters.glwe_noise.standard_dev(),
std_err,
ggsw_noise.standard_dev(),
variance_to_stddev(noise_prediction),
mean_runtime_ns,
mean_prep_time_ns,
dir,
id,
);
// TODO output raw data
} else {
write_to_file(
&parameters,
parameters.glwe_noise.standard_dev(),
variance_to_stddev(Variance::from_variance(1. / 12.)),
ggsw_noise.standard_dev(),
variance_to_stddev(Variance::from_variance(1. / 12.)),
0,
0,
dir,
id,
)
}
}
};
let u128_tool =
|secret_rng: &mut SecretRandomGenerator<ActivatedRandomGenerator>,
encrypt_rng: &mut EncryptionRandomGenerator<ActivatedRandomGenerator>| {
for (
curr_idx,
HyperCubeParams {
glwe_dimension,
base_level:
BaseLevel {
base: decomposition_base_log,
level: decomposition_level_count,
},
polynomial_size,
},
) in chunk.iter().enumerate()
{
let glwe_dimension = *glwe_dimension;
let decomposition_base_log = *decomposition_base_log;
let decomposition_level_count = *decomposition_level_count;
let polynomial_size = *polynomial_size;
let ciphertext_modulus = CiphertextModulus::try_new(modulus).unwrap();
let modulus_log2 = if ciphertext_modulus.is_native_modulus() {
u128::BITS
} else if ciphertext_modulus.is_power_of_two() {
ciphertext_modulus.get_custom_modulus().ilog2()
} else {
todo!("Non power of 2 moduli are currently not supported")
};
println!("Chunk part: {:?}/{chunk_size:?} done", curr_idx + 1);
let sample_size = base_sample_size * max_polynomial_size.0 / polynomial_size.0;
let ggsw_noise = Gaussian::from_dispersion_parameter(
minimal_variance_for_security(glwe_dimension, polynomial_size, modulus_log2),
0.0,
);
// We measure the noise added to a GLWE ciphertext,here we can choose to have no
// input noise
// It also avoid potential cases where the noise is so big it gets decomposed
// during computations,it's an assumption we apparently already make ("small noise
// regime")
let glwe_noise = Gaussian::from_dispersion_parameter(Variance(0.0), 0.0);
// minimal_variance_for_security_64(glwe_dimension, poly_size));
let parameters = GlweCiphertextGgswCiphertextExternalProductParameters::<u128> {
ggsw_noise,
glwe_noise,
glwe_dimension,
ggsw_encrypted_value: 1,
polynomial_size,
decomposition_base_log,
decomposition_level_count,
ciphertext_modulus,
};
println!("params: {parameters:?}");
let noise_prediction = match algo.as_str() {
EXT_PROD_U128_SPLIT_ALGO | EXT_PROD_U128_ALGO => {
external_product_no_fft_additive_variance132_bits_security_gaussian(
glwe_dimension,
polynomial_size,
decomposition_base_log,
decomposition_level_count,
2.0f64.powi(modulus_log2 as i32),
)
}
_ => unreachable!(),
};
let fft = Fft128::new(parameters.polynomial_size);
let mut computation_buffers = ComputationBuffers::new();
computation_buffers.resize(
programmable_bootstrap_f128_lwe_ciphertext_mem_optimized_requirement::<u128>(
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
fft.as_view(),
)
.unwrap()
.unaligned_bytes_required()
.max(
fft.as_view()
.backward_scratch()
.unwrap()
.unaligned_bytes_required(),
),
);
let mut errors = vec![0.; sample_size * polynomial_size.0 * total_repetitions];
if noise_prediction.get_variance() < 1. / 12. {
let mut total_runtime_ns = 0u128;
let mut total_prep_time_ns = 0u128;
for (_, errs) in (0..total_repetitions)
.zip(errors.chunks_mut(sample_size * polynomial_size.0))
{
let mut raw_inputs = Vec::with_capacity(sample_size);
let mut outputs = Vec::with_capacity(sample_size);
let (sample_runtime_ns, prep_time_ns) = match algo.as_str() {
EXT_PROD_U128_SPLIT_ALGO => classic_pbs_external_product_u128_split(
&parameters,
&mut raw_inputs,
&mut outputs,
sample_size,
secret_rng,
encrypt_rng,
fft.as_view(),
&mut computation_buffers,
),
EXT_PROD_U128_ALGO => classic_pbs_external_product_u128(
&parameters,
&mut raw_inputs,
&mut outputs,
sample_size,
secret_rng,
encrypt_rng,
fft.as_view(),
&mut computation_buffers,
),
_ => unreachable!(),
};
total_runtime_ns += sample_runtime_ns;
total_prep_time_ns += prep_time_ns;
let raw_input_plaintext_vector =
raw_inputs.into_iter().flatten().collect::<Vec<_>>();
let output_plaintext_vector =
outputs.into_iter().flatten().collect::<Vec<_>>();
compute_torus_diff(
errs,
output_plaintext_vector,
raw_input_plaintext_vector,
parameters.ciphertext_modulus,
parameters.ggsw_encrypted_value,
);
}
let _mean_err = mean(&errors).unwrap();
let std_err = std_deviation(&errors).unwrap();
let mean_runtime_ns =
total_runtime_ns / ((total_repetitions * sample_size) as u128);
// GGSW is prepared only once per sample
let mean_prep_time_ns = total_prep_time_ns / (total_repetitions as u128);
write_to_file(
&parameters,
parameters.glwe_noise.standard_dev(),
std_err,
ggsw_noise.standard_dev(),
variance_to_stddev(noise_prediction),
mean_runtime_ns,
mean_prep_time_ns,
dir,
id,
);
// TODO output raw data
} else {
write_to_file(
&parameters,
parameters.glwe_noise.standard_dev(),
variance_to_stddev(Variance::from_variance(1. / 12.)),
ggsw_noise.standard_dev(),
variance_to_stddev(Variance::from_variance(1. / 12.)),
0,
0,
dir,
id,
)
}
}
};
match algo.as_str() {
EXT_PROD_ALGO | MULTI_BIT_EXT_PROD_ALGO | STD_MULTI_BIT_EXT_PROD_ALGO => u64_tool(
&mut secret_random_generator,
&mut encryption_random_generator,
),
EXT_PROD_U128_ALGO | EXT_PROD_U128_SPLIT_ALGO => u128_tool(
&mut secret_random_generator,
&mut encryption_random_generator,
),
_ => unreachable!(),
};
}

View File

@@ -1,30 +0,0 @@
use tfhe::core_crypto::prelude::*;
pub fn classic_pbs_estimate_external_product_noise_with_binary_ggsw_and_glwe<D1>(
_polynomial_size: PolynomialSize,
_glwe_dimension: GlweDimension,
_ggsw_noise: D1,
_base_log: DecompositionBaseLog,
_level: DecompositionLevelCount,
_log2_modulus: u32,
) -> Variance
where
D1: DispersionParameter,
{
todo!()
}
pub fn multi_bit_pbs_estimate_external_product_noise_with_binary_ggsw_and_glwe<D1>(
_polynomial_size: PolynomialSize,
_glwe_dimension: GlweDimension,
_ggsw_noise: D1,
_base_log: DecompositionBaseLog,
_level: DecompositionLevelCount,
_log2_modulus: u32,
_grouping_factor: LweBskGroupingFactor,
) -> Variance
where
D1: DispersionParameter,
{
todo!()
}

View File

@@ -1,533 +0,0 @@
use crate::GlweCiphertextGgswCiphertextExternalProductParameters;
use aligned_vec::CACHELINE_ALIGN;
use tfhe::core_crypto::commons::math::decomposition::SignedDecomposer;
use tfhe::core_crypto::commons::parameters::{DecompositionBaseLog, DecompositionLevelCount};
use tfhe::core_crypto::fft_impl::fft128::crypto::ggsw::{
add_external_product_assign, Fourier128GgswCiphertext,
};
use tfhe::core_crypto::fft_impl::fft128_u128::crypto::ggsw::add_external_product_assign_split;
use tfhe::core_crypto::fft_impl::fft128_u128::math::fft::Fft128View;
use tfhe::core_crypto::fft_impl::fft64::crypto::ggsw::FourierGgswCiphertext;
use tfhe::core_crypto::fft_impl::fft64::math::fft::FftView;
use tfhe::core_crypto::prelude::{
add_external_product_assign_mem_optimized, allocate_and_generate_new_binary_glwe_secret_key,
convert_standard_ggsw_ciphertext_to_fourier_mem_optimized, decrypt_glwe_ciphertext,
encrypt_constant_ggsw_ciphertext, encrypt_glwe_ciphertext,
karatsuba_add_external_product_assign_mem_optimized, ActivatedRandomGenerator,
CiphertextModulus, Cleartext, ComputationBuffers, EncryptionRandomGenerator, GgswCiphertext,
GlweCiphertext, GlweCiphertextMutView, GlweCiphertextView, Numeric, PlaintextCount,
PlaintextList, SecretRandomGenerator,
};
#[allow(clippy::too_many_arguments)]
pub fn classic_pbs_external_product(
parameters: &GlweCiphertextGgswCiphertextExternalProductParameters<u64>,
raw_inputs: &mut Vec<Vec<u64>>,
outputs: &mut Vec<Vec<u64>>,
sample_size: usize,
secret_random_generator: &mut SecretRandomGenerator<ActivatedRandomGenerator>,
encryption_random_generator: &mut EncryptionRandomGenerator<ActivatedRandomGenerator>,
use_fft: bool,
fft: FftView,
computation_buffers: &mut ComputationBuffers,
) -> (u128, u128) {
let ciphertext_modulus = parameters.ciphertext_modulus;
let glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
parameters.glwe_dimension,
parameters.polynomial_size,
secret_random_generator,
);
let mut std_ggsw = GgswCiphertext::new(
0u64,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
parameters.decomposition_base_log,
parameters.decomposition_level_count,
ciphertext_modulus,
);
encrypt_constant_ggsw_ciphertext(
&glwe_secret_key,
&mut std_ggsw,
Cleartext(parameters.ggsw_encrypted_value),
parameters.ggsw_noise,
encryption_random_generator,
);
let mut fourier_ggsw = FourierGgswCiphertext::new(
std_ggsw.glwe_size(),
std_ggsw.polynomial_size(),
std_ggsw.decomposition_base_log(),
std_ggsw.decomposition_level_count(),
);
if use_fft {
convert_standard_ggsw_ciphertext_to_fourier_mem_optimized(
&std_ggsw,
&mut fourier_ggsw,
fft,
computation_buffers.stack(),
);
}
let mut sample_runtime_ns = 0u128;
for _ in 0..sample_size {
let input_plaintext_list =
PlaintextList::new(0u64, PlaintextCount(parameters.polynomial_size.0));
// encryption_random_generator
// .fill_slice_with_random_uniform_mask(input_plaintext_list.as_mut());
// let scaling_to_native_torus = parameters
// .ciphertext_modulus
// .get_power_of_two_scaling_to_native_torus();
// // Shift to match the behavior of the previous concrete-core fixtures
// // Divide as encryption will encode the power of two in the MSBs
// input_plaintext_list.as_mut().iter_mut().for_each(|x| {
// *x = (*x << (<u64 as Numeric>::BITS - parameters.decomposition_base_log.0))
// / scaling_to_native_torus
// });
// Sanity check
if !ciphertext_modulus.is_native_modulus() {
let modulus: u64 = ciphertext_modulus.get_custom_modulus() as u64;
assert!(input_plaintext_list.as_ref().iter().all(|x| *x < modulus));
}
let mut input_glwe_ciphertext = GlweCiphertext::new(
0u64,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
ciphertext_modulus,
);
encrypt_glwe_ciphertext(
&glwe_secret_key,
&mut input_glwe_ciphertext,
&input_plaintext_list,
parameters.glwe_noise,
encryption_random_generator,
);
let mut output_glwe_ciphertext = GlweCiphertext::new(
0u64,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
ciphertext_modulus,
);
let start = std::time::Instant::now();
if use_fft {
add_external_product_assign_mem_optimized(
&mut output_glwe_ciphertext,
&fourier_ggsw,
&input_glwe_ciphertext,
fft,
computation_buffers.stack(),
);
} else {
karatsuba_add_external_product_assign_mem_optimized(
&mut output_glwe_ciphertext,
&std_ggsw,
&input_glwe_ciphertext,
computation_buffers.stack(),
);
}
if !ciphertext_modulus.is_native_modulus() {
// When we convert back from the fourier domain, integer values will contain up to 53
// MSBs with information. In our representation of power of 2 moduli < native modulus we
// fill the MSBs and leave the LSBs empty, this usage of the signed decomposer allows to
// round while keeping the data in the MSBs
let signed_decomposer = SignedDecomposer::new(
DecompositionBaseLog(ciphertext_modulus.get_custom_modulus().ilog2() as usize),
DecompositionLevelCount(1),
);
output_glwe_ciphertext
.as_mut()
.iter_mut()
.for_each(|x| *x = signed_decomposer.closest_representable(*x));
}
let elapsed = start.elapsed().as_nanos();
sample_runtime_ns += elapsed;
let mut output_plaintext_list = input_plaintext_list.clone();
decrypt_glwe_ciphertext(
&glwe_secret_key,
&output_glwe_ciphertext,
&mut output_plaintext_list,
);
// Sanity check
if !ciphertext_modulus.is_native_modulus() {
let modulus: u64 = ciphertext_modulus.get_custom_modulus() as u64;
assert!(output_plaintext_list.as_ref().iter().all(|x| *x < modulus));
}
raw_inputs.push(input_plaintext_list.into_container());
outputs.push(output_plaintext_list.into_container());
}
// No prep time in this case
(sample_runtime_ns, 0)
}
#[allow(clippy::too_many_arguments)]
pub fn classic_pbs_external_product_u128_split(
parameters: &GlweCiphertextGgswCiphertextExternalProductParameters<u128>,
raw_inputs: &mut Vec<Vec<u128>>,
outputs: &mut Vec<Vec<u128>>,
sample_size: usize,
secret_random_generator: &mut SecretRandomGenerator<ActivatedRandomGenerator>,
encryption_random_generator: &mut EncryptionRandomGenerator<ActivatedRandomGenerator>,
fft: Fft128View,
computation_buffers: &mut ComputationBuffers,
) -> (u128, u128) {
let ciphertext_modulus = parameters.ciphertext_modulus;
let glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
parameters.glwe_dimension,
parameters.polynomial_size,
secret_random_generator,
);
let mut std_ggsw = GgswCiphertext::new(
0u128,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
parameters.decomposition_base_log,
parameters.decomposition_level_count,
ciphertext_modulus,
);
encrypt_constant_ggsw_ciphertext(
&glwe_secret_key,
&mut std_ggsw,
Cleartext(parameters.ggsw_encrypted_value),
parameters.ggsw_noise,
encryption_random_generator,
);
let mut fourier_ggsw = Fourier128GgswCiphertext::new(
std_ggsw.glwe_size(),
std_ggsw.polynomial_size(),
std_ggsw.decomposition_base_log(),
std_ggsw.decomposition_level_count(),
);
fourier_ggsw
.as_mut_view()
.fill_with_forward_fourier(&std_ggsw, fft);
let mut sample_runtime_ns = 0u128;
for _ in 0..sample_size {
let mut input_plaintext_list =
PlaintextList::new(0u128, PlaintextCount(parameters.polynomial_size.0));
encryption_random_generator
.fill_slice_with_random_uniform_mask(input_plaintext_list.as_mut());
let scaling_to_native_torus = parameters
.ciphertext_modulus
.get_power_of_two_scaling_to_native_torus();
// Shift to match the behavior of the previous concrete-core fixtures
// Divide as encryption will encode the power of two in the MSBs
input_plaintext_list.as_mut().iter_mut().for_each(|x| {
*x = (*x << (<u128 as Numeric>::BITS - parameters.decomposition_base_log.0))
/ scaling_to_native_torus
});
// Sanity check
if !ciphertext_modulus.is_native_modulus() {
let modulus = ciphertext_modulus.get_custom_modulus();
assert!(input_plaintext_list.as_ref().iter().all(|x| *x < modulus));
}
let mut input_glwe_ciphertext = GlweCiphertext::new(
0u128,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
ciphertext_modulus,
);
encrypt_glwe_ciphertext(
&glwe_secret_key,
&mut input_glwe_ciphertext,
&input_plaintext_list,
parameters.glwe_noise,
encryption_random_generator,
);
let mut output_glwe_ciphertext = GlweCiphertext::new(
0u128,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
ciphertext_modulus,
);
let stack = computation_buffers.stack();
let align = CACHELINE_ALIGN;
let (input_glwe_lo, stack) = stack.collect_aligned(
align,
input_glwe_ciphertext.as_ref().iter().map(|i| *i as u64),
);
let (input_glwe_hi, stack) = stack.collect_aligned(
align,
input_glwe_ciphertext
.as_ref()
.iter()
.map(|i| (*i >> 64) as u64),
);
let input_glwe_lo = GlweCiphertextView::from_container(
&*input_glwe_lo,
input_glwe_ciphertext.polynomial_size(),
// Here we split a u128 to two u64 containers and the ciphertext modulus does not
// match anymore in terms of the underlying Scalar type, so we'll provide a dummy
// native modulus
CiphertextModulus::new_native(),
);
let input_glwe_hi = GlweCiphertextView::from_container(
&*input_glwe_hi,
input_glwe_ciphertext.polynomial_size(),
// Here we split a u128 to two u64 containers and the ciphertext modulus does not
// match anymore in terms of the underlying Scalar type, so we'll provide a dummy
// native modulus
CiphertextModulus::new_native(),
);
let (output_glwe_lo, stack) = stack.collect_aligned(
align,
output_glwe_ciphertext.as_ref().iter().map(|i| *i as u64),
);
let (output_glwe_hi, stack) = stack.collect_aligned(
align,
output_glwe_ciphertext
.as_ref()
.iter()
.map(|i| (*i >> 64) as u64),
);
let mut output_glwe_lo = GlweCiphertextMutView::from_container(
&mut *output_glwe_lo,
output_glwe_ciphertext.polynomial_size(),
// Here we split a u128 to two u64 containers and the ciphertext modulus does not
// match anymore in terms of the underlying Scalar type, so we'll provide a dummy
// native modulus
CiphertextModulus::new_native(),
);
let mut output_glwe_hi = GlweCiphertextMutView::from_container(
&mut *output_glwe_hi,
output_glwe_ciphertext.polynomial_size(),
// Here we split a u128 to two u64 containers and the ciphertext modulus does not
// match anymore in terms of the underlying Scalar type, so we'll provide a dummy
// native modulus
CiphertextModulus::new_native(),
);
let start = std::time::Instant::now();
add_external_product_assign_split(
&mut output_glwe_lo,
&mut output_glwe_hi,
&fourier_ggsw,
&input_glwe_lo,
&input_glwe_hi,
fft,
stack,
);
let elapsed = start.elapsed().as_nanos();
sample_runtime_ns += elapsed;
output_glwe_ciphertext
.as_mut()
.iter_mut()
.zip(
output_glwe_lo
.as_ref()
.iter()
.zip(output_glwe_hi.as_ref().iter()),
)
.for_each(|(out, (&lo, &hi))| *out = lo as u128 | ((hi as u128) << 64));
if !ciphertext_modulus.is_native_modulus() {
// When we convert back from the fourier domain, integer values will contain up to 53
// MSBs with information. In our representation of power of 2 moduli < native modulus we
// fill the MSBs and leave the LSBs empty, this usage of the signed decomposer allows to
// round while keeping the data in the MSBs
let signed_decomposer = SignedDecomposer::new(
DecompositionBaseLog(ciphertext_modulus.get_custom_modulus().ilog2() as usize),
DecompositionLevelCount(1),
);
output_glwe_ciphertext
.as_mut()
.iter_mut()
.for_each(|x| *x = signed_decomposer.closest_representable(*x));
}
let mut output_plaintext_list = input_plaintext_list.clone();
decrypt_glwe_ciphertext(
&glwe_secret_key,
&output_glwe_ciphertext,
&mut output_plaintext_list,
);
// Sanity check
if !ciphertext_modulus.is_native_modulus() {
let modulus = ciphertext_modulus.get_custom_modulus();
assert!(output_plaintext_list.as_ref().iter().all(|x| *x < modulus));
}
raw_inputs.push(input_plaintext_list.into_container());
outputs.push(output_plaintext_list.into_container());
}
// No prep time in this case
(sample_runtime_ns, 0)
}
#[allow(clippy::too_many_arguments)]
pub fn classic_pbs_external_product_u128(
parameters: &GlweCiphertextGgswCiphertextExternalProductParameters<u128>,
raw_inputs: &mut Vec<Vec<u128>>,
outputs: &mut Vec<Vec<u128>>,
sample_size: usize,
secret_random_generator: &mut SecretRandomGenerator<ActivatedRandomGenerator>,
encryption_random_generator: &mut EncryptionRandomGenerator<ActivatedRandomGenerator>,
fft: Fft128View,
computation_buffers: &mut ComputationBuffers,
) -> (u128, u128) {
let ciphertext_modulus = parameters.ciphertext_modulus;
let glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
parameters.glwe_dimension,
parameters.polynomial_size,
secret_random_generator,
);
let mut std_ggsw = GgswCiphertext::new(
0u128,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
parameters.decomposition_base_log,
parameters.decomposition_level_count,
ciphertext_modulus,
);
encrypt_constant_ggsw_ciphertext(
&glwe_secret_key,
&mut std_ggsw,
Cleartext(parameters.ggsw_encrypted_value),
parameters.ggsw_noise,
encryption_random_generator,
);
let mut fourier_ggsw = Fourier128GgswCiphertext::new(
std_ggsw.glwe_size(),
std_ggsw.polynomial_size(),
std_ggsw.decomposition_base_log(),
std_ggsw.decomposition_level_count(),
);
fourier_ggsw
.as_mut_view()
.fill_with_forward_fourier(&std_ggsw, fft);
let mut sample_runtime_ns = 0u128;
for _ in 0..sample_size {
let mut input_plaintext_list =
PlaintextList::new(0u128, PlaintextCount(parameters.polynomial_size.0));
encryption_random_generator
.fill_slice_with_random_uniform_mask(input_plaintext_list.as_mut());
let scaling_to_native_torus = parameters
.ciphertext_modulus
.get_power_of_two_scaling_to_native_torus();
// Shift to match the behavior of the previous concrete-core fixtures
// Divide as encryption will encode the power of two in the MSBs
input_plaintext_list.as_mut().iter_mut().for_each(|x| {
*x = (*x << (<u128 as Numeric>::BITS - parameters.decomposition_base_log.0))
/ scaling_to_native_torus
});
// Sanity check
if !ciphertext_modulus.is_native_modulus() {
let modulus = ciphertext_modulus.get_custom_modulus();
assert!(input_plaintext_list.as_ref().iter().all(|x| *x < modulus));
}
let mut input_glwe_ciphertext = GlweCiphertext::new(
0u128,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
ciphertext_modulus,
);
encrypt_glwe_ciphertext(
&glwe_secret_key,
&mut input_glwe_ciphertext,
&input_plaintext_list,
parameters.glwe_noise,
encryption_random_generator,
);
let mut output_glwe_ciphertext = GlweCiphertext::new(
0u128,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
ciphertext_modulus,
);
let start = std::time::Instant::now();
add_external_product_assign(
&mut output_glwe_ciphertext,
&fourier_ggsw,
&input_glwe_ciphertext,
fft,
computation_buffers.stack(),
);
if !ciphertext_modulus.is_native_modulus() {
// When we convert back from the fourier domain, integer values will contain up to 53
// MSBs with information. In our representation of power of 2 moduli < native modulus we
// fill the MSBs and leave the LSBs empty, this usage of the signed decomposer allows to
// round while keeping the data in the MSBs
let signed_decomposer = SignedDecomposer::new(
DecompositionBaseLog(ciphertext_modulus.get_custom_modulus().ilog2() as usize),
DecompositionLevelCount(1),
);
output_glwe_ciphertext
.as_mut()
.iter_mut()
.for_each(|x| *x = signed_decomposer.closest_representable(*x));
}
let elapsed = start.elapsed().as_nanos();
sample_runtime_ns += elapsed;
let mut output_plaintext_list = input_plaintext_list.clone();
decrypt_glwe_ciphertext(
&glwe_secret_key,
&output_glwe_ciphertext,
&mut output_plaintext_list,
);
// Sanity check
if !ciphertext_modulus.is_native_modulus() {
let modulus = ciphertext_modulus.get_custom_modulus();
assert!(output_plaintext_list.as_ref().iter().all(|x| *x < modulus));
}
raw_inputs.push(input_plaintext_list.into_container());
outputs.push(output_plaintext_list.into_container());
}
// No prep time in this case
(sample_runtime_ns, 0)
}

View File

@@ -1,2 +0,0 @@
pub mod classic_pbs;
pub mod multi_bit_pbs;

View File

@@ -1,393 +0,0 @@
use crate::GlweCiphertextGgswCiphertextExternalProductParameters;
use tfhe::core_crypto::algorithms::polynomial_algorithms;
use tfhe::core_crypto::fft_impl::common::pbs_modulus_switch;
use tfhe::core_crypto::fft_impl::fft64::crypto::ggsw::FourierGgswCiphertext;
use tfhe::core_crypto::fft_impl::fft64::math::fft::FftView;
use tfhe::core_crypto::fft_impl::fft64::math::polynomial::FourierPolynomial;
use tfhe::core_crypto::prelude::{
add_external_product_assign_mem_optimized, allocate_and_generate_new_binary_glwe_secret_key,
allocate_and_generate_new_lwe_multi_bit_bootstrap_key,
convert_standard_lwe_multi_bit_bootstrap_key_to_fourier_mem_optimized, decrypt_glwe_ciphertext,
encrypt_glwe_ciphertext, karatsuba_add_external_product_assign_mem_optimized,
modulus_switch_multi_bit, prepare_multi_bit_ggsw_mem_optimized, std_prepare_multi_bit_ggsw,
ActivatedRandomGenerator, ComputationBuffers, ContiguousEntityContainer,
EncryptionRandomGenerator, FourierLweMultiBitBootstrapKey, GgswCiphertext, GlweCiphertext,
LweBskGroupingFactor, LweSecretKey, MonomialDegree, Numeric, PlaintextCount, PlaintextList,
SecretRandomGenerator,
};
#[allow(clippy::too_many_arguments)]
pub fn multi_bit_pbs_external_product(
parameters: &GlweCiphertextGgswCiphertextExternalProductParameters<u64>,
raw_inputs: &mut Vec<Vec<u64>>,
outputs: &mut Vec<Vec<u64>>,
sample_size: usize,
secret_random_generator: &mut SecretRandomGenerator<ActivatedRandomGenerator>,
encryption_random_generator: &mut EncryptionRandomGenerator<ActivatedRandomGenerator>,
use_fft: bool,
fft: FftView,
computation_buffers: &mut ComputationBuffers,
grouping_factor: LweBskGroupingFactor,
) -> (u128, u128) {
let lwe_sk = LweSecretKey::from_container(vec![1u64; grouping_factor.0]);
let glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
parameters.glwe_dimension,
parameters.polynomial_size,
secret_random_generator,
);
let bsk = allocate_and_generate_new_lwe_multi_bit_bootstrap_key(
&lwe_sk,
&glwe_secret_key,
parameters.decomposition_base_log,
parameters.decomposition_level_count,
grouping_factor,
parameters.ggsw_noise,
parameters.ciphertext_modulus,
encryption_random_generator,
);
let mut fbsk = FourierLweMultiBitBootstrapKey::new(
bsk.input_lwe_dimension(),
bsk.glwe_size(),
bsk.polynomial_size(),
bsk.decomposition_base_log(),
bsk.decomposition_level_count(),
bsk.grouping_factor(),
);
if use_fft {
convert_standard_lwe_multi_bit_bootstrap_key_to_fourier_mem_optimized(
&bsk,
&mut fbsk,
fft,
computation_buffers.stack(),
);
}
let std_ggsw_vec: Vec<_> = bsk.iter().collect();
let ggsw_vec: Vec<_> = fbsk.ggsw_iter().collect();
let grouping_factor = fbsk.grouping_factor();
let ggsw_per_multi_bit_element = grouping_factor.ggsw_per_multi_bit_element();
assert_eq!(ggsw_vec.len(), ggsw_per_multi_bit_element.0);
let mut random_mask = vec![0u64; grouping_factor.0];
encryption_random_generator.fill_slice_with_random_uniform_mask(&mut random_mask);
// Recompute it here to rotate and negate the input or output vector to compute errors that make
// sense, this corresponds to all key bits == 1, which is a worse case on a single ext prod
let equivalent_monomial_degree = MonomialDegree(pbs_modulus_switch(
random_mask.iter().sum::<u64>(),
parameters.polynomial_size,
));
let mut fourier_a_monomial = FourierPolynomial::new(fbsk.polynomial_size());
let mut std_ggsw = GgswCiphertext::new(
0u64,
bsk.glwe_size(),
bsk.polynomial_size(),
bsk.decomposition_base_log(),
bsk.decomposition_level_count(),
bsk.ciphertext_modulus(),
);
let mut tmp_std_ggsw = GgswCiphertext::new(
0u64,
bsk.glwe_size(),
bsk.polynomial_size(),
bsk.decomposition_base_log(),
bsk.decomposition_level_count(),
bsk.ciphertext_modulus(),
);
let mut fourier_ggsw = FourierGgswCiphertext::new(
fbsk.glwe_size(),
fbsk.polynomial_size(),
fbsk.decomposition_base_log(),
fbsk.decomposition_level_count(),
);
let prep_start = std::time::Instant::now();
if use_fft {
prepare_multi_bit_ggsw_mem_optimized(
&mut fourier_ggsw,
&ggsw_vec,
modulus_switch_multi_bit(
fbsk.polynomial_size().to_blind_rotation_input_modulus_log(),
grouping_factor,
&random_mask,
),
&mut fourier_a_monomial,
fft,
);
} else {
std_prepare_multi_bit_ggsw(
&mut std_ggsw,
&mut tmp_std_ggsw,
&std_ggsw_vec,
modulus_switch_multi_bit(
bsk.polynomial_size().to_blind_rotation_input_modulus_log(),
grouping_factor,
&random_mask,
),
);
}
let prep_time_ns = prep_start.elapsed().as_nanos();
let mut sample_runtime_ns = 0u128;
for _ in 0..sample_size {
let input_plaintext_list =
PlaintextList::new(0u64, PlaintextCount(parameters.polynomial_size.0));
// encryption_random_generator
// .fill_slice_with_random_uniform_mask(input_plaintext_list.as_mut());
// // Shift to match the behavior of the previous concrete-core fixtures
// input_plaintext_list
// .as_mut()
// .iter_mut()
// .for_each(|x| *x <<= <u64 as Numeric>::BITS - parameters.decomposition_base_log.0);
let mut input_glwe_ciphertext = GlweCiphertext::new(
0u64,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
parameters.ciphertext_modulus,
);
encrypt_glwe_ciphertext(
&glwe_secret_key,
&mut input_glwe_ciphertext,
&input_plaintext_list,
parameters.glwe_noise,
encryption_random_generator,
);
let mut output_glwe_ciphertext = GlweCiphertext::new(
0u64,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
parameters.ciphertext_modulus,
);
let start = std::time::Instant::now();
if use_fft {
add_external_product_assign_mem_optimized(
&mut output_glwe_ciphertext,
&fourier_ggsw,
&input_glwe_ciphertext,
fft,
computation_buffers.stack(),
);
} else {
karatsuba_add_external_product_assign_mem_optimized(
&mut output_glwe_ciphertext,
&std_ggsw,
&input_glwe_ciphertext,
computation_buffers.stack(),
);
}
let elapsed = start.elapsed().as_nanos();
sample_runtime_ns += elapsed;
let mut output_plaintext_list = input_plaintext_list.clone();
decrypt_glwe_ciphertext(
&glwe_secret_key,
&output_glwe_ciphertext,
&mut output_plaintext_list,
);
let mut output_pt_list_as_polynomial = output_plaintext_list.as_mut_polynomial();
// As we performed a monomial multiplication, we need to apply a monomial div to get outputs
// in the right order
polynomial_algorithms::polynomial_wrapping_monic_monomial_div_assign(
&mut output_pt_list_as_polynomial,
equivalent_monomial_degree,
);
raw_inputs.push(input_plaintext_list.into_container());
outputs.push(output_plaintext_list.into_container());
}
(sample_runtime_ns, prep_time_ns)
}
#[allow(clippy::too_many_arguments)]
pub fn std_multi_bit_pbs_external_product(
parameters: &GlweCiphertextGgswCiphertextExternalProductParameters<u64>,
raw_inputs: &mut Vec<Vec<u64>>,
outputs: &mut Vec<Vec<u64>>,
sample_size: usize,
secret_random_generator: &mut SecretRandomGenerator<ActivatedRandomGenerator>,
encryption_random_generator: &mut EncryptionRandomGenerator<ActivatedRandomGenerator>,
use_fft: bool,
fft: FftView,
computation_buffers: &mut ComputationBuffers,
grouping_factor: LweBskGroupingFactor,
) -> (u128, u128) {
let lwe_sk = LweSecretKey::from_container(vec![1u64; grouping_factor.0]);
let glwe_secret_key = allocate_and_generate_new_binary_glwe_secret_key(
parameters.glwe_dimension,
parameters.polynomial_size,
secret_random_generator,
);
let bsk = allocate_and_generate_new_lwe_multi_bit_bootstrap_key(
&lwe_sk,
&glwe_secret_key,
parameters.decomposition_base_log,
parameters.decomposition_level_count,
grouping_factor,
parameters.ggsw_noise,
parameters.ciphertext_modulus,
encryption_random_generator,
);
let ggsw_vec: Vec<_> = bsk.iter().collect();
let grouping_factor = bsk.grouping_factor();
let ggsw_per_multi_bit_element = grouping_factor.ggsw_per_multi_bit_element();
assert_eq!(ggsw_vec.len(), ggsw_per_multi_bit_element.0);
let mut random_mask = vec![0u64; grouping_factor.0];
encryption_random_generator.fill_slice_with_random_uniform_mask(&mut random_mask);
// Recompute it here to rotate and negate the input or output vector to compute errors that make
// sense
let equivalent_monomial_degree = MonomialDegree(pbs_modulus_switch(
random_mask.iter().sum::<u64>(),
parameters.polynomial_size,
));
let mut fourier_ggsw = FourierGgswCiphertext::new(
bsk.glwe_size(),
bsk.polynomial_size(),
bsk.decomposition_base_log(),
bsk.decomposition_level_count(),
);
let mut std_ggsw = GgswCiphertext::new(
0u64,
bsk.glwe_size(),
bsk.polynomial_size(),
bsk.decomposition_base_log(),
bsk.decomposition_level_count(),
bsk.ciphertext_modulus(),
);
let mut tmp_std_ggsw = GgswCiphertext::new(
0u64,
bsk.glwe_size(),
bsk.polynomial_size(),
bsk.decomposition_base_log(),
bsk.decomposition_level_count(),
bsk.ciphertext_modulus(),
);
let prep_start = std::time::Instant::now();
std_prepare_multi_bit_ggsw(
&mut std_ggsw,
&mut tmp_std_ggsw,
&ggsw_vec,
modulus_switch_multi_bit(
bsk.polynomial_size().to_blind_rotation_input_modulus_log(),
grouping_factor,
&random_mask,
),
);
if use_fft {
fourier_ggsw.as_mut_view().fill_with_forward_fourier(
std_ggsw.as_view(),
fft,
computation_buffers.stack(),
);
}
let prep_time_ns = prep_start.elapsed().as_nanos();
let mut sample_runtime_ns = 0u128;
for _ in 0..sample_size {
let input_plaintext_list =
PlaintextList::new(0u64, PlaintextCount(parameters.polynomial_size.0));
// encryption_random_generator
// .fill_slice_with_random_uniform_mask(input_plaintext_list.as_mut());
// // Shift to match the behavior of the previous concrete-core fixtures
// input_plaintext_list
// .as_mut()
// .iter_mut()
// .for_each(|x| *x <<= <u64 as Numeric>::BITS - parameters.decomposition_base_log.0);
let mut input_glwe_ciphertext = GlweCiphertext::new(
0u64,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
parameters.ciphertext_modulus,
);
encrypt_glwe_ciphertext(
&glwe_secret_key,
&mut input_glwe_ciphertext,
&input_plaintext_list,
parameters.glwe_noise,
encryption_random_generator,
);
let mut output_glwe_ciphertext = GlweCiphertext::new(
0u64,
parameters.glwe_dimension.to_glwe_size(),
parameters.polynomial_size,
parameters.ciphertext_modulus,
);
let start = std::time::Instant::now();
if use_fft {
add_external_product_assign_mem_optimized(
&mut output_glwe_ciphertext,
&fourier_ggsw,
&input_glwe_ciphertext,
fft,
computation_buffers.stack(),
);
} else {
karatsuba_add_external_product_assign_mem_optimized(
&mut output_glwe_ciphertext,
&std_ggsw,
&input_glwe_ciphertext,
computation_buffers.stack(),
);
}
let elapsed = start.elapsed().as_nanos();
sample_runtime_ns += elapsed;
let mut output_plaintext_list = input_plaintext_list.clone();
decrypt_glwe_ciphertext(
&glwe_secret_key,
&output_glwe_ciphertext,
&mut output_plaintext_list,
);
let mut output_pt_list_as_polynomial = output_plaintext_list.as_mut_polynomial();
// As we performed a monomial multiplication, we need to apply a monomial div to get outputs
// in the right order
polynomial_algorithms::polynomial_wrapping_monic_monomial_div_assign(
&mut output_pt_list_as_polynomial,
equivalent_monomial_degree,
);
raw_inputs.push(input_plaintext_list.into_container());
outputs.push(output_plaintext_list.into_container());
}
(sample_runtime_ns, prep_time_ns)
}

View File

@@ -1,3 +0,0 @@
numpy
scipy
scikit-learn

View File

@@ -1,30 +0,0 @@
#!/usr/bin/env gnuplot
GF = 2
SFX = "-tanh" # -tanh
# sort by 4-th column
DATAFILE = "< sort -nk4 log-real-to-pred-".GF.SFX.".dat"
set term pngcairo size 1800,600 linewidth 2
set grid
set xtics 2
do for [nu=9:14] {
do for [k=1:2] {
N = 2**nu
set out "logratio-".GF."-k=".k."-N=".N.SFX.".png"
x0 = y0 = NaN
plot \
DATAFILE u (($2 == N && $3 == k && $5 == 1) ? (y0=$1,x0=$4) : x0):(y0) w lp lt 1 t 'B = 2^1', \
'' u (x0 = NaN):(y0 = NaN) notitle, \
'' u (($2 == N && $3 == k && $5 == 2) ? (y0=$1,x0=$4) : x0):(y0) w lp lt 2 t 'B = 2^2', \
'' u (x0 = NaN):(y0 = NaN) notitle, \
'' u (($2 == N && $3 == k && $5 == 3) ? (y0=$1,x0=$4) : x0):(y0) w lp lt 3 t 'B = 2^3', \
'' u (x0 = NaN):(y0 = NaN) notitle, \
'' u (($2 == N && $3 == k && $5 == 4) ? (y0=$1,x0=$4) : x0):(y0) w lp lt 4 t 'B = 2^4', \
'' u (x0 = NaN):(y0 = NaN) notitle, \
'' u (($2 == N && $3 == k && $5 == 5) ? (y0=$1,x0=$4) : x0):(y0) w lp lt 5 t 'B = 2^5'
}
}

View File

@@ -1,6 +1,6 @@
[package]
name = "tfhe-zk-pok"
version = "0.3.0"
version = "0.3.1"
edition = "2021"
keywords = ["zero", "knowledge", "proof", "vector-commitments"]
homepage = "https://zama.ai/"

View File

@@ -1,8 +1,12 @@
pub mod pke;
pub mod pke_v2;
use std::error::Error;
use std::fmt::Display;
use tfhe_versionable::VersionsDispatch;
use crate::curve_api::{Compressible, Curve};
use crate::proofs::pke::{CompressedProof as PKEv1CompressedProof, Proof as PKEv1Proof};
use crate::proofs::pke_v2::{CompressedProof as PKEv2CompressedProof, Proof as PKEv2Proof};
use crate::curve_api::Curve;
use crate::proofs::GroupElements;
use crate::serialization::{
SerializableAffine, SerializableCubicExtField, SerializableFp, SerializableFp2,
@@ -34,33 +38,20 @@ pub type SerializableG1AffineVersions = SerializableAffineVersions<SerializableF
pub type SerializableG2AffineVersions = SerializableAffineVersions<SerializableFp2>;
pub type SerializableFp12Versions = SerializableQuadExtFieldVersions<SerializableFp6>;
#[derive(VersionsDispatch)]
pub enum PKEv1ProofVersions<G: Curve> {
V0(PKEv1Proof<G>),
/// The proof was missing some elements
#[derive(Debug)]
pub struct IncompleteProof;
impl Display for IncompleteProof {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"incomplete serialized ZK proof, missing some pre-computed elements"
)
}
}
#[derive(VersionsDispatch)]
pub enum PKEv2ProofVersions<G: Curve> {
V0(PKEv2Proof<G>),
}
#[derive(VersionsDispatch)]
pub enum PKEv1CompressedProofVersions<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
V0(PKEv1CompressedProof<G>),
}
#[derive(VersionsDispatch)]
pub enum PKEv2CompressedProofVersions<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
V0(PKEv2CompressedProof<G>),
}
impl Error for IncompleteProof {}
#[derive(VersionsDispatch)]
#[allow(dead_code)]

View File

@@ -0,0 +1,117 @@
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};
use crate::curve_api::{CompressedG1, CompressedG2, Compressible, Curve};
use crate::proofs::pke::{
CompressedComputeLoadProofFields, CompressedProof, ComputeLoadProofFields, Proof,
};
use super::IncompleteProof;
#[derive(Version)]
pub struct ProofV0<G: Curve> {
c_hat: G::G2,
c_y: G::G1,
pi: G::G1,
c_hat_t: Option<G::G2>,
c_h: Option<G::G1>,
pi_kzg: Option<G::G1>,
}
impl<G: Curve> Upgrade<Proof<G>> for ProofV0<G> {
type Error = IncompleteProof;
fn upgrade(self) -> Result<Proof<G>, Self::Error> {
let compute_load_proof_fields = match (self.c_hat_t, self.c_h, self.pi_kzg) {
(None, None, None) => None,
(Some(c_hat_t), Some(c_h), Some(pi_kzg)) => Some(ComputeLoadProofFields {
c_hat_t,
c_h,
pi_kzg,
}),
_ => {
return Err(IncompleteProof);
}
};
Ok(Proof {
c_hat: self.c_hat,
c_y: self.c_y,
pi: self.pi,
compute_load_proof_fields,
})
}
}
#[derive(VersionsDispatch)]
pub enum ProofVersions<G: Curve> {
V0(ProofV0<G>),
V1(Proof<G>),
}
#[derive(VersionsDispatch)]
#[allow(dead_code)]
pub(crate) enum ComputeLoadProofFieldVersions<G: Curve> {
V0(ComputeLoadProofFields<G>),
}
pub struct CompressedProofV0<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
c_hat: CompressedG2<G>,
c_y: CompressedG1<G>,
pi: CompressedG1<G>,
c_hat_t: Option<CompressedG2<G>>,
c_h: Option<CompressedG1<G>>,
pi_kzg: Option<CompressedG1<G>>,
}
impl<G: Curve> Upgrade<CompressedProof<G>> for CompressedProofV0<G>
where
G::G1: Compressible,
G::G2: Compressible,
{
type Error = IncompleteProof;
fn upgrade(self) -> Result<CompressedProof<G>, Self::Error> {
let compute_load_proof_fields = match (self.c_hat_t, self.c_h, self.pi_kzg) {
(None, None, None) => None,
(Some(c_hat_t), Some(c_h), Some(pi_kzg)) => Some(CompressedComputeLoadProofFields {
c_hat_t,
c_h,
pi_kzg,
}),
_ => {
return Err(IncompleteProof);
}
};
Ok(CompressedProof {
c_hat: self.c_hat,
c_y: self.c_y,
pi: self.pi,
compute_load_proof_fields,
})
}
}
#[derive(VersionsDispatch)]
pub enum CompressedProofVersions<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
V0(CompressedProofV0<G>),
V1(CompressedProof<G>),
}
#[derive(VersionsDispatch)]
#[allow(dead_code)]
pub(crate) enum CompressedComputeLoadProofFieldsVersions<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
V0(CompressedComputeLoadProofFields<G>),
}

View File

@@ -0,0 +1,142 @@
// to follow the notation of the paper
#![allow(non_snake_case)]
use tfhe_versionable::{Upgrade, Version, VersionsDispatch};
use crate::curve_api::{CompressedG1, CompressedG2, Compressible, Curve};
use crate::proofs::pke_v2::{
CompressedComputeLoadProofFields, CompressedProof, ComputeLoadProofFields, Proof,
};
use super::IncompleteProof;
#[derive(Version)]
pub struct ProofV0<G: Curve> {
C_hat_e: G::G2,
C_e: G::G1,
C_r_tilde: G::G1,
C_R: G::G1,
C_hat_bin: G::G2,
C_y: G::G1,
C_h1: G::G1,
C_h2: G::G1,
C_hat_t: G::G2,
pi: G::G1,
pi_kzg: G::G1,
C_hat_h3: Option<G::G2>,
C_hat_w: Option<G::G2>,
}
impl<G: Curve> Upgrade<Proof<G>> for ProofV0<G> {
type Error = IncompleteProof;
fn upgrade(self) -> Result<Proof<G>, Self::Error> {
let compute_load_proof_fields = match (self.C_hat_h3, self.C_hat_w) {
(None, None) => None,
(Some(C_hat_h3), Some(C_hat_w)) => Some(ComputeLoadProofFields { C_hat_h3, C_hat_w }),
_ => return Err(IncompleteProof),
};
Ok(Proof {
C_hat_e: self.C_hat_e,
C_e: self.C_e,
C_r_tilde: self.C_r_tilde,
C_R: self.C_R,
C_hat_bin: self.C_hat_bin,
C_y: self.C_y,
C_h1: self.C_h1,
C_h2: self.C_h2,
C_hat_t: self.C_hat_t,
pi: self.pi,
pi_kzg: self.pi_kzg,
compute_load_proof_fields,
})
}
}
#[derive(VersionsDispatch)]
pub enum ProofVersions<G: Curve> {
V0(ProofV0<G>),
V1(Proof<G>),
}
#[derive(VersionsDispatch)]
#[allow(dead_code)]
pub(crate) enum ComputeLoadProofFieldVersions<G: Curve> {
V0(ComputeLoadProofFields<G>),
}
pub struct CompressedProofV0<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
C_hat_e: CompressedG2<G>,
C_e: CompressedG1<G>,
C_r_tilde: CompressedG1<G>,
C_R: CompressedG1<G>,
C_hat_bin: CompressedG2<G>,
C_y: CompressedG1<G>,
C_h1: CompressedG1<G>,
C_h2: CompressedG1<G>,
C_hat_t: CompressedG2<G>,
pi: CompressedG1<G>,
pi_kzg: CompressedG1<G>,
C_hat_h3: Option<CompressedG2<G>>,
C_hat_w: Option<CompressedG2<G>>,
}
impl<G: Curve> Upgrade<CompressedProof<G>> for CompressedProofV0<G>
where
G::G1: Compressible,
G::G2: Compressible,
{
type Error = IncompleteProof;
fn upgrade(self) -> Result<CompressedProof<G>, Self::Error> {
let compute_load_proof_fields = match (self.C_hat_h3, self.C_hat_w) {
(None, None) => None,
(Some(C_hat_h3), Some(C_hat_w)) => {
Some(CompressedComputeLoadProofFields { C_hat_h3, C_hat_w })
}
_ => return Err(IncompleteProof),
};
Ok(CompressedProof {
C_hat_e: self.C_hat_e,
C_e: self.C_e,
C_r_tilde: self.C_r_tilde,
C_R: self.C_R,
C_hat_bin: self.C_hat_bin,
C_y: self.C_y,
C_h1: self.C_h1,
C_h2: self.C_h2,
C_hat_t: self.C_hat_t,
pi: self.pi,
pi_kzg: self.pi_kzg,
compute_load_proof_fields,
})
}
}
#[derive(VersionsDispatch)]
pub enum CompressedProofVersions<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
V0(CompressedProofV0<G>),
V1(CompressedProof<G>),
}
#[derive(VersionsDispatch)]
#[allow(dead_code)]
pub(crate) enum CompressedComputeLoadProofFieldsVersions<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
V0(CompressedComputeLoadProofFields<G>),
}

View File

@@ -128,6 +128,9 @@ pub trait Compressible: Sized {
fn uncompress(compressed: Self::Compressed) -> Result<Self, Self::UncompressError>;
}
pub type CompressedG1<G> = <<G as Curve>::G1 as Compressible>::Compressed;
pub type CompressedG2<G> = <<G as Curve>::G2 as Compressible>::Compressed;
pub trait PairingGroupOps<Zp, G1, G2>:
Copy
+ Send

View File

@@ -1,6 +1,9 @@
// TODO: refactor copy-pasted code in proof/verify
use crate::backward_compatibility::{PKEv1CompressedProofVersions, PKEv1ProofVersions};
use crate::backward_compatibility::pke::{
CompressedComputeLoadProofFieldsVersions, CompressedProofVersions,
ComputeLoadProofFieldVersions, ProofVersions,
};
use crate::serialization::{
try_vec_to_array, InvalidSerializedAffineError, InvalidSerializedPublicParamsError,
SerializableGroupElements, SerializablePKEv1PublicParams,
@@ -186,14 +189,26 @@ impl<G: Curve> PublicParams<G> {
deserialize = "G: Curve, G::G1: serde::Deserialize<'de>, G::G2: serde::Deserialize<'de>",
serialize = "G: Curve, G::G1: serde::Serialize, G::G2: serde::Serialize"
))]
#[versionize(PKEv1ProofVersions)]
#[versionize(ProofVersions)]
pub struct Proof<G: Curve> {
c_hat: G::G2,
c_y: G::G1,
pi: G::G1,
c_hat_t: Option<G::G2>,
c_h: Option<G::G1>,
pi_kzg: Option<G::G1>,
pub(crate) c_hat: G::G2,
pub(crate) c_y: G::G1,
pub(crate) pi: G::G1,
pub(crate) compute_load_proof_fields: Option<ComputeLoadProofFields<G>>,
}
/// These fields can be pre-computed on the prover side in the faster Verifier scheme. If that's the
/// case, they should be included in the proof.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, Versionize)]
#[serde(bound(
deserialize = "G: Curve, G::G1: serde::Deserialize<'de>, G::G2: serde::Deserialize<'de>",
serialize = "G: Curve, G::G1: serde::Serialize, G::G2: serde::Serialize"
))]
#[versionize(ComputeLoadProofFieldVersions)]
pub(crate) struct ComputeLoadProofFields<G: Curve> {
pub(crate) c_hat_t: G::G2,
pub(crate) c_h: G::G1,
pub(crate) pi_kzg: G::G1,
}
type CompressedG2<G> = <<G as Curve>::G2 as Compressible>::Compressed;
@@ -204,18 +219,32 @@ type CompressedG1<G> = <<G as Curve>::G1 as Compressible>::Compressed;
deserialize = "G: Curve, CompressedG1<G>: serde::Deserialize<'de>, CompressedG2<G>: serde::Deserialize<'de>",
serialize = "G: Curve, CompressedG1<G>: serde::Serialize, CompressedG2<G>: serde::Serialize"
))]
#[versionize(PKEv1CompressedProofVersions)]
#[versionize(CompressedProofVersions)]
pub struct CompressedProof<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
c_hat: CompressedG2<G>,
c_y: CompressedG1<G>,
pi: CompressedG1<G>,
c_hat_t: Option<CompressedG2<G>>,
c_h: Option<CompressedG1<G>>,
pi_kzg: Option<CompressedG1<G>>,
pub(crate) c_hat: CompressedG2<G>,
pub(crate) c_y: CompressedG1<G>,
pub(crate) pi: CompressedG1<G>,
pub(crate) compute_load_proof_fields: Option<CompressedComputeLoadProofFields<G>>,
}
#[derive(Serialize, Deserialize, Versionize)]
#[serde(bound(
deserialize = "G: Curve, CompressedG1<G>: serde::Deserialize<'de>, CompressedG2<G>: serde::Deserialize<'de>",
serialize = "G: Curve, CompressedG1<G>: serde::Serialize, CompressedG2<G>: serde::Serialize"
))]
#[versionize(CompressedComputeLoadProofFieldsVersions)]
pub(crate) struct CompressedComputeLoadProofFields<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
pub(crate) c_hat_t: CompressedG2<G>,
pub(crate) c_h: CompressedG1<G>,
pub(crate) pi_kzg: CompressedG1<G>,
}
impl<G: Curve> Compressible for Proof<G>
@@ -232,18 +261,24 @@ where
c_hat,
c_y,
pi,
c_hat_t,
c_h,
pi_kzg,
compute_load_proof_fields,
} = self;
CompressedProof {
c_hat: c_hat.compress(),
c_y: c_y.compress(),
pi: pi.compress(),
c_hat_t: c_hat_t.map(|val| val.compress()),
c_h: c_h.map(|val| val.compress()),
pi_kzg: pi_kzg.map(|val| val.compress()),
compute_load_proof_fields: compute_load_proof_fields.as_ref().map(
|ComputeLoadProofFields {
c_hat_t,
c_h,
pi_kzg,
}| CompressedComputeLoadProofFields {
c_hat_t: c_hat_t.compress(),
c_h: c_h.compress(),
pi_kzg: pi_kzg.compress(),
},
),
}
}
@@ -252,28 +287,29 @@ where
c_hat,
c_y,
pi,
c_hat_t,
c_h,
pi_kzg,
compute_load_proof_fields,
} = compressed;
Ok(Proof {
c_hat: G::G2::uncompress(c_hat)?,
c_y: G::G1::uncompress(c_y)?,
pi: G::G1::uncompress(pi)?,
c_hat_t: c_hat_t.map(G::G2::uncompress).transpose()?,
c_h: c_h.map(G::G1::uncompress).transpose()?,
pi_kzg: pi_kzg.map(G::G1::uncompress).transpose()?,
})
}
}
impl<G: Curve> Proof<G> {
pub fn content_is_usable(&self) -> bool {
matches!(
(self.c_hat_t, self.c_h, self.pi_kzg),
(None, None, None) | (Some(_), Some(_), Some(_))
)
compute_load_proof_fields: if let Some(CompressedComputeLoadProofFields {
c_hat_t,
c_h,
pi_kzg,
}) = compute_load_proof_fields
{
Some(ComputeLoadProofFields {
c_hat_t: G::G2::uncompress(c_hat_t)?,
c_h: G::G1::uncompress(c_h)?,
pi_kzg: G::G1::uncompress(pi_kzg)?,
})
} else {
None
},
})
}
}
@@ -546,7 +582,7 @@ pub fn prove<G: Curve>(
let x_bytes = &*[
q.to_le_bytes().as_slice(),
d.to_le_bytes().as_slice(),
(d as u64).to_le_bytes().as_slice(),
b_i.to_le_bytes().as_slice(),
t.to_le_bytes().as_slice(),
msbs_zero_padding_bit_count.to_le_bytes().as_slice(),
@@ -793,18 +829,18 @@ pub fn prove<G: Curve>(
c_hat,
c_y,
pi,
c_hat_t: Some(c_hat_t),
c_h: Some(c_h),
pi_kzg: Some(pi_kzg),
compute_load_proof_fields: Some(ComputeLoadProofFields {
c_hat_t,
c_h,
pi_kzg,
}),
}
} else {
Proof {
c_hat,
c_y,
pi,
c_hat_t: None,
c_h: None,
pi_kzg: None,
compute_load_proof_fields: None,
}
}
}
@@ -939,10 +975,9 @@ pub fn verify<G: Curve>(
c_hat,
c_y,
pi,
c_hat_t,
c_h,
pi_kzg,
ref compute_load_proof_fields,
} = proof;
let e = G::Gt::pairing;
let &PublicParams {
@@ -992,7 +1027,7 @@ pub fn verify<G: Curve>(
let x_bytes = &*[
q.to_le_bytes().as_slice(),
d.to_le_bytes().as_slice(),
(d as u64).to_le_bytes().as_slice(),
b_i.to_le_bytes().as_slice(),
t.to_le_bytes().as_slice(),
msbs_zero_padding_bit_count.to_le_bytes().as_slice(),
@@ -1081,7 +1116,12 @@ pub fn verify<G: Curve>(
let [delta_eq, delta_y] = delta;
let delta = [delta_eq, delta_y, delta_theta];
if let (Some(pi_kzg), Some(c_hat_t), Some(c_h)) = (pi_kzg, c_hat_t, c_h) {
if let Some(&ComputeLoadProofFields {
c_hat_t,
c_h,
pi_kzg,
}) = compute_load_proof_fields.as_ref()
{
let mut z = G::Zp::ZERO;
G::Zp::hash(
core::array::from_mut(&mut z),

View File

@@ -2,7 +2,8 @@
#![allow(non_snake_case)]
use super::*;
use crate::backward_compatibility::{PKEv2CompressedProofVersions, PKEv2ProofVersions};
use crate::backward_compatibility::pke_v2::{CompressedProofVersions, ProofVersions};
use crate::curve_api::{CompressedG1, CompressedG2};
use crate::four_squares::*;
use crate::serialization::{
try_vec_to_array, InvalidSerializedAffineError, InvalidSerializedPublicParamsError,
@@ -229,52 +230,69 @@ impl<G: Curve> PublicParams<G> {
deserialize = "G: Curve, G::G1: serde::Deserialize<'de>, G::G2: serde::Deserialize<'de>",
serialize = "G: Curve, G::G1: serde::Serialize, G::G2: serde::Serialize"
))]
#[versionize(PKEv2ProofVersions)]
#[versionize(ProofVersions)]
pub struct Proof<G: Curve> {
C_hat_e: G::G2,
C_e: G::G1,
C_r_tilde: G::G1,
C_R: G::G1,
C_hat_bin: G::G2,
C_y: G::G1,
C_h1: G::G1,
C_h2: G::G1,
C_hat_t: G::G2,
pi: G::G1,
pi_kzg: G::G1,
pub(crate) C_hat_e: G::G2,
pub(crate) C_e: G::G1,
pub(crate) C_r_tilde: G::G1,
pub(crate) C_R: G::G1,
pub(crate) C_hat_bin: G::G2,
pub(crate) C_y: G::G1,
pub(crate) C_h1: G::G1,
pub(crate) C_h2: G::G1,
pub(crate) C_hat_t: G::G2,
pub(crate) pi: G::G1,
pub(crate) pi_kzg: G::G1,
C_hat_h3: Option<G::G2>,
C_hat_w: Option<G::G2>,
pub(crate) compute_load_proof_fields: Option<ComputeLoadProofFields<G>>,
}
type CompressedG2<G> = <<G as Curve>::G2 as Compressible>::Compressed;
type CompressedG1<G> = <<G as Curve>::G1 as Compressible>::Compressed;
/// These fields can be pre-computed on the prover side in the faster Verifier scheme. If that's the
/// case, they should be included in the proof.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub(crate) struct ComputeLoadProofFields<G: Curve> {
pub(crate) C_hat_h3: G::G2,
pub(crate) C_hat_w: G::G2,
}
#[derive(Serialize, Deserialize, Versionize)]
#[serde(bound(
deserialize = "G: Curve, CompressedG1<G>: serde::Deserialize<'de>, CompressedG2<G>: serde::Deserialize<'de>",
serialize = "G: Curve, CompressedG1<G>: serde::Serialize, CompressedG2<G>: serde::Serialize"
))]
#[versionize(PKEv2CompressedProofVersions)]
#[versionize(CompressedProofVersions)]
pub struct CompressedProof<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
C_hat_e: CompressedG2<G>,
C_e: CompressedG1<G>,
C_r_tilde: CompressedG1<G>,
C_R: CompressedG1<G>,
C_hat_bin: CompressedG2<G>,
C_y: CompressedG1<G>,
C_h1: CompressedG1<G>,
C_h2: CompressedG1<G>,
C_hat_t: CompressedG2<G>,
pi: CompressedG1<G>,
pi_kzg: CompressedG1<G>,
pub(crate) C_hat_e: CompressedG2<G>,
pub(crate) C_e: CompressedG1<G>,
pub(crate) C_r_tilde: CompressedG1<G>,
pub(crate) C_R: CompressedG1<G>,
pub(crate) C_hat_bin: CompressedG2<G>,
pub(crate) C_y: CompressedG1<G>,
pub(crate) C_h1: CompressedG1<G>,
pub(crate) C_h2: CompressedG1<G>,
pub(crate) C_hat_t: CompressedG2<G>,
pub(crate) pi: CompressedG1<G>,
pub(crate) pi_kzg: CompressedG1<G>,
C_hat_h3: Option<CompressedG2<G>>,
C_hat_w: Option<CompressedG2<G>>,
pub(crate) compute_load_proof_fields: Option<CompressedComputeLoadProofFields<G>>,
}
#[derive(Serialize, Deserialize)]
#[serde(bound(
deserialize = "G: Curve, CompressedG1<G>: serde::Deserialize<'de>, CompressedG2<G>: serde::Deserialize<'de>",
serialize = "G: Curve, CompressedG1<G>: serde::Serialize, CompressedG2<G>: serde::Serialize"
))]
pub(crate) struct CompressedComputeLoadProofFields<G: Curve>
where
G::G1: Compressible,
G::G2: Compressible,
{
pub(crate) C_hat_h3: CompressedG2<G>,
pub(crate) C_hat_w: CompressedG2<G>,
}
impl<G: Curve> Compressible for Proof<G>
@@ -299,8 +317,7 @@ where
C_hat_t,
pi,
pi_kzg,
C_hat_h3,
C_hat_w,
compute_load_proof_fields,
} = self;
CompressedProof {
@@ -315,8 +332,13 @@ where
C_hat_t: C_hat_t.compress(),
pi: pi.compress(),
pi_kzg: pi_kzg.compress(),
C_hat_h3: C_hat_h3.map(|val| val.compress()),
C_hat_w: C_hat_w.map(|val| val.compress()),
compute_load_proof_fields: compute_load_proof_fields.as_ref().map(
|ComputeLoadProofFields { C_hat_h3, C_hat_w }| CompressedComputeLoadProofFields {
C_hat_h3: C_hat_h3.compress(),
C_hat_w: C_hat_w.compress(),
},
),
}
}
@@ -333,8 +355,7 @@ where
C_hat_t,
pi,
pi_kzg,
C_hat_h3,
C_hat_w,
compute_load_proof_fields,
} = compressed;
Ok(Proof {
@@ -349,8 +370,19 @@ where
C_hat_t: G::G2::uncompress(C_hat_t)?,
pi: G::G1::uncompress(pi)?,
pi_kzg: G::G1::uncompress(pi_kzg)?,
C_hat_h3: C_hat_h3.map(G::G2::uncompress).transpose()?,
C_hat_w: C_hat_w.map(G::G2::uncompress).transpose()?,
compute_load_proof_fields: if let Some(CompressedComputeLoadProofFields {
C_hat_h3,
C_hat_w,
}) = compute_load_proof_fields
{
Some(ComputeLoadProofFields {
C_hat_h3: G::G2::uncompress(C_hat_h3)?,
C_hat_w: G::G2::uncompress(C_hat_w)?,
})
} else {
None
},
})
}
}
@@ -775,7 +807,7 @@ pub fn prove<G: Curve>(
let x_bytes = &*[
q.to_le_bytes().as_slice(),
d.to_le_bytes().as_slice(),
(d as u64).to_le_bytes().as_slice(),
B.to_le_bytes().as_slice(),
t_input.to_le_bytes().as_slice(),
msbs_zero_padding_bit_count.to_le_bytes().as_slice(),
@@ -1383,42 +1415,50 @@ pub fn prove<G: Curve>(
.collect::<Box<[_]>>();
scalars.reverse();
let C_h2 = G::G1::multi_mul_scalar(&g_list[..n], &scalars);
let (C_hat_h3, C_hat_w) = match load {
ComputeLoad::Proof => rayon::join(
|| {
Some(G::G2::multi_mul_scalar(
&g_hat_list[n - (d + k)..n],
&(0..d + k)
.rev()
.map(|j| {
let mut acc = G::Zp::ZERO;
for (i, &phi) in phi.iter().enumerate() {
match R(i, d + k + 4 + j) {
0 => {}
1 => acc += phi,
-1 => acc -= phi,
_ => unreachable!(),
let compute_load_proof_fields = match load {
ComputeLoad::Proof => {
let (C_hat_h3, C_hat_w) = rayon::join(
|| {
G::G2::multi_mul_scalar(
&g_hat_list[n - (d + k)..n],
&(0..d + k)
.rev()
.map(|j| {
let mut acc = G::Zp::ZERO;
for (i, &phi) in phi.iter().enumerate() {
match R(i, d + k + 4 + j) {
0 => {}
1 => acc += phi,
-1 => acc -= phi,
_ => unreachable!(),
}
}
}
delta_r * acc - delta_theta_q * theta[j]
})
.collect::<Box<[_]>>(),
))
},
|| {
Some(G::G2::multi_mul_scalar(
&g_hat_list[..d + k + 4],
&w[..d + k + 4],
))
},
),
ComputeLoad::Verify => (None, None),
delta_r * acc - delta_theta_q * theta[j]
})
.collect::<Box<[_]>>(),
)
},
|| G::G2::multi_mul_scalar(&g_hat_list[..d + k + 4], &w[..d + k + 4]),
);
Some(ComputeLoadProofFields { C_hat_h3, C_hat_w })
}
ComputeLoad::Verify => None,
};
let C_hat_h3_bytes = C_hat_h3.map(G::G2::to_le_bytes);
let C_hat_w_bytes = C_hat_w.map(G::G2::to_le_bytes);
let C_hat_h3_bytes = C_hat_h3_bytes.as_ref().map(|x| x.as_ref()).unwrap_or(&[]);
let C_hat_w_bytes = C_hat_w_bytes.as_ref().map(|x| x.as_ref()).unwrap_or(&[]);
let byte_generators =
if let Some(ComputeLoadProofFields { C_hat_h3, C_hat_w }) = compute_load_proof_fields {
Some((G::G2::to_le_bytes(C_hat_h3), G::G2::to_le_bytes(C_hat_w)))
} else {
None
};
let (C_hat_h3_bytes, C_hat_w_bytes): (&[u8], &[u8]) =
if let Some((C_hat_h3_bytes_owner, C_hat_w_bytes_owner)) = byte_generators.as_ref() {
(C_hat_h3_bytes_owner.as_ref(), C_hat_w_bytes_owner.as_ref())
} else {
(&[], &[])
};
let C_hat_t = G::G2::multi_mul_scalar(g_hat_list, &t);
@@ -1622,10 +1662,9 @@ pub fn prove<G: Curve>(
C_h1,
C_h2,
C_hat_t,
C_hat_h3,
C_hat_w,
pi,
pi_kzg,
compute_load_proof_fields,
}
}
@@ -1747,11 +1786,11 @@ pub fn verify<G: Curve>(
C_h1,
C_h2,
C_hat_t,
C_hat_h3,
C_hat_w,
pi,
pi_kzg,
ref compute_load_proof_fields,
} = proof;
let pairing = G::Gt::pairing;
let &PublicParams {
@@ -1803,14 +1842,24 @@ pub fn verify<G: Curve>(
return Err(());
}
let C_hat_h3_bytes = C_hat_h3.map(G::G2::to_le_bytes);
let C_hat_w_bytes = C_hat_w.map(G::G2::to_le_bytes);
let C_hat_h3_bytes = C_hat_h3_bytes.as_ref().map(|x| x.as_ref()).unwrap_or(&[]);
let C_hat_w_bytes = C_hat_w_bytes.as_ref().map(|x| x.as_ref()).unwrap_or(&[]);
let byte_generators = if let Some(&ComputeLoadProofFields { C_hat_h3, C_hat_w }) =
compute_load_proof_fields.as_ref()
{
Some((G::G2::to_le_bytes(C_hat_h3), G::G2::to_le_bytes(C_hat_w)))
} else {
None
};
let (C_hat_h3_bytes, C_hat_w_bytes): (&[u8], &[u8]) =
if let Some((C_hat_h3_bytes_owner, C_hat_w_bytes_owner)) = byte_generators.as_ref() {
(C_hat_h3_bytes_owner.as_ref(), C_hat_w_bytes_owner.as_ref())
} else {
(&[], &[])
};
let x_bytes = &*[
q.to_le_bytes().as_slice(),
d.to_le_bytes().as_slice(),
(d as u64).to_le_bytes().as_slice(),
B.to_le_bytes().as_slice(),
t_input.to_le_bytes().as_slice(),
msbs_zero_padding_bit_count.to_le_bytes().as_slice(),
@@ -2059,8 +2108,11 @@ pub fn verify<G: Curve>(
let lhs2 = pairing(
C_r_tilde,
match C_hat_h3 {
Some(C_hat_h3) => C_hat_h3,
match compute_load_proof_fields.as_ref() {
Some(&ComputeLoadProofFields {
C_hat_h3,
C_hat_w: _,
}) => C_hat_h3,
None => G::G2::multi_mul_scalar(
&g_hat_list[n - (d + k)..n],
&(0..d + k)
@@ -2093,8 +2145,11 @@ pub fn verify<G: Curve>(
);
let lhs4 = pairing(
C_e.mul_scalar(delta_e),
match C_hat_w {
Some(C_hat_w) => C_hat_w,
match compute_load_proof_fields.as_ref() {
Some(&ComputeLoadProofFields {
C_hat_h3: _,
C_hat_w,
}) => C_hat_w,
None => G::G2::multi_mul_scalar(&g_hat_list[..d + k + 4], &w[..d + k + 4]),
},
);
@@ -2140,7 +2195,7 @@ pub fn verify<G: Curve>(
],
);
let load = if C_hat_h3.is_some() && C_hat_w.is_some() {
let load = if compute_load_proof_fields.is_some() {
ComputeLoad::Proof
} else {
ComputeLoad::Verify
@@ -2293,10 +2348,8 @@ pub fn verify<G: Curve>(
g,
{
let mut C_hat = C_hat_t.mul_scalar(chi2);
if let Some(C_hat_h3) = C_hat_h3 {
if let Some(ComputeLoadProofFields { C_hat_h3, C_hat_w }) = compute_load_proof_fields {
C_hat += C_hat_h3.mul_scalar(chi3);
}
if let Some(C_hat_w) = C_hat_w {
C_hat += C_hat_w.mul_scalar(chi4);
}
C_hat
@@ -2573,7 +2626,7 @@ mod tests {
rng,
);
let compressed_proof = bincode::serialize(&proof.clone().compress()).unwrap();
let compressed_proof = bincode::serialize(&proof.compress()).unwrap();
let proof =
Proof::uncompress(bincode::deserialize(&compressed_proof).unwrap()).unwrap();

View File

@@ -225,7 +225,7 @@ pub fn prove<G: Curve>(
core::slice::from_mut(s),
&[
hash_s,
&i.to_le_bytes(),
&(i as u64).to_le_bytes(),
v_hat.to_le_bytes().as_ref(),
c_hat.to_le_bytes().as_ref(),
c_y.to_le_bytes().as_ref(),
@@ -336,7 +336,7 @@ pub fn verify<G: Curve>(
core::slice::from_mut(s),
&[
hash_s,
&i.to_le_bytes(),
&(i as u64).to_le_bytes(),
v_hat.to_le_bytes().as_ref(),
c_hat.to_le_bytes().as_ref(),
c_y.to_le_bytes().as_ref(),

View File

@@ -81,9 +81,14 @@ pub struct Proof<G: Curve> {
c_hat: G::G2,
c_y: G::G1,
pi: G::G1,
c_hat_t: Option<G::G2>,
c_h: Option<G::G1>,
pi_kzg: Option<G::G1>,
compute_load_proof_fields: Option<ComputeLoadProofFields<G>>,
}
#[derive(Clone, Debug)]
struct ComputeLoadProofFields<G: Curve> {
c_hat_t: G::G2,
c_h: G::G1,
pi_kzg: G::G1,
}
pub fn crs_gen<G: Curve>(
@@ -594,18 +599,18 @@ pub fn prove<G: Curve>(
c_hat,
c_y,
pi,
c_hat_t: Some(c_hat_t),
c_h: Some(c_h),
pi_kzg: Some(pi_kzg),
compute_load_proof_fields: Some(ComputeLoadProofFields {
c_hat_t,
c_h,
pi_kzg,
}),
}
} else {
Proof {
c_hat,
c_y,
pi,
c_hat_t: None,
c_h: None,
pi_kzg: None,
compute_load_proof_fields: None,
}
}
}
@@ -619,10 +624,9 @@ pub fn verify<G: Curve>(
c_hat,
c_y,
pi,
c_hat_t,
c_h,
pi_kzg,
ref compute_load_proof_fields,
} = proof;
let e = G::Gt::pairing;
let &PublicParams {
@@ -785,7 +789,12 @@ pub fn verify<G: Curve>(
}
}
if let (Some(pi_kzg), Some(c_hat_t), Some(c_h)) = (pi_kzg, c_hat_t, c_h) {
if let Some(&ComputeLoadProofFields {
c_hat_t,
c_h,
pi_kzg,
}) = compute_load_proof_fields.as_ref()
{
let mut z = G::Zp::ZERO;
G::Zp::hash(
core::array::from_mut(&mut z),

View File

@@ -1,6 +1,6 @@
[package]
name = "tfhe"
version = "0.9.0"
version = "0.10.0"
edition = "2021"
readme = "../README.md"
keywords = ["fully", "homomorphic", "encryption", "fhe", "cryptography"]
@@ -46,7 +46,7 @@ hex = "0.4.3"
# End regex-engine deps
# Used for backward compatibility test metadata
ron = "0.8"
tfhe-backward-compat-data = { git = "https://github.com/zama-ai/tfhe-backward-compat-data.git", branch = "v0.3", default-features = false, features = [
tfhe-backward-compat-data = { git = "https://github.com/zama-ai/tfhe-backward-compat-data.git", branch = "v0.4", default-features = false, features = [
"load",
] }
@@ -65,7 +65,7 @@ bincode = "1.3.3"
concrete-fft = { version = "0.5.1", features = ["serde", "fft128"] }
concrete-ntt = { version = "0.2.0" }
pulp = "0.18.22"
tfhe-cuda-backend = { version = "0.5.0", path = "../backends/tfhe-cuda-backend", optional = true }
tfhe-cuda-backend = { version = "0.6.0", path = "../backends/tfhe-cuda-backend", optional = true }
aligned-vec = { version = "0.5", features = ["serde"] }
dyn-stack = { version = "0.10" }
paste = "1.0.7"
@@ -75,7 +75,7 @@ sha3 = { version = "0.10", optional = true }
# While we wait for repeat_n in rust standard library
itertools = "0.11.0"
rand_core = { version = "0.6.4", features = ["std"] }
tfhe-zk-pok = { version = "0.3.0", path = "../tfhe-zk-pok", optional = true }
tfhe-zk-pok = { version = "0.3.1", path = "../tfhe-zk-pok", optional = true }
tfhe-versionable = { version = "0.3.2", path = "../utils/tfhe-versionable" }
# wasm deps

View File

@@ -7,54 +7,64 @@ use serde::Serialize;
use tfhe::boolean::prelude::*;
use tfhe::core_crypto::prelude::*;
use tfhe::keycache::NamedParam;
use tfhe::shortint::parameters::{
COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64, PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64, PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
};
#[cfg(feature = "gpu")]
use tfhe::shortint::parameters::{
PARAM_GPU_MULTI_BIT_MESSAGE_1_CARRY_1_GROUP_3_KS_PBS,
PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS,
PARAM_GPU_MULTI_BIT_MESSAGE_3_CARRY_3_GROUP_3_KS_PBS,
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_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
PARAM_GPU_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
};
#[cfg(not(feature = "gpu"))]
use tfhe::shortint::parameters::{
PARAM_MULTI_BIT_MESSAGE_1_CARRY_1_GROUP_2_KS_PBS,
PARAM_MULTI_BIT_MESSAGE_1_CARRY_1_GROUP_3_KS_PBS,
PARAM_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_2_KS_PBS,
PARAM_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS,
PARAM_MULTI_BIT_MESSAGE_3_CARRY_3_GROUP_2_KS_PBS,
PARAM_MULTI_BIT_MESSAGE_3_CARRY_3_GROUP_3_KS_PBS,
PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M64,
PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
};
use tfhe::shortint::prelude::*;
use tfhe::shortint::{MultiBitPBSParameters, PBSParameters};
#[cfg(not(feature = "gpu"))]
const SHORTINT_BENCH_PARAMS: [ClassicPBSParameters; 4] = [
PARAM_MESSAGE_1_CARRY_1_KS_PBS,
PARAM_MESSAGE_2_CARRY_2_KS_PBS,
PARAM_MESSAGE_3_CARRY_3_KS_PBS,
PARAM_MESSAGE_4_CARRY_4_KS_PBS,
const SHORTINT_BENCH_PARAMS: [ClassicPBSParameters; 5] = [
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
PARAM_MESSAGE_4_CARRY_4_KS_PBS_GAUSSIAN_2M64,
];
#[cfg(feature = "gpu")]
const SHORTINT_BENCH_PARAMS: [ClassicPBSParameters; 3] = [
PARAM_MESSAGE_1_CARRY_1_KS_PBS,
PARAM_MESSAGE_2_CARRY_2_KS_PBS,
PARAM_MESSAGE_3_CARRY_3_KS_PBS,
const SHORTINT_BENCH_PARAMS: [ClassicPBSParameters; 4] = [
PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
PARAM_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
PARAM_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
];
#[cfg(not(feature = "gpu"))]
const SHORTINT_MULTI_BIT_BENCH_PARAMS: [MultiBitPBSParameters; 6] = [
PARAM_MULTI_BIT_MESSAGE_1_CARRY_1_GROUP_2_KS_PBS,
PARAM_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_2_KS_PBS,
PARAM_MULTI_BIT_MESSAGE_3_CARRY_3_GROUP_2_KS_PBS,
PARAM_MULTI_BIT_MESSAGE_1_CARRY_1_GROUP_3_KS_PBS,
PARAM_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS,
PARAM_MULTI_BIT_MESSAGE_3_CARRY_3_GROUP_3_KS_PBS,
PARAM_MULTI_BIT_GROUP_2_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
PARAM_MULTI_BIT_GROUP_2_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_MULTI_BIT_GROUP_2_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
PARAM_MULTI_BIT_GROUP_3_MESSAGE_1_CARRY_1_KS_PBS_GAUSSIAN_2M64,
PARAM_MULTI_BIT_GROUP_3_MESSAGE_2_CARRY_2_KS_PBS_GAUSSIAN_2M64,
PARAM_MULTI_BIT_GROUP_3_MESSAGE_3_CARRY_3_KS_PBS_GAUSSIAN_2M64,
];
#[cfg(feature = "gpu")]
const SHORTINT_MULTI_BIT_BENCH_PARAMS: [MultiBitPBSParameters; 3] = [
PARAM_GPU_MULTI_BIT_MESSAGE_1_CARRY_1_GROUP_3_KS_PBS,
PARAM_GPU_MULTI_BIT_MESSAGE_2_CARRY_2_GROUP_3_KS_PBS,
PARAM_GPU_MULTI_BIT_MESSAGE_3_CARRY_3_GROUP_3_KS_PBS,
const SHORTINT_MULTI_BIT_BENCH_PARAMS: [MultiBitPBSParameters; 4] = [
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,
];
const BOOLEAN_BENCH_PARAMS: [(&str, BooleanParameters); 2] = [
@@ -514,9 +524,6 @@ mod cuda {
#[cfg(feature = "gpu")]
use cuda::cuda_keyswitch_group;
use tfhe::shortint::parameters::{
COMP_PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64, PARAM_MESSAGE_2_CARRY_2_KS_PBS_TUNIFORM_2M64,
};
pub fn keyswitch_group() {
let mut criterion: Criterion<_> = (Criterion::default()

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