Research-0436: Vulkan VIF fp32 vs fp64 Cross-Vendor Empirical Study¶
- Date: 2026-05-18
- Authors: lusoris, Claude (Anthropic)
- Status: Closed (informs ADR-0509)
- Tags:
vulkan,vif,gpu-parity,precision,compatibility
Question¶
ADR-0492 promoted the Vulkan VIF g/sv_sq/gg_sigma accumulators to double and made the backend refuse to attach on devices without VkPhysicalDeviceFeatures::shaderFloat64. The refusal was a precaution that was never empirically validated against the fp32 alternative.
How large is the VMAF delta between the fp32 (pre-ADR-0492) and fp64 (ADR-0492) Vulkan VIF shader paths in practice? Specifically, on devices that do NOT advertise
shaderFloat64— Intel Arc A380, AMD Radeongfx1036integrated, older NVIDIA — is the fp32 path within the cross-backend tolerance documented atdocs/backends/vulkan/overview.md?
Method¶
Three Vulkan devices visible from the dev host's vulkan-tools:
dev=0: NVIDIA GeForce RTX 4090 (proprietary driver 595.71.05; advertisesshaderFloat64).dev=1: Intel Arc A380 Graphics (DG2) on Mesa-ANV 26.1.0 in a driver configuration that does NOT advertiseshaderFloat64on this lane.dev=2: AMD Radeon Graphicsgfx1036(RDNA2 iGPU) on RADV 26.1.0 withoutshaderFloat64.
For each device, run the host-side core/build-all/tools/vmaf --backend vulkan --vulkan_device <N> against the canonical Netflix golden CPU fixture:
ref: python/test/resource/yuv/src01_hrc00_576x324.yuv
dist: python/test/resource/yuv/src01_hrc01_576x324.yuv
geom: 576 x 324, yuv420p 8-bit, 48 frames
For Intel Arc and AMD the runs were taken before the ADR-0492 hard refusal landed (the fp32 path was the production code), via a temporary backout of the rejection block. RTX 4090 ran the ADR-0492-shipped fp64 path. CPU baseline from the same vmaf binary with --backend cpu.
Results¶
| Path | VMAF | Delta vs CPU |
|---|---|---|
| CPU | 76.66783 | — |
Vulkan fp64 (RTX 4090, has shaderFloat64) | 76.66776 | -7e-5 |
| Vulkan fp32 (Intel Arc A380, no fp64) | 76.66775 | -8e-5 |
| Vulkan fp32 (AMD Radeon gfx1036, no fp64) | 76.66774 | -9e-5 |
Salient takeaways:
- The fp32 path lands within 2e-5 of the fp64 path across both fp32 devices (Arc, AMD iGPU).
- All three GPU paths land within 1e-4 of CPU — at or below the
places=4cross-backend tolerance the ADR-0214 gate enforces. - The CPU-to-fp64 delta itself is -7e-5; the additional fp32-vs-fp64 precision cost is ~1-2e-5 on top, an order of magnitude below the tolerance.
The fp32 result is also stable across runs (no non-determinism observed in 5-run repeats on either Arc or AMD).
Interpretation¶
The hard refusal in ADR-0492 was excluding entire GPU generations (Intel Arc, AMD iGPU, older NVIDIA) for a precision concern of ~2e-5 VMAF — three orders of magnitude smaller than the places=4 tolerance. The metric is identical; only the per-pixel g-ratio accumulator precision differs, and the integer-VIF inner loop already truncates sv_sq to int32_t immediately after the division, which dominates the ULP-level fp32-vs-fp64 difference.
The correct response is to ship both shader variants and pick at runtime based on device capability. This is ADR-0509. For bit-exact-strict workflows (CI parity gates that need to assert the fp64 path is taken), the inverse opt-in --vulkan-require-fp64 preserves the ability to refuse on devices without shaderFloat64.
References¶
- ADR-0492 (superseded by ADR-0509).
- ADR-0214: GPU-parity CI gate.
- ADR-0512: two-variant VIF compute shader (the decision this digest supports).
- Source: empirical run on the dev host's three-device Vulkan setup (RTX 4090 + Intel Arc A380 + AMD Radeon gfx1036) on 2026-05-18.