Part I · Today's module · Chapter 9 of 18

A real workload: an FHE bootstrap

A recorded OpenFHE bootstrap replayed stage by stage: utilisation, roofline, hot-spots and what binds.

A recorded OpenFHE bootstrap, replayeddatasheetillustrative
Bootstrap replay (loads when scrolled into view)
Busy fraction of HBM, FPGA compute and PCIe in each of the replay’s time bins (FPGA-only placement, the only one recorded over time), with the stage bands of the recorded kernel stream. Stage boundaries are placed from the analytic per-stage times, scaled to the replay’s length. The panel shows the current stage’s binding resource under each placement, its kernel mix and its time.
Data table
Per-stage summary
trace · stageFPGA-only (ms)NTTs on module (ms)NTTs split (ms)NTT sharebinds (FPGA-only)binds (module)
sparse16 · ModRaise19.81946.54790.426fpgamodule
sparse16 · CoeffToSlot8.024183.594.990.199hbmmodule
sparse16 · EvalMod56.973,3311,6790.525fpgamodule
sparse16 · SlotToCoeff2.14126.9714.450.106hbmmodule
sparse16 · post-processing0.363318.999.5920.47fpgamodule
full14 · ModRaise0.17616.239.2870.848fpgamodule
full14 · CoeffToSlot29.75328.4199.30.0923hbmmodule
full14 · EvalMod49.662,5701,4800.469fpgamodule
full14 · SlotToCoeff15.92142.587.760.0737hbmmodule
achieved≤min⁡(CFPGA,  I⋅BHBM)\text{achieved} \le \min\big(\hl{sum}{C_{\text{FPGA}}},\; I \cdot \hl{filter}{B_{\text{HBM}}}\big)
Smax⁡=11−fNTTS_{\max} = \frac{1}{1 - \hl{amdahl}{f_{\text{NTT}}}}

What this stage does

Fully homomorphic encryption lets a server compute on encrypted data. Its most expensive step is the bootstrap, which refreshes a ciphertext’s noise budget. A CKKS bootstrap runs four stages: ModRaise, CoeffToSlot (homomorphic linear transforms built from rotations and key switching), EvalMod (a polynomial approximation of the modular reduction) and SlotToCoeff. Every stage is full of number-theoretic transforms over many residue limbs, which is why a photonic NTT engine is interesting here.

This chapter replays two real bootstraps recorded from instrumented OpenFHE: sparse16 (N = 65,536, 1,732 kernels) and full14 (N = 16,384, 3,917 kernels), on an FPGA card with HBM, a PCIe host link and the module behind one QSFP56 port.

How it’s modelled

Each kernel of the trace becomes a demand on six resources: HBM bytes (limbs, evaluation keys and plaintexts unless cached in on-chip SRAM), FPGA add-equivalents, optical symbol slots on the module, bits through the port in each direction, and PCIe for the ciphertext. Kernels run in recorded order (OpenFHE ran single-threaded); a kernel takes its largest demand over capacity plus a latency. A SimPy replay then cuts kernels into bursts that contend for the same servers and SRAM buffers, which gives the utilisation over time shown above.

The capacities: HBM at 819 GB/s datasheet with 0.8 illustrative achievable, one port at 25 GB/s datasheet, 64 illustrative butterfly units at 400 MHz illustrative, and the module at 14 GBd paper on 1 paper wavelength. The replay’s FPGA-only time is within a fraction of the analytic bound (ratio 1.011 for sparse16).

Stage time by NTT placementillustrative
0.11101001,00010⁴modraisectsevalmodstcposttime (ms)modraise, sparse16, FPGA only: 19.81modraise, sparse16, NTTs on the module: 946.5modraise, sparse16, NTTs split: 479cts, sparse16, FPGA only: 8.024cts, sparse16, NTTs on the module: 183.5cts, sparse16, NTTs split: 94.99evalmod, sparse16, FPGA only: 56.97evalmod, sparse16, NTTs on the module: 3,331evalmod, sparse16, NTTs split: 1,679stc, sparse16, FPGA only: 2.141stc, sparse16, NTTs on the module: 26.97stc, sparse16, NTTs split: 14.45post, sparse16, FPGA only: 0.3633post, sparse16, NTTs on the module: 18.99post, sparse16, NTTs split: 9.592
0.11101001,00010⁴modraisectsevalmodstctime (ms)modraise, full14, FPGA only: 0.176modraise, full14, NTTs on the module: 16.23modraise, full14, NTTs split: 9.287cts, full14, FPGA only: 29.75cts, full14, NTTs on the module: 328.4cts, full14, NTTs split: 199.3evalmod, full14, FPGA only: 49.66evalmod, full14, NTTs on the module: 2,570evalmod, full14, NTTs split: 1,480stc, full14, FPGA only: 15.92stc, full14, NTTs on the module: 142.5stc, full14, NTTs split: 87.76
Log scale. With NTTs on the module, every stage slows down by one to two orders of magnitude.
Data table
Stage time by placement (ms)
stageFPGA onlyNTTs on the moduleNTTs split
ModRaise19.81946.5479
CoeffToSlot8.024183.594.99
EvalMod56.973,3311,679
SlotToCoeff2.14126.9714.45
post-processing0.363318.999.592

What we found

FPGA-only, memory binds the key-switching stages. A bootstrap takes 87.44 ms (sparse16) and 95.59 ms (full14) on 64 butterfly units. CoeffToSlot and SlotToCoeff stream evaluation keys from HBM and are HBM-bound (CoeffToSlot is HBM-bound for 70.6 % of its time insparse16), while EvalMod and ModRaise are dominated by NTTs and bound by FPGA compute. Over the whole bootstrap HBM binds for 42.4 % of the time in sparse16 and 61 % in full14.

With the NTTs on the module, the module binds every stage. At the paper’s operating point the bootstrap is 51.55× slower for sparse16 (4.507 s) and 31.98× slower forfull14. The module is busy 93.7 % of the time and the return port 50.9 %: a w-bit butterfly costs w symbol slots, and one wavelength at this baud delivers far fewer butterflies than the FPGA’s units. Splitting the NTT stages between FPGA and module (hybrid) halves the damage but does not remove it.

The ceiling is low anyway. NTTs are 46.2 % of the FPGA-only time in sparse16 and 28.6 % in full14, so even infinitely fast NTTs would give at most 1.858× and 1.402×. More FPGA logic makes the bootstrap HBM-bound (from 87.44 ms at the default down to 52.97 ms at the largest swept FPGA, where memory has the last word); more HBM bandwidth alone gets sparse16to 61.05 ms at the top of the HBM sweep. Keeping up with the fastest swept module (112 GBd × 8 λ) would take 34.76 QSFP56 ports’ worth of bandwidth.

Per-stage rooflinedatasheetillustrative
0.111010010¹⁰10¹¹10¹²arithmetic intensity (add-equivalents per HBM byte)achieved rate (add-equivalents/s)

Roofs: 7.168 × 10¹¹ add-equivalents/s of FPGA compute and 655.2 GB/s of achievable HBM bandwidth.

Each point is one stage under one placement: arithmetic intensity (modular-add equivalents per HBM byte) against the achieved rate. FPGA-only points sit on or near the roof; with NTTs on the module they fall far below it, because the module, not the FPGA or HBM, sets the pace.
Data table
Roofline points
trace · placement · stageintensity (ops/B)achieved (ops/s)binding
sparse16 · FPGA only · ModRaise1.55.279 × 10¹¹fpga
sparse16 · FPGA only · CoeffToSlot0.65513.393 × 10¹¹hbm
sparse16 · FPGA only · EvalMod1.3535.084 × 10¹¹fpga
sparse16 · FPGA only · SlotToCoeff0.38882.302 × 10¹¹hbm
sparse16 · FPGA only · post-processing1.3014.95 × 10¹¹fpga
sparse16 · NTTs on the module · ModRaise3.1742.251 × 10¹⁰module
sparse16 · NTTs on the module · CoeffToSlot1.1922.578 × 10¹⁰module
sparse16 · NTTs on the module · EvalMod3.2862.018 × 10¹⁰module
sparse16 · NTTs on the module · SlotToCoeff0.63962.86 × 10¹⁰module
sparse16 · NTTs on the module · post-processing3.0072.099 × 10¹⁰module
sparse16 · NTTs split · ModRaise2.3373.275 × 10¹⁰module
sparse16 · NTTs split · CoeffToSlot0.92373.863 × 10¹⁰module
sparse16 · NTTs split · EvalMod2.322.825 × 10¹⁰module
sparse16 · NTTs split · SlotToCoeff0.51424.305 × 10¹⁰module
sparse16 · NTTs split · post-processing2.1542.975 × 10¹⁰module
full14 · FPGA only · ModRaise2.186.154 × 10¹¹fpga
full14 · FPGA only · CoeffToSlot0.46472.656 × 10¹¹hbm
full14 · FPGA only · EvalMod1.355.08 × 10¹¹fpga
full14 · FPGA only · SlotToCoeff0.38572.309 × 10¹¹hbm
full14 · NTTs on the module · ModRaise6.2111.81 × 10¹⁰module
full14 · NTTs on the module · CoeffToSlot0.68933.383 × 10¹⁰module
full14 · NTTs on the module · EvalMod3.0562.108 × 10¹⁰module
full14 · NTTs on the module · SlotToCoeff0.55623.493 × 10¹⁰module
full14 · NTTs split · ModRaise4.4832.282 × 10¹⁰module
full14 · NTTs split · CoeffToSlot0.5934.809 × 10¹⁰module
full14 · NTTs split · EvalMod2.3252.784 × 10¹⁰module
full14 · NTTs split · SlotToCoeff0.48314.946 × 10¹⁰module
Hot spots: where the time goesillustrative
FPGA only
Hot kernels, sparse16, FPGA only
kernelcounttime (ms)stall (ms)
NTT45633.64249.9
EW14816.78160.2
BCONV17610.1874.8
INTT4567.5746.66
KS526.99864.7
RESCALE2786.1666.58
NTTs on the module
Hot kernels, sparse16, NTTs on the module
kernelcounttime (ms)stall (ms)
NTT4563,84927,410
INTT456865.65,127
EW14816.78160.2
BCONV17610.1874.8
KS526.99864.7
RESCALE2786.1666.58
Kernel kinds of the sparse16 trace ranked by time, with the queueing they accumulate (stall), FPGA-only and with NTTs on the module.
What binds as the FPGA growsdatasheetillustrative
1101001,000101001,000FPGA butterfly unitstime (ms)
1101001,000101001,000FPGA butterfly unitstime (ms)
FPGA-only bootstrap time against butterfly units. The dashed line is the time HBM alone would need: once the FPGA is fast enough, the bootstrap is memory-bound.
Data table
sparse16: bootstrap time vs FPGA logic and HBM
FPGA butterfly unitsFPGA-onlyHBM bound only (819 GB/s)
8484.752.33
1624552.33
32137.852.33
6487.4452.33
12862.4652.33
25652.9752.33
51252.9752.33
What binds as HBM bandwidth scalesdatasheetillustrative
0.1110100101001,000HBM bandwidth scale (×)time (ms)
What moves each stage's binding
trace · stagebinds nowscale HBM down to flipscale HBM up to flip
sparse16 · CoeffToSlothbm—4×
sparse16 · EvalModfpga0.5×—
sparse16 · ModRaisefpga0.5×—
sparse16 · post-processingfpga0.5×—
sparse16 · SlotToCoeffhbm—4×
full14 · CoeffToSlothbm—4×
full14 · EvalModfpga0.5×—
full14 · ModRaisefpga0.25×—
full14 · SlotToCoeffhbm—8×
FPGA-only bootstrap time with the HBM bandwidth scaled from a quarter of its default to sixteen times it, at the default FPGA logic.
Data table
HBM scaling
HBM scalesparse16 (ms)sparse16 HBM-bound sharefull14 (ms)full14 HBM-bound share
0.25×2101280.50.967
0.5×124.30.596153.30.758
1×87.440.42495.590.61
2×69.210.26267.130.427
4×61.740.080354.360.2
8×61.150.0036353.210.00672
16×61.050.0019853.050.00385

What would need measured data

The trace is real: kernel kinds, counts and order come from OpenFHE. The costs are not. The FPGA’s logic budget and cost per butterfly, the HBM efficiency and latency, the SRAM caching policy, and the module’s framing and port behaviour are illustrative or datasheet values. To trust the absolute times one would need a real FPGA implementation of the bootstrap kernels (resources, clock and power), measured HBM traffic per kernel, and the module’s sustained throughput and latency behind a real port, including its framing and retries. The direction of the result is robust to all of these: the module would have to get orders of magnitude faster, and its port with it, before NTT placement matters more than HBM.