Fix WebGPU grouped Conv vectorization across group boundaries (#33129)
### Description
<!-- Describe your changes. -->
Choose the general NHWC grouped-Conv vector width from the number of
output channels **per group**, rather than the total output channel
count. This prevents a vector from straddling two groups while the
shader uses one input-group offset for all its components.
Keep the dedicated depthwise vector path unchanged: its one-to-one
input/output channel correspondence permits vectorization across groups.
NCHW and existing aligned-group vector widths are unchanged.
Add 128 parameterized operator regressions with an independent scalar
convolution reference:
- Two/four groups and one/three input channels per group.
- 1, 3, 4, 5, 6, 7, 8, and 12 output channels per group.
- NHWC/NCHW and bias/no bias, with batch size two and a non-pointwise
kernel.
- Explicit WebGPU selection with CPU EP fallback disabled; unavailable
providers skip before constructing the tester.
### Motivation and Context
<!-- - Why is this change required? What problem does it solve?
- If it fixes an open issue, please link to the issue here. -->
Fixes #33086.
For example, two groups with six output channels each previously
selected `vec4` from the total of twelve channels. The vector covering
channels 4–7 crosses the group boundary, but all four lanes use the
first group's input channels. Selecting `vec2` from six channels per
group preserves group boundaries.
Validation on Linux Release with Mesa lavapipe (software Vulkan),
executing actual WebGPU shaders:
- Full WebGPU provider-test build — **passed**:
```bash
source .venv/bin/activate
python tools/ci_build/build.py --config Release --build_dir
build/linux_webgpu \
--use_webgpu --cmake_generator Ninja --parallel 24 --skip_tests \
--update --build --target onnxruntime_provider_test
```
- Temporarily restoring the original vector-width selection and
rebuilding reproduced **three numerical failures** for NHWC with 5, 6,
and 7 output channels per group:
```bash
cmake --build build/linux_webgpu/Release --target
onnxruntime_provider_test -j 24
cd build/linux_webgpu/Release
VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json \
timeout 180 ./onnxruntime_provider_test \
--gtest_filter='Conv_WebGPU/GroupedConvVectorizationTest.OutputVectorsStayWithinGroups/13:Conv_WebGPU/GroupedConvVectorizationTest.OutputVectorsStayWithinGroups/17:Conv_WebGPU/GroupedConvVectorizationTest.OutputVectorsStayWithinGroups/21'
```
- Restoring the fix and rebuilding — **passed**. Final targeted
execution — **129 passed, none skipped**, including the existing padding
regression:
```bash
cmake --build build/linux_webgpu/Release --target
onnxruntime_provider_test -j 24
cd build/linux_webgpu/Release
VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json \
timeout 180 ./onnxruntime_provider_test \
--gtest_filter='Conv_WebGPU.GroupedConvWithPaddingUsesSignedCoordinates:Conv_WebGPU/GroupedConvVectorizationTest.*'
```
- Formatting and whitespace — **passed**:
```bash
.venv/bin/clang-format --dry-run --Werror \
onnxruntime/core/providers/webgpu/nn/conv.cc \
onnxruntime/test/providers/webgpu/grouped_conv_padding_test.cc
git diff --check
```
Not validated locally: physical GPU drivers, Metal/D3D12, FP16, graph
capture, or the full test suite. Software Vulkan establishes correctness
for these MatMul-free grouped-Conv cases, not GPU performance.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>