opencoti F5 bug-225 — block-align cpy_k/cpy_v dependency-tie views over quantized KV At 256k + q8_0 KV with M2 head split (--headinfer-gpu-heads-frac < 1.0) on Gemma 4 iswa, server boot crashed during common_init_result's graph_reserve with: ggml.c:1301: assert(ne % ggml_blck_size(type) == 0) failed Root cause: the M2 and Phase-4 branches of cpy_k / cpy_v built a graph-topology dependency tie via `ggml_view_1d(ctx, store, 1, 0)` over the K/V cache scatter result. The tie value is never read by computation — it only forces multiple per-stream / per-head writes to be reachable from one ggml_build_forward_expand call. At f16 (block size 1), ne=1 passes ggml_row_size silently. At q8_0 (block size 32), ne=1 fails the assert at graph_reserve before any inference runs. Fix at all 4 callsites (cpy_k M2 branch + Phase-4 multi-stream branch; cpy_v M2 branch + Phase-4 !v_trans multi-stream branch — 12 view sites total): - Replace `ne = 1` with `ggml_blck_size(target->type)` so the view passes the quantized-alignment check. - Wrap each view in `ggml_cast(..., GGML_TYPE_F32)` so the subsequent `ggml_add` survives CUDA bin_bcast's F32/F16-only check (binbcast.cu:376). At f16 KV both wraps are no-ops (blck_size==1, cast on f16-view is byte-identical for ne=1 tie semantics never read). At q8_0 the wraps unblock 256k boot. Verification: - Boot at 4096 / 32768 / 262144 + q8_0 + M2 frac=0.5 on Gemma 4 A4B Q4_K_M: all succeed (no graph_reserve crash). - RULER vt@4096 + vt@32768 + niah_single_1@{4096,32768} ours-c1 scored 100/100 against the post-fix binary on 2026-05-29 — confirms no semantic regression at moderate ctx. Related: bug-222 (n_kv/view stride on iswa tail microbatch); bug-224 (concat-F32 on iswa); bug-226 (256k semantic collapse — different root cause, separate fix). Patch order: applies after 0031-per-stream-split (Phase 4) and 0032-m2-state-io. Cosmocc-only edit; CUDA DSO unchanged. diff --git a/llama.cpp/src/llama-kv-cache.cpp b/llama.cpp/src/llama-kv-cache.cpp --- a/llama.cpp/src/llama-kv-cache.cpp +++ b/llama.cpp/src/llama-kv-cache.cpp @@ -2231,14 +2231,14 @@ ggml_tensor * llama_kv_cache::cpy_k(ggml_context * ctx, ggml_tensor * k_cur, ggm ggml_tensor * store_g = ggml_set_rows(ctx, k_s, cur_g, idxs_s); ggml_tensor * store_c = ggml_set_rows(ctx, kc_s, cur_c, idxs_s); ggml_tensor * pair = ggml_add(ctx, - ggml_view_1d(ctx, store_g, 1, 0), - ggml_view_1d(ctx, store_c, 1, 0)); + ggml_cast(ctx, ggml_view_1d(ctx, store_g, ggml_blck_size(store_g->type), 0), GGML_TYPE_F32), + ggml_cast(ctx, ggml_view_1d(ctx, store_c, ggml_blck_size(store_c->type), 0), GGML_TYPE_F32)); if (!tie) { tie = pair; } else { tie = ggml_add(ctx, - ggml_view_1d(ctx, tie, 1, 0), - ggml_view_1d(ctx, pair, 1, 0)); + ggml_cast(ctx, ggml_view_1d(ctx, tie, ggml_blck_size(tie->type), 0), GGML_TYPE_F32), + ggml_cast(ctx, ggml_view_1d(ctx, pair, ggml_blck_size(pair->type), 0), GGML_TYPE_F32)); } } return tie; @@ -2287,8 +2287,8 @@ ggml_tensor * llama_kv_cache::cpy_k(ggml_context * ctx, ggml_tensor * k_cur, ggm tie = store_s; } else { tie = ggml_add(ctx, - ggml_view_1d(ctx, tie, 1, 0), - ggml_view_1d(ctx, store_s, 1, 0)); + ggml_cast(ctx, ggml_view_1d(ctx, tie, ggml_blck_size(tie->type), 0), GGML_TYPE_F32), + ggml_cast(ctx, ggml_view_1d(ctx, store_s, ggml_blck_size(store_s->type), 0), GGML_TYPE_F32)); } } return tie; @@ -2345,14 +2345,14 @@ ggml_tensor * llama_kv_cache::cpy_v(ggml_context * ctx, ggml_tensor * v_cur, ggm ggml_tensor * store_g = ggml_set_rows(ctx, v_s, cur_g, idxs_s); ggml_tensor * store_c = ggml_set_rows(ctx, vc_s, cur_c, idxs_s); ggml_tensor * pair = ggml_add(ctx, - ggml_view_1d(ctx, store_g, 1, 0), - ggml_view_1d(ctx, store_c, 1, 0)); + ggml_cast(ctx, ggml_view_1d(ctx, store_g, ggml_blck_size(store_g->type), 0), GGML_TYPE_F32), + ggml_cast(ctx, ggml_view_1d(ctx, store_c, ggml_blck_size(store_c->type), 0), GGML_TYPE_F32)); if (!tie) { tie = pair; } else { tie = ggml_add(ctx, - ggml_view_1d(ctx, tie, 1, 0), - ggml_view_1d(ctx, pair, 1, 0)); + ggml_cast(ctx, ggml_view_1d(ctx, tie, ggml_blck_size(tie->type), 0), GGML_TYPE_F32), + ggml_cast(ctx, ggml_view_1d(ctx, pair, ggml_blck_size(pair->type), 0), GGML_TYPE_F32)); } } return tie; @@ -2400,8 +2400,8 @@ ggml_tensor * llama_kv_cache::cpy_v(ggml_context * ctx, ggml_tensor * v_cur, ggm tie = store_s; } else { tie = ggml_add(ctx, - ggml_view_1d(ctx, tie, 1, 0), - ggml_view_1d(ctx, store_s, 1, 0)); + ggml_cast(ctx, ggml_view_1d(ctx, tie, ggml_blck_size(tie->type), 0), GGML_TYPE_F32), + ggml_cast(ctx, ggml_view_1d(ctx, store_s, ggml_blck_size(store_s->type), 0), GGML_TYPE_F32)); } } return tie;