How the simulator works
A parametric model of the photonic link module described by Kundu et al. in “Programmable Compute-in-Transit using Integrated Photonics” (arXiv:2608.21536), built to find break-even conditions rather than to advocate. Here is what it models, where each parameter comes from, what the tests prove and what it leaves out.
The four layers
The simulator splits the module into four layers, each behind a small interface so that an ideal, a noisy or a measured version can be swapped in without touching the others.
- Functional (bit-exact): the DFT of 4-bit planes, PAM4 with saturation, the 256-entry decode table with its valid flag, bit-plane split and shift-and-add, the j→ω mapping and radix-4 NTTs built only from the 4-point kernel. See chapter 8.
- Analogue (per symbol): MZM cosine transfer, per-lane errors, the OFT unitary or heater mesh, the self-homodyne projection, noise, TIA compression and thresholds. Its error counts come from a portable Monte Carlo written identically in NumPy and Rust. See chapter 5.
- Control: heater drift, the ordered truth-table calibration, pilot tracking, marker frames, retries and recalibration pauses, which give availability. See chapter 6.
- Timing: SimPy frames from host to lanes to optical passes to the FPGA stage, needing only an error rate and a pass rate from below. Energy, workload generators, the recorded OpenFHE bootstrap and the HBM/host-link model sit on top. See chapter 9.
Workloads hand operands to the functional layer. The functional layer passes bit planes to an optical core and gets back symbols, decoded spectra and a valid flag; the analogue layer is one such core. The control layer turns heater errors into impairments for the analogue layer and reads back truth-table residuals. The analogue and control layers give the timing layer a link state (word error rate, mean time between recalibrations, recalibration time); timing gives energy its rates. The analogue chain’s tables feed the portable Monte Carlo, implemented identically in NumPy and Rust. The bootstrap and memory models turn a recorded OpenFHE trace into per-kernel demands on HBM, FPGA logic, the module, its port and PCIe.
Model card and source tags
Every default parameter carries a source tag. Wherever a parameter or an assumption appears on this site, its tag is shown next to it.
- paper stated in the paper (arXiv:2608.21536)
- patent from the cited patents on packing and calibration
- datasheet from a component datasheet (TIA noise, HBM and PCIe bandwidths, link energy)
- textbook physics or arithmetic that follows from the design (shot noise, butterfly operation counts)
- public-statement something the developer has said in public about its next system: not a measurement and not a paper figure (Part II only)
- illustrative a modelling choice made to make the worked example concrete; swept or overridable, never a measurement
Most analogue and control parameters are illustrative. They were chosen so that the model reproduces its worked example; they show the design is self-consistent, not that the hardware achieves it. No illustrative number on this site is a measurement of the real module. For example the drive swing (0.22 π rad illustrative) and the LO power (−5 dBm illustrative) are modelling choices.
Showing 162 of 162 parameters.
| parameter | value | unit | source | note |
|---|---|---|---|---|
link.baud_GBd | 14 | GBd | paper | binary NRZ per lane from the host FPGA |
link.n_lanes | 4 | paper | QSFP56 lanes, one MZM each | |
link.n_wavelengths | 1 | paper | one laser, LO split from it (self-homodyne) | |
link.frame_symbols | 4,096 | symbols/lane | illustrative | Driver IP frame length |
link.framing_efficiency | 0.97 | illustrative | payload fraction after framing | |
mzm.p_max_uW | 43.6 | µW | illustrative | per-lane maximum optical power |
mzm.bias_pi | 0.5 | π rad | paper | arm phase difference at quadrature bias |
mzm.swing_pi | 0.22 | π rad | illustrative | arm phase change for '1'/'0' |
oft.fab_error_rms | 0 | illustrative | Hermitian generator scale for U error | |
receiver.lo_dBm | −5 | dBm | illustrative | LO power per balanced detector pair |
receiver.responsivity_A_W | 0.65 | A/W | illustrative | photodiode responsivity |
receiver.tia_noise_uA | 2 | µA rms | datasheet | 400G-class linear TIA input noise |
receiver.tia_noise_bw_GHz | 35 | GHz | datasheet | bandwidth of the TIA noise figure |
receiver.noise_bw_ratio | 0.47 | × baud | illustrative | receiver noise bandwidth |
receiver.rin_dB_Hz | −150 | dB/Hz | illustrative | LO relative intensity noise |
receiver.cmrr_dB | 20 | dB | illustrative | balanced-detector common-mode rejection |
receiver.signal_shot_noise | true | textbook | signal power on each pair adds shot noise | |
receiver.tia_ohm | 1,000 | ohm | illustrative | linear TIA transimpedance |
receiver.compression | false | illustrative | soft (tanh) TIA compression on/off | |
receiver.knee_steps | 3.5 | level steps | illustrative | compression knee from TIA zero |
receiver.headroom_steps | 0.5 | level steps | illustrative | tanh scale above the knee |
receiver.linewidth_MHz | 1 | MHz | illustrative | laser linewidth |
receiver.path_mismatch_mm | 1 | mm | illustrative | signal/LO path mismatch |
receiver.group_index | 3.9 | textbook | silicon waveguide group index | |
receiver.target_ser | 1 × 10⁻⁶ | illustrative | symbol error rate target | |
channel.bw_ratio | 0.75 | × baud | illustrative | lane channel 3 dB bandwidth |
channel.model | gaussian | illustrative | gaussian or rc (first order) | |
channel.taps_each_side | 6 | symbols | illustrative | ISI truncation |
heater.n_heaters | 17 | patent | 17-18 thermo-optic phase shifters | |
heater.dac_bits | 12 | bits | illustrative | microcontroller DAC resolution |
heater.v_pi | 4.36 | V | illustrative | heater V_pi; phase grows as V^2 |
heater.v_fs | 6.5 | V | illustrative | DAC full scale (covers > 2 pi) |
control.pass_half_step | 0.5 | level steps | patent | calibration pass criterion |
control.pilot_period_frames | 1,000 | frames | patent | pilot perturbation period |
control.monitor_period_s | 0.5 | s | patent | monitoring period (GUI timescale) |
control.sample_interval_s | 0.06 | s | patent | GUI sample interval; recorded, not used by the v0.1 loop |
control.retry_marker_once | true | patent | re-apply a failed marker frame once | |
control.marker_words | 256 | words | illustrative | symbols in one marker frame |
control.drift_rad_sqrt_s | 0.01 | rad/√s | illustrative | per-heater random walk |
control.temp_K_sqrt_s | 0.01 | K/√s | illustrative | common temperature walk |
control.temp_coeff_rad_K | 0.1 | rad/K | illustrative | mean heater phase per kelvin |
control.fab_offset_rms_rad | 0.3 | rad | illustrative | static phase offsets at power-up |
control.track_gain | 0.1 | illustrative | pilot tracker gain per update | |
control.track_noise_rad | 0.002 | rad | illustrative | tracker measurement noise |
control.recal_time_s | 1 | s | illustrative | duration of a full recalibration |
control.coarse_points | 64 | illustrative | coarse scan points per heater | |
control.fine_half_width | 48 | codes | illustrative | fine scan half width |
control.sweeps | 3 | illustrative | passes through the ordered heater list | |
timing.fpga_clock_MHz | 400 | MHz | illustrative | pipelined radix-4 butterfly clock |
timing.fpga_butterfly_units | 1 | illustrative | k butterfly units in the baseline | |
timing.mul_add_ratio | 5 | adds | illustrative | modular multiply cost (swept 3-10) |
timing.twiddle_muls | 3 | textbook | twiddle multiplies per radix-4 butterfly | |
timing.omega_muls | 1 | textbook | multiplies by omega (sqrt(-1)) per butterfly | |
timing.butterfly_adds | 8 | textbook | modular add/sub per radix-4 butterfly | |
timing.hybrid_post_adds | 4 | illustrative | j->omega combine (2) + X0,X2 reduce (2) | |
timing.recombine_add_per_plane | 0.25 | adds | illustrative | shift-add per plane/output |
timing.link_latency_ns | 200 | ns | illustrative | host->module->host latency |
timing.fpga_pipeline_cycles | 20 | cycles | illustrative | FPGA stage pipeline depth |
ac.hp_corner_Hz | 100,000 | Hz | illustrative | TIA DC-offset-cancel high-pass corner |
ac.code_frame_symbols | 256 | symbols | illustrative | frame-inversion code frame |
ac.biased_p_one | 0.8 | illustrative | P(bit = 1) for the biased workload | |
ac.run_symbols | 32,768 | symbols | illustrative | run length, one-word-runs workload |
ac.settle_tol_steps | 0.05 | level steps | illustrative | settled when wander below |
ac.cal_dwell_symbols | 4,096 | symbols | illustrative | dwell per calibration pattern |
ac.cal_pair_symbols | 64 | symbols | illustrative | pattern/inverse alternation |
energy.module_static_W | 9.7 | W | paper | module power |
energy.link_pJ_bit | 2.76 | pJ/bit | datasheet | developer website, 45 nm, excl. laser |
energy.fpga_pJ_modadd | 2 | pJ | illustrative | FPGA energy per modular add |
fhe.placement | fpga | illustrative | NTT placement: fpga, optical or hybrid | |
fhe.residue_bits | 59 | bits | illustrative | limb prime width; 59 as recorded (q_bits=59), swept 28-59 |
fhe.recorded_bits | 59 | bits | illustrative | prime width of the recording; limb counts scale by this / width |
fhe.hybrid_optical_fraction | 0.5 | illustrative | share of radix-4 stages sent through the module | |
fhe.fpga_units | 64 | illustrative | radix-4 butterfly units of FPGA logic in the bootstrap design | |
fhe.ew_macs_per_point | 1 | MACs | illustrative | element-wise op cost per point |
fhe.auto_adds_per_point | 1 | adds | illustrative | automorphism (permute) cost |
memory.hbm_GBps | 819 | GB/s | datasheet | Alveo V80 HBM2e, AMD DS1013 v1.0 Table 1 |
memory.hbm_efficiency | 0.8 | illustrative | achievable fraction of HBM peak | |
memory.hbm_latency_ns | 300 | ns | illustrative | HBM access latency |
memory.hbm_capacity_GB | 32 | GB | datasheet | Alveo V80 HBM2e, AMD DS1013 v1.0 Table 1 |
memory.pcie_GBps | 63 | GB/s | datasheet | PCIe Gen5 x8x8 (DS1013 Table 1): 2 x 31.5 GB/s per direction |
memory.pcie_efficiency | 0.8 | illustrative | achievable fraction of PCIe peak | |
memory.pcie_latency_us | 1 | µs | illustrative | host round-trip setup latency |
memory.port_GBps | 25 | GB/s | datasheet | one QSFP56 port, 4 x 56G PAM4 = 200 Gb/s (DS1013 Table 1) |
memory.ports | 1 | paper | QSFP56 ports to the module (4 on the card) | |
memory.sram_MB | 94 | MB | datasheet | XCV80 total PL memory 752 Mb (DS1013 Table 2) |
memory.sram_cache_fraction | 0.5 | illustrative | share of SRAM caching keys/plaintexts; rest buffers | |
memory.burst_kB | 256 | kB | illustrative | transaction size in the SimPy model |
memory.max_bursts | 16 | illustrative | cap on bursts per kernel (simulation speed) | |
future.stacked | true | public-statement | photonic layer 3D-stacked on the logic (hybrid bonding), no package port between optics and logic | |
future.units | 64 | illustrative | U: 4-point optical transform units | |
future.wavelengths | 4 | illustrative | W: wavelengths sharing each unit's mesh | |
future.baud_GBd | 112 | GBd | paper | section V projection: 112 GBd PIC |
future.frontend_logic_GHz | 28 | GHz | paper | section V: 28 GHz logic; clocks the per-unit decision and bit-serial accumulators |
future.slot_efficiency | 0.95 | illustrative | useful fraction of symbol slots (pipeline bubbles) | |
future.heaters_per_unit | 18 | patent | phase shifters per 4-point unit today | |
future.heaters_per_wavelength | 8 | illustrative | extra tuners per unit per wavelength (4 modulator rings + 4 demux filters) | |
future.conv_pJ_bit | 0.5 | pJ/bit | illustrative | E_conv: one optical-electrical crossing, either direction |
future.conv_latency_ns | 1 | ns | illustrative | latency of one crossing |
future.out_bits_per_plane | 2 | bits | illustrative | decision bits per output per bit plane (PAM4 as today) |
future.recombine_pJ_plane | 0.05 | pJ | illustrative | bit-serial shift-add per output per plane |
future.mode | exact | illustrative | exact (FHE) or approximate (FFT/AI) | |
future.chain_stages | 1 | illustrative | S: radix-4 stages chained optically (approximate mode only) | |
future.stage_loss_dB | 1 | dB | illustrative | optical loss per chained stage |
future.stage_phase_rms_rad | 0.01 | rad | illustrative | residual phase error per waveguide per chained stage |
future.unit_area_mm2 | 0.2 | mm2 | illustrative | photonic area per unit |
future.wavelength_area_mm2 | 0.05 | mm2 | illustrative | extra photonic area per unit per wavelength |
future.logic_area_mm2 | 100 | mm2 | illustrative | stacked logic for modular arithmetic (twiddles, reduction, non-NTT kernels) |
future.power_cap_W | 500 | W | illustrative | chip power envelope (laser at the wall, heaters, conversions, logic) |
future.c_t_fF | 30 | fF | illustrative | receiver input capacitance, hybrid-bonded (tens of fF) |
future.c_t_pluggable_fF | 300 | fF | illustrative | receiver input capacitance, packaged (hundreds of fF) |
future.tia_gbw_THz | 1 | THz | illustrative | TIA amplifier gain-bandwidth A f_A |
future.tia_bw_ratio | 0.7 | × baud | illustrative | TIA 3 dB bandwidth |
future.tia_excess_noise | 2 | illustrative | TIA noise power over the R_T thermal noise | |
laser.power_dBm | 20 | dBm | illustrative | one external fibre-fed laser (all its wavelengths) |
laser.wall_plug | 0.15 | illustrative | laser wall-plug efficiency | |
laser.coupler_dB | 1.5 | dB | illustrative | fibre-to-chip coupler loss |
laser.split_excess_dB | 0.1 | dB | illustrative | excess loss per 1x2 splitter |
laser.prop_dB_cm | 1 | dB/cm | illustrative | waveguide propagation loss |
laser.mzm_il_dB | 4 | dB | illustrative | modulator insertion loss |
laser.wdm_dB | 1.5 | dB | illustrative | WDM mux + demux loss when W > 1 |
laser.margin_dB | 6 | dB | illustrative | design margin the laser must hold |
thermal.p_pi_mW | 10 | mW | illustrative | thermo-optic heater power per pi; silicon heaters are reported at about 2-30 mW (e.g. Harris et al., Opt. Express 22, 10487, 2014) |
thermal.settle_us | 10 | µs | illustrative | thermo-optic settle time |
thermal.mems_p_pi_mW | 0.001 | mW | illustrative | MEMS phase shifter hold power |
thermal.mems_settle_us | 5 | µs | illustrative | MEMS settle time |
thermal.nv_p_pi_mW | 0 | mW | illustrative | non-volatile trim hold power |
thermal.nv_settle_us | 1,000 | µs | illustrative | non-volatile write-and-verify time |
thermal.cal_dwell_us | 10 | µs | illustrative | measurement dwell per calibration evaluation |
thermal.crosstalk_nn | 0.1 | illustrative | thermal crosstalk to the nearest heater (phase ratio) | |
thermal.crosstalk_length_um | 30 | um | illustrative | crosstalk decay length |
thermal.heater_pitch_um | 50 | um | illustrative | heater spacing |
thermal.dn_dT | 0.00018 | 1/K | textbook | silicon thermo-optic coefficient |
thermal.wavelength_um | 1.31 | um | illustrative | optical wavelength |
thermal.heated_length_um | 100 | um | illustrative | phase-sensitive arm length |
thermal.logic_W_mm2 | 0.5 | W/mm2 | illustrative | stacked logic heat flux, busy |
thermal.hotspot_W_mm2 | 2 | W/mm2 | illustrative | heat flux of logic hot spots |
thermal.hotspot_fraction | 0.1 | illustrative | share of the area in hot spots | |
thermal.r_th_K_mm2_W | 5 | K mm2/W | illustrative | stack thermal resistance |
thermal.spread_mm | 0.5 | mm | illustrative | lateral heat-spreading length |
thermal.activity_interval_s | 10 | s | illustrative | mean time between busy/idle changes of the logic |
thermal.logic_drift_rad_sqrt_s | 0.005 | rad/√s | illustrative | extra per-heater random walk from logic heat |
thermal.cal_parallelism | 4 | illustrative | units the shared calibration controller serves at once | |
asic.clock_GHz | 1.5 | GHz | illustrative | modular-arithmetic logic clock (both the all-digital ASIC and the stacked logic layer) |
asic.bfly_area_mm2 | 0.15 | mm2 | illustrative | radix-4 modular butterfly unit, 59-bit, same node |
asic.pJ_add32 | 0.1 | pJ | textbook | 32-bit integer add, 45 nm (Horowitz 2014) |
asic.pJ_mul32 | 3.1 | pJ | textbook | 32-bit integer multiply, 45 nm (Horowitz 2014) |
asic.node_scale | 0.25 | illustrative | energy scaling 45 nm -> target node | |
asic.modmul_muls | 3 | illustrative | full multiplies per modular multiply (Barrett/Montgomery) | |
asic.modadd_adds | 2 | illustrative | adds per modular add (add + correct) | |
asic.hbm_pJ_bit | 3.9 | pJ/bit | illustrative | HBM access energy (HBM2e class) |
wdm.lambda0_nm | 1,310 | nm | illustrative | centre wavelength lambda0, O-band (the CW-WDM MSA defines O-band grids; its numbers are not used here) |
wdm.spacing_GHz | 200 | GHz | illustrative | channel spacing of the default plan (W = future.wavelengths) |
wdm.band_nm | 100 | nm | textbook | O-band width (1260-1360 nm); wider plans are flagged |
wdm.ng_over_neff | 1.7 | illustrative | n_g / n_eff of the mesh waveguides: a designed phase scales as phi0 (1 - (n_g/n_eff) delta) | |
wdm.heater_phase_fraction | 0.5 | illustrative | share of each nominal mesh phase that is heater-set and scales as phi0 (1 - delta); thermo-optic dispersion ignored | |
wdm.path_mismatch_um | 0 | um | illustrative | extra length of the two lines that cross between the mesh stages (a1, b0) |
wdm.coupler_dkappa_per_pct | 0 | illustrative | fractional change of each directional coupler's power coupling per 1 % of delta | |
wdm.ring_radius_um | 5 | um | illustrative | modulator and demux ring radius; FSR = lambda0^2 / (n_g 2 pi R) with n_g = receiver.group_index |
wdm.calibration | least_squares | illustrative | shared-mesh heater calibration: centre or least_squares over the W channels | |
wdm.output_trim | false | illustrative | per-channel output-phase trim (a diagonal phase per output port, set by per-channel LOs after the demux filters); off by default | |
wdm.ref_margin_dB | 10 | dB | illustrative | ideal-transform margin of the reference receiver for the exact-mode span limit (about v0.1's worked example) |
seed | 2.02608 × 10⁷ | illustrative | master RNG seed |
Inferred, not stated by the sources
The MZM swing (±0.22π) and per-lane power; the LO power, responsivity and receiver noise bandwidth (0.47 × baud, chosen so the worked example's 1.09 µA total reproduces); RIN and CMRR; the TIA knee and headroom; the heater mesh topology (4 input phases, 4 tunable couplers, 4 mid phases including the −j twiddle, 4 + 1 LO phases = 17); the DAC full scale; all drift rates, tracker gain and recalibration time; frame length and framing efficiency; FPGA costs (multiply/add ratio, recombination cost, energy per add); link latency. Each is swept or can be overridden.
The future chip (v0.3)
The simulator’s v0.3 (Part II of this site) models the next system the developer has described in public: a dense layer of photonic units stacked on its logic. Only the stacking is the developer’s statement; almost everything else is an engineering inference, tagged illustrative and swept. The simulator describes its v0.3 model as follows.
The v0.3 brief models a future chip: U photonic units (each a 4-point transform with its modulators, balanced receivers and phase shifters) at B GBd with W wavelengths, stacked on a logic layer, fed by one or more external lasers. Nothing about it is measured; the parameters live in four config sections (future, laser, thermal, asic), tagged paper (112 GBd, 28 GHz logic), public-statement (3D stacking), patent (18 phase shifters per unit), textbook (dn/dT, the 45 nm digital energies) or illustrative.
- Receiver and laser budget (
future.tia,margin_dB,best_margin). The receiver is the v0.1 analogue chain with the future chip's baud, the signal and LO power that reach it, and the TIA noise of the largest transimpedance the amplifier allows at that bandwidth and input capacitance.margin_dBis experiment 2's noise headroom (worst output, 16 equiprobable inputs), vectorised over powers. The laser's power is shared by W wavelengths and U units, less coupler, WDM, splitter excess and propagation loss; the signal/LO share is optimised on a 41-point grid. - Bootstrap (
future.evaluate). Reuses v0.2's kernel table and demands (bytes, add-equivalents, symbol slots). Resources: HBM, logic (butterfly units × clock), photonic slots (U × W × B × slot efficiency), dynamic power (power cap less laser and phase shifters) and PCIe. Exact mode: each optical butterfly leaves 4 multiplies and 4 adds to the logic (hybrid_post_costwith recombination moved to per-unit bit-serial accumulators, which cost energy but not logic) and costs 4w(1 + out_bits) crossings.split="optimal"picks, per NTT kernel, the optical share f ∈ [0, 1] that minimises the kernel's time (every resource time is linear in f, so the optimum is an end point or a crossing).Design(units=0)is the all-digital ASIC; with v0.2's 64 units at 400 MHz it reproduces v0.2's FPGA-only time exactly (tested).free_ntt="all"/"post"give the NTT-free and exact-mode ceilings. - Energy: Horowitz's 45 nm add/multiply energies × a node factor; modular add = 2 adds, modular multiply = 3 multiplies (Barrett/Montgomery), scaled by w and w². Laser at the wall (lasers × power / wall-plug) and phase-shifter hold power (mean phase π, so p_π each) are static; the bootstrap charges them for its whole duration.
- Thermal (
plms.thermal). A heat-flux map of the busy logic (background plus seeded hot-spot blocks), times the stack's thermal resistance, spread by a Gaussian, minus the mean (the TEC). Heater phase error = 2π dn/dT L/λ × (local ΔT − unit mean ΔT); each unit's word error comes from the v0.1 chain viaimpairments_from_errors. Crosstalk is K_ij = k_nn exp(−(d_ij − pitch)/L);ordered_calibration_residualis Gauss–Seidel on (I + K) h = θ. - Calibration at scale (
plms.cal_scale). One unit = the v0.1 loop with its pilot period × ⌈U/P⌉ (shared tracking) and logic-heat drift added in quadrature; at U = 1 without logic heat the config is v0.1's unchanged (tested). The fleet is an M/M/P//U machine-repair queue (in_service_analytic, exact);simulate_fleetis the SimPy version with fixed recalibration times and logic-heat storms. - Approximate mode (
plms.approx). A float radix-4 DIF FFT built stage by stage (validated against numpy). Every block of S stages: DAC → S unitary stages with loss and phase error → receiver noise → ADC → rescale.
Future-chip assumptions
Every v0.3 parameter with its default, source tag and where it is swept, rendered from the vendored results/results.md.
| parameter | default | source | swept | meaning |
|---|---|---|---|---|
future.stacked | yes | public-statement | 30 fF (stacked) vs 300 fF (packaged) receiver, e14 | photonic layer 3D-stacked on the logic (hybrid bonding), no package port between optics and logic |
future.units | 64 | illustrative | 4–4,096 (e12, e13), 1–16,384 (e15) | U: 4-point optical transform units |
future.wavelengths | 4 | illustrative | 1–8 (e12, e13, e14) | W: wavelengths sharing each unit's mesh |
future.baud_GBd | 112 GBd | paper | 14–112 (e12, e14) | section V projection: 112 GBd PIC |
future.frontend_logic_GHz | 28 GHz | paper | fixed | section V: 28 GHz logic; clocks the per-unit decision and bit-serial accumulators |
future.slot_efficiency | 0.95 | illustrative | fixed | useful fraction of symbol slots (pipeline bubbles) |
future.heaters_per_unit | 18 | patent | fixed | phase shifters per 4-point unit today |
future.heaters_per_wavelength | 8 | illustrative | fixed | extra tuners per unit per wavelength (4 modulator rings + 4 demux filters) |
future.conv_pJ_bit | 0.5 pJ/bit | illustrative | 0.05–2 (e12, e13) | E_conv: one optical-electrical crossing, either direction |
future.conv_latency_ns | 1 ns | illustrative | fixed | latency of one crossing |
future.out_bits_per_plane | 2 bits | illustrative | fixed | decision bits per output per bit plane (PAM4 as today) |
future.recombine_pJ_plane | 0.05 pJ | illustrative | fixed | bit-serial shift-add per output per plane |
future.mode | exact | illustrative | fixed | exact (FHE) or approximate (FFT/AI) |
future.chain_stages | 1 | illustrative | 1–6 (e16) | S: radix-4 stages chained optically (approximate mode only) |
future.stage_loss_dB | 1 dB | illustrative | default and 3 (e16) | optical loss per chained stage |
future.stage_phase_rms_rad | 0.01 rad | illustrative | fixed | residual phase error per waveguide per chained stage |
future.unit_area_mm2 | 0.2 mm2 | illustrative | fixed | photonic area per unit |
future.wavelength_area_mm2 | 0.05 mm2 | illustrative | fixed | extra photonic area per unit per wavelength |
future.logic_area_mm2 | 100 mm2 | illustrative | 5–200 (e12); 10 in the compute-bound regime | stacked logic for modular arithmetic (twiddles, reduction, non-NTT kernels) |
future.power_cap_W | 500 W | illustrative | fixed | chip power envelope (laser at the wall, heaters, conversions, logic) |
future.c_t_fF | 30 fF | illustrative | vs future.c_t_pluggable_fF (e14) | receiver input capacitance, hybrid-bonded (tens of fF) |
future.c_t_pluggable_fF | 300 fF | illustrative | fixed | receiver input capacitance, packaged (hundreds of fF) |
future.tia_gbw_THz | 1 THz | illustrative | fixed | TIA amplifier gain-bandwidth A f_A |
future.tia_bw_ratio | 0.7 x baud | illustrative | fixed | TIA 3 dB bandwidth |
future.tia_excess_noise | 2 | illustrative | fixed | TIA noise power over the R_T thermal noise |
laser.power_dBm | 20 dBm | illustrative | 13–27 (e14) | one external fibre-fed laser (all its wavelengths) |
laser.wall_plug | 0.15 | illustrative | fixed | laser wall-plug efficiency |
laser.coupler_dB | 1.5 dB | illustrative | fixed | fibre-to-chip coupler loss |
laser.split_excess_dB | 0.1 dB | illustrative | fixed | excess loss per 1x2 splitter |
laser.prop_dB_cm | 1 dB/cm | illustrative | fixed | waveguide propagation loss |
laser.mzm_il_dB | 4 dB | illustrative | fixed | modulator insertion loss |
laser.wdm_dB | 1.5 dB | illustrative | fixed | WDM mux + demux loss when W > 1 |
laser.margin_dB | 6 dB | illustrative | 6 and 10 (e14) | design margin the laser must hold |
thermal.p_pi_mW | 10 mW | illustrative | 2–30, MEMS and non-volatile (e14) | thermo-optic heater power per pi; silicon heaters are reported at about 2-30 mW (e.g. Harris et al., Opt. Express 22, 10487, 2014) |
thermal.settle_us | 10 us | illustrative | fixed | thermo-optic settle time |
thermal.mems_p_pi_mW | 0.001 mW | illustrative | fixed | MEMS phase shifter hold power |
thermal.mems_settle_us | 5 us | illustrative | fixed | MEMS settle time |
thermal.nv_p_pi_mW | 0 mW | illustrative | fixed | non-volatile trim hold power |
thermal.nv_settle_us | 1000 us | illustrative | fixed | non-volatile write-and-verify time |
thermal.cal_dwell_us | 10 us | illustrative | fixed | measurement dwell per calibration evaluation |
thermal.crosstalk_nn | 0.1 | illustrative | 0–0.3 (e14) | thermal crosstalk to the nearest heater (phase ratio) |
thermal.crosstalk_length_um | 30 um | illustrative | fixed | crosstalk decay length |
thermal.heater_pitch_um | 50 um | illustrative | fixed | heater spacing |
thermal.dn_dT | 1.8e-4 1/K | textbook | fixed | silicon thermo-optic coefficient |
thermal.wavelength_um | 1.31 um | illustrative | fixed | optical wavelength |
thermal.heated_length_um | 100 um | illustrative | fixed | phase-sensitive arm length |
thermal.logic_W_mm2 | 0.5 W/mm2 | illustrative | 0.1–4 (e14); 2 for storms (e15) | stacked logic heat flux, busy |
thermal.hotspot_W_mm2 | 2 W/mm2 | illustrative | fixed | heat flux of logic hot spots |
thermal.hotspot_fraction | 0.1 | illustrative | fixed | share of the area in hot spots |
thermal.r_th_K_mm2_W | 5 K mm2/W | illustrative | fixed | stack thermal resistance |
thermal.spread_mm | 0.5 mm | illustrative | fixed | lateral heat-spreading length |
thermal.activity_interval_s | 10 s | illustrative | fixed | mean time between busy/idle changes of the logic |
thermal.logic_drift_rad_sqrt_s | 0.005 rad/sqrt(s) | illustrative | fixed | extra per-heater random walk from logic heat |
thermal.cal_parallelism | 4 | illustrative | 1–64 (e15) | units the shared calibration controller serves at once |
asic.clock_GHz | 1.5 GHz | illustrative | fixed | modular-arithmetic logic clock (both the all-digital ASIC and the stacked logic layer) |
asic.bfly_area_mm2 | 0.15 mm2 | illustrative | sets the equal-silicon ASIC; break-even area reported (e12) | radix-4 modular butterfly unit, 59-bit, same node |
asic.pJ_add32 | 0.1 pJ | textbook | fixed | 32-bit integer add, 45 nm (Horowitz 2014) |
asic.pJ_mul32 | 3.1 pJ | textbook | fixed | 32-bit integer multiply, 45 nm (Horowitz 2014) |
asic.node_scale | 0.25 | illustrative | fixed | energy scaling 45 nm -> target node |
asic.modmul_muls | 3 | illustrative | fixed | full multiplies per modular multiply (Barrett/Montgomery) |
asic.modadd_adds | 2 | illustrative | fixed | adds per modular add (add + correct) |
asic.hbm_pJ_bit | 3.9 pJ/bit | illustrative | fixed | HBM access energy (HBM2e class) |
control.drift_rad_sqrt_s | 0.01 rad/sqrt(s) | illustrative | 0.01–0.1 (e15) | per-heater random walk |
fhe.residue_bits | 59 bits | illustrative | 28–59 (e12, e13) | limb prime width; 59 as recorded (q_bits=59), swept 28-59 |
memory.hbm_GBps | 819 GB/s | datasheet | 819–3276 and unconstrained (e12) | Alveo V80 HBM2e, AMD DS1013 v1.0 Table 1 |
Reading the v0.3 results honestly
From the simulator’s README: the chip does not pay for exact FHE arithmetic under any swept condition, for structural reasons.
- Exact arithmetic converts every stage. Each radix-4 stage of an NTT must be decided, recombined and reduced mod p before its twiddle multiply, so the optics replace only the modular adds of a butterfly; the multiplies stay in logic. That caps the gain over the same logic at the exact-mode ceiling in item 12, whatever U, W or B, and the equal-silicon ASIC is faster unless a photonic unit takes less area than item 12's break-even figure.
- Memory binds first. With v0.2's HBM and the default logic layer the bootstrap is HBM-bound, so the chip and the ASIC take the same time; NTT compute matters only with far more memory bandwidth and much less logic (the compute-bound regime of item 12).
- Energy goes the wrong way. A w-bit butterfly costs w bit planes of crossings and bit-serial recombination to save a few adds (item 13). Thermo-optic phase shifters, not the laser, dominate static power (item 14); MEMS or non-volatile trimming would remove most of it, but not the crossings.
- Lasers and calibration scale. One laser feeds only a handful of units at 112 GBd and a 6 dB margin, so lasers multiply with U (item 14). The v0.1 control loop per unit scales if the calibration controller's parallelism grows with U; tracking shared too thinly is what makes calibration, not compute, the limit (item 15).
- Approximate mode is where the optics carry an operand per symbol. Chaining stages cuts crossings and raises throughput, but at the receiver SNR the laser budget allows, the output keeps only a few effective bits, and a digital butterfly at that precision is cheaper still (item 16).
Break-even would need, together: a workload whose arithmetic tolerates analogue error (so a symbol carries an operand, not a bit plane), crossings and recombination far cheaper than the digital operations they replace, photonic units smaller than the logic they displace, low-power phase shifters, and a memory system fast enough that compute binds at all.
New simplifications
- Future chip (v0.3): analytic per-kernel timing, as in v0.2; every unit is in service (experiment 15 gives the derating); the photonic layer adds no latency beyond the crossings; the laser feeds units in equal shares and lasers come in whole numbers; the TIA noise is the thermal noise of R_T times an excess factor; phase shifters sit at a mean phase of π; logic leakage, SRAM access and PCIe energy are left out (they are common to the chip and the ASIC); the ASIC and the stacked logic share one clock, area and energy per operation; approximate mode uses the exact-mode laser and phase shifters and takes SNR per level step as the analogue SNR.
- Calibration at scale: failure rates come from a finite v0.1 run (zero when none were seen); recalibrations are independent and memoryless in the analytic queue; tracking is shared by dividing pilot updates, and a recalibration does not pause other units.
Open questions
The simulator’s results do not list open questions for v0.3 beyond the illustrative status of its parameters. Each Part II chapter ends with what would need measured data; the most decisive are the energy of one bonded optical-electrical crossing, the area of a photonic unit next to a modular butterfly in the same node, the hold power of the phase shifters actually used, and the drift of many units under a real workload’s heat. See what would have to change.
Wavelength dependence (v0.4)
The simulator’s v0.4 adds one term to the future chip: every phase in a mesh scales with wavelength, so W wavelengths sharing a unit’s mesh each see a slightly different transform (chapter 18). The simulator describes the model as follows.
v0.3 shares each unit's mesh across W wavelengths but makes nothing in the transform depend on wavelength. v0.4 adds that term to first order in δ = Δλ/λ0, in its own config section (wdm, all illustrative except the O-band width, textbook).
- Phase scaling. Each nominal mesh phase φ0 (the MZI internal π/2 and the −π/2 twiddle on b1) is split into a heater-set part, scaling as φ0 (1 − δ), and a designed part, scaling as φ0 (1 − (n_g/n_eff) δ). Heater corrections from calibration scale as (1 − δ) too. A path mismatch on the two crossing lines adds −2π n_g ΔL δ/λ0. All of it lands on v0.3's
coupler_errandmid_err, so δ = 0 gives exactly v0.3's errors and a channel with no error getsU_DFTitself (tested byte for byte). - Couplers.
mesh_unitary(…, kappa)builds each MZI from two directional couplers of power coupling κ = ½(1 + k·100δ);kappa=Nonekeeps v0.3's ideal 50:50 MZI. - Calibration. Centre: the nominal settings (the model has no fabrication offsets). Least squares: Gauss–Newton on the stacked real and imaginary parts of U(δ_i) − DFT4, accepting only steps that lower the mean squared error, so it is never worse than centre on that mean. On a grid symmetric about λ0 the first-order errors cancel in the mean and least squares barely moves the heaters.
- Determinism. Each least-squares step solves the 8 × 8 normal equations with exactly rounded sums (
math.fsum) and Gaussian elimination in Python, not LAPACK, and the corrections are rounded to 1e-8 rad (CAL_TOL_RAD), so results files do not depend on the CPU or BLAS of the machine that writes them. - Output-phase trim (
wdm.output_trim, off by default). Per channel, a diagonal phase per output port, θ_k = −arg Σ_n U_kn DFT*_kn (closed form), as per-channel LOs after the demux filters could set. The heaters are calibrated without it. In approximate mode it acts only on the last stage of each chained block (fft_error(…, kernel_end=…)), where a receiver reads the mesh. - Exact mode.
channel_margin_dBisfuture.margin_dBwith the channel's transform in the chain (levels after tracked pedestal removal, signal shot noise, decisions); on the ideal transform it returnsmargin_dB's numbers exactly.max_units_channelsrestates e14's largest U per laser with the worst channels' transforms. - Approximate mode.
approx.fft_error(…, kernel, tw_eps)applies the channel's 4-point transform at every optical stage and scales the optical twiddles inside a chained block (phases wrapped to (−π, π]); the twiddle at each conversion is digital. The defaults reproduce v0.3's random draws and numbers exactly.
Wavelength-dependence assumptions
Every v0.4 parameter with its default, source tag and where the simulator sweeps it, rendered from the vendored results/results.md.
| parameter | default | source | swept | meaning |
|---|---|---|---|---|
wdm.lambda0_nm | 1310 nm | illustrative | fixed | centre wavelength lambda0, O-band (the CW-WDM MSA defines O-band grids; its numbers are not used here) |
wdm.spacing_GHz | 200 GHz | illustrative | 100–800 and a 20 nm grid, W = 1–32 (e17) | channel spacing of the default plan (W = future.wavelengths) |
wdm.band_nm | 100 nm | textbook | fixed | O-band width (1260-1360 nm); wider plans are flagged |
wdm.ng_over_neff | 1.7 | illustrative | 1–2.2 (e17) | n_g / n_eff of the mesh waveguides: a designed phase scales as phi0 (1 - (n_g/n_eff) delta) |
wdm.heater_phase_fraction | 0.5 | illustrative | 0–1 (e17) | share of each nominal mesh phase that is heater-set and scales as phi0 (1 - delta); thermo-optic dispersion ignored |
wdm.path_mismatch_um | 0 um | illustrative | 0–100 (e17) | extra length of the two lines that cross between the mesh stages (a1, b0) |
wdm.coupler_dkappa_per_pct | 0 | illustrative | 0–0.3 (e17, reported separately) | fractional change of each directional coupler's power coupling per 1 % of delta |
wdm.ring_radius_um | 5 um | illustrative | 3–20 (e17) | modulator and demux ring radius; FSR = lambda0^2 / (n_g 2 pi R) with n_g = receiver.group_index |
wdm.calibration | least_squares | illustrative | centre and least_squares (e17) | shared-mesh heater calibration: centre or least_squares over the W channels |
wdm.output_trim | no | illustrative | off and on at 16 and 32 channels on the default grid (e17) | per-channel output-phase trim (a diagonal phase per output port, set by per-channel LOs after the demux filters); off by default |
wdm.ref_margin_dB | 10 dB | illustrative | fixed | ideal-transform margin of the reference receiver for the exact-mode span limit (about v0.1's worked example) |
New simplifications
- Wavelength dependence (v0.4): first order in δ; thermo-optic dispersion ignored (heater-set phases scale as 1 − δ); heater phases scale from their nominal value, not from a 2π-wrapped one; no fabrication offsets on the mesh; the LO path is assumed matched (to about 0.08 µm) or trimmed per channel; experiment 17 reports the phase an unmatched path would add; ring spectra (beyond the FSR check), polarisation and crosstalk between channels are not modelled; the exact-mode span limit is taken at a reference receiver whose ideal transform has
wdm.ref_margin_dB. - Not modelled: ring spectra beyond the FSR check, thermo-optic dispersion (heater phases scale exactly as 1/λ), polarisation, crosstalk between channels, and the signal/LO path rotation above (assumed matched or trimmed, not applied).
Open questions
- the mesh's real n_g/n_eff and its split between designed and heater-set phase, and whether its couplers are directional couplers (whose drift would dominate) or MMIs;
- the ring radius and group index of the O-band modulator and demux rings, which set the free spectral range that binds first.
Validation: what each test proves
The simulator’s own test suite, as described in its documentation. Each table lists the tests in one file and what passing them establishes.
tests/test_functional.pybit-exact layer21 tests
| test | proves |
|---|---|
test_primes_are_ntt_friendly | the test primes (65,537; 12,289; 7,340,033; 998,244,353 ≈ 2³⁰; a 55-bit prime) are prime and support the transform sizes used |
test_dft_of_worked_example | DFT([1,0,1,1]) = [3, j, 1, −j] under the e^{−j2πkn/4} convention |
test_output_alphabet_ranges | X0 ∈ 0..4, X2 ∈ −2..2 (both real), X1, X3 parts ∈ {−1,0,1}, X3 = X1* |
test_parity_relation | X0 − X2 = 2(x1 + x3), so X0 and X2 share parity |
test_only_two_inputs_clip_never_together | only [1,1,1,1] and [1,0,1,0] saturate, never on the same word twice |
test_decode_table_has_16_valid_distinct_entries | 16 valid entries of 256, all distinct spectra |
test_decode_table_round_trip | encode → decode returns the exact DFT for all 16 inputs |
test_all_108_single_slips_detected | every in-range ±1-level slip on one output lands on an invalid entry (108/108) |
test_parity_recovery_matches_table | the patent-style parity recovery (no table) agrees with the table on all 256 entries |
test_bit_plane_shift_add_is_linear | (hypothesis) bit planes through the ideal core + shift-and-add equal the integer DFT |
test_twos_complement_planes | (hypothesis) signed operands round-trip through two's-complement planes |
test_ntt4_from_dft_sign_convention | a + ωb is the 4-point NTT with root −ω; a − ωb with root ω (all primes) |
test_optical_ntt_equals_reference | (hypothesis) the radix-4 NTT built only from the optical kernel equals the naive NTT, N ≤ 256, all primes |
test_ntt_round_trip_without_bit_reversal | (hypothesis) DIF forward then DIT inverse returns the input with no reordering pass |
test_convolution_theorem | (hypothesis) the reference NTT diagonalises cyclic convolution |
test_negacyclic_polymul_optical_vs_schoolbook | (hypothesis) the twisted-NTT negacyclic product (modular and optical kernels) equals schoolbook mod (xᴺ+1, p) |
test_wide_prime_optical_path | the optical path is exact for a 55-bit modulus (55 planes per operand) |
test_radix2_reference_equals_naive | the independent radix-2 reference equals the naive NTT (all primes, N ≤ 256) |
test_65536_point_optical_equals_reference | at N = 65,536 the whole optical radix-4 output vector equals the independent radix-2 reference and the pure-modular radix-4 transform (p = 65,537 and 998,244,353). It takes (N/4)·8·w passes with no invalid words, and spot outputs match the definition |
test_65536_point_round_trip_through_optics | forward DIF and inverse DIT, both through the optical kernel, return the input at N = 65,536 |
test_digit_reverse_is_involution | the base-4 digit reversal is its own inverse |
tests/test_analog.pyanalogue chain14 tests
| test | proves |
|---|---|
test_worked_example_currents_to_0p1_uA | currents 239.6, 0, 36.6, −36.6 µA; pedestal 130.0 µA; step 36.6 µA, each within 0.1 µA |
test_worked_example_fields | field fractions 0.905/0.426, fields 5.97/2.81 √µW, d = 3.16, E_LO = 17.8, 23.1 µA/√µW, Y = [10.36, 1.58j, 1.58, −1.58j] |
test_noise_and_margin | total noise 1.09 µA rms, required step ≈ 9.8σ, ≈ 37 dB available, ≈ 0.5° phase noise |
test_mesh_is_half_dft_and_unitary | the heater mesh is ½·DFT at zero error and unitary for any heater errors; random fabrication perturbations stay unitary |
test_mesh_periodic_in_heater_phase | heater phases are 2π-periodic (physically required) |
test_ideal_levels_equal_dft | with no impairments the analogue levels equal the integer port values |
test_fabrication_error_from_config | oft.fab_error_rms produces a seeded, unitary OFT error (none by default); link.n_lanes must be 4 |
test_compress_inverse | the soft limiter and its inverse are consistent; values beyond the asymptote map to ∞ |
test_monte_carlo_matches_analytic | Monte Carlo SER agrees with the analytic SER within 5σ at two LO powers |
test_errors_mostly_detected | at low LO most symbol errors land on invalid table entries (detected) |
test_noisy_core_at_default_lo_gives_exact_ntt | a 256-point NTT through the noisy analogue core at −5 dBm LO is bit-exact with no invalid words |
test_lo_phase_rotates_quadratures | a 90° LO error swaps the read quadrature (rotation) |
test_isi_drive_wide_band_is_ideal | a very wide channel gives back the ideal NRZ samples |
test_skew_hurts_at_narrow_bandwidth | skew shrinks the eye at 0.75 × baud |
tests/test_calibration.pycontrol layer7 tests
| test | proves |
|---|---|
test_seventeen_heaters | the layout matches the config's 17 phase shifters |
test_heater_v_squared_law | phase = π(V/Vπ)², the full scale covers 2π, and the LSB phase step grows with code |
test_zero_error_is_ideal | zero heater error gives a perfect truth table; batching works |
test_ordered_calibration_passes | from random (including uniformly random) offsets the ordered calibration passes, far inside half a step |
test_loop_step_matches_explicit_iteration | the closed-form tracker equals n explicit first-order updates |
test_no_recalibration_at_low_drift | default drift: no recalibration, availability 1 |
test_fast_drift_slow_pilot_forces_recalibration | fast drift with a slow pilot triggers marker failures, recalibrations and lost availability |
tests/test_timing_energy_workloads.py10 tests
| test | proves |
|---|---|
test_simpy_latency_matches_analytic | the SimPy frame model reproduces the analytic NTT latency for N = 256 / 4,096 / 65,536 at 8, 17 and 55 bits (hybrid and FPGA-only) |
test_butterfly_counts | (N/4)·log₄N butterflies |
test_amdahl_bound | removing the 8 adds gives at most 1 + 2/r |
test_optical_rate_scales | rate ∝ baud / width |
test_hybrid_rate_limits | the hybrid rate is the minimum of its optical and FPGA sides |
test_pauses_and_retries_reduce_throughput | calibration pauses and detected-error retries cost throughput in SimPy |
test_energy_components | energy terms add up; link energy = 2.76 pJ × 4w; FPGA-only = (4r+8) adds |
test_random_clip_duty_is_one_eighth | random bits clip 2/16 of words |
test_word_inversion_removes_clipping | per-word inversion removes all clipping words at a flag rate equal to the clip duty |
test_run_lengths, test_fp4_reference | helpers |
tests/test_config_results.pyprovenance and reproducibility15 tests
| test | proves |
|---|---|
test_every_field_has_a_source_tag | every default parameter is tagged paper/patent/datasheet/textbook/public-statement/illustrative |
test_default_yaml_in_sync | configs/default.yaml is exactly what the code defaults generate and loads back equal |
test_yaml_round_trip_with_override | overrides load; unknown keys are rejected |
test_sig6_and_fmt | 6-significant-figure rounding and markdown formatting |
test_rerun_is_byte_identical | run_all --profile ci reproduces the committed results/ci/results.json byte for byte |
test_readme_numbers_come_from_results_md | the README headline lines are copied verbatim from results/results.md, and every number token in the README's prose (outside code, document identifiers and links) is a number token in results/results.md |
test_committed_full_results_match_code | the committed full-profile results/results.json is what the current code produces (every experiment except the slow drift study, the timing benchmark and the calibration-scaling study is re-run), and its config hash matches the defaults |
test_every_experiment_has_section_figure_and_web_json | each experiment has its results.md section, a figure PNG and results/web/<experiment>.json |
test_every_config_field_is_used_or_declared_unused | no dead configuration: every field is read by the model, or its note says it is not used |
test_web_json_schema | each results/web/e*.json follows schema v3 and carries the run's config hash |
test_roofline_json | every roofline point lies under min(compute roof, intensity × HBM roof) |
test_fixtures_consistent | the portable fixtures agree with the functional layer |
test_bar_figures_keep_category_labels | bar charts rendered from the web JSON keep their category labels (regression) |
test_naming_check_detects_and_passes | the naming checker finds a planted (dummy) forbidden string |
test_repository_passes_naming_check | no tracked file or path contains the forbidden name |
tests/test_dc_balance.pyAC coupling and frame-inversion DC balance9 tests
| test | proves |
|---|---|
test_low_pass_matches_explicit_recursion | the blockwise high-pass/low-pass evaluation equals the sample-by-sample recursion |
test_tau_at_100kHz | τ = baud / (2π f_c): about 22,282 symbols at 100 kHz and 14 GBd |
test_inversion_flips_every_deviation | DFT(1 − x) = 4δ − X, so inversion negates every output's deviation from mid-level |
test_frame_inversion_round_trip_is_bit_exact | encode → ideal core → uninvert recovers the exact spectra |
test_vector_rds_is_bounded_by_one_frame | the vector encoder keeps the running digital sum bounded on run-heavy data |
test_biased_data_wander_matches_planner_check | the brief's planner numbers at τ = 22,000: uncoded 1.1–1.6 steps on 80 %-ones data; small with 64-symbol frames, about 0.08 with 1,024 |
test_scalar_balance_leaves_other_outputs_wandering | balancing output 1 alone leaves outputs 2–4 beyond half a step on runs; the vector encoder does not |
test_balanced_idle_and_pause_costs | balanced idle fill does not wander; a dark pause offsets output 1 by its full deviation; settling time is τ·ln(offset / tol) |
test_pattern_inverse_pairs_reduce_calibration_error | single-pattern dwell error is 2(1 − e^(−M/τ)); pattern/inverse pairs cut it more than twenty-fold |
tests/test_fast_path.pyportable Monte Carlo and the Rust fast path10 tests
| test | proves |
|---|---|
test_splitmix64_reference_values | the counter stream reproduces SplitMix64's published first outputs |
test_special_functions_accurate | the arithmetic-only ln, sin and cos agree with libm to ~1e-15 |
test_normals_are_standard | the Box–Muller draws have mean 0, variance 1 and the right 3σ tail |
test_blocks_are_counter_based | any block of symbols can be generated independently; batch size does not change results |
test_noiseless_symbols_match_reference_chain | with noise off, the portable chain's decisions equal AnalogChain slicing for every input word, with lane and LO phase errors |
test_portable_mc_matches_analytic | Monte Carlo SER (per-sample signal shot noise, phase noise) agrees with the analytic SER within 5σ |
test_fallback_without_rust | without the extension, auto warns and runs NumPy with the same counts; asking for rust raises |
test_rust_python_parity_exact | (needs the extension) identical words, symbols and error counts on three configurations (default, impairments + compression + strong phase noise, fabrication error without signal shot noise) and three seeds incl. one above 2⁶³ |
test_rust_normals_identical | (needs the extension) the Rust Gaussian stream equals NumPy's bit for bit |
test_rust_built_when_required | in the CI job that builds the extension (PLMS_REQUIRE_RUST=1) the parity tests cannot silently skip |
tests/test_bootstrap_memory.pyOpenFHE traces, bootstrap mapping, memory model13 tests
| test | proves |
|---|---|
test_vendored_files_match_source_json | the vendored logs are byte-identical to the pinned source (SHA-256 in SOURCE.json) |
test_trace_totals | per-kind event totals and line counts of all four logs equal counts summarised from the files (27,666 and 9,035 lines for full14 and sparse16) |
test_trace_per_stage | events per stage and NTT/iNTT limb counts per stage, and NTT points = limbs × N |
test_header_and_relin | header fields, relinearisation key and output towers parse |
test_bad_lines_rejected | unknown lines and events before the header are errors, not silently skipped |
test_kernel_merge_conserves_work | merging repeated events keeps every event and every limb NTT |
test_lru_cache | key/plaintext LRU hits, eviction and never-fitting objects |
test_word_bytes_and_width_scaling | narrower primes need 59/w times the butterflies |
test_fpga_placement_uses_no_module | FPGA-only sends nothing to the module; hybrid sends less than optical; memory traffic does not depend on placement |
test_stage_times_add_up | stage times plus host transfers equal the total; shares lie in [0, 1] |
test_simpy_conservation_and_bounds | in the SimPy replay, bytes and work served equal what was requested on every resource; no resource exceeds 100 % in any time bin or stage; the replay is never faster than the analytic bound and within 15 % of it |
test_more_hbm_bandwidth_helps_memory_bound_stage | an HBM-bound stage (CoeffToSlot) speeds up with more bandwidth |
test_signal_shot_noise_lowers_output1_margin | output 1 (carrier pedestal) is the noisiest output for every input and its margin is lower than output 3's; with signal shot noise off they are equal again |
tests/test_future.pythe future 3D-stacked chip (v0.3)19 tests
| test | proves |
|---|---|
test_transform_energy_parts_add_up | the per-transform energy components sum to the total; static power = laser at the wall + phase shifters, and charged per transform it gives that power back at the transform rate; crossings = 4w(1 + out_bits) × E_conv |
test_bootstrap_energy_and_power_conservation | per bootstrap (chip, all-optical, ASIC, compute-bound): energy components sum to the total; laser and phase-shifter energy = their power × the bootstrap time; stage times + host = total; static + average dynamic power stays within the power cap |
test_photonic_slots_never_exceed_capacity | symbol slots used never exceed U × W × B × efficiency × time; the optical share lies in [0, 1] |
test_tia_transimpedance_limit | R_T ∝ 1/C_T and ∝ 1/f_3dB²; TIA noise ∝ 1/√R_T |
test_margin_monotone_in_powers | margin rises with signal and with LO power and falls with baud |
test_laser_budget_monotonic | margin falls as one laser feeds more units; the largest U per laser rises with laser power, falls with the margin and with baud; the reported U holds the margin and U + 1 does not; lasers needed never fall as U grows |
test_heater_power_scales_and_technologies | phase-shifter power ∝ U; MEMS ≪ thermo-optic; non-volatile holds at zero; no photonic layer, no static power |
test_unit_config_is_v01_at_u1_without_logic_heat | at U = 1 (no sharing, no logic heat) a unit's control config is v0.1's, unchanged |
test_calibration_reduces_to_v01_at_u1 | with recalibrations happening, the queueing model's availability at U = 1 equals simulate_control's exactly |
test_fleet_simpy_matches_queueing_theory | the SimPy fleet with exponential recalibration times matches the exact M/M/P//U result; more channels never hurt, more units per channel never help; storms only reduce the in-service fraction |
test_asic_reduces_to_v02_fpga_with_its_logic | the digital-ASIC baseline with 64 butterfly units at 400 MHz gives v0.2's FPGA-only bootstrap time exactly |
test_asic_sanity | the ASIC uses no optics, laser or crossings; it gets faster with more logic and never slower with more HBM; modular multiply energy ∝ w², add ∝ w |
test_optimal_split_bounds | the optimal optical share is never slower than the chip's logic alone or than all-optical, and never faster than the exact-mode ceiling, which is never faster than NTT-free |
test_power_cap_makes_huge_designs_infeasible | a design whose static power exceeds the cap is reported infeasible (infinite time) |
test_temperature_map_and_uniform_heat | the TEC removes a uniform temperature rise; with no hot spots no unit sees a phase error; phase errors scale linearly with logic heat flux |
test_crosstalk | the crosstalk matrix is symmetric with zero diagonal; no crosstalk, no residual; more ordered sweeps, less residual |
test_fft_dif_matches_numpy | the stage-by-stage radix-4 FFT equals numpy's FFT in digit-reversed order |
test_fft_error_ideal_and_degrading | with no loss, phase error, noise or quantisation the chained FFT is exact; more ENOB and more SNR give more effective bits |
test_approx_energy_falls_with_chaining | energy per butterfly-stage falls and throughput never falls as more stages chain; parts add up |
tests/test_wdm.pywavelength dependence on a shared mesh (v0.4)18 tests
| test | proves |
|---|---|
test_zero_offset_gives_v03_mesh_exactly | at δ = 0 the phase errors are exactly the heater corrections (zero by default) and the mesh is v0.3's U_DFT itself, also with coupler drift on; W = 1 is δ = 0 |
test_coupler_with_kappa_half_is_the_v03_coupler | an MZI built from two 50:50 directional couplers equals v0.3's coupler; off 50:50 it stays unitary |
test_margin_on_ideal_transform_is_v03_margin_exactly | the per-channel margin on the ideal transform equals future.margin_dB bit for bit |
test_single_wavelength_restates_v03_laser_limit | with no transform error the restated largest U per laser is e14's |
test_fft_with_ideal_kernel_is_v03_byte_for_byte | approximate mode with no kernel and no twiddle scaling returns v0.3's result exactly (same draws) |
test_e17_single_channel_rows_equal_e16 | experiment 17's W = 1 rows equal experiment 16's effective bits after rounding, with zero error and the reference margin |
test_error_is_linear_and_slope_matches_ng_over_neff | the transform error is linear (doubling δ doubles it) and even in δ to first order; the slope ratio of designed to heater-set phases equals n_g/n_eff (1.0, 1.7, 2.2) |
test_phase_errors_scale_with_the_right_slope | phase errors are −φ0 (h + (1 − h) n_g/n_eff) δ; path mismatch adds −2π n_g ΔL δ/λ0 on the crossing lines only |
test_first_order_estimate_of_the_brief | 16 channels at 200 GHz around 1310 nm span about 18.3 nm with edge offsets of about ±0.66 % on a uniform, centred grid |
test_least_squares_never_worse_than_centre_on_the_mean | (hypothesis) over plans, phase mixes, coupler drift and path mismatch, least squares never has a higher mean squared error than centre calibration |
test_least_squares_helps_an_asymmetric_plan | with all channels on one side of λ0, least squares halves the error at least; unknown strategies are rejected |
test_per_wavelength_mesh_has_zero_wavelength_error | a mesh per wavelength, calibrated for its own channel, has zero error (also with path mismatch and coupler drift), where the shared mesh does not |
test_fsr_at_known_values | FSR = λ0²/(n_g 2πR) = 14.006 nm at R = 5 µm, halves at twice the radius; 200 GHz is 1.1449 nm; 8 channels fit and 16 do not; one channel always fits |
test_margin_falls_with_offset_and_is_symmetric | the reference receiver has the reference margin; margin falls and SER rises with \|δ\| on both sides of λ0 |
test_normal_step_matches_lstsq_and_calibration_sits_on_its_grid | the deterministic normal-equation step (exactly rounded sums, Python elimination) equals LAPACK's least-squares solution; least-squares corrections lie on the 1e-8 rad grid, repeat exactly and contain no −0.0 |
test_output_trim | the per-channel output-phase trim never increases any channel's error and lowers the worst; it is the identity on the ideal transform and removes a pure output phase; it is off by default and leaves the heater calibration unchanged |
test_lo_path_tolerance_is_sub_micron | an unmatched 1 mm signal/LO path rotates the edge channel of 16 × 200 GHz by 122.6 rad; the mismatch at which that equals 0.01 rad is under 0.1 µm |
test_ring_table_counts_single_channels | experiment 17's "max W that also fits the ring" counts a single channel as fitting (1 on the 20 nm grid), as ring_feasible does |
This site’s own tests
- Functional port vs fixtures
- The TypeScript DFT, PAM4 mapping, decode table, parity recovery and radix-4 NTTs reproduce the vendored fixtures exactly (alphabet, decode table, and the 16- and 256-point NTTs), and the optical NTT, inverse NTT and negacyclic product match vectors generated by running the vendored Python.
- Monte Carlo, bit for bit
- On the reference's own tables, the browser's per-symbol Monte Carlo produces the same words, symbols and error counts as the Python reference for four configurations, including impairments, compression and phase noise; the SplitMix64 stream, the polynomial ln/sin/cos and the Box–Muller normals are bit-identical.
- Analogue chain
- Link budget, currents, levels, noise, thresholds, analytic SER, the heater mesh, compression, the pulse response and ISI drive agree with the reference to stated tolerances; the worked example matches the vendored fixture to its six significant figures.
- DC balance
- Frame-inversion flags are identical to the reference's; baseline wander, settling, pause offsets and calibration error agree to rounding; encode → ideal core → un-invert is exact.
- Number traceability
- Every number id resolves to a value in the vendored results; an unknown id fails the build; an end-to-end check fails any page that shows a number in prose that is not drawn from those files.
- Animations
- Each animation's state sequence is a pure function of the tested model; frame tests compare key frames with the Python reference; the clock is unit-tested; end-to-end tests play, step, scrub and reset every animation in both themes at desktop and phone widths, and check nothing auto-plays with reduced motion.
- Future chip (Part II)
- The browser's port of the transimpedance limit, the laser budget, the heater-phase sampling of the temperature map and the M/M/P//U fleet queue reproduces the simulator's receiver table, losses, per-receiver powers, phase errors and every in-service fraction; the stacked-stage animation reproduces the Python NTT reference stage by stage; every sliced design point of experiment 12 reads back exactly.
- Wavelength dependence
- The browser's port of the v0.4 phase scaling (channel plan, ring FSR, designed and heater-set phases, the output-phase trim) reproduces the simulator's per-channel errors and worst outputs for every channel of its per-channel example plan, with the simulator's heater settings; the plan explorer's readouts equal the vendored plan table for every swept plan.
- Landing diagram gestures
- The gesture state machine is unit-tested for tap, press-and-hold, release after hold, move-to-cancel and keyboard, and exercised with touch emulation at phone width.
- Provenance and naming
- The vendored files' SHA-256 hashes are checked against vendor/plms/SOURCE.json; the naming check scans every tracked file and the built site.
Reproducibility
The site is built from a pinned copy of the simulator’s outputs and reference code: commit fe2ee0a of BrendanJamesLynskey/Photonic_Link_Module_Sim (private), configuration hash 8f28f943c232. Every web data file carries that hash and the tests check it. The simulator pins every dependency, so its committed results regenerate byte for byte; its own tests check this.
The SHA-256 of every vendored file is recorded in vendor/plms/SOURCE.json, and CI fails if any file differs or an unlisted file appears. To refresh the site, re-copy the simulator’s outputs at a new commit and update that file.
To build the static site locally (it lands in out/):
pnpm install
pnpm buildLimitations
The noise is Gaussian at the TIA input; shot noise includes the signal power on each pair (since v0.2), which costs output 1 some margin through its carrier pedestal. Phase noise is in the Monte Carlo only. Skew/ISI uses a Gaussian or first-order channel on the drive with circular convolution. The calibration's joint refinement step stands in for the patent's procedure, whose details are not given. The tracker is a closed-form first-order loop per heater. Timing uses stage barriers and ignores DMA and host software. Energy charges the module's whole static power to NTT work and applies the link pJ/bit figure to input bits only. AC coupling is a single first-order high-pass at the TIA input, the frame-inversion encoder uses the running digital sum (not the filter state), and flag errors are not modelled. The arXiv paper itself could not be fetched from the build environment, so the build relied on the brief's summary of it.
Simplifications in the model
- Noise is Gaussian, referred to the TIA input. Shot noise counts the LO and the signal power on each balanced pair, per input word (
receiver.signal_shot_noise, on by default since v0.2): output 1's carrier pedestal makes it the noisiest output. Phase noise is in Monte Carlo, not in the analytic SER. - Monte Carlo slices against thresholds referred to the TIA input instead of compressing each sample (equivalent because the compression is monotonic).
- Bootstrap: kernels run serially in recorded order; a kernel's bursts pipeline. Limb counts scale fractionally with residue width. The INTT scaling by n⁻¹ (n multiplies per limb, a few per cent of the butterfly work) is left out. Keys and plaintexts start resident in HBM (no host transfer); only the ciphertext crosses PCIe. HBM is one aggregate server (no channel or bank model). MODUP markers carry no work (their conversions and NTTs are logged separately).
- Noise bandwidth is a fixed fraction of baud (0.47, illustrative, chosen to reproduce the brief's 1.09 µA).
- Skew/ISI: a linear Gaussian or first-order channel on the electrical drive, a per-lane delay, sampling at the unskewed optimum, and a short periodic sequence. The optical path and receiver are treated as wideband.
- The OFT is modelled as a 2-stage radix-2 mesh of tunable MZI couplers and phase shifters with ideal fixed parts. The real layout is not given.
- Calibration: cost evaluations are noiseless (long averaging assumed). The joint refinement stands in for the patent's procedure.
- Tracking: an independent first-order loop per heater, with drift inside a monitoring period treated as a ramp.
- Timing: stage barriers between NTT stages, no DMA or host software overhead, FPGA post-processing as a single pipelined server.
- Energy: the module's whole static power is charged to the work, and the link pJ/bit is applied to input bits only.
- AC coupling: a single first-order high-pass. The frame-inversion encoder balances the running digital sum, not the filter state. Flag transmission errors are not modelled.
control.sample_interval_sis recorded but not used. The loop is evaluated once per monitoring period.
Simplifications on this site
- The browser runs the functional layer and the per-symbol analogue chain only. Heavy sweeps (noise margin against LO power, drift and availability, the bootstrap sweeps, the SimPy replays) are plotted from the simulator’s results, never recomputed.
- Illustrations that need random data (eyes, histograms, scrolling lanes) draw it from the same counter-based stream as the simulator’s Monte Carlo, but with the site’s own seeds; they illustrate the model rather than reproduce a particular published run.
- The break-even explorer (chapter 10) only shows points the simulator computed; it interpolates between computed widths and does not extrapolate to combinations outside the vendored sweep slices.
How to extend
The simulator
- Measured analogue model. Implement
transform(planes) -> CoreResult(theOpticalCoreprotocol inplms.functional) or subclassAnalogChain, then hand it toOpticalKernel. Everything above it is unchanged. - Fast paths (C++/Rust/RTL). The seam is the same protocol plus
ntt_dif_radix4/intt_dit_radix4'skernelargument; fixtures inresults/web/fixtures/give bit-exact vectors to check against. The Monte Carlo already has one (rust/); a new backend only needsChainTables.flat()and the stream layout inplms/portable_mc.py. - Another FHE trace or accelerator. Any log in the same line format works with
read_trace; changefhe.*andmemory.*in the config or pass abootstrap.Point. - New experiment. Add
plms/experiments/eN_name.pywithKEY,TITLEandrun(cfg, profile) -> Result, list it inrun_all.EXPERIMENTS. Its web JSON and figure are produced automatically. - Future-chip variants (v0.3). Every chip, laser, thermal and ASIC figure is a config field (
future.*,laser.*,thermal.*,asic.*);plms.future.evaluatetakes aDesign(U, W, B, width, E_conv, HBM, SRAM, logic units, split, phase-shifter technology), andDesign(units=0)is the all-digital ASIC. - FP4 (E2M1) MAC.
plms/fp4.pyholds the interface and an exact digital reference. An optical model would need the operand-to-amplitude encoding, the analogue multiply and accumulate mechanism, its precision and noise, and energy figures (see the paper's section V projection, quoted indocs/build_brief.md).
This site
- A new number in prose: register an id in
src/data/nums/pointing at its path in the vendored results, then write<Num id="…" />. Unknown ids fail the build. - A new animation: build its state sequence from the tested model in
src/anim/, add frame tests against the Python reference intest/anim/, and render it inside<Player>, which supplies the controls, captions, reduced-motion handling and off-screen pausing. - A measured model: port it behind the same interfaces as
src/model/and regenerate the reference vectors withscripts/reference/gen_vectors.py. - Conventions are in
docs/site_conventions.md; the visual standard isdocs/visual_standard.md.