Skip to content

Commit 76e7b42

Browse files
authored
[Optimization] Optimize split_q_block kernel (PaddlePaddle#4367)
1 parent f630f7e commit 76e7b42

1 file changed

Lines changed: 41 additions & 11 deletions

File tree

custom_ops/gpu_ops/append_attn/get_block_shape_and_split_kv_block.cu

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -197,25 +197,55 @@ __global__ void split_q_block(const int *__restrict__ seq_lens_q,
197197
const int *__restrict__ seq_lens_encoder,
198198
int *__restrict__ batch_ids,
199199
int *__restrict__ tile_ids_per_batch,
200-
int *__restrict__ num_blocks_x, const int bsz,
200+
int *__restrict__ num_blocks_x,
201+
const int bsz,
201202
const int num_rows_per_block,
202203
const int group_size) {
203-
if (threadIdx.x == 0) {
204-
int gridx = 0;
205-
int index = 0;
206-
for (uint32_t bid = 0; bid < bsz; bid++) {
204+
// one block one warp
205+
const int lane_id = threadIdx.x % warpSize;
206+
int prev_offset = 0;
207+
208+
// loop on warp tile:[base, base+32)
209+
for (int base = 0; base < bsz; base += warpSize) {
210+
const int bid = base + lane_id;
211+
212+
// calculate loop_times for bid
213+
int loop_times = 0;
214+
if (bid < bsz) {
207215
int seq_len = seq_lens_q[bid];
208216
if (seq_lens_encoder && seq_lens_encoder[bid] > 0) {
209217
seq_len = 0;
210218
}
211-
const int loop_times = div_up(seq_len * group_size, num_rows_per_block);
212-
for (uint32_t tile_id = 0; tile_id < loop_times; tile_id++) {
213-
batch_ids[index] = bid;
214-
tile_ids_per_batch[index++] = tile_id;
219+
loop_times = div_up(seq_len * group_size, num_rows_per_block);
220+
}
221+
222+
// prefix sum for each lane, get the start offset in this tile
223+
// inclusive scan
224+
int x = loop_times;
225+
for (int offset = 1; offset < warpSize; offset <<= 1) {
226+
int y = __shfl_up_sync(0xffffffff, x, offset);
227+
if (lane_id >= offset) x += y;
228+
}
229+
// exclusive prefix sum
230+
int bid_offset = x - loop_times;
231+
int tile_sum = __shfl_sync(0xffffffff, x, warpSize - 1);
232+
233+
// write batch_ids and tile_ids_per_batch
234+
if (bid < bsz && loop_times > 0) {
235+
int write_base = prev_offset + bid_offset;
236+
for (int t = 0; t < loop_times; ++t) {
237+
int pos = write_base + t;
238+
batch_ids[pos] = bid;
239+
tile_ids_per_batch[pos] = t;
215240
}
216-
gridx += loop_times;
217241
}
218-
*num_blocks_x = gridx;
242+
243+
// for next warp tile
244+
prev_offset += tile_sum;
245+
}
246+
247+
if (threadIdx.x == 0) {
248+
*num_blocks_x = prev_offset;
219249
}
220250
}
221251

0 commit comments

Comments
 (0)