diff --git a/ggml/src/ggml-cuda/mmvq.cu b/ggml/src/ggml-cuda/mmvq.cu index bf51b61e17b1..f8736382c54e 100644 --- a/ggml/src/ggml-cuda/mmvq.cu +++ b/ggml/src/ggml-cuda/mmvq.cu @@ -597,6 +597,9 @@ static __global__ void mul_mat_vec_q( const uint32_t sample_x = fastdiv(sample_dst, sample_ratio); const uint32_t sample_y = sample_dst; + // dst rows are contiguous; with ids the per-slot row stride is stride_channel_dst, not stride_col_dst + const uint32_t nrows_dst = ids ? stride_channel_dst : stride_col_dst; + constexpr bool use_gate = has_gate; bool use_bias = false; bool use_gate_bias = false; @@ -634,7 +637,7 @@ static __global__ void mul_mat_vec_q( // 2. load only on threads that won't die after partial sum calculation const uint32_t channel_bias = ids ? channel_x : channel_dst; if (threadIdx.x < rows_per_cuda_block && threadIdx.y == 0 && - (rows_per_cuda_block == 1 || uint32_t(row0 + threadIdx.x) < stride_col_dst)) { + (rows_per_cuda_block == 1 || uint32_t(row0 + threadIdx.x) < nrows_dst)) { if (use_bias) { x_bias = x_bias + sample_dst * stride_sample_dst + channel_bias * stride_channel_dst + row0; #pragma unroll @@ -805,7 +808,7 @@ static __global__ void mul_mat_vec_q( } } - if (threadIdx.x == i && (rows_per_cuda_block == 1 || uint32_t(row0 + i) < stride_col_dst)) { + if (threadIdx.x == i && (rows_per_cuda_block == 1 || uint32_t(row0 + i) < nrows_dst)) { float result = tmp[j][i]; if constexpr (has_fusion) { if constexpr (type == GGML_TYPE_NVFP4) {