Metal already provides a strong precise floating-point contract. With fast math disabled (mathMode = .safe and mathFloatingPointFunctions = .precise, or -fno-fast-math), the Metal Shading Language specification requires correctly rounded FP32 add, subtract, multiply, reciprocal, divide, sqrt, rsqrt, and fma.
I am looking for clarification and, if necessary, API support for the two remaining pieces needed for portable bit-exact numerical shaders:
- Arithmetic rounding mode
MSL §8.2 says either round-to-nearest-ties-to-even or round-toward-zero may be supported for floating-point operations. I cannot find a way to select or query the arithmetic rounding mode. The newer MTLCompileOptions.floatingPointConversionRoundingMode appears to apply only to narrowing float-to-float conversions, not arithmetic operations.
Do all currently supported Apple GPU families use round-to-nearest-ties-to-even for precise FP32 add/subtract/multiply/divide/sqrt? If so, could that be made a documented guarantee? Otherwise, could Metal expose an arithmetic rounding-mode compile option and a corresponding MTLDevice capability query?
- Denormal behavior
MSL §8.1 and §8.5 permit denormalized FP32 operands and results to be flushed to zero, including with fast math disabled. I cannot find a control or capability query for preserving denormal inputs and results.
Do current Apple GPU families support denormal-preserving FP32 arithmetic? Could Metal expose a preserve/flush mode and a MTLDevice query?
A convenient end state would be a queryable strict FP32 configuration combining:
- safe math;
- precise FP32 functions;
- contraction disabled when separate rounding points are required;
- round-to-nearest-ties-to-even arithmetic;
- preserved FP32 denormal inputs and results;
- defined signed-zero, infinity, and NaN behavior.
My use case is deterministic GPU numerical simulation. A small compute-shader probe can identify effective rounding and denormal behavior on one GPU/OS/compiler combination, but it cannot provide the portable or future-proof contract needed by applications and higher-level APIs such as WebGPU.
Related cross-API work:
- SPIR-V/Vulkan: https://github.com/KhronosGroup/SPIRV-Registry/issues/448
- HLSL/DXIL/D3D12: https://github.com/microsoft/hlsl-specs/issues/926
- WebGPU/WGSL umbrella issue: https://github.com/gpuweb/gpuweb/issues/2259
Relevant Metal documentation:
- Metal Shading Language Specification, §§1.6.3 and 8.1–8.5: https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf
MTLCompileOptions.mathMode: https://developer.apple.com/documentation/metal/mtlcompileoptions/mathmodeMTLCompileOptions.floatingPointConversionRoundingMode: https://developer.apple.com/documentation/metal/mtlcompileoptions/floatingpointconversionroundingmode
No API selects or queries the FP32 arithmetic rounding mode, and none controls or queries denormal handling. I checked the Metal framework headers in both the current and the upcoming SDK. There is no denormal-related declaration of any kind, and the only rounding controls present are for conversions and for texture writes.
The specification states its position on both in the two sentences you cited. Metal Shading Language Specification (https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf), section 8.2:
Either round ties to even or round toward zero rounding mode may be supported for single-precision, half-precision, and brain floating-point operations.
And section 8.1:
Denormalized single-precision, half-precision, or brain floating-point numbers passed as input to or produced as the output of single-precision, half-precision, or brain floating-point arithmetic operations may be flushed to zero.
Both are written as permissions, and neither is conditioned on the math mode.
One item on your list is available today. Section 1.6.3 documents one compiler option and two pragmas that disable contraction:
-ffp-contract=off#pragma METAL fp contract([off | on | fast])#pragma STDC FP_CONTRACT OFF
Selecting safe math is not sufficient on its own. The same section says of safe mode that it "sets the FP contract to on".
Conversion rounding, unlike arithmetic rounding, has a documented default. In Metal 4.1 and later, -fmetal-rtz-fp-conversion changes "the default rounding mode for float-to-float conversions from RTNE (round to nearest, ties to even) to RTZ (round toward zero)". The floatingPointConversionRoundingMode property on MTLCompileOptions (https://developer.apple.com/documentation/metal/mtlcompileoptions) covers the same narrowing conversions, and is annotated for macOS 27 and iOS 27.
Section 1.6.7 refers to the Metal Feature Set Tables (https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf) for which GPU families support rounding modes other than native. That document contains no rounding entries, so it won't help here.
For the rest, Feedback Assistant (https://feedback.apple.com) is where those requests would go. I suggest two separate reports:
- A request that chapter 8 state the arithmetic rounding mode and the denormal behavior for the GPU families Metal supports, including the texture-write rounding support that section 1.6.7 refers to
- A request for the compile-time controls and the
MTLDevicequeries
Your probe results are evidence for the first report, because they show what current hardware does.