Skip to content

Commit 62f4f99

Browse files
committed
fix(cuda): pin turbo4 cooperative warp-collectives to WARP_SIZE (gfx803 corruption)
The mt_paged_attention turbo4 scatter/decode/tile kernels and the set-rows turbo4 quant kernel are written for 32-lane warps (WARP_SIZE=32, DECODE_NUM_WARPS=NUM_THREADS/32, lane=tid%32). They issued bare 3-arg __shfl_*_sync, which the HIP shim maps to width=warpSize. On gfx803 (GCN) warpSize=64, so two logical 32-lane warps share one 64-wide hardware wave: * scatter/set-rows nibble pack: __shfl_sync(.., my_nibble, lane^1) read the partner from the wrong half of the wave for threads 32-63/96-127, corrupting ~25% of packed K/V nibbles. * decode/tile dequant: __shfl_sync(.., norm_f, 0) broadcast lane-0s norm
1 parent 8d078ea commit 62f4f99

5 files changed

Lines changed: 15 additions & 15 deletions

File tree

ggml/src/ggml-cuda/mt_pagedattn.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ __global__ void mt_scatter_kv_turbo4_0_kernel(
421421
// ---- Step 6: Pack qs (nibble packed, warp-cooperative) ----
422422
const int lane = j % WARP_SIZE;
423423
const uint8_t my_nibble = idx & 0xF;
424-
const uint8_t partner_nibble = __shfl_sync(0xffffffffu, my_nibble, lane ^ 1);
424+
const uint8_t partner_nibble = __shfl_sync(0xffffffffu, my_nibble, lane ^ 1, WARP_SIZE);
425425
if ((j & 1) == 0) {
426426
blk->qs[j / 2] = my_nibble | (partner_nibble << 4);
427427
}

ggml/src/ggml-cuda/mt_pagedattn_aiter.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ __global__ void mt_scatter_kv_turbo4_aiter_kernel(
322322
{
323323
const int lane = j % WARP_SIZE;
324324
const uint8_t my_nibble = idx & 0xF;
325-
const uint8_t partner_nibble = __shfl_sync(0xffffffffu, my_nibble, lane ^ 1);
325+
const uint8_t partner_nibble = __shfl_sync(0xffffffffu, my_nibble, lane ^ 1, WARP_SIZE);
326326
if ((j & 1) == 0) {
327327
blk->qs[j / 2] = my_nibble | (partner_nibble << 4);
328328
}

ggml/src/ggml-cuda/mt_pagedattn_decode.cu

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ static __device__ __forceinline__ void decode_coop_stage_turbo4(
238238
}
239239
}
240240
}
241-
norm_f = __shfl_sync(0xFFFFFFFF, norm_f, 0);
241+
norm_f = __shfl_sync(0xFFFFFFFF, norm_f, 0, WARP_SIZE);
242242

243243
uint16_t packed = 0;
244244
if (blk != nullptr) {
@@ -302,7 +302,7 @@ static __device__ __forceinline__ void decode_coop_stage_turbo3(
302302
}
303303
}
304304
}
305-
norm_f = __shfl_sync(0xFFFFFFFF, norm_f, 0);
305+
norm_f = __shfl_sync(0xFFFFFFFF, norm_f, 0, WARP_SIZE);
306306

307307
uint8_t qs_byte = 0;
308308
uint8_t signs_byte = 0;
@@ -386,7 +386,7 @@ template <typename T>
386386
__device__ __forceinline__ T decode_warp_reduce_sum(T v) {
387387
#pragma unroll
388388
for (int mask = WARP_SIZE / 2; mask > 0; mask >>= 1) {
389-
v += __shfl_xor_sync(0xFFFFFFFF, v, mask);
389+
v += __shfl_xor_sync(0xFFFFFFFF, v, mask, WARP_SIZE);
390390
}
391391
return v;
392392
}
@@ -395,7 +395,7 @@ template <typename T>
395395
__device__ __forceinline__ T decode_warp_reduce_max(T v) {
396396
#pragma unroll
397397
for (int mask = WARP_SIZE / 2; mask > 0; mask >>= 1) {
398-
v = max(v, __shfl_xor_sync(0xFFFFFFFF, v, mask));
398+
v = max(v, __shfl_xor_sync(0xFFFFFFFF, v, mask, WARP_SIZE));
399399
}
400400
return v;
401401
}
@@ -938,7 +938,7 @@ __global__ void mt_paged_attention_decode_kernel_wmma(
938938
float local_max = -INFINITY;
939939
#pragma unroll
940940
for (int l = 0; l < scores.ne; ++l) local_max = max(local_max, scores.x[l]);
941-
const float row_max = max(local_max, __shfl_xor_sync(0xFFFFFFFF, local_max, 16));
941+
const float row_max = max(local_max, __shfl_xor_sync(0xFFFFFFFF, local_max, 16, WARP_SIZE));
942942

943943
const float new_max = max(running_max, row_max);
944944
float rescale = 1.0f;
@@ -959,7 +959,7 @@ __global__ void mt_paged_attention_decode_kernel_wmma(
959959
scores.x[l] = e;
960960
local_sum += e;
961961
}
962-
const float row_sum = local_sum + __shfl_xor_sync(0xFFFFFFFF, local_sum, 16);
962+
const float row_sum = local_sum + __shfl_xor_sync(0xFFFFFFFF, local_sum, 16, WARP_SIZE);
963963
running_sum += row_sum;
964964
running_max = new_max;
965965

ggml/src/ggml-cuda/mt_pagedattn_tile.cu

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ static __device__ __forceinline__ void coop_stage_turbo4_tile(
230230
}
231231

232232
// Broadcast norm from lane 0 to all 32 lanes of this warp.
233-
norm_f = __shfl_sync(0xFFFFFFFF, norm_f, 0);
233+
norm_f = __shfl_sync(0xFFFFFFFF, norm_f, 0, WARP_SIZE);
234234

235235
// Each lane reads 2 bytes (4 nibbles = 4 elements). qs is uint8_t[64],
236236
// 2-byte aligned at qs[2*lane_id] for any lane.
@@ -308,7 +308,7 @@ static __device__ __forceinline__ void coop_stage_turbo3_tile(
308308
}
309309

310310
// Broadcast norm from lane 0 to all 32 lanes of this warp.
311-
norm_f = __shfl_sync(0xFFFFFFFF, norm_f, 0);
311+
norm_f = __shfl_sync(0xFFFFFFFF, norm_f, 0, WARP_SIZE);
312312

313313
// Each lane reads 1 byte of qs (its 4 elements' low2 bits) and 1
314314
// byte of signs (covers this lane's 4 elements' high1 bits, plus
@@ -476,7 +476,7 @@ __global__ void mt_paged_attention_tile_kernel(
476476
for (int l = 0; l < scores.ne; ++l) {
477477
local_max = max(local_max, scores.x[l]);
478478
}
479-
const float row_max = max(local_max, __shfl_xor_sync(0xFFFFFFFF, local_max, 16));
479+
const float row_max = max(local_max, __shfl_xor_sync(0xFFFFFFFF, local_max, 16, WARP_SIZE));
480480

481481
const float new_max = max(running_max, row_max);
482482

@@ -502,7 +502,7 @@ __global__ void mt_paged_attention_tile_kernel(
502502
scores.x[l] = e;
503503
local_sum += e;
504504
}
505-
const float row_sum = local_sum + __shfl_xor_sync(0xFFFFFFFF, local_sum, 16);
505+
const float row_sum = local_sum + __shfl_xor_sync(0xFFFFFFFF, local_sum, 16, WARP_SIZE);
506506
running_sum += row_sum;
507507
running_max = new_max;
508508

@@ -861,7 +861,7 @@ __global__ void mt_paged_attention_tile_mw_kernel(
861861
for (int l = 0; l < scores.ne; ++l) {
862862
local_max = max(local_max, scores.x[l]);
863863
}
864-
const float row_max = max(local_max, __shfl_xor_sync(0xFFFFFFFF, local_max, 16));
864+
const float row_max = max(local_max, __shfl_xor_sync(0xFFFFFFFF, local_max, 16, WARP_SIZE));
865865

866866
const float new_max = max(running_max, row_max);
867867

@@ -887,7 +887,7 @@ __global__ void mt_paged_attention_tile_mw_kernel(
887887
scores.x[l] = e;
888888
local_sum += e;
889889
}
890-
const float row_sum = local_sum + __shfl_xor_sync(0xFFFFFFFF, local_sum, 16);
890+
const float row_sum = local_sum + __shfl_xor_sync(0xFFFFFFFF, local_sum, 16, WARP_SIZE);
891891
running_sum += row_sum;
892892
running_max = new_max;
893893

ggml/src/ggml-cuda/set-rows.cu

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,7 @@ static __global__ void k_set_rows_turbo4(
10681068
const uint8_t my_nibble = idx & 0xF;
10691069
uint8_t qs_byte = 0;
10701070
// Gather nibble from partner thread
1071-
uint8_t partner_nibble = __shfl_sync(0xffffffff, my_nibble, lane ^ 1);
1071+
uint8_t partner_nibble = __shfl_sync(0xffffffff, my_nibble, lane ^ 1, WARP_SIZE);
10721072
if (j % 2 == 0) {
10731073
qs_byte = my_nibble | (partner_nibble << 4);
10741074
blk->qs[j / 2] = qs_byte;

0 commit comments

Comments
 (0)