You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[ET-VK][conv2d] Use * and + instead of fma() on f16 vectors - #24856
Optimizing the FP16 1x1 convolutions of the DSR model on mobile GPUs.
Rationale
What: A mul_add(a, b, c) helper in common.glslh computes a * b + c. In shaders that define HAS_FLOAT16_ACCUMULATION, it uses * and + for f16vec4 and fma() for vec4; in other shaders it is fma(). The GEMM tile helper and conv2d_tiled call it instead of fma(), and the conv2d shaders that accumulate in f16 vectors define the marker: conv2d_pw_tiled, conv2d_tiled and the buffer input conv2d_gemm.
Why: Adreno 740 and 750 run fma() on f16 vectors at about half the speed of a multiply and an add. With this commit, Half pointwise convolutions take 0.37 to 0.49 of the time on a Galaxy S23 (Adreno 740) and a Galaxy S24 (Adreno 750). Replacing fma() in every shader regardless of type made Float shaders up to 1.35 times as slow on the same phones, so the form depends on the type.
Details
Before: Multiply-accumulates call fma() for both dtypes.
After: In the Half variants of conv2d_pw_tiled, conv2d_tiled and the buffer input conv2d_gemm, multiply-accumulates on f16 vectors compute c + a * b. Every other shader still calls fma(), including the other users of the GEMM tile helper (linear, matmul, Q4 and Q8 linear, fused SDPA).
f16vec4 is a type only when GL_EXT_shader_explicit_arithmetic_types_float16 is enabled, so a shader opts in by defining HAS_FLOAT16_ACCUMULATION before it includes common.glslh; without it, mul_add is a macro for fma(). Two alternatives do not work:
Enabling the extension in common.glslh for every shader changes implicit conversions in shaders that do not use f16 arithmetic (max_pool2d's mix() call becomes ambiguous).
The extension's own macro cannot be the guard: glslang defines GL_EXT_shader_explicit_arithmetic_types_float16 whether or not the extension is enabled.
Other shaders that accumulate in f16 vectors can opt in once their accuracy and performance are measured.
c + a * b rounds the product before the add, which fma() does not. On Adreno 740 and 750, the f16 error statistics of some conv2d correctness configurations change; all still pass. Outputs on Adreno 840, Mali-G715 and Xclipse 940 are bit-identical to the parent's.
Only 16 SPIR-V modules change: the Half conv2d_pw_tiled (4), conv2d_tiled (11) and conv2d_gemm_buffer_half modules.
This comment was automatically generated by Dr. CI and updates every 15 minutes.
meta-claBot
added
the
CLA Signed
This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
label
Nov 10, 2026
If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.
To add a label, you can comment to pytorchbot, for example @pytorchbot label "release notes: none"
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CLA SignedThis label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.meta-exported
1 participant
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack from ghstack (oldest at bottom):
Ulterior Motive
Optimizing the FP16 1x1 convolutions of the DSR model on mobile GPUs.
Rationale
What: A
mul_add(a, b, c)helper incommon.glslhcomputesa * b + c. In shaders that defineHAS_FLOAT16_ACCUMULATION, it uses*and+forf16vec4andfma()forvec4; in other shaders it isfma(). The GEMM tile helper andconv2d_tiledcall it instead offma(), and the conv2d shaders that accumulate in f16 vectors define the marker:conv2d_pw_tiled,conv2d_tiledand the buffer inputconv2d_gemm.Why: Adreno 740 and 750 run
fma()on f16 vectors at about half the speed of a multiply and an add. With this commit, Half pointwise convolutions take 0.37 to 0.49 of the time on a Galaxy S23 (Adreno 740) and a Galaxy S24 (Adreno 750). Replacingfma()in every shader regardless of type made Float shaders up to 1.35 times as slow on the same phones, so the form depends on the type.Details
fma()for both dtypes.conv2d_pw_tiled,conv2d_tiledand the buffer inputconv2d_gemm, multiply-accumulates on f16 vectors computec + a * b. Every other shader still callsfma(), including the other users of the GEMM tile helper (linear, matmul, Q4 and Q8 linear, fused SDPA).f16vec4is a type only whenGL_EXT_shader_explicit_arithmetic_types_float16is enabled, so a shader opts in by definingHAS_FLOAT16_ACCUMULATIONbefore it includescommon.glslh; without it,mul_addis a macro forfma(). Two alternatives do not work:common.glslhfor every shader changes implicit conversions in shaders that do not use f16 arithmetic (max_pool2d'smix()call becomes ambiguous).GL_EXT_shader_explicit_arithmetic_types_float16whether or not the extension is enabled.Other shaders that accumulate in f16 vectors can opt in once their accuracy and performance are measured.
c + a * brounds the product before the add, whichfma()does not. On Adreno 740 and 750, the f16 error statistics of some conv2d correctness configurations change; all still pass. Outputs on Adreno 840, Mali-G715 and Xclipse 940 are bit-identical to the parent's.Only 16 SPIR-V modules change: the Half
conv2d_pw_tiled(4),conv2d_tiled(11) andconv2d_gemm_buffer_halfmodules.Differential Revision: D130986954