Skip to content

ggml : support convrot group size 64 in CUDA/HIP and Vulkan kernels - #7

Open
noctrex wants to merge 3 commits into
leejet:int8_convrotfrom
noctrex:int8-convrot-h64
Open

ggml : support convrot group size 64 in CUDA/HIP and Vulkan kernels#7
noctrex wants to merge 3 commits into
leejet:int8_convrotfrom
noctrex:int8-convrot-h64

Conversation

@noctrex

@noctrex noctrex commented Aug 27, 2026

Copy link
Copy Markdown

Z-Image int8_tensorwise (z_image_turbo_int8_convrot.safetensors) use convrot_groupsize 64.
The CPU path already handles any radix-4 group size; every GPU backend rejected 64, so those models fell back to CPU. This adds G64 to CUDA/HIP and Vulkan, stacked on #6.

CUDA/HIP (0ec2d6a):

  • Template the convrot quantization kernels on group_size; instantiate 64 alongside 256.
  • Hadamard normalization derived from the group size (2^-log4(group_size): 1/8 for G=64, 1/16 for G=256).
  • Small-kernel max reduction uses a shared-memory tree instead of warp shuffles so it stays correct for 16-thread blocks.
  • Capability gates accept {64, 256}.

Vulkan (d61707b):

  • quantize_i8_convrot.comp parameterized by a GROUP_SIZE macro (default 256, {64, 256} validated); quantize_i8_convrot_h64 SPIR-V variant registered via the existing defines mechanism.
  • Both Vulkan gates (quantize, tensorwise mulmat) accept {64, 256}; pipeline selected by the op-param group size.
  • GEMM shaders are group-size agnostic and unchanged.
  • The G256 shader variant compiles to byte-identical SPIR-V before and after the change (sha256-verified), so G256 behavior is provably untouched.

Verification (RX 7900 XTX / gfx1100, Windows, ROCm 7.1 + Adrenalin):

  • HIP: exact-reference tests pass for H64 and H256; CPU-vs-GPU bit-exact at real Z-Image shapes (K=3840/10240, N<=11520, 8104 rows), payload, scales and output all zero-mismatch.
  • Vulkan: exact-reference H64 test passes (payload bit-exact, row scales within 1 ulp, output within 1e-5); full-shape CPU-vs-GPU diff shows only the pre-existing Vulkan float-stage divergence class: rare single-byte payload diffs, always exactly 1 LSB at a .5 rounding boundary (e.g. 139/31.1M bytes), row scales within 1 ulp (~4% of rows), and their bounded propagation to outputs.
    The shipped G256 path shows the same class and magnitude.

Known limitation (pre-existing, affects G256 equally): the Vulkan backend accepts only the packed (pre-quantized) form of mul_mat_i8_tensorwise; the F32-input form that CUDA quantizes inline is rejected and such graphs fall back to CPU via the scheduler. Not introduced by this PR; can be addressed separately.

Not yet verified: NVIDIA hardware, CDNA, Linux.

Related: ggml-org/llama.cpp#26914, leejet/stable-diffusion.cpp#1857, #6 (HIP enablement, stacked base).

LLM Disclose: YES, used GLM-5.3 for the grunt work

Remove the blanket GGML_USE_HIP exclusion from the INT8 tensorwise
convrot ops and scope the capability check to GPUs with working
integer GEMM support (turing_mma_available, amd_wmma_available,
amd_mfma_available). RDNA2 stays excluded: hipBLASLt INT8 is broken
there.

vendors/hip.h: map CUDA_R_8I, CUDA_R_32I, CUBLAS_COMPUTE_32I and
__shfl_down_sync to their HIP equivalents. HIP's masked shuffle
templates require a 64-bit mask, so route to the maskless intrinsic
like the other __shfl_*_sync mappings.

Verified on gfx1100 (Windows ROCm 7.1): ggml tests/test-int8-convrot
passes, and CPU-vs-GPU output is bit-exact at real model shapes
(K=3840/10240, N up to 11520, 8104 rows).
Template the INT8 convrot quantization kernels on group_size and
instantiate 64 alongside 256. The Hadamard normalization is now
derived from the group size (2^-log4(group_size): 1/8 for G=64,
1/16 for G=256). The small-kernel max reduction uses a shared-memory
tree instead of warp shuffles so it stays correct for 16-thread
blocks. Capability gates accept group size 64 and 256.

Z-Image int8_tensorwise exports in the wild use convrot_groupsize
64; without this they fall back to CPU on every GPU backend.

Verified on gfx1100 (Windows ROCm 7.1): exact-reference tests pass
for H64 (single-group and multi-group packed GEMM), H256 unchanged,
and CPU-vs-GPU output is bit-exact at real Z-Image shapes.
Parameterize the quantize shader with a GROUP_SIZE macro (default 256,
validated {64, 256}), register the G64 SPIR-V variant, relax the quantize
and tensorwise mulmat gates to accept group size 64, and select the
pipeline by the op param group size. The GEMM shaders are group-size
agnostic and unchanged. The G256 variant compiles to byte-identical
SPIR-V as before.
@noctrex noctrex closed this Aug 27, 2026
@noctrex noctrex reopened this Aug 27, 2026
@noctrex
noctrex changed the base branch from master to int8_convrot August 27, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant