vulkan 1D convolution family: conv1d winograd/subgroup, convolutiondepthwise1d, deconvolution1d - #6909
vulkan 1D convolution family: conv1d winograd/subgroup, convolutiondepthwise1d, deconvolution1d#6909futz12 wants to merge 18 commits into
Conversation
Add Winograd transform path for Convolution1D_vulkan when kernel_w=3, stride_w=1, dilation_w=1, num_input>=16, num_output>=16. The three-stage pipeline (transform_input -> gemm -> transform_output) reuses existing 2D Winograd GEMM shaders and adds new 1D transform_input/output shaders for both F(2,3) and F(4,3) tile sizes with pack1/pack4 variants.
Add Vulkan backend for 1D depthwise separable convolution with depthwise and group convolution paths, supporting pack1/pack4/pack1to4/pack4to1 variants, fused activation, bias, and 1D padding (explicit/SAME_UPPER/SAME_LOWER).
The 1D winograd transform shaders produce a memory layout with 1 spatial element per channel per tile, but the reused 2D winograd GEMM shaders expect 4 consecutive spatial elements per channel per tile. This layout mismatch caused completely wrong output. Add 4 dedicated 1D winograd GEMM shaders (sfp, pack4, pack1to4, pack4to1) and update pipeline creation to use them. Verified: winograd ON = winograd OFF (fp32).
Add per-column bounds checks when reading bottom_tm data in the convolution1d_3s1d1_winograd_gemm shader, preventing garbage values from being accumulated near the right edge when outw is not a multiple of 4.
Change accumulation from fp16 to fp32 in convolution1d_packed.comp and convolution1d_packed_sg.comp to prevent precision degradation when use_fp16_arithmetic=true. Storage remains fp16 for bandwidth efficiency, but accumulation now happens in fp32 to avoid rounding error accumulation in large convolutions.
There was a problem hiding this comment.
💡 Codex Review
When Winograd, SGEMM, and cooperative matrices are enabled for a 3-tap convolution, the Winograd pipelines and weights are first built using an optimal tuple for K = num_input, but this call overwrites the shared tuple and unroll fields using K = num_input * maxk. The Winograd forward path later calculates its dispatch from these overwritten fields, so on devices where the optimizer selects a different matrix shape or subgroup size for the two K dimensions, the dispatch no longer matches the baked pipeline and packed weights, resulting in missing work, out-of-bounds access, or incorrect output. Keep separate cooperative-matrix parameters for the Winograd and generic GEMM pipelines, or avoid constructing the unused generic pipeline for this case.
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
When both Winograd and SGEMM cooperative-matrix paths are enabled for a 3-tap convolution, this second query overwrites the coopmat_* and UNROLL_* members used to create and pack the Winograd pipeline earlier. On devices where the optimal tuple differs between K = num_input and K = 3 * num_input, forward() consequently calculates the Winograd dispatch with the SGEMM tuple even though the shader specializations, local size, and packed weights use the original tuple, producing incomplete or incorrectly indexed output. Keep separate parameters for the two pipelines or avoid overwriting the Winograd values.
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5dda8a5cef
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8fbd049f1c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d284c9c04d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f573c12b1b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…size - convolution1d_vulkan: pass per-component weight stride (num_input/elempack * num_output/out_elempack) as wcstep push constant instead of the flattened 1D blob cstep which covered all winograd components; the old value made components 1..5 read out-of-bounds garbage for both winograd23/43 gemm. - gemm shaders: reference p.wcstep (push constant) instead of the undeclared psc(wcstep). - test_convolutiondepthwise1d: allocate kernel (not kernel*kernel) sized weights to match the 1D depthwise layout.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 766c478289
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| afpmat4 k = afpmat4(weight_data[w_offset + x]); | ||
| #endif | ||
|
|
||
| sum += v * k; |
There was a problem hiding this comment.
Use a vec4 for pack1-to-pack4 weights
When each group has pack1 inputs but pack4 outputs, the CPU packer stores one four-component weight vector per input channel and kernel position, but this shader constructs k as a matrix and evaluates the vector-invalid expression sum += v * k. Consequently the selected convolutiondepthwise1d_group_pack1to4 pipeline cannot compile correctly (and the fp16-storage branch additionally reads four consecutive weight vectors instead of one), so configurations such as 4 inputs, 8 outputs, and 2 groups cannot run on Vulkan; load a single afpvec4 here as the existing 2D pack1-to-pack4 shader does.
Useful? React with 👍 / 👎.
|
Please enable github action in YOUR FORKED REPO to make code-format workflow work |
This branch adds and accelerates Vulkan implementations for the 1D
convolution operators used by sequence/audio models.
Convolution1D Vulkan
= one subgroup; lanes cooperatively load input/weight tiles and
share them via subgroup shuffle. Tile unroll factors are tuned per
device subgroup size (16/32/64/128), with a guard for fp16 shuffle
(subgroup extended types).
in/out channels >= 16: transform input -> GEMM over the winograd
tiles (4 or 6) -> transform output. F(2,3) is auto-selected for
short sequences and F(4,3) for longer ones; weights are
pre-transformed into the winograd domain at create_pipeline.
replace the generic 2D GEMM path.
the packed and subgroup shaders, tensor-stride fix, out-of-bounds
fix in the non-shared-memory GEMM path, and removal of redundant
bounds checks.
ConvolutionDepthWise1D Vulkan (new operator)
pipelines, mirroring the existing 2D ConvolutionDepthWise operator.
Deconvolution1D Vulkan (new operator)
GEMM shaders), with an optional cooperative-matrix path and pack4
support.
Files added (highlights):
Motivation: RVC-style voice conversion graphs are dominated by Conv1d
(kernel 10/3/2/5/1), depthwise Conv1d and Deconv1d. These operators let
the whole graph run on Vulkan and give a large speedup over the CPU
fallbacks / naive paths.