Repository navigation
Add a benchmark for CKKS FE functional bootstrapping - #1372
Conversation
Benchmarks EvalFEFuncBootstrap for identity, exp, tanh, sigmoid and GELU (Fourier extensions generated with fefbt-python) with SPARSE_ENCAPSULATED secrets and full packing: - 29-bit FLEXIBLEAUTO with 1 and 6 levels after bootstrapping (N = 2^15) - 59-bit FLEXIBLEAUTO/FIXEDMANUAL with 1 level (N = 2^16) - 53/55-bit FLEXIBLEAUTO/FIXEDMANUAL with 6 levels (N = 2^16) - 59-bit FLEXIBLEAUTO/FIXEDMANUAL with 10 levels (N = 2^17) Each configuration uses the smallest ring dimension and number of digits that keep log(QP) within 767 / 1553 / 3104 bits; the series degrees are the lowest that reach the precision floor of the scaling factor. Each run reports precision and log(QP) counters and is skipped if log(QP) exceeds the limit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Measured on icelake (2× Intel Xeon Platinum 8360Y, 72 cores, all cores fixed at 2.4 GHz, turbo off, machine otherwise idle), PR head
|
Re-tune three configuration groups (36-thread times on a Xeon 8360Y):
- 29-bit, six levels: N = 2^15 {2,2} dnum 24 -> N = 2^16 {5,4} dnum 2,
36-42% faster, a third of the memory; the full-degree tanh, sigmoid
and GELU series now fit (+1.3 bits).
- six levels: N = 2^16 {2,2} dnum 13-14 at 53/55 bits -> N = 2^17 {5,4}
dnum 4 at 59 bits, 8-17% faster, half the memory, 1-4 bits more
precise.
- 59-bit, ten levels, N = 2^17: {4,3} dnum 2 -> {5,4} dnum 3, 14-18%
faster, less memory.
The one-level rows are unchanged: N = 2^17 is 29-46% slower per
ciphertext for them. Update the configuration comment accordingly.
|
Pushed updated benchmark configurations for three groups, plus the context-release fix. All changes keep log(QP) within the 128-bit limits for sparse secrets (767 / 1553 / 3104 bits at N = 2^15 / 2^16 / 2^17).
Precision is the same or better in every row: +1.3 bits for tanh, sigmoid and GELU in the 29-bit six-level group (the full-degree series now fit), +1 to +4 bits for the six-level 59-bit group, and unchanged to +0.7 bits for the ten-level group. In the six-level 59-bit group GELU uses the degree-45 series, like the other 59-bit rows. The degree-5 series are no longer used but are kept in the file. Why they are faster. Near the security limit, the smaller ring dimension forces a {2,2} budget and a very large dnum, and that costs more than doubling N. In the ten-level rows, the deeper {5,4} budget does 13% fewer key switches per call (641 → 555 for identity, 661 → 575 for tanh), and dnum 3 shrinks the auxiliary modulus from 17 to 12 primes. On the dnum > 8 suggestion. It holds when the chain is deep: both six-level groups are faster at 2N with a small dnum, with less memory and twice the slots. It does not hold per ciphertext for the one-level 59-bit rows (dnum 8 and 12). Their fastest N = 2^17 configuration ({5,4}, dnum 3; also tried {5,4} with dnum 2 and 4, {4,4}, {5,5}, {6,4}) is 29–46% slower per ciphertext, although about a third cheaper per value with twice the slots. Those rows, and the 29-bit one-level rows, are unchanged. Memory fix (separate commit). Each case now ends with Method. Xeon Platinum 8360Y (2 × 36 cores, fixed 2.4 GHz, turbo off), GCC 13.3 Release with OpenMP, |
Benchmark for CKKS FE functional bootstrapping
Adds
benchmark/src/ckks-fe-functional-bootstrapping.cpp, a benchmark forEvalFEFuncBootstrap. It covers continuous functions evaluated through their Fourier extensions, alongside the existing discrete benchmarkckks-functional-bootstrapping.cpp. No library code changes.Functions
The Fourier coefficients were generated with fefbt-python. For each scaling factor, the degree is the lowest at which FE functional bootstrapping reaches its noise floor. Within a depth step, a higher degree costs no extra level: degrees 6–13, 14–27 and 28–59 use 3, 4 and 5 levels.
At 59 bits these degrees match or beat the tables in
FE-functional-bootstrapping-ckks.cpp/ckksrns-fhe.h:Configurations
All rows use
SPARSE_ENCAPSULATED, all N/2 slots, and a first modulus one bit larger than the scaling factor, as FE functional bootstrapping requires. The ring dimension is the smallest one that keeps log(QP) within the 128-bit limits for sparse secrets: 767 / 1553 / 3104 bits for N = 2^15 / 2^16 / 2^17. The number of digits is the smallest that fits under that limit, which also keeps the keys small. The level budget was then tuned for runtime.Notes:
GetFEFBTDepth+ levels after bootstrapping. Because SlotsToCoeffs runs first, the output also keepslevelBudget[1]extra levels for the next bootstrap.Precision
Mean error relative to the range of the function, in bits, measured at N = 2^15 with the same moduli:
Each benchmark reports a
precisioncounter and alogQPcounter. A row whose log(QP) exceeds the limit for its ring dimension is skipped with an error.Results
Time per
EvalFEFuncBootstrapcall, 4 iterations, measured on:NATIVE_SIZE=64,WITH_NATIVEOPT=OFFThe 29-bit rows with 6 levels (N = 2^15, 24 digits) and all N = 2^16 / 2^17 rows need more than 15 GB of RAM. Results on a larger machine:
Running