# CUDA IO benchmark, 2026-10-23

Physical device: **NVIDIA RTX PRO 6000 Blackwell Workstation Edition**. Source fingerprint: `8efd434d9626dd30cfffaeb377fcafd6ca2042b4748ce2910605457398fdc201`.
Runtime: Python 3.14.6, PyTorch 2.13.0, CuPy 14.2.0, CUDA runtime 12.9; 96 GB GPU memory.

Private experiment: `20261023-qem-backend-verification`. All input files were SHA-256 matched across systems.

This report keeps first observations separate from the median of repetitions two and three. OS caches were uncontrolled; these are not cold-disk results. Three repetitions are a small diagnostic sample, not a tail-latency guarantee.

Every successful conversion compares every source count exactly, including flagged pixels. Loading uses native precision and explicitly disables pixel correction; no cropping or binning is applied.

[Shared definitions and implementation](2026-10-23-qem-verification.md). Reproduce with `scripts/benchmark_io_scale.py SOURCE_FOLDER --backend cuda --output-dir PRIVATE_DIRECTORY --reps 3`.

HDF5 timing is synchronized public `io.load` wall time, including reading, decoding, ANS encoding and indexing. The first process may reuse a persistent frame index; repetitions reuse that process. Fresh-index startup is reported separately below. QEM reload timing ends at encoded residency; it does not expand the complete logical tensor.

QEM measurements retain their original source snapshots: `8efd434d9626dd30cfffaeb377fcafd6ca2042b4748ce2910605457398fdc201`, `9b041692a539689251fe0a31a42081420ff83c4dba67b0e98fa8b8827bfe2de2`. The later driver revision makes the raw-count loading policy explicit and benchmarks the two expanded copies; it does not change their GPU arithmetic.

Initial QEM reopen is measured inside verification (Python) or the native round trip. The dedicated reloads occur afterward; their first observation is not the first-ever opening of the file. An unavailable isolated reopen timing is shown as a dash.

## Loading

| Acquisition | Scan × detector | HDF5 first (s) | HDF5 repeated median (s) | Initial QEM reopen (s) | Dedicated QEM reload 1 (s) | QEM repeated median (s) |
|---|---|---:|---:|---:|---:|---:|
| acquisition-03 | 256² × 192² | 2.81 | 0.22 | 0.14 | 0.10 | 0.08 |
| acquisition-06 | 512² × 96² | 2.91 | 0.28 | — | 0.23 | 0.23 |
| acquisition-07 | 512² × 96² | 2.73 | 0.26 | — | 0.24 | 0.24 |
| acquisition-01 | 512² × 192² | 3.33 | 0.43 | 0.31 | 0.28 | 0.27 |
| acquisition-02 | 512² × 192² | 3.24 | 0.44 | 0.32 | 0.27 | 0.27 |
| acquisition-04 | 512² × 192² | 3.30 | 0.60 | 0.34 | 0.31 | 0.31 |
| acquisition-05 | 512² × 192² | 3.40 | 0.63 | 0.36 | 0.31 | 0.32 |
| acquisition-11 | 512² × 192² | 3.43 | 0.63 | 0.32 | 0.27 | 0.27 |
| acquisition-08 | 1024² × 192² | 5.83 | 2.69 | 1.36 | 4.95 | 4.11 |
| acquisition-09 | 1024² × 192² | 5.78 | 2.95 | 1.27 | 5.45 | 1.51 |
| acquisition-10 | 2048² × 192² | 14.09 | 11.13 | 10.36 | 10.32 | 13.74 |

## Fresh frame-index startup

Each acquisition was loaded once in a fresh process with its own empty frame-index cache directory. This includes index creation and process-local initialization. Disk and compiler caches were uncontrolled; these are not cold-disk results. The main loading table above allows an existing frame index.

| Acquisition | HDF5 fresh-index startup (s) |
|---|---:|
| acquisition-01 | 3.79 |
| acquisition-02 | 3.58 |
| acquisition-03 | 2.76 |
| acquisition-04 | 3.90 |
| acquisition-05 | 3.92 |
| acquisition-06 | 3.39 |
| acquisition-07 | 3.35 |
| acquisition-08 | 7.51 |
| acquisition-09 | 7.98 |
| acquisition-10 | 23.03 |
| acquisition-11 | 3.91 |

Reproduce with `QUANTEM_GPU_HDF5_FRAME_SOURCE_CACHE_DIR=EMPTY_TEMP_DIRECTORY python scripts/benchmark_hdf5_load.py SOURCE --backend cuda --dtype native --hot-pixel-correction none --reps 1 --json-out PRIVATE_REPORT.json`, using a new empty directory for each input.

## Encoding, saving and verification

Encode and index columns are accumulated CUDA event times from the loader. They are GPU stage diagnostics within HDF5 loading and must not be added to its wall time. Verification includes QEM reopen.

| Acquisition | Encode (s) | Index (s) | QEM save (s) | Full verification (s) | Conversion total (s) | QEM GiB | HDF5 / QEM | Logical uint16 / QEM |
|---|---:|---:|---:|---:|---:|---:|---:|---:|
| acquisition-03 | 0.02 | 0.01 | 1.72 | 0.45 | 3.14 | 0.456 | 1.47× | 9.87× |
| acquisition-06 | 0.06 | 0.01 | 0.92 | 0.61 | — | 1.597 | 0.80× | 2.82× |
| acquisition-07 | 0.06 | 0.01 | 0.92 | 0.56 | — | 1.597 | 0.80× | 2.82× |
| acquisition-01 | 0.07 | 0.03 | 3.09 | 1.10 | 5.87 | 1.913 | 1.48× | 9.41× |
| acquisition-02 | 0.07 | 0.03 | 1.15 | 1.28 | 4.07 | 1.920 | 1.48× | 9.38× |
| acquisition-04 | 0.08 | 0.03 | 4.59 | 1.20 | 7.74 | 2.193 | 1.43× | 8.21× |
| acquisition-05 | 0.08 | 0.03 | 2.81 | 1.15 | 5.82 | 2.200 | 1.43× | 8.18× |
| acquisition-11 | 0.07 | 0.03 | 2.71 | 1.27 | 5.67 | 1.916 | 1.48× | 9.40× |
| acquisition-08 | 0.29 | 0.11 | 20.89 | 8.79 | 36.99 | 8.767 | 1.43× | 8.21× |
| acquisition-09 | 0.29 | 0.11 | 8.72 | 5.02 | 18.94 | 8.863 | 1.43× | 8.12× |
| acquisition-10 | 1.20 | 0.44 | 22.91 | 39.44 | 91.27 | 35.700 | 1.42× | 8.07× |

Ratios above one mean smaller QEM storage. The HDF5 ratio includes the acquisition master and detector shards. Logical storage is the complete original uint16 tensor. Conversion totals include source hashing and metadata work; they are not sums of the overlapping diagnostic columns.

For the two 96²-detector cases, the production converter declines to publish a larger copy. Save, full verification, and reload timings use an explicitly created disposable QEM. A production conversion total is therefore not reported.

## Default median-correction loading

The following additional measurements retain the public loader default of median correction. They are separate from the raw-count timings above; QEM preservation and full verification always use uncorrected counts.

| Acquisition | HDF5 first (s) | HDF5 repeated median (s) |
|---|---:|---:|
| acquisition-01 | 4.01 | 0.44 |
| acquisition-02 | 3.66 | 0.45 |
| acquisition-03 | 2.96 | 0.24 |
| acquisition-04 | 4.16 | 0.62 |
| acquisition-05 | 4.23 | 0.64 |
| acquisition-06 | 3.57 | 0.26 |
| acquisition-07 | 3.58 | 0.27 |
| acquisition-08 | 8.10 | 2.79 |
| acquisition-09 | 8.79 | 1.76 |
| acquisition-10 | 24.93 | 11.42 |
| acquisition-11 | 5.25 | 0.55 |

## Qualification limits

11 successful acquisitions, 287,494,373,376 values exhaustively compared, zero mismatches. Each QEM is removed after testing. HDF5 loading repetitions validate shape/dtype; full count verification is performed by the separate conversion workflow, not repeated during each load timing.

These measurements use a source checkout, not an installed release. Broader typed/FP8 failures and unavailable real-data gates remain visible in the [shared acceptance record](2026-10-23-qem-verification.md). Background system/storage activity and existing memory pressure are retained in private telemetry; these are observed workflow timings, not isolated hardware rankings.
