Skip to content

Commit bdb23e8

Browse files
authored
openpangu: use fused indexer top_k with -fidx (CPU-only op) (#2111)
Route DSA indexer selection through ggml_indexer_topk when -fidx is set: one op computes the weighted-relu head sum plus causal mask and returns top-k rows without materializing the [n_kv, n_ihead, T] score tensor. Off by default; the unfused chunked/full paths are unchanged. Composes with gathered DSA, deferred attention-chunk masks, and the set_rows mask path. Co-authored-by: Joel Farthing <262452229+joelfarthing@users.noreply.github.com>
1 parent 3a9d373 commit bdb23e8

2 files changed

Lines changed: 31 additions & 1 deletion

File tree

src/graphs/build_openpangu.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,31 @@ ggml_tensor * llm_build_context::build_openpangu_attention(
408408
!dsa_gather_allowed &&
409409
openpangu_att_score_should_chunk(n_kv, hparams.param_sink_number, n_head, n_tokens,
410410
OPENPANGU_ATT_SCORE_CHUNK, OPENPANGU_ATT_FULL_KQ_MAX_MIB);
411-
if (chunk_scores) {
411+
if (lctx.cparams.fused_idx_topk) {
412+
// Fused indexer top-k (CPU-only op): one op computes sum_g w * relu(q.k) + causal
413+
// mask -> top-k without materializing the [n_kv, n_ihead, T] score tensor, so no
414+
// score chunking is needed. CUDA backends do not implement GGML_OP_INDEXER_TOPK;
415+
// the scheduler runs it on CPU and copies the operands across the backend boundary.
416+
// The op reads the mask row-strided, so the raw view suffices.
417+
ggml_tensor * idx_mask = ggml_view_2d(ctx0, KQ_mask, n_kv, n_tokens,
418+
KQ_mask->nb[1], 0);
419+
sel_idx = ggml_indexer_topk(ctx0, k_all_idx, q_idx, w_idx, idx_mask,
420+
GGML_UNARY_OP_RELU, (int) topk); // [topk, T] i32
421+
if (il == 0) ggml_set_name(sel_idx, "opg0_idx_sel");
422+
dsa_gather_engaged = dsa_gather_allowed;
423+
if (dsa_gather_engaged) {
424+
GGML_ASSERT(n_kv >= topk + (int64_t) pad + n_tokens);
425+
} else if (defer_sel_mask_to_att_chunks) {
426+
sel_mask = nullptr;
427+
} else {
428+
ggml_tensor * base = ggml_new_tensor_3d(ctx0, GGML_TYPE_F32, 1, n_kv, n_tokens);
429+
base = ggml_fill(ctx0, base, -1e30f);
430+
ggml_tensor * zeros = ggml_new_tensor_3d(ctx0, GGML_TYPE_F32, 1, topk, n_tokens);
431+
zeros = ggml_fill(ctx0, zeros, 0.0f);
432+
sel_mask = ggml_set_rows(ctx0, base, zeros, sel_idx);
433+
sel_mask = ggml_reshape_2d(ctx0, sel_mask, n_kv, n_tokens);
434+
}
435+
} else if (chunk_scores) {
412436
ggml_tensor * sel_mask_parts = nullptr;
413437
for (int64_t c0 = 0; c0 < n_tokens; c0 += OPENPANGU_IDX_SCORE_CHUNK) {
414438
const int64_t tc = std::min<int64_t>(OPENPANGU_IDX_SCORE_CHUNK, n_tokens - c0);

src/llama.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7772,6 +7772,12 @@ struct llama_context * llama_init_from_model(
77727772
LLAMA_LOG_INFO("%s: dsa_top_k = %d\n", __func__, cparams.dsa_top_k);
77737773
}
77747774
}
7775+
if (model->arch == LLM_ARCH_OPENPANGU) {
7776+
LLAMA_LOG_INFO("%s: dsa_idx_topk = %d\n", __func__, cparams.fused_idx_topk);
7777+
if (cparams.dsa_top_k > 0) {
7778+
LLAMA_LOG_INFO("%s: dsa_top_k = %d\n", __func__, cparams.dsa_top_k);
7779+
}
7780+
}
77757781
LLAMA_LOG_INFO("%s: k_cache_hadam = %d\n", __func__, cparams.k_cache_hadamard);
77767782
LLAMA_LOG_INFO("%s: v_cache_hadam = %d\n", __func__, cparams.v_cache_hadamard);
77777783
LLAMA_LOG_INFO("%s: split_mode_graph_scheduling = %d\n", __func__, cparams.split_mode_graph_scheduling);

0 commit comments

Comments
 (0)