research/determinism-cost.md §4.6, in the same record and by the same procedure: the 192 payloads decoded again on every platform with every kernel set it runs (15 new runs, 0 decodes differing from the record's), and the record's time and energy runs repeated in one session per host beside the record's own build and the float decoder. On x86_64 host A the integer decode on the narrow kernels took 144.8 ms and 12.43 J of marginal package energy at quality 6 against 210.7 ms and 14.03 J for the float decode beside it (the record's build: 728.0 ms, 92.14 J). On the build host its own CPU energy fell from 11.01 J to 6.43 J at quality 6 and is still above the float decode's 1.28 J by that count. Host B's integer decode was measured before and after, without a float decode beside it. The scripts that took the readings are in runs/; decode-throughput.md notes the new sets; the changelog records the change. Co-Authored-By: Claude Opus 5.5 <[email protected]>
452 lines
67 KiB
Markdown
452 lines
67 KiB
Markdown
# What exactness costs: `wai.neural.int_hyper` against its float model
|
||
|
||
> **Status.** A measured record and its procedure, informative. Every figure below is
|
||
> computed from the readings in [`determinism-cost/record.json`](determinism-cost/record.json),
|
||
> and `tools/wai_determinism_cost_verify.py` recomputes each one from those readings and
|
||
> checks every figure this page and [determinism-tiers](../extensions/determinism-tiers.md)
|
||
> §7 quote from it (each is followed by a `det` marker naming its place in the record).
|
||
> What WAI claims, and does not, on the strength of this record is in determinism-tiers §7.
|
||
> Measured 2026-10-22; the runs of §4.6, on the narrow kernel sets, 2026-10-24 and 2026-10-25.
|
||
|
||
## 1. What is measured, and what is not
|
||
|
||
`wai.neural.int_hyper` is an integer export of one pretrained learned codec: the
|
||
mean-scale hyperprior `mbt2018_mean` (MSE), quantised to per-channel 12-bit weights and
|
||
activations at 2¹², with an integer inverse GDN and an integer hyper-decoder that decides
|
||
every entropy table (determinism-tiers §5). The float model is the same checkpoint, coded
|
||
and decoded by the library its checkpoints are published with. This record measures what
|
||
the integer decode costs against that float model, at all eight published qualities, on
|
||
pictures of the pinned reference set:
|
||
|
||
1. **Rate and distortion**: the BD-rate of the integer codec against the float codec, by
|
||
PSNR and by MS-SSIM (§2.4).
|
||
2. **Reproducibility across platforms**: each codec's streams decoded on every platform
|
||
reached, and each decode compared byte for byte with the first platform's (§2.5).
|
||
3. **Time and energy** of a decode, both codecs, on the CPU and on a GPU (§2.6).
|
||
|
||
Not measured here, and why:
|
||
|
||
- **`wai.image.jpegai`'s exact decoder.** It implements one configuration of the base
|
||
standard, which gives one rate point per picture, so it has no rate-distortion curve to
|
||
take a BD-rate over; and coding the reference set needs the standard's reference
|
||
encoder, which was not run. Its one comparison with the reference decoder, on one
|
||
codestream, is determinism-tiers §5 and §6.
|
||
- **`wai.neural.int_synth` and `wai.neural.int_mlicpp`.** Neither has a float model with a
|
||
rate axis to compare with: the committed `int_synth` vectors are a synthesis from a
|
||
given latent (one of them a quantised float model trained on one photograph, the others
|
||
seeded integer weights), and the `int_mlicpp` vector has seeded weights.
|
||
- **`wai.neural.mbt2018_mean`**, WAI's float capability over the same model family, which
|
||
decodes through an ONNX runtime. The float side here is the model's own library.
|
||
- **A neural processor.** No decoder on main runs its graphs on one
|
||
(determinism-tiers §5).
|
||
- **The encoder.** Both codecs analyse the picture in floating point. The integer tier
|
||
covers the decode: the bytes of a payload depend on the machine that encoded it, and
|
||
every conforming sink then decodes those bytes to the same picture.
|
||
|
||
## 2. Procedure
|
||
|
||
### 2.1 Pictures
|
||
|
||
The pinned reference manifest `wai-image-references.json` (SHA-256 `db33c663…6b554b66`,
|
||
the manifest `tools/wai_visual_provenance_check.py` pins) lists 384 files. The rule:
|
||
every PNG entry the manifest marks `self_test` that holds one picture of 768×512 or
|
||
512×768 samples. That gives 24 pictures, each checked against the manifest's SHA-256
|
||
before it is read and named in the record by the first 16 hex digits of that digest.
|
||
Both sides are multiples of 64, so every picture is coded whole.
|
||
|
||
### 2.2 The two codecs
|
||
|
||
- **Checkpoints.** The eight published `mbt2018_mean` (MSE) checkpoints, qualities 1–8,
|
||
each pinned by the SHA-256 of its bytes (`CKPT_SHA256` in
|
||
`tools/wai_determinism_cost.py`, and in the record) and loaded as tensors only.
|
||
Qualities 1–4 have N = 128, M = 192; qualities 5–8, N = 192, M = 320.
|
||
- **Float codec.** The library's own `compress` and `decompress` (release 1.2.8, on the
|
||
pinned stack of `tools/requirements-sota-int.txt`): the float analysis, the factorised
|
||
hyper-latent, the float hyper-decoder deciding each scale bucket, the float synthesis.
|
||
Its reconstruction in [0, 1] becomes 8-bit samples by ×255 and rounding half to even.
|
||
- **Integer codec.** The same model exported per quality exactly as
|
||
`tools/wai_sota_int_synth_export.py` exports quality 6, coded as a `WIH1` payload
|
||
(integer-payloads §4), and decoded by `wai_det_cost`, which runs `int_payload::decode_int`,
|
||
the integer decode path every reference sink runs. Two cross-checks tie the export to
|
||
the one CI already checks, both run on the build host: the quality-6 set this procedure
|
||
writes (`g_s.whm`, `h_s.whm`, `entropy.json`) is byte for byte the set the export tool
|
||
writes; and on the export tool's pinned photograph (from `tools/wai_sota_source_image.py`),
|
||
this procedure's integer encoder gives the export tool's hyper-decoder output and writes
|
||
both rANS streams byte for byte as the export tool does.
|
||
- **Encoding.** The library on one CPU thread with deterministic algorithms, on the build
|
||
host (§3).
|
||
|
||
### 2.3 Rate and distortion
|
||
|
||
- **Rate**: the bytes of the two entropy-coded streams, hyper-latent and latent, for both
|
||
codecs, ×8 over the picture's samples per channel (bits per pixel). A `WIH1` payload adds
|
||
a 32-byte header and two 4-byte lengths, which are not counted; the record keeps each
|
||
payload's size.
|
||
- **PSNR**: 10·log₁₀(255²·n / SSE) over all n samples of the three channels, against the
|
||
picture's 8-bit samples.
|
||
- **MS-SSIM**, the perceptual metric: per channel on 8-bit samples (dynamic range 255),
|
||
five scales, an 11-tap Gaussian window of σ = 1.5 applied over the valid region,
|
||
K₁ = 0.01, K₂ = 0.03, 2×2 mean pooling between scales, the contrast-structure term at
|
||
the first four scales and luminance-contrast-structure at the fifth, exponents 0.0448,
|
||
0.2856, 0.3001, 0.2363 and 0.1333, each term clamped at zero; the mean over the three
|
||
channels. BD-rate reads it as −10·log₁₀(1 − MS-SSIM).
|
||
|
||
### 2.4 BD-rate
|
||
|
||
Per picture, the integer codec's eight (rate, quality) points against the float codec's
|
||
eight, by the Bjøntegaard delta of ITU-T VCEG-M33: log₁₀ of the rate interpolated as a
|
||
function of quality by a monotone piecewise-cubic Hermite interpolant (the
|
||
Fritsch–Carlson slopes with the three-point shape-preserving ends), each curve integrated
|
||
over the quality range the two share, and the mean difference in log rate turned into a
|
||
percentage. A positive figure is the extra rate the integer codec needs for the float
|
||
codec's quality. A curve whose quality does not rise strictly with rate has no BD-rate, and
|
||
the record lists such pictures. The record states each picture's figure, and their
|
||
median, mean, minimum and maximum.
|
||
|
||
### 2.5 Reproducibility across platforms
|
||
|
||
Every integer payload is decoded on each platform of §3, and each decode's RGB8 compared
|
||
by SHA-256 with the build host's first decode of it. Every float stream is decoded again
|
||
in a fresh process on each platform and device of §3, under the entropy tables the
|
||
encoder used (their SHA-256 is recorded per platform, so a difference in the tables would
|
||
show), and its RGB8, its decoded entropy-table indexes and its decoded symbols compared,
|
||
each by SHA-256, with the encoding process's own decode. A decode whose indexes or symbols
|
||
differ has diverged in the entropy decode; one whose symbols agree and whose samples
|
||
differ has diverged after it. For every float decode that differs, the record keeps its
|
||
PSNR change.
|
||
|
||
### 2.6 Time and energy
|
||
|
||
`tools/wai_det_energy.py` runs a decoder as a child process that loads its models and
|
||
streams, decodes each once, and then decodes the same eight pictures (the first eight of
|
||
§2.1, at quality 2 and at quality 6) in each of seven rounds on command, blocking between
|
||
rounds. A round's time is the child's own clock around its decodes; every decode's output is
|
||
hashed and compared with its first decode, so no time is reported for a different output.
|
||
The counters, each with its scope:
|
||
|
||
- **The decoder's own CPU energy** (macOS): the kernel's per-task energy count
|
||
(`ri_energy_nj`, `proc_pid_rusage`), read while the child blocks and only once its CPU
|
||
time has stopped moving, so every thread's energy has folded into the count. Scope: the
|
||
decoding process, CPU only; it excludes the GPU. Class `OnChipCounter`, filtering
|
||
unknown. Energy that system services spend on the process's behalf is billed to it in a
|
||
separate count, which the record keeps beside it.
|
||
- **The GPU rail** (macOS): IOReport's `GPU Energy` channel, the whole GPU, read every
|
||
100 ms. A round's GPU figure counts only where the decoder held at least 99% of the GPU
|
||
time that every accelerator client accumulated over the round (the I/O Registry's
|
||
`accumulatedGPUTime`), which the record keeps per round.
|
||
- **Package energy** (Linux): powercap `package-0`, the whole package, read every 100 ms.
|
||
|
||
A whole-device counter is bracketed by 5 s idle windows before and after every round. A
|
||
round's marginal energy is the counter's advance over the round minus the mean idle power
|
||
of its two brackets times the round's span, and its ratio is the marginal power over the
|
||
larger idle standard deviation (energy-measurement §3, §4). A round's figure is used only
|
||
where the counter was live in the round and in both its brackets (energy-measurement §3.1:
|
||
advancing in two intervals in a row, in five or more and in at least four of every five,
|
||
over at least 300 ms) and its ratio is at least 3; a figure is publishable only where all
|
||
seven rounds are used and read clean (ratio ≥ 10). The record
|
||
gives every round's readings, and per run the median, minimum and maximum over rounds of
|
||
the time and of each energy figure per decode, with the host's load average.
|
||
|
||
## 3. Platforms
|
||
|
||
| platform | machine | what ran |
|
||
|---|---|---|
|
||
| build host | arm64 desktop SoC, 24 performance and 8 efficiency cores, 80-core integrated GPU; macOS 27.0.1; shared, under heavy load from other work | both encoders; the integer decode on the CPU (all cores, one core), on the GPU (Metal) and as wasm32-wasip2 under wasmtime 49.0.3; the float decode on the CPU (one thread, the library's default of 24) and on the GPU (Metal); the timed runs with the per-task count and the GPU rail |
|
||
| x86_64 host A | x86_64 SoC, 16 cores and 32 threads, AVX-512, integrated GPU of PCI vendor 0x1002 (device 0x1586); Linux 7.0, glibc 2.43; shared, otherwise lightly loaded | the integer decode on the CPU, on the GPU (Vulkan, Mesa 26.0.8) and as the build host's wasm32-wasip2 binary under wasmtime 49.0.3; the float decode on the CPU (one thread, the library's default of 16); the timed runs with the package counter |
|
||
| x86_64 host B | x86_64 laptop CPU, 14 cores and 20 threads, AVX2, discrete GPU of PCI vendor 0x10de (device 0x28e1); Linux 7.0, glibc 2.39 | the integer decode on the CPU and on the GPU (Vulkan, driver 595.84); the float decode on the CPU (the library's default of 14 threads) and on the GPU (through the GPU vendor's compute API, in the float stack's 2.14.0 build for it) |
|
||
|
||
Builds: rustc 1.98.0, release profile, `--no-default-features --features neural_int`
|
||
(with `ops_gpu` for the GPU decodes, wgpu 30.0.1); the wasm32-wasip2 binary was built once,
|
||
on the build host, and the same file ran on both hosts. Float stack: Python 3.11 (3.12 on
|
||
host B), the pinned versions of `tools/requirements-sota-int.txt` (its CPU-only build on
|
||
host A, its GPU build on host B), with deterministic algorithms requested. The tags under which the record
|
||
keeps each platform are in `determinism-cost/runs/README.md`.
|
||
|
||
§4.6's builds are the same, from the change that added the narrow kernel sets, made on each
|
||
host (the wasm32-wasip2 file again once, on the build host), beside each host's build of the
|
||
record's own commit; on host A the float stack was set up again from the same pinned
|
||
versions. Host B's GPU was not reached for §4.6 (its driver was not loaded when the runs
|
||
were taken), so its GPU decode is the record's only.
|
||
|
||
## 4. Results
|
||
|
||
Every figure here is the record's, and the verifier of §6 recomputes it; each is followed by a marker naming
|
||
its place in `record.json`, and `wai_determinism_cost_verify.py` holds the text to the
|
||
record.
|
||
|
||
In brief:
|
||
|
||
- **Rate.** At equal PSNR the integer codec needs a median of
|
||
+1.61 %<!--det:summary.bd_rate_percent.psnr.median--> more rate than the float codec over
|
||
the 24 pictures, and at equal MS-SSIM a median of
|
||
+0.95 %<!--det:summary.bd_rate_percent.ms_ssim.median-->. The smallest figure of any
|
||
picture is +0.56 %<!--det:summary.bd_rate_percent.psnr.min--> by PSNR and
|
||
+0.52 %<!--det:summary.bd_rate_percent.ms_ssim.min--> by MS-SSIM: the export costs rate on
|
||
every picture (§4.1, and each picture's figure in the record).
|
||
- **Bytes.** The integer decode gave the same bytes on every platform, under every kernel
|
||
set: 0<!--det:summary.integer_cross_platform_total.differ--> of
|
||
4608<!--det:summary.integer_cross_platform_total.decodes--> decodes differed (§4.3, §4.6). The
|
||
float decode gave the encoder's bytes only on the encoder's own CPU. Everywhere else it
|
||
gave other bytes for every stream, and its entropy decode diverged on many of them, from
|
||
76<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.symbols_differ--> of 192 on host
|
||
B's CPU to 192<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.symbols_differ--> on
|
||
its GPU (§4.4).
|
||
- **Time and energy.** On host A, where every round read clean, the record's integer
|
||
decode took longer and drew more package energy than the float decode on the same CPU, at
|
||
both qualities, and so did the integer decode with its graphs on the integrated GPU
|
||
(§4.5). On the narrow kernel sets (§4.6) the same integer decode, giving the same bytes,
|
||
took 144.8<!--det:summary.timing.linux-int-cpu-q6-after.ms_per_decode.median--> ms and
|
||
12.43<!--det:summary.timing.linux-int-cpu-q6-after.rapl.marginal_j_per_decode.median--> J at quality 6
|
||
against 210.7<!--det:summary.timing.linux-float-cpu-q6-again.ms_per_decode.median--> ms and
|
||
14.03<!--det:summary.timing.linux-float-cpu-q6-again.rapl.marginal_j_per_decode.median--> J for the float
|
||
decode measured beside it, and less time and energy than the float decode at quality 2
|
||
as well. On the build host it still drew more of its own CPU energy than the float decode
|
||
(§4.6, and §5 on what that count covers there).
|
||
|
||
### 4.1 BD-rate, integer codec against float codec
|
||
|
||
| quality metric | pictures | median | mean | min | max |
|
||
|---|---:|---:|---:|---:|---:|
|
||
| PSNR | 24<!--det:summary.bd_rate_percent.psnr.n--> | +1.61<!--det:summary.bd_rate_percent.psnr.median--> % | +1.71<!--det:summary.bd_rate_percent.psnr.mean--> % | +0.56<!--det:summary.bd_rate_percent.psnr.min--> % | +2.97<!--det:summary.bd_rate_percent.psnr.max--> % |
|
||
| MS-SSIM | 24<!--det:summary.bd_rate_percent.ms_ssim.n--> | +0.95<!--det:summary.bd_rate_percent.ms_ssim.median--> % | +1.03<!--det:summary.bd_rate_percent.ms_ssim.mean--> % | +0.52<!--det:summary.bd_rate_percent.ms_ssim.min--> % | +2.45<!--det:summary.bd_rate_percent.ms_ssim.max--> % |
|
||
|
||
### 4.2 Per quality (medians over the pictures)
|
||
|
||
| quality | float bpp | float PSNR (dB) | integer rate ÷ float rate | ΔPSNR (dB), integer − float | ΔMS-SSIM (dB), integer − float |
|
||
|---:|---:|---:|---:|---:|---:|
|
||
| 1 | 0.106<!--det:summary.per_quality.q1.float_bpp.median--> | 28.16<!--det:summary.per_quality.q1.float_psnr_db.median--> | 1.0006<!--det:summary.per_quality.q1.rate_ratio.median--> | -0.005<!--det:summary.per_quality.q1.delta_psnr_db.median--> | -0.005<!--det:summary.per_quality.q1.delta_ms_ssim_db.median--> |
|
||
| 2 | 0.166<!--det:summary.per_quality.q2.float_bpp.median--> | 29.74<!--det:summary.per_quality.q2.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q2.rate_ratio.median--> | -0.007<!--det:summary.per_quality.q2.delta_psnr_db.median--> | -0.007<!--det:summary.per_quality.q2.delta_ms_ssim_db.median--> |
|
||
| 3 | 0.248<!--det:summary.per_quality.q3.float_bpp.median--> | 31.36<!--det:summary.per_quality.q3.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q3.rate_ratio.median--> | -0.016<!--det:summary.per_quality.q3.delta_psnr_db.median--> | -0.010<!--det:summary.per_quality.q3.delta_ms_ssim_db.median--> |
|
||
| 4 | 0.370<!--det:summary.per_quality.q4.float_bpp.median--> | 32.99<!--det:summary.per_quality.q4.float_psnr_db.median--> | 1.0001<!--det:summary.per_quality.q4.rate_ratio.median--> | -0.032<!--det:summary.per_quality.q4.delta_psnr_db.median--> | -0.018<!--det:summary.per_quality.q4.delta_ms_ssim_db.median--> |
|
||
| 5 | 0.550<!--det:summary.per_quality.q5.float_bpp.median--> | 34.78<!--det:summary.per_quality.q5.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q5.rate_ratio.median--> | -0.022<!--det:summary.per_quality.q5.delta_psnr_db.median--> | -0.010<!--det:summary.per_quality.q5.delta_ms_ssim_db.median--> |
|
||
| 6 | 0.792<!--det:summary.per_quality.q6.float_bpp.median--> | 36.79<!--det:summary.per_quality.q6.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q6.rate_ratio.median--> | -0.174<!--det:summary.per_quality.q6.delta_psnr_db.median--> | -0.073<!--det:summary.per_quality.q6.delta_ms_ssim_db.median--> |
|
||
| 7 | 1.106<!--det:summary.per_quality.q7.float_bpp.median--> | 38.79<!--det:summary.per_quality.q7.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q7.rate_ratio.median--> | -0.176<!--det:summary.per_quality.q7.delta_psnr_db.median--> | -0.108<!--det:summary.per_quality.q7.delta_ms_ssim_db.median--> |
|
||
| 8 | 1.511<!--det:summary.per_quality.q8.float_bpp.median--> | 40.78<!--det:summary.per_quality.q8.float_psnr_db.median--> | 1.0000<!--det:summary.per_quality.q8.rate_ratio.median--> | -0.942<!--det:summary.per_quality.q8.delta_psnr_db.median--> | -0.481<!--det:summary.per_quality.q8.delta_ms_ssim_db.median--> |
|
||
|
||
### 4.3 The integer decode across platforms
|
||
|
||
Tags (§3): `macos-arm64-cpu` the build host's CPU, all cores, and `-1t` one core; `macos-arm64-gpu-metal` its GPU; `wasm32-wasip2` the WebAssembly build under wasmtime there, and `wasm32-wasip2-x86_64` the same file on host A; `linux-x86_64-cpu` and `linux-x86_64-gpu-vulkan` host A's CPU and integrated GPU; `linux-x86_64-b-cpu` and `linux-x86_64-b-gpu-vulkan` host B's CPU and discrete GPU. Each line's decodes are the 192 payloads, 24 pictures at 8 qualities.
|
||
|
||
| platform | decodes | identical to the build host's CPU decode | differ | refused |
|
||
|---|---:|---:|---:|---:|
|
||
| `linux-x86_64-b-cpu` | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu.refused--> |
|
||
| `linux-x86_64-b-gpu-vulkan` | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-gpu-vulkan.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-gpu-vulkan.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-gpu-vulkan.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-gpu-vulkan.refused--> |
|
||
| `linux-x86_64-cpu` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu.refused--> |
|
||
| `linux-x86_64-gpu-vulkan` | 192<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan.refused--> |
|
||
| `macos-arm64-cpu` | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu.refused--> |
|
||
| `macos-arm64-cpu-1t` | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t.refused--> |
|
||
| `macos-arm64-gpu-metal` | 192<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal.refused--> |
|
||
| `wasm32-wasip2` | 192<!--det:summary.integer_cross_platform.wasm32-wasip2.decodes--> | 192<!--det:summary.integer_cross_platform.wasm32-wasip2.identical--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2.differ--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2.refused--> |
|
||
| `wasm32-wasip2-x86_64` | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64.decodes--> | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64.identical--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64.differ--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64.refused--> |
|
||
|
||
### 4.4 The float decode across platforms
|
||
|
||
Against the encoding process's own decode. Tags: `macos-arm64-cpu-1t` and `macos-arm64-cpu` the build host's CPU with one thread and with the library's default of 24, each in a fresh process; `macos-arm64-gpu-mps` its GPU; `linux-x86_64-cpu` and `linux-x86_64-cpu-1t` host A's CPU with the library's default of 16 threads and with one; `linux-x86_64-b-cpu` host B's CPU (14 threads); `linux-x86_64-b-cuda` host B's GPU. Where the symbols differ, the entropy decode diverged.
|
||
|
||
| platform | decodes | identical to the encoder's decode | differ | of which the indexes differ | of which the symbols differ | ΔPSNR where they differ (dB): median, min, max | ΔPSNR where the symbols differ (dB): median |
|
||
|---|---:|---:|---:|---:|---:|---|---:|
|
||
| `linux-x86_64-b-cpu` | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.decodes--> | 0<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.identical--> | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.rgb_differ--> | 76<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.indexes_differ--> | 76<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.symbols_differ--> | -0.000<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.delta_psnr_db_where_differ.median-->, -30.126<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.delta_psnr_db_where_differ.min-->, +0.000<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.delta_psnr_db_where_differ.max--> | -17.582<!--det:summary.float_cross_platform.linux-x86_64-b-cpu.delta_psnr_db_where_symbols_differ.median--> |
|
||
| `linux-x86_64-b-cuda` | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.decodes--> | 0<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.identical--> | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.rgb_differ--> | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.indexes_differ--> | 192<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.symbols_differ--> | -19.697<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.delta_psnr_db_where_differ.median-->, -30.518<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.delta_psnr_db_where_differ.min-->, -9.500<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.delta_psnr_db_where_differ.max--> | -19.697<!--det:summary.float_cross_platform.linux-x86_64-b-cuda.delta_psnr_db_where_symbols_differ.median--> |
|
||
| `linux-x86_64-cpu` | 192<!--det:summary.float_cross_platform.linux-x86_64-cpu.decodes--> | 0<!--det:summary.float_cross_platform.linux-x86_64-cpu.identical--> | 192<!--det:summary.float_cross_platform.linux-x86_64-cpu.rgb_differ--> | 183<!--det:summary.float_cross_platform.linux-x86_64-cpu.indexes_differ--> | 183<!--det:summary.float_cross_platform.linux-x86_64-cpu.symbols_differ--> | -17.037<!--det:summary.float_cross_platform.linux-x86_64-cpu.delta_psnr_db_where_differ.median-->, -30.686<!--det:summary.float_cross_platform.linux-x86_64-cpu.delta_psnr_db_where_differ.min-->, +0.000<!--det:summary.float_cross_platform.linux-x86_64-cpu.delta_psnr_db_where_differ.max--> | -17.434<!--det:summary.float_cross_platform.linux-x86_64-cpu.delta_psnr_db_where_symbols_differ.median--> |
|
||
| `linux-x86_64-cpu-1t` | 192<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.decodes--> | 0<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.identical--> | 192<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.rgb_differ--> | 182<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.indexes_differ--> | 182<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.symbols_differ--> | -17.037<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.delta_psnr_db_where_differ.median-->, -30.457<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.delta_psnr_db_where_differ.min-->, +0.000<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.delta_psnr_db_where_differ.max--> | -17.345<!--det:summary.float_cross_platform.linux-x86_64-cpu-1t.delta_psnr_db_where_symbols_differ.median--> |
|
||
| `macos-arm64-cpu` | 192<!--det:summary.float_cross_platform.macos-arm64-cpu.decodes--> | 192<!--det:summary.float_cross_platform.macos-arm64-cpu.identical--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu.rgb_differ--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu.indexes_differ--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu.symbols_differ--> | — | — |
|
||
| `macos-arm64-cpu-1t` | 192<!--det:summary.float_cross_platform.macos-arm64-cpu-1t.decodes--> | 192<!--det:summary.float_cross_platform.macos-arm64-cpu-1t.identical--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu-1t.rgb_differ--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu-1t.indexes_differ--> | 0<!--det:summary.float_cross_platform.macos-arm64-cpu-1t.symbols_differ--> | — | — |
|
||
| `macos-arm64-gpu-mps` | 192<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.decodes--> | 0<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.identical--> | 192<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.rgb_differ--> | 184<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.indexes_differ--> | 184<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.symbols_differ--> | -17.200<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.delta_psnr_db_where_differ.median-->, -34.147<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.delta_psnr_db_where_differ.min-->, +0.000<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.delta_psnr_db_where_differ.max--> | -17.358<!--det:summary.float_cross_platform.macos-arm64-gpu-mps.delta_psnr_db_where_symbols_differ.median--> |
|
||
|
||
### 4.5 Time and energy per decode (median over rounds; min–max)
|
||
|
||
Eight pictures per round, seven rounds; the runs' labels give the host (`linux` is host A, `macos` the build host), the codec, the fabric and the quality. The own CPU energy is the per-task count (macOS); the whole-device figure is the package counter (`rapl`, host A) or the GPU rail (`ioreport-gpu`, the build host), as the round's marginal over its idle brackets, from the rounds used (§2.6). The build host's rounds ran under the load average shown.
|
||
|
||
| run | time (ms) | own CPU energy (J) | whole-device marginal energy (J) | whole-device rounds | load average |
|
||
|---|---|---|---|---|---|
|
||
| `linux-float-cpu-q2` | 123.9<!--det:summary.timing.linux-float-cpu-q2.ms_per_decode.median--> (108.2<!--det:summary.timing.linux-float-cpu-q2.ms_per_decode.min-->–134.3<!--det:summary.timing.linux-float-cpu-q2.ms_per_decode.max-->) | — | rapl: 9.1<!--det:summary.timing.linux-float-cpu-q2.rapl.marginal_j_per_decode.median--> (8.0<!--det:summary.timing.linux-float-cpu-q2.rapl.marginal_j_per_decode.min-->–9.5<!--det:summary.timing.linux-float-cpu-q2.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-float-cpu-q2.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-float-cpu-q2.rapl.live_rounds--> live; 7 clean | 2<!--det:summary.timing.linux-float-cpu-q2.load_avg_1min.min-->–3<!--det:summary.timing.linux-float-cpu-q2.load_avg_1min.max--> |
|
||
| `linux-float-cpu-q6` | 191.5<!--det:summary.timing.linux-float-cpu-q6.ms_per_decode.median--> (181.0<!--det:summary.timing.linux-float-cpu-q6.ms_per_decode.min-->–200.3<!--det:summary.timing.linux-float-cpu-q6.ms_per_decode.max-->) | — | rapl: 13.7<!--det:summary.timing.linux-float-cpu-q6.rapl.marginal_j_per_decode.median--> (13.3<!--det:summary.timing.linux-float-cpu-q6.rapl.marginal_j_per_decode.min-->–14.0<!--det:summary.timing.linux-float-cpu-q6.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-float-cpu-q6.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-float-cpu-q6.rapl.live_rounds--> live; 7 clean | 5<!--det:summary.timing.linux-float-cpu-q6.load_avg_1min.min-->–7<!--det:summary.timing.linux-float-cpu-q6.load_avg_1min.max--> |
|
||
| `linux-int-cpu-q2` | 347.3<!--det:summary.timing.linux-int-cpu-q2.ms_per_decode.median--> (346.4<!--det:summary.timing.linux-int-cpu-q2.ms_per_decode.min-->–348.6<!--det:summary.timing.linux-int-cpu-q2.ms_per_decode.max-->) | — | rapl: 42.4<!--det:summary.timing.linux-int-cpu-q2.rapl.marginal_j_per_decode.median--> (42.1<!--det:summary.timing.linux-int-cpu-q2.rapl.marginal_j_per_decode.min-->–42.5<!--det:summary.timing.linux-int-cpu-q2.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q2.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q2.rapl.live_rounds--> live; 7 clean | 1<!--det:summary.timing.linux-int-cpu-q2.load_avg_1min.min-->–4<!--det:summary.timing.linux-int-cpu-q2.load_avg_1min.max--> |
|
||
| `linux-int-cpu-q6` | 729.6<!--det:summary.timing.linux-int-cpu-q6.ms_per_decode.median--> (728.7<!--det:summary.timing.linux-int-cpu-q6.ms_per_decode.min-->–731.6<!--det:summary.timing.linux-int-cpu-q6.ms_per_decode.max-->) | — | rapl: 92.5<!--det:summary.timing.linux-int-cpu-q6.rapl.marginal_j_per_decode.median--> (92.2<!--det:summary.timing.linux-int-cpu-q6.rapl.marginal_j_per_decode.min-->–92.7<!--det:summary.timing.linux-int-cpu-q6.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q6.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q6.rapl.live_rounds--> live; 7 clean | 3<!--det:summary.timing.linux-int-cpu-q6.load_avg_1min.min-->–11<!--det:summary.timing.linux-int-cpu-q6.load_avg_1min.max--> |
|
||
| `linux-int-gpu-q2` | 378.5<!--det:summary.timing.linux-int-gpu-q2.ms_per_decode.median--> (377.2<!--det:summary.timing.linux-int-gpu-q2.ms_per_decode.min-->–379.7<!--det:summary.timing.linux-int-gpu-q2.ms_per_decode.max-->) | — | rapl: 41.9<!--det:summary.timing.linux-int-gpu-q2.rapl.marginal_j_per_decode.median--> (41.0<!--det:summary.timing.linux-int-gpu-q2.rapl.marginal_j_per_decode.min-->–43.4<!--det:summary.timing.linux-int-gpu-q2.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-gpu-q2.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-gpu-q2.rapl.live_rounds--> live; 7 clean | 1<!--det:summary.timing.linux-int-gpu-q2.load_avg_1min.min-->–3<!--det:summary.timing.linux-int-gpu-q2.load_avg_1min.max--> |
|
||
| `linux-int-gpu-q6` | 845.4<!--det:summary.timing.linux-int-gpu-q6.ms_per_decode.median--> (844.1<!--det:summary.timing.linux-int-gpu-q6.ms_per_decode.min-->–846.2<!--det:summary.timing.linux-int-gpu-q6.ms_per_decode.max-->) | — | rapl: 93.5<!--det:summary.timing.linux-int-gpu-q6.rapl.marginal_j_per_decode.median--> (91.7<!--det:summary.timing.linux-int-gpu-q6.rapl.marginal_j_per_decode.min-->–93.8<!--det:summary.timing.linux-int-gpu-q6.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-gpu-q6.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-gpu-q6.rapl.live_rounds--> live; 7 clean | 1<!--det:summary.timing.linux-int-gpu-q6.load_avg_1min.min-->–5<!--det:summary.timing.linux-int-gpu-q6.load_avg_1min.max--> |
|
||
| `macos-float-cpu-q2` | 714.2<!--det:summary.timing.macos-float-cpu-q2.ms_per_decode.median--> (209.0<!--det:summary.timing.macos-float-cpu-q2.ms_per_decode.min-->–5663.9<!--det:summary.timing.macos-float-cpu-q2.ms_per_decode.max-->) | 0.7<!--det:summary.timing.macos-float-cpu-q2.task_j_per_decode.median--> (0.7<!--det:summary.timing.macos-float-cpu-q2.task_j_per_decode.min-->–0.7<!--det:summary.timing.macos-float-cpu-q2.task_j_per_decode.max-->) | — | — | 45<!--det:summary.timing.macos-float-cpu-q2.load_avg_1min.min-->–199<!--det:summary.timing.macos-float-cpu-q2.load_avg_1min.max--> |
|
||
| `macos-float-cpu-q6` | 403.4<!--det:summary.timing.macos-float-cpu-q6.ms_per_decode.median--> (214.6<!--det:summary.timing.macos-float-cpu-q6.ms_per_decode.min-->–736.4<!--det:summary.timing.macos-float-cpu-q6.ms_per_decode.max-->) | 1.2<!--det:summary.timing.macos-float-cpu-q6.task_j_per_decode.median--> (1.1<!--det:summary.timing.macos-float-cpu-q6.task_j_per_decode.min-->–1.5<!--det:summary.timing.macos-float-cpu-q6.task_j_per_decode.max-->) | — | — | 85<!--det:summary.timing.macos-float-cpu-q6.load_avg_1min.min-->–126<!--det:summary.timing.macos-float-cpu-q6.load_avg_1min.max--> |
|
||
| `macos-float-gpu-q2` | 51.7<!--det:summary.timing.macos-float-gpu-q2.ms_per_decode.median--> (50.0<!--det:summary.timing.macos-float-gpu-q2.ms_per_decode.min-->–55.3<!--det:summary.timing.macos-float-gpu-q2.ms_per_decode.max-->) | 0.1<!--det:summary.timing.macos-float-gpu-q2.task_j_per_decode.median--> (0.1<!--det:summary.timing.macos-float-gpu-q2.task_j_per_decode.min-->–0.1<!--det:summary.timing.macos-float-gpu-q2.task_j_per_decode.max-->) | ioreport-gpu: none usable | 0<!--det:summary.timing.macos-float-gpu-q2.ioreport-gpu.usable_rounds--> of 7 used; 0<!--det:summary.timing.macos-float-gpu-q2.ioreport-gpu.live_rounds--> live; 2 clean, 5 no ratio; GPU share 1.000<!--det:summary.timing.macos-float-gpu-q2.ioreport-gpu.gpu_share.min-->–1.000<!--det:summary.timing.macos-float-gpu-q2.ioreport-gpu.gpu_share.max--> | 126<!--det:summary.timing.macos-float-gpu-q2.load_avg_1min.min-->–149<!--det:summary.timing.macos-float-gpu-q2.load_avg_1min.max--> |
|
||
| `macos-float-gpu-q6` | 66.4<!--det:summary.timing.macos-float-gpu-q6.ms_per_decode.median--> (60.0<!--det:summary.timing.macos-float-gpu-q6.ms_per_decode.min-->–77.8<!--det:summary.timing.macos-float-gpu-q6.ms_per_decode.max-->) | 0.2<!--det:summary.timing.macos-float-gpu-q6.task_j_per_decode.median--> (0.1<!--det:summary.timing.macos-float-gpu-q6.task_j_per_decode.min-->–0.2<!--det:summary.timing.macos-float-gpu-q6.task_j_per_decode.max-->) | ioreport-gpu: none usable | 0<!--det:summary.timing.macos-float-gpu-q6.ioreport-gpu.usable_rounds--> of 7 used; 0<!--det:summary.timing.macos-float-gpu-q6.ioreport-gpu.live_rounds--> live; 4 no ratio, 3 clean; GPU share 0.113<!--det:summary.timing.macos-float-gpu-q6.ioreport-gpu.gpu_share.min-->–1.000<!--det:summary.timing.macos-float-gpu-q6.ioreport-gpu.gpu_share.max--> | 74<!--det:summary.timing.macos-float-gpu-q6.load_avg_1min.min-->–81<!--det:summary.timing.macos-float-gpu-q6.load_avg_1min.max--> |
|
||
| `macos-int-cpu-q2` | 152.4<!--det:summary.timing.macos-int-cpu-q2.ms_per_decode.median--> (115.1<!--det:summary.timing.macos-int-cpu-q2.ms_per_decode.min-->–376.8<!--det:summary.timing.macos-int-cpu-q2.ms_per_decode.max-->) | 4.6<!--det:summary.timing.macos-int-cpu-q2.task_j_per_decode.median--> (4.4<!--det:summary.timing.macos-int-cpu-q2.task_j_per_decode.min-->–4.8<!--det:summary.timing.macos-int-cpu-q2.task_j_per_decode.max-->) | — | — | 44<!--det:summary.timing.macos-int-cpu-q2.load_avg_1min.min-->–57<!--det:summary.timing.macos-int-cpu-q2.load_avg_1min.max--> |
|
||
| `macos-int-cpu-q6` | 648.9<!--det:summary.timing.macos-int-cpu-q6.ms_per_decode.median--> (519.5<!--det:summary.timing.macos-int-cpu-q6.ms_per_decode.min-->–865.7<!--det:summary.timing.macos-int-cpu-q6.ms_per_decode.max-->) | 10.5<!--det:summary.timing.macos-int-cpu-q6.task_j_per_decode.median--> (10.2<!--det:summary.timing.macos-int-cpu-q6.task_j_per_decode.min-->–10.9<!--det:summary.timing.macos-int-cpu-q6.task_j_per_decode.max-->) | — | — | 113<!--det:summary.timing.macos-int-cpu-q6.load_avg_1min.min-->–130<!--det:summary.timing.macos-int-cpu-q6.load_avg_1min.max--> |
|
||
| `macos-int-gpu-q2` | 251.3<!--det:summary.timing.macos-int-gpu-q2.ms_per_decode.median--> (248.7<!--det:summary.timing.macos-int-gpu-q2.ms_per_decode.min-->–253.5<!--det:summary.timing.macos-int-gpu-q2.ms_per_decode.max-->) | 0.1<!--det:summary.timing.macos-int-gpu-q2.task_j_per_decode.median--> (0.1<!--det:summary.timing.macos-int-gpu-q2.task_j_per_decode.min-->–0.1<!--det:summary.timing.macos-int-gpu-q2.task_j_per_decode.max-->) | ioreport-gpu: none usable | 0<!--det:summary.timing.macos-int-gpu-q2.ioreport-gpu.usable_rounds--> of 7 used; 5<!--det:summary.timing.macos-int-gpu-q2.ioreport-gpu.live_rounds--> live; 7 clean; GPU share 0.788<!--det:summary.timing.macos-int-gpu-q2.ioreport-gpu.gpu_share.min-->–0.916<!--det:summary.timing.macos-int-gpu-q2.ioreport-gpu.gpu_share.max--> | 117<!--det:summary.timing.macos-int-gpu-q2.load_avg_1min.min-->–128<!--det:summary.timing.macos-int-gpu-q2.load_avg_1min.max--> |
|
||
| `macos-int-gpu-q6` | 529.9<!--det:summary.timing.macos-int-gpu-q6.ms_per_decode.median--> (527.9<!--det:summary.timing.macos-int-gpu-q6.ms_per_decode.min-->–546.0<!--det:summary.timing.macos-int-gpu-q6.ms_per_decode.max-->) | 0.1<!--det:summary.timing.macos-int-gpu-q6.task_j_per_decode.median--> (0.1<!--det:summary.timing.macos-int-gpu-q6.task_j_per_decode.min-->–0.1<!--det:summary.timing.macos-int-gpu-q6.task_j_per_decode.max-->) | ioreport-gpu: none usable | 0<!--det:summary.timing.macos-int-gpu-q6.ioreport-gpu.usable_rounds--> of 7 used; 0<!--det:summary.timing.macos-int-gpu-q6.ioreport-gpu.live_rounds--> live; 2 clean, 5 no ratio; GPU share 0.923<!--det:summary.timing.macos-int-gpu-q6.ioreport-gpu.gpu_share.min-->–1.000<!--det:summary.timing.macos-int-gpu-q6.ioreport-gpu.gpu_share.max--> | 37<!--det:summary.timing.macos-int-gpu-q6.load_avg_1min.min-->–68<!--det:summary.timing.macos-int-gpu-q6.load_avg_1min.max--> |
|
||
|
||
|
||
On the build host no GPU-rail figure is used. While the GPU idled between rounds its rail
|
||
did not advance at all, so the idle brackets around most rounds were not live (§2.6); and
|
||
in some rounds another client held more than 1% of the GPU's time (the table's GPU share). Those rounds' readings are
|
||
in the record, and nothing is drawn from them. The per-task counts there are the
|
||
decoding process's own CPU energy, which the load on the host changes less than it changes
|
||
the time, but does change; §5 states what they cover.
|
||
|
||
### 4.6 The integer decode on the narrow kernel sets
|
||
|
||
The record's integer decoder (§4.3, §4.5) ran the wide kernels of `wai-rs`'s `int_kernels`:
|
||
32×32→64-bit multiply-accumulates, NEON on arm64 and portable Rust elsewhere. The runs of
|
||
this section are of the build that added the narrow kernel sets (`int_kernels::Isa`):
|
||
convolutions on 16-bit operands with 32-bit partial sums in blocks bounded so that no value
|
||
leaves its type (NEON on arm64; AVX2, AVX2 with VNNI, AVX-512 and AVX-512 with VNNI on
|
||
x86_64), the inverse GDN's norms and outputs in SIMD lanes, and the element-wise operators
|
||
and the requantisation in 64-bit arithmetic where their values fit. Every operator still
|
||
gives the interpreter's integers (the `int_kernels` documentation states how, and the tests
|
||
it names hold each set to the interpreter); the set is chosen by the processor's features,
|
||
or by `WAI_INT_ISA`. The wasm32-wasip2 build has no narrow set and runs the wide kernels, as
|
||
`wide` names below, with the build's other changes.
|
||
|
||
**Bytes.** Every payload decoded again on each platform with each kernel set the platform
|
||
runs, against the record's build host CPU decode (the GPU decodes run both graphs on the
|
||
device and are unchanged by the kernel sets; the runs check it):
|
||
|
||
| platform | kernel set | decodes | identical to the build host's CPU decode | differ | refused |
|
||
|---|---|---:|---:|---:|---:|
|
||
| `linux-x86_64-b-cpu` | `avx2` | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2.refused--> |
|
||
| `linux-x86_64-b-cpu` | `avx2-vnni` | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2-vnni.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2-vnni.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2-vnni.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-avx2-vnni.refused--> |
|
||
| `linux-x86_64-b-cpu` | `wide` | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-wide.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-wide.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-wide.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-b-cpu-isa-wide.refused--> |
|
||
| `linux-x86_64-cpu` | `avx2` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2.refused--> |
|
||
| `linux-x86_64-cpu` | `avx2-vnni` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2-vnni.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2-vnni.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2-vnni.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx2-vnni.refused--> |
|
||
| `linux-x86_64-cpu` | `avx512` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512.refused--> |
|
||
| `linux-x86_64-cpu` | `avx512-vnni` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512-vnni.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512-vnni.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512-vnni.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-avx512-vnni.refused--> |
|
||
| `linux-x86_64-cpu` | `wide` | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-wide.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-wide.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-wide.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-cpu-isa-wide.refused--> |
|
||
| `linux-x86_64-gpu-vulkan` | `avx512-vnni` | 192<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan-isa-avx512-vnni.decodes--> | 192<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan-isa-avx512-vnni.identical--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan-isa-avx512-vnni.differ--> | 0<!--det:summary.integer_cross_platform.linux-x86_64-gpu-vulkan-isa-avx512-vnni.refused--> |
|
||
| `macos-arm64-cpu-1t` | `neon` | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t-isa-neon.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t-isa-neon.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t-isa-neon.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-1t-isa-neon.refused--> |
|
||
| `macos-arm64-cpu` | `neon` | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-neon.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-neon.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-neon.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-neon.refused--> |
|
||
| `macos-arm64-cpu` | `wide` | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-wide.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-wide.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-wide.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-cpu-isa-wide.refused--> |
|
||
| `macos-arm64-gpu-metal` | `neon` | 192<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal-isa-neon.decodes--> | 192<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal-isa-neon.identical--> | 0<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal-isa-neon.differ--> | 0<!--det:summary.integer_cross_platform.macos-arm64-gpu-metal-isa-neon.refused--> |
|
||
| `wasm32-wasip2` | `wide` | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-isa-wide.decodes--> | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-isa-wide.identical--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-isa-wide.differ--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-isa-wide.refused--> |
|
||
| `wasm32-wasip2-x86_64` | `wide` | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64-isa-wide.decodes--> | 192<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64-isa-wide.identical--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64-isa-wide.differ--> | 0<!--det:summary.integer_cross_platform.wasm32-wasip2-x86_64-isa-wide.refused--> |
|
||
|
||
**Time and energy.** The procedure of §2.6, on the same eight pictures. On each host the
|
||
runs were taken in one session: `-before` the record's own build of the integer decoder run
|
||
again, `-after` this section's build (its kernel set chosen by the processor: AVX-512 with
|
||
VNNI on host A, AVX2 with VNNI on host B, NEON on the build host; `-after-avx2` the AVX2 set
|
||
on host A), `-again` the float decoder run again. `linux-b` is host B, measured only for the
|
||
integer decode (its float stack was not set up again), under the load of the CI jobs it
|
||
also serves.
|
||
|
||
| run | time (ms) | own CPU energy (J) | whole-device marginal energy (J) | whole-device rounds | load average |
|
||
|---|---|---|---|---|---|
|
||
| `linux-b-int-cpu-q2-after` | 170.2<!--det:summary.timing.linux-b-int-cpu-q2-after.ms_per_decode.median--> (168.9<!--det:summary.timing.linux-b-int-cpu-q2-after.ms_per_decode.min-->–203.6<!--det:summary.timing.linux-b-int-cpu-q2-after.ms_per_decode.max-->) | — | rapl: 11.56<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.marginal_j_per_decode.median--> (9.31<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.marginal_j_per_decode.min-->–11.91<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.live_rounds--> live; 2 relative-only, 5 clean | 5<!--det:summary.timing.linux-b-int-cpu-q2-after.load_avg_1min.min-->–6<!--det:summary.timing.linux-b-int-cpu-q2-after.load_avg_1min.max--> |
|
||
| `linux-b-int-cpu-q2-before` | 714.0<!--det:summary.timing.linux-b-int-cpu-q2-before.ms_per_decode.median--> (704.2<!--det:summary.timing.linux-b-int-cpu-q2-before.ms_per_decode.min-->–716.3<!--det:summary.timing.linux-b-int-cpu-q2-before.ms_per_decode.max-->) | — | rapl: 43.84<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.marginal_j_per_decode.median--> (42.71<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.marginal_j_per_decode.min-->–44.30<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.live_rounds--> live; 7 clean | 2<!--det:summary.timing.linux-b-int-cpu-q2-before.load_avg_1min.min-->–9<!--det:summary.timing.linux-b-int-cpu-q2-before.load_avg_1min.max--> |
|
||
| `linux-b-int-cpu-q6-after` | 294.3<!--det:summary.timing.linux-b-int-cpu-q6-after.ms_per_decode.median--> (292.3<!--det:summary.timing.linux-b-int-cpu-q6-after.ms_per_decode.min-->–301.1<!--det:summary.timing.linux-b-int-cpu-q6-after.ms_per_decode.max-->) | — | rapl: 19.97<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.marginal_j_per_decode.median--> (18.83<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.marginal_j_per_decode.min-->–20.20<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.live_rounds--> live; 7 clean | 6<!--det:summary.timing.linux-b-int-cpu-q6-after.load_avg_1min.min-->–11<!--det:summary.timing.linux-b-int-cpu-q6-after.load_avg_1min.max--> |
|
||
| `linux-b-int-cpu-q6-before` | 1582.1<!--det:summary.timing.linux-b-int-cpu-q6-before.ms_per_decode.median--> (1555.6<!--det:summary.timing.linux-b-int-cpu-q6-before.ms_per_decode.min-->–1598.9<!--det:summary.timing.linux-b-int-cpu-q6-before.ms_per_decode.max-->) | — | rapl: 84.92<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.marginal_j_per_decode.median--> (83.95<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.marginal_j_per_decode.min-->–87.95<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.live_rounds--> live; 7 clean | 6<!--det:summary.timing.linux-b-int-cpu-q6-before.load_avg_1min.min-->–12<!--det:summary.timing.linux-b-int-cpu-q6-before.load_avg_1min.max--> |
|
||
| `linux-float-cpu-q2-again` | 132.2<!--det:summary.timing.linux-float-cpu-q2-again.ms_per_decode.median--> (123.2<!--det:summary.timing.linux-float-cpu-q2-again.ms_per_decode.min-->–139.7<!--det:summary.timing.linux-float-cpu-q2-again.ms_per_decode.max-->) | — | rapl: 9.26<!--det:summary.timing.linux-float-cpu-q2-again.rapl.marginal_j_per_decode.median--> (9.00<!--det:summary.timing.linux-float-cpu-q2-again.rapl.marginal_j_per_decode.min-->–9.33<!--det:summary.timing.linux-float-cpu-q2-again.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-float-cpu-q2-again.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-float-cpu-q2-again.rapl.live_rounds--> live; 7 clean | 2<!--det:summary.timing.linux-float-cpu-q2-again.load_avg_1min.min-->–4<!--det:summary.timing.linux-float-cpu-q2-again.load_avg_1min.max--> |
|
||
| `linux-float-cpu-q6-again` | 210.7<!--det:summary.timing.linux-float-cpu-q6-again.ms_per_decode.median--> (200.8<!--det:summary.timing.linux-float-cpu-q6-again.ms_per_decode.min-->–226.1<!--det:summary.timing.linux-float-cpu-q6-again.ms_per_decode.max-->) | — | rapl: 14.03<!--det:summary.timing.linux-float-cpu-q6-again.rapl.marginal_j_per_decode.median--> (13.65<!--det:summary.timing.linux-float-cpu-q6-again.rapl.marginal_j_per_decode.min-->–14.41<!--det:summary.timing.linux-float-cpu-q6-again.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-float-cpu-q6-again.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-float-cpu-q6-again.rapl.live_rounds--> live; 7 clean | 6<!--det:summary.timing.linux-float-cpu-q6-again.load_avg_1min.min-->–8<!--det:summary.timing.linux-float-cpu-q6-again.load_avg_1min.max--> |
|
||
| `linux-int-cpu-q2-after` | 92.9<!--det:summary.timing.linux-int-cpu-q2-after.ms_per_decode.median--> (90.8<!--det:summary.timing.linux-int-cpu-q2-after.ms_per_decode.min-->–93.1<!--det:summary.timing.linux-int-cpu-q2-after.ms_per_decode.max-->) | — | rapl: 7.31<!--det:summary.timing.linux-int-cpu-q2-after.rapl.marginal_j_per_decode.median--> (7.29<!--det:summary.timing.linux-int-cpu-q2-after.rapl.marginal_j_per_decode.min-->–7.50<!--det:summary.timing.linux-int-cpu-q2-after.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q2-after.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q2-after.rapl.live_rounds--> live; 7 clean | 3<!--det:summary.timing.linux-int-cpu-q2-after.load_avg_1min.min-->–5<!--det:summary.timing.linux-int-cpu-q2-after.load_avg_1min.max--> |
|
||
| `linux-int-cpu-q2-after-avx2` | 101.6<!--det:summary.timing.linux-int-cpu-q2-after-avx2.ms_per_decode.median--> (101.3<!--det:summary.timing.linux-int-cpu-q2-after-avx2.ms_per_decode.min-->–103.0<!--det:summary.timing.linux-int-cpu-q2-after-avx2.ms_per_decode.max-->) | — | rapl: 9.27<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.marginal_j_per_decode.median--> (9.22<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.marginal_j_per_decode.min-->–9.35<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.live_rounds--> live; 7 clean | 3<!--det:summary.timing.linux-int-cpu-q2-after-avx2.load_avg_1min.min-->–5<!--det:summary.timing.linux-int-cpu-q2-after-avx2.load_avg_1min.max--> |
|
||
| `linux-int-cpu-q2-before` | 345.8<!--det:summary.timing.linux-int-cpu-q2-before.ms_per_decode.median--> (345.2<!--det:summary.timing.linux-int-cpu-q2-before.ms_per_decode.min-->–346.4<!--det:summary.timing.linux-int-cpu-q2-before.ms_per_decode.max-->) | — | rapl: 42.25<!--det:summary.timing.linux-int-cpu-q2-before.rapl.marginal_j_per_decode.median--> (42.17<!--det:summary.timing.linux-int-cpu-q2-before.rapl.marginal_j_per_decode.min-->–42.33<!--det:summary.timing.linux-int-cpu-q2-before.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q2-before.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q2-before.rapl.live_rounds--> live; 7 clean | 2<!--det:summary.timing.linux-int-cpu-q2-before.load_avg_1min.min-->–5<!--det:summary.timing.linux-int-cpu-q2-before.load_avg_1min.max--> |
|
||
| `linux-int-cpu-q6-after` | 144.8<!--det:summary.timing.linux-int-cpu-q6-after.ms_per_decode.median--> (142.7<!--det:summary.timing.linux-int-cpu-q6-after.ms_per_decode.min-->–147.7<!--det:summary.timing.linux-int-cpu-q6-after.ms_per_decode.max-->) | — | rapl: 12.43<!--det:summary.timing.linux-int-cpu-q6-after.rapl.marginal_j_per_decode.median--> (12.28<!--det:summary.timing.linux-int-cpu-q6-after.rapl.marginal_j_per_decode.min-->–12.58<!--det:summary.timing.linux-int-cpu-q6-after.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q6-after.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q6-after.rapl.live_rounds--> live; 7 clean | 8<!--det:summary.timing.linux-int-cpu-q6-after.load_avg_1min.min-->–11<!--det:summary.timing.linux-int-cpu-q6-after.load_avg_1min.max--> |
|
||
| `linux-int-cpu-q6-after-avx2` | 166.3<!--det:summary.timing.linux-int-cpu-q6-after-avx2.ms_per_decode.median--> (164.7<!--det:summary.timing.linux-int-cpu-q6-after-avx2.ms_per_decode.min-->–166.8<!--det:summary.timing.linux-int-cpu-q6-after-avx2.ms_per_decode.max-->) | — | rapl: 16.46<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.marginal_j_per_decode.median--> (16.36<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.marginal_j_per_decode.min-->–16.53<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.live_rounds--> live; 7 clean | 2<!--det:summary.timing.linux-int-cpu-q6-after-avx2.load_avg_1min.min-->–4<!--det:summary.timing.linux-int-cpu-q6-after-avx2.load_avg_1min.max--> |
|
||
| `linux-int-cpu-q6-before` | 728.0<!--det:summary.timing.linux-int-cpu-q6-before.ms_per_decode.median--> (725.8<!--det:summary.timing.linux-int-cpu-q6-before.ms_per_decode.min-->–729.8<!--det:summary.timing.linux-int-cpu-q6-before.ms_per_decode.max-->) | — | rapl: 92.14<!--det:summary.timing.linux-int-cpu-q6-before.rapl.marginal_j_per_decode.median--> (91.96<!--det:summary.timing.linux-int-cpu-q6-before.rapl.marginal_j_per_decode.min-->–92.67<!--det:summary.timing.linux-int-cpu-q6-before.rapl.marginal_j_per_decode.max-->) | 7<!--det:summary.timing.linux-int-cpu-q6-before.rapl.usable_rounds--> of 7 used; 7<!--det:summary.timing.linux-int-cpu-q6-before.rapl.live_rounds--> live; 7 clean | 4<!--det:summary.timing.linux-int-cpu-q6-before.load_avg_1min.min-->–12<!--det:summary.timing.linux-int-cpu-q6-before.load_avg_1min.max--> |
|
||
| `macos-float-cpu-q2-again` | 212.5<!--det:summary.timing.macos-float-cpu-q2-again.ms_per_decode.median--> (140.4<!--det:summary.timing.macos-float-cpu-q2-again.ms_per_decode.min-->–330.5<!--det:summary.timing.macos-float-cpu-q2-again.ms_per_decode.max-->) | 0.92<!--det:summary.timing.macos-float-cpu-q2-again.task_j_per_decode.median--> (0.81<!--det:summary.timing.macos-float-cpu-q2-again.task_j_per_decode.min-->–1.07<!--det:summary.timing.macos-float-cpu-q2-again.task_j_per_decode.max-->) | — | — | 40<!--det:summary.timing.macos-float-cpu-q2-again.load_avg_1min.min-->–47<!--det:summary.timing.macos-float-cpu-q2-again.load_avg_1min.max--> |
|
||
| `macos-float-cpu-q6-again` | 271.3<!--det:summary.timing.macos-float-cpu-q6-again.ms_per_decode.median--> (215.7<!--det:summary.timing.macos-float-cpu-q6-again.ms_per_decode.min-->–598.7<!--det:summary.timing.macos-float-cpu-q6-again.ms_per_decode.max-->) | 1.28<!--det:summary.timing.macos-float-cpu-q6-again.task_j_per_decode.median--> (1.22<!--det:summary.timing.macos-float-cpu-q6-again.task_j_per_decode.min-->–1.51<!--det:summary.timing.macos-float-cpu-q6-again.task_j_per_decode.max-->) | — | — | 46<!--det:summary.timing.macos-float-cpu-q6-again.load_avg_1min.min-->–61<!--det:summary.timing.macos-float-cpu-q6-again.load_avg_1min.max--> |
|
||
| `macos-int-cpu-q2-after` | 274.1<!--det:summary.timing.macos-int-cpu-q2-after.ms_per_decode.median--> (98.3<!--det:summary.timing.macos-int-cpu-q2-after.ms_per_decode.min-->–385.0<!--det:summary.timing.macos-int-cpu-q2-after.ms_per_decode.max-->) | 2.96<!--det:summary.timing.macos-int-cpu-q2-after.task_j_per_decode.median--> (2.83<!--det:summary.timing.macos-int-cpu-q2-after.task_j_per_decode.min-->–3.12<!--det:summary.timing.macos-int-cpu-q2-after.task_j_per_decode.max-->) | — | — | 32<!--det:summary.timing.macos-int-cpu-q2-after.load_avg_1min.min-->–46<!--det:summary.timing.macos-int-cpu-q2-after.load_avg_1min.max--> |
|
||
| `macos-int-cpu-q2-before` | 130.9<!--det:summary.timing.macos-int-cpu-q2-before.ms_per_decode.median--> (106.2<!--det:summary.timing.macos-int-cpu-q2-before.ms_per_decode.min-->–338.3<!--det:summary.timing.macos-int-cpu-q2-before.ms_per_decode.max-->) | 4.76<!--det:summary.timing.macos-int-cpu-q2-before.task_j_per_decode.median--> (4.47<!--det:summary.timing.macos-int-cpu-q2-before.task_j_per_decode.min-->–4.90<!--det:summary.timing.macos-int-cpu-q2-before.task_j_per_decode.max-->) | — | — | 34<!--det:summary.timing.macos-int-cpu-q2-before.load_avg_1min.min-->–42<!--det:summary.timing.macos-int-cpu-q2-before.load_avg_1min.max--> |
|
||
| `macos-int-cpu-q6-after` | 477.5<!--det:summary.timing.macos-int-cpu-q6-after.ms_per_decode.median--> (392.1<!--det:summary.timing.macos-int-cpu-q6-after.ms_per_decode.min-->–909.3<!--det:summary.timing.macos-int-cpu-q6-after.ms_per_decode.max-->) | 6.43<!--det:summary.timing.macos-int-cpu-q6-after.task_j_per_decode.median--> (6.12<!--det:summary.timing.macos-int-cpu-q6-after.task_j_per_decode.min-->–6.63<!--det:summary.timing.macos-int-cpu-q6-after.task_j_per_decode.max-->) | — | — | 32<!--det:summary.timing.macos-int-cpu-q6-after.load_avg_1min.min-->–62<!--det:summary.timing.macos-int-cpu-q6-after.load_avg_1min.max--> |
|
||
| `macos-int-cpu-q6-before` | 268.1<!--det:summary.timing.macos-int-cpu-q6-before.ms_per_decode.median--> (228.4<!--det:summary.timing.macos-int-cpu-q6-before.ms_per_decode.min-->–409.0<!--det:summary.timing.macos-int-cpu-q6-before.ms_per_decode.max-->) | 11.01<!--det:summary.timing.macos-int-cpu-q6-before.task_j_per_decode.median--> (10.93<!--det:summary.timing.macos-int-cpu-q6-before.task_j_per_decode.min-->–11.16<!--det:summary.timing.macos-int-cpu-q6-before.task_j_per_decode.max-->) | — | — | 33<!--det:summary.timing.macos-int-cpu-q6-before.load_avg_1min.min-->–47<!--det:summary.timing.macos-int-cpu-q6-before.load_avg_1min.max--> |
|
||
|
||
|
||
On host A every round of every run read clean. At quality 6 the narrow kernels took the
|
||
integer decode from 728.0<!--det:summary.timing.linux-int-cpu-q6-before.ms_per_decode.median--> ms and
|
||
92.14<!--det:summary.timing.linux-int-cpu-q6-before.rapl.marginal_j_per_decode.median--> J to
|
||
144.8<!--det:summary.timing.linux-int-cpu-q6-after.ms_per_decode.median--> ms and
|
||
12.43<!--det:summary.timing.linux-int-cpu-q6-after.rapl.marginal_j_per_decode.median--> J, against
|
||
210.7<!--det:summary.timing.linux-float-cpu-q6-again.ms_per_decode.median--> ms and
|
||
14.03<!--det:summary.timing.linux-float-cpu-q6-again.rapl.marginal_j_per_decode.median--> J for the float decode;
|
||
at quality 2 from 345.8<!--det:summary.timing.linux-int-cpu-q2-before.ms_per_decode.median--> ms and
|
||
42.25<!--det:summary.timing.linux-int-cpu-q2-before.rapl.marginal_j_per_decode.median--> J to
|
||
92.9<!--det:summary.timing.linux-int-cpu-q2-after.ms_per_decode.median--> ms and
|
||
7.31<!--det:summary.timing.linux-int-cpu-q2-after.rapl.marginal_j_per_decode.median--> J, against
|
||
132.2<!--det:summary.timing.linux-float-cpu-q2-again.ms_per_decode.median--> ms and
|
||
9.26<!--det:summary.timing.linux-float-cpu-q2-again.rapl.marginal_j_per_decode.median--> J. With the AVX2 set
|
||
on the same host the integer decode drew
|
||
9.27<!--det:summary.timing.linux-int-cpu-q2-after-avx2.rapl.marginal_j_per_decode.median--> J at quality 2 and
|
||
16.46<!--det:summary.timing.linux-int-cpu-q6-after-avx2.rapl.marginal_j_per_decode.median--> J at quality 6.
|
||
The record's own runs of 2026-10-22 (§4.5) and the `-before` runs agree within a few
|
||
tenths of a joule.
|
||
|
||
On host B, under the load of the CI jobs it serves, the integer decode went from
|
||
1582.1<!--det:summary.timing.linux-b-int-cpu-q6-before.ms_per_decode.median--> ms and
|
||
84.92<!--det:summary.timing.linux-b-int-cpu-q6-before.rapl.marginal_j_per_decode.median--> J to
|
||
294.3<!--det:summary.timing.linux-b-int-cpu-q6-after.ms_per_decode.median--> ms and
|
||
19.97<!--det:summary.timing.linux-b-int-cpu-q6-after.rapl.marginal_j_per_decode.median--> J at quality 6, and
|
||
from 714.0<!--det:summary.timing.linux-b-int-cpu-q2-before.ms_per_decode.median--> ms and
|
||
43.84<!--det:summary.timing.linux-b-int-cpu-q2-before.rapl.marginal_j_per_decode.median--> J to
|
||
170.2<!--det:summary.timing.linux-b-int-cpu-q2-after.ms_per_decode.median--> ms and
|
||
11.56<!--det:summary.timing.linux-b-int-cpu-q2-after.rapl.marginal_j_per_decode.median--> J at quality 2, where
|
||
two of the seven rounds were relative-only against their idle brackets and the rest clean. No float decode was measured
|
||
beside them there.
|
||
|
||
On the build host the narrow kernels lowered the decoder's own CPU energy from
|
||
11.01<!--det:summary.timing.macos-int-cpu-q6-before.task_j_per_decode.median--> J to
|
||
6.43<!--det:summary.timing.macos-int-cpu-q6-after.task_j_per_decode.median--> J at quality 6 and from
|
||
4.76<!--det:summary.timing.macos-int-cpu-q2-before.task_j_per_decode.median--> J to
|
||
2.96<!--det:summary.timing.macos-int-cpu-q2-after.task_j_per_decode.median--> J at quality 2. The float decode's
|
||
own CPU energy there was 1.28<!--det:summary.timing.macos-float-cpu-q6-again.task_j_per_decode.median--> J and
|
||
0.92<!--det:summary.timing.macos-float-cpu-q2-again.task_j_per_decode.median--> J: by that count the integer
|
||
decode still costs more on this host, and the count may leave out the float decode's matrix
|
||
unit (§5). The host was under heavy load from other work throughout (the load averages in
|
||
the table). Its times swing with that load from round to round and from run to run by more
|
||
than the kernels change them, so that a run's median time there says little: the `-after`
|
||
runs' medians lie above the `-before` runs' though their ranges overlap, while each run's
|
||
per-task counts stay within a few tenths of a joule of each other. The per-task count is the
|
||
build host's comparable figure.
|
||
|
||
## 5. What this does and does not show
|
||
|
||
- **One model, one export.** The integer codec is a post-training quantisation of one
|
||
model family with one recipe: per-channel 12-bit weights, activations at 2¹², no
|
||
retraining. Another model, a wider export or quantisation-aware training costs
|
||
something else, and this record does not say what.
|
||
- **One set of pictures.** 24 pictures of one source set at 768×512, whole. Rate and
|
||
quality are picture-dependent, so the record keeps every picture's figure.
|
||
- **What the BD-rate includes.** The integer codec's rate is its own: its hyper-decoder
|
||
decides the tables in integers, so its streams differ from the float codec's even before
|
||
its synthesis runs. The BD-rate is the cost of the whole integer codec at equal quality,
|
||
rate and distortion together.
|
||
- **Reproducibility.** An integer decode that gave the same bytes on every platform
|
||
reached is evidence of the construction on those platforms. It is not the ground of the
|
||
tier's claim (determinism-tiers §7). A float decode that reproduced on a platform here
|
||
says nothing of another platform, another build of the library or another device.
|
||
- **Time and energy.** Both hosts are shared, and the build host was under heavy load
|
||
from other work throughout; the record keeps the load average of every round. The
|
||
per-task count is the decoder's own CPU energy and nothing else; the GPU rail and the
|
||
package counter cover their whole device, and a figure from them is the round's marginal
|
||
over its idle brackets. The record's integer decoder is CPU code with the wide kernels of
|
||
`int_kernels` (NEON on arm64, portable Rust elsewhere), §4.6's with the narrow kernel sets
|
||
(NEON on arm64, AVX2 and AVX-512 on x86_64), and its GPU decode runs the graphs the
|
||
device takes through `wai-ops-gpu`; the float decode runs the library's own kernels. The
|
||
figures compare those implementations on those hosts, not integer and float arithmetic in
|
||
general.
|
||
- **What the per-task count covers on the build host.** It is the kernel's account of the
|
||
process's CPU energy. The float library's CPU kernels on that host may hand matrix work to
|
||
a matrix unit the CPU clusters share, and this record does not establish whether the
|
||
per-task count includes that unit's energy; so on the build host, the float codec's CPU
|
||
figure may be lower than the energy its decode caused. Host A's package counter has no
|
||
such gap for the CPU: it covers the whole package, the decode's share of it being the
|
||
marginal over the idle brackets. Whether it also covers the package's integrated GPU, the
|
||
interface does not state, so host A's figure for the integer decode with its graphs on that
|
||
GPU is the package's marginal and nothing more.
|
||
- **The encoder** is float in both codecs and is not measured.
|
||
|
||
## 6. Reproduce
|
||
|
||
```sh
|
||
W=/some/work/dir; T=wai/tools
|
||
python3 $T/wai_determinism_cost.py select $W <reference-root> # 24 pictures, checked
|
||
python3 $T/wai_determinism_cost.py export $W # 8 pinned checkpoints -> integer sets
|
||
python3 $T/wai_determinism_cost.py encode $W # both codecs; float decode in-process
|
||
python3 $T/wai_determinism_cost.py jobs $W native > jobs.tsv
|
||
wai_det_cost decode jobs.tsv > $W/int.native.tsv # the integer decodes (wai-rs bin)
|
||
python3 $T/wai_determinism_cost.py metrics $W
|
||
# per platform: wai_det_cost [--gpu] decode <jobs> > $W/xplat/<tag>.tsv (+ <tag>.json, the platform)
|
||
# wai_determinism_cost.py fdecode $W <tag> --device cpu|mps [--threads 1]
|
||
# per run: wai_det_energy.py --label L --counter task|ioreport-gpu|rapl -- <child> > $W/energy/L.json
|
||
python3 $T/wai_determinism_cost.py record $W wai/research/determinism-cost/record.json
|
||
python3 -I $T/wai_determinism_cost_verify.py wai/research/determinism-cost/record.json \
|
||
wai/research/determinism-cost.md wai/extensions/determinism-tiers.md
|
||
```
|
||
|
||
The scripts that ran each step on each host are in [`determinism-cost/runs/`](determinism-cost/runs/README.md).
|