From b4b85abbc7ffff048dbc2021898bbbef191c9a26 Mon Sep 17 00:00:00 2001 From: Nils Homer Date: Mon, 22 Jun 2026 09:44:10 -0700 Subject: [PATCH 1/2] perf(metal): add opt-in DV_METAL_FP16 reduced-precision inference MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gate MPSGraph precision on DV_METAL_FP16: when set, use optimizationLevel1 + reducedPrecisionFastMath=Default (FP16 Winograd / operand conversion) instead of the forced Level0/FP32 path. Default (unset) is unchanged and remains contractual full FP32. Validated on chr20 (HG002, 4731 examples): metadata and record order are identical to FP32, and fp16-vs-fp32 genotype-call agreement is 60/4731 (1.27%) — exactly the FP32 backend's own run-to-run nondeterminism baseline, i.e. reduced precision adds no divergence beyond what the default metal backend already exhibits. A true ANE path is not added: the 7-channel Inception-v3 input is rejected by the ANE, so MPSGraph stays on the GPU. Any default flip should still be gated behind GIAB concordance. --- deepvariant/native/metal_inference.mm | 31 ++++++++++++++++++++------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/deepvariant/native/metal_inference.mm b/deepvariant/native/metal_inference.mm index b6e99ade..918a1e3f 100644 --- a/deepvariant/native/metal_inference.mm +++ b/deepvariant/native/metal_inference.mm @@ -738,18 +738,33 @@ FusedConv FoldConvBn(const DvwWeights& dvw, int conv_n, int bn_n) { // produces channel-permuted output for our FP32 Inception-v3 conv. // Level0 forces GPU-only, full-precision execution at the cost of // some perf optimisations. + // DV_METAL_FP16=1 opts into reduced-precision inference: MPSGraph is + // allowed to use FP16 Winograd intermediates + operand conversion and the + // Level1 perf optimisations. This is faster on Apple Silicon but is NOT + // bit-identical to the FP32 path and changes genotype likelihoods at the + // last digits — gate any default flip behind a GIAB concordance check. + // Default (unset) keeps the contractual full-FP32 behaviour unchanged. + const char* fp16_env = std::getenv("DV_METAL_FP16"); + const bool fp16 = fp16_env && fp16_env[0] == '1'; I.compileDesc = [MPSGraphCompilationDescriptor new]; - I.compileDesc.optimizationLevel = MPSGraphOptimizationLevel0; + I.compileDesc.optimizationLevel = + fp16 ? MPSGraphOptimizationLevel1 : MPSGraphOptimizationLevel0; I.compileDesc.waitForCompilationCompletion = YES; - // macOS 26+: explicitly disable any reduced-precision fast-math paths - // (FP16 Winograd intermediates, FP19/TF32 operand conversion). Default - // is `None` already — setting explicitly to make this behaviour - // contractually visible and to log it on supported macOS versions. + // macOS 26+: control reduced-precision fast-math paths (FP16 Winograd + // intermediates, FP19/TF32 operand conversion). Default is `None` already + // — set explicitly to make the behaviour contractually visible and logged. if (@available(macOS 26.0, iOS 26.0, *)) { I.compileDesc.reducedPrecisionFastMath = - MPSGraphReducedPrecisionFastMathNone; - LOG(INFO) << "MPSGraph: reducedPrecisionFastMath=None (full FP32, " - << "no Winograd-FP16, no FP19/TF32 operand conversion)"; + fp16 ? MPSGraphReducedPrecisionFastMathDefault + : MPSGraphReducedPrecisionFastMathNone; + LOG(INFO) << "MPSGraph: reducedPrecisionFastMath=" + << (fp16 ? "Default (FP16 fast-math allowed)" + : "None (full FP32)"); + } + if (fp16) { + LOG(INFO) << "MetalInception: DV_METAL_FP16=1 — reduced-precision " + "inference (Level1, FP16 fast-math). NOT bit-identical to " + "FP32; validate accuracy before relying on it."; } I.execCache = [NSMutableDictionary dictionary]; I.taps = [NSMutableDictionary dictionary]; From 5f628e04d879917cded6432b26285c10fb83a8d5 Mon Sep 17 00:00:00 2001 From: Nils Homer Date: Mon, 22 Jun 2026 11:58:30 -0700 Subject: [PATCH 2/2] docs: clarify TF32 in reduced-precision comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reword the nonstandard 'FP19/TF32' to 'TF32 (19-bit)' — TF32 is the 19-bit operand format; it is not FP16 (already named as the Winograd path). --- deepvariant/native/metal_inference.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deepvariant/native/metal_inference.mm b/deepvariant/native/metal_inference.mm index 918a1e3f..00b6a870 100644 --- a/deepvariant/native/metal_inference.mm +++ b/deepvariant/native/metal_inference.mm @@ -751,7 +751,7 @@ FusedConv FoldConvBn(const DvwWeights& dvw, int conv_n, int bn_n) { fp16 ? MPSGraphOptimizationLevel1 : MPSGraphOptimizationLevel0; I.compileDesc.waitForCompilationCompletion = YES; // macOS 26+: control reduced-precision fast-math paths (FP16 Winograd - // intermediates, FP19/TF32 operand conversion). Default is `None` already + // intermediates, TF32 (19-bit) operand conversion). Default is `None` already // — set explicitly to make the behaviour contractually visible and logged. if (@available(macOS 26.0, iOS 26.0, *)) { I.compileDesc.reducedPrecisionFastMath =