Repository navigation
ggml : support truncate=false for YaRN - #30206
Conversation
|
Generally seems ok, @ggerganov would have to weight in on the implementation. I assume there will be follow ups for at least one backend with test and conversion/loading? |
|
Added CUDA backend support and tests. |
|
|
c79bb16 to
79ece22
Compare
|
One more rebase and we can merge. |
|
Same as CUDA, Vulkan already supports this, so disabling it is not needed, it can just be forwarded. E.g. with this diff: diffdiff --git a/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ggml/src/ggml-vulkan/ggml-vulkan.cpp
index cb891e354..75f8dfb69 100644
--- a/ggml/src/ggml-vulkan/ggml-vulkan.cpp
+++ b/ggml/src/ggml-vulkan/ggml-vulkan.cpp
@@ -10786,7 +10786,6 @@ static vk_op_rope_push_constants ggml_vk_make_rope_constants(const ggml_tensor *
const int n_dims = ((const int32_t *) dst->op_params)[1];
const int mode = ((const int32_t *) dst->op_params)[2];
const int n_offs = ((const int32_t *) dst->op_params)[15];
- // const int n_ctx = ((const int32_t *) dst->op_params)[3];
const int n_ctx_orig = ((const int32_t *) dst->op_params)[4];
const float freq_base = ((const float *) dst->op_params)[5];
const float freq_scale = ((const float *) dst->op_params)[6];
@@ -10802,7 +10801,7 @@ static vk_op_rope_push_constants ggml_vk_make_rope_constants(const ggml_tensor *
const bool is_imrope = mode == GGML_ROPE_TYPE_IMROPE;
float corr_dims[2];
- ggml_rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow, true, corr_dims);
+ ggml_rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow, ggml_rope_get_truncate(dst), corr_dims);
const float theta_scale = powf(freq_base, -2.0f/n_dims);
@@ -11286,20 +11285,6 @@ void ggml_vk_rope(ggml_backend_vk_context * ctx, vk_context& subctx, const ggml_
const ggml_tensor * src1 = dst->src[1];
const ggml_tensor * src2 = dst->src[2];
const ggml_tensor * src3 = nullptr;
- const int n_dims = ((int32_t *) dst->op_params)[1];
- const int mode = ((int32_t *) dst->op_params)[2];
- // const int n_ctx = ((int32_t *) dst->op_params)[3];
- const int n_ctx_orig = ((int32_t *) dst->op_params)[4];
- const float freq_base = ((float *) dst->op_params)[5];
- const float beta_fast = ((float *) dst->op_params)[9];
- const float beta_slow = ((float *) dst->op_params)[10];
- int sections[4] {};
- if (mode & GGML_ROPE_TYPE_MROPE) {
- memcpy(sections, (int32_t *) dst->op_params + 11, sizeof(int)*4);
- }
-
- float corr_dims[2];
- ggml_rope_yarn_corr_dims(n_dims, n_ctx_orig, freq_base, beta_fast, beta_slow, true, corr_dims);
uint32_t set_rows_stride = 0;
// Fused rope + view + set_rows passes the set_rows destination stride in set_rows_stride
@@ -14074,7 +14059,7 @@ bool ggml_vk_can_fuse_rope_set_rows(ggml_backend_vk_context * ctx, const struct
return false;
}
- return ggml_rope_get_truncate(rope);
+ return true;
}
bool ggml_vk_can_fuse_rms_norm_set_rows(ggml_backend_vk_context * ctx, const struct ggml_cgraph * cgraph,
@@ -14212,7 +14197,7 @@ bool ggml_vk_can_fuse_rms_norm_mul_rope(ggml_backend_vk_context * ctx, const str
return false;
}
- return ggml_rope_get_truncate(rope);
+ return true;
}
uint32_t ggml_vk_fuse_multi_add(ggml_backend_vk_context * ctx, const struct ggml_cgraph * cgraph, int node_idx) {
@@ -15762,12 +15747,8 @@ static bool ggml_backend_vk_device_supports_op(ggml_backend_dev_t dev, const ggm
case GGML_OP_REPEAT_BACK:
return op->type == GGML_TYPE_F32 && op->src[0]->type == GGML_TYPE_F32;
case GGML_OP_ROPE:
- if (!ggml_rope_get_truncate(op)) {
- return false;
- }
return ggml_is_contiguous_rows(op) && ggml_is_contiguous_rows(op->src[0]);
case GGML_OP_ROPE_BACK:
- return ggml_rope_get_truncate(op);
case GGML_OP_NONE:
case GGML_OP_RESHAPE:
case GGML_OP_VIEW:If you prefer I can also just do this as a follow-up PR. |
@0cc4m Thanks for the suggestion! I've already opened a draft follow-up PR (#30802) to support truncation config on other backends I have access to, including Vulkan. Supporting the remaining backends (metal, hexagon, etc.) should be fairly straightforward as well, but I've left them out for now since I can't verify the changes myself. I can also incorporate those changes into this PR if that's preferred :) |
|
No, that's fine as well, I hadn't seen that PR. |
YaRN calculates correction intervals to switch frequency interpolation methods, but the setting to not round the boundaries of these intervals to integers (`truncate=false`) was not supported. Models that use `truncate=false` include gpt-oss and some PLaMo-3 models; to support them correctly, the GGML operations and CPU backend are modified to handle calculations without rounding. The default behavior is `truncate=true`, and existing calls not explicitly configured will maintain their previous behavior.
79ece22 to
d372c1e
Compare
* ggml : support `truncate=false` for YaRN YaRN calculates correction intervals to switch frequency interpolation methods, but the setting to not round the boundaries of these intervals to integers (`truncate=false`) was not supported. Models that use `truncate=false` include gpt-oss and some PLaMo-3 models; to support them correctly, the GGML operations and CPU backend are modified to handle calculations without rounding. The default behavior is `truncate=true`, and existing calls not explicitly configured will maintain their previous behavior. * support CUDA backend * add tests * move RoPE helpers to internal header * format (cherry picked from commit 1fa7f1c)
…W (Goal A) and an attendance POOL (Goal B), both opt-in Re-based onto a691b23 (r236) The rung collided with everything the streamed KV binds to: the memory instances (ggml-org#31141 no_alloc, ggml-org#31200 n_pad removed, ggml-org#31142), the KV cache internals (ggml-org#30541 on-device state copy sizes, ggml-org#31073 the rotation constants moved into a per-cache buffer, ggml-org#31570 kv_rows), the Meta (tensor-split) device (ggml-org#31447) and the qwen4exp rewrite. 8 files conflicted / 12 hunks (9 expected: src/models/qwen4exp.cpp auto-merged, the D3 residue did not conflict this time and its 59/-7 lines all landed). A distinctive-added-line check over the 25 auto-merged files found no dropped delivery code. D13 (memory instances) -- re-derived, not carried: * llama_memory_params keeps upstream's `no_alloc` and adds the delivery's `kv_pool` (llama-context.cpp's designated init passes both); the three `hparams.no_alloc` reads the block added follow ggml-org#31141 out of the hparams and become the ctor's `no_alloc`. * memory_breakdown() is re-derived over `ctxs_bufs.bufs` + `ctxs_bufs.no_alloc` instead of the old per-cache loop: upstream moved the no_alloc/plain accounting into llama_memory_bufs and added attn_rot_bufs (ggml-org#31073), whose bytes are summed on top. The pool's mirror-to-host-bucket and the window's resident/spill split accounting are unchanged. * the MTP draft window's llama_kv_cache construction drops the `n_pad` argument (ggml-org#31200), and the pool's cell count is rounded to whole PAGES (it used to round to the cache's n_pad, which no longer exists as a parameter -- n_ctx is unpadded now). * create_memory() takes upstream's `params` name back (the delivery-side `params_l` rename is gone; the body was upstream's everywhere but two lines). * src/llama-ext.h keeps upstream's classifier-free-guidance declaration, src/llama-memory.h keeps upstream's llama_memory_bufs struct, ggml-backend-meta.cpp keeps upstream's view-slab helpers next to ggml_backend_meta_kv_region_grow. src/llama-context.cpp takes upstream's readback-sync hunk -- the delivery side of it was stale F1 code (layer_inp_host_fill, deleted at R13). D12 (quantized-KV state, rotation) -- the provider still binds at the BUFFER TYPE and no kernel addresses cells differently: the rotation constants are a per-cache, per-layer buffer (attn_rot_bufs), not cell-indexed, so they are outside the region; state_write/state_read keep going through the region buffer's own copy. Proven by the gates below, whose spilling arms really spill (16 mapping flips, 64 MiB host-backed) and whose state arm (win2mtp) takes the region path. The r193 draft reserve is preserved (r236 absorbed the fit plumbing): common/common.cpp takes upstream's common_fit_apply() call, and block 15's mtp_shared branch is folded into common_draft_reserve_derive() -- the one function both `--fit` and the MoE preflight call. Measured, 35B-A3B Q8_0 1 GPU -ncmoe 48 -c 262144 with --spec-type draft-mtp: window auto derives "draft CONTEXT 1102 MiB (kv 142 + compute 768 + slack 192)" -> arena 20527.5 MiB / 62.9 % residency; window 0 keeps the flat 3584 MiB -> arena 17977.5 MiB / 55.1 %. +2550 MiB of arena, +7.8 points. Fixed on the way: * src/llama-memory-hybrid.cpp passed its attention cache to the extended ctor positionally, so after upstream inserted `is_indexer` before `v_enabled` the delivery's `kv_pool` landed in `v_enabled`: the cache allocated NO V tensor and llama_kv_cache::cpy_v null-dereferenced on the first graph build (every hybrid/GDN model segfaulted at load; the dense 4B arm died before generating). `is_indexer` is now named explicitly. The other ctor call sites were audited: hybrid-idx already named it, model.cpp stops at `share`, and dsa/dsa-iswa/msa/dsv4 are upstream's and correct. * ggml/src/ggml-cuda/indexer-score.cu is NOT an R16 drift but a latent R12 defect (b1b0fa807): the fused GGML_OP_INDEXER_SCORE node called ggml_rope_get_truncate(dst), and upstream's ggml-org#30206 added an assert that the argument is a ROPE/ROPE_BACK node. Every qwen4exp sparse QSA decode run has aborted on this tree since R12 (no R12-R15 gate reaches that arm -- the coherence arms and both qwen4exp gates run the dense arm; block 15's residency gate reaches it because its `pref` arm sets LLAMA_QSA_DENSE_DECODE_UNTIL=0, and aborted after 63 generated tokens at ggml.c:4648). Both call sites now pass /*truncate*/ true, which is the graph's own rope node default (ggml_rope_impl initialises no_trunc 0 and nothing calls ggml_rope_set_truncate on the indexer-key node) and the pre-ggml-org#30206 5-argument helper's unconditional floor/ceil, i.e. pre-re-base numerics. Coherence (same session, same commands, this build family): dense 4B 1de99b7e6ee6, 30B-A3B 4b4d56191368, 35B-A3B 3 GPU tensor rccl 86b7f9b5aa80, Flash-Next GSQ 7a8734a9f1a6 -- all four unchanged from R13. Gates: * gate-kv-residency.sh PASS. Window: wref == wres == wspill be904e86f248, wres 0 flips / 0 MiB host-backed, wspill 16 flips / 64 MiB, every slide on the map grid. Pool: pref == pres == pfloor f260d1824ab3, bad 0, 8192 pages (408.0 MiB) on pres vs 4104 (204.4 MiB) on pfloor, 252 resolves both, claims 137.7 -> 217.1 per resolve, hits 91.02 -> 89.63 %. Multi-device (-sm layer 0,1): pmref == pmres == pmfloor f260d1824ab3, one mirror/pool/counter block per device, 2 counter blocks summed, 117.8 -> 268.1 claims per resolve. * gate-kv-window-split.sh PASS, 38/38: one region per device on a 3-device 4B, a 27B at -c 524288 sliding on BOTH devices (32 flips each), -c 1048576 windowed, 1-device unchanged, -nkvo still declines, all five fit arms (fixed/auto/ram/ram-drop/off), and win2mtp == ref2mtp with identical acceptance 0.46154 whose batched state save takes the region path. * gate-spec-draft-window.sh PASS: LLAMA_SPEC_DRAFT_WINDOW=1024 gives "1024 cells per sequence, cache 3072 cells ((win + 512) x 2)" and all six requests across both slots are byte-identical to win 0, acceptance identical (0.47222 / 17-36, 1.0 / 23-23). * check-gpu-faults.sh --since the session start: clean.
…W (Goal A) and an attendance POOL (Goal B), both opt-in Re-based onto a691b23 (r236) The rung collided with everything the streamed KV binds to: the memory instances (ggml-org#31141 no_alloc, ggml-org#31200 n_pad removed, ggml-org#31142), the KV cache internals (ggml-org#30541 on-device state copy sizes, ggml-org#31073 the rotation constants moved into a per-cache buffer, ggml-org#31570 kv_rows), the Meta (tensor-split) device (ggml-org#31447) and the qwen4exp rewrite. 8 files conflicted / 12 hunks (9 expected: src/models/qwen4exp.cpp auto-merged, the D3 residue did not conflict this time and its 59/-7 lines all landed). A distinctive-added-line check over the 25 auto-merged files found no dropped delivery code. D13 (memory instances) -- re-derived, not carried: * llama_memory_params keeps upstream's `no_alloc` and adds the delivery's `kv_pool` (llama-context.cpp's designated init passes both); the three `hparams.no_alloc` reads the block added follow ggml-org#31141 out of the hparams and become the ctor's `no_alloc`. * memory_breakdown() is re-derived over `ctxs_bufs.bufs` + `ctxs_bufs.no_alloc` instead of the old per-cache loop: upstream moved the no_alloc/plain accounting into llama_memory_bufs and added attn_rot_bufs (ggml-org#31073), whose bytes are summed on top. The pool's mirror-to-host-bucket and the window's resident/spill split accounting are unchanged. * the MTP draft window's llama_kv_cache construction drops the `n_pad` argument (ggml-org#31200), and the pool's cell count is rounded to whole PAGES (it used to round to the cache's n_pad, which no longer exists as a parameter -- n_ctx is unpadded now). * create_memory() takes upstream's `params` name back (the delivery-side `params_l` rename is gone; the body was upstream's everywhere but two lines). * src/llama-ext.h keeps upstream's classifier-free-guidance declaration, src/llama-memory.h keeps upstream's llama_memory_bufs struct, ggml-backend-meta.cpp keeps upstream's view-slab helpers next to ggml_backend_meta_kv_region_grow. src/llama-context.cpp takes upstream's readback-sync hunk -- the delivery side of it was stale F1 code (layer_inp_host_fill, deleted at R13). D12 (quantized-KV state, rotation) -- the provider still binds at the BUFFER TYPE and no kernel addresses cells differently: the rotation constants are a per-cache, per-layer buffer (attn_rot_bufs), not cell-indexed, so they are outside the region; state_write/state_read keep going through the region buffer's own copy. Proven by the gates below, whose spilling arms really spill (16 mapping flips, 64 MiB host-backed) and whose state arm (win2mtp) takes the region path. The r193 draft reserve is preserved (r236 absorbed the fit plumbing): common/common.cpp takes upstream's common_fit_apply() call, and block 15's mtp_shared branch is folded into common_draft_reserve_derive() -- the one function both `--fit` and the MoE preflight call. Measured, 35B-A3B Q8_0 1 GPU -ncmoe 48 -c 262144 with --spec-type draft-mtp: window auto derives "draft CONTEXT 1102 MiB (kv 142 + compute 768 + slack 192)" -> arena 20527.5 MiB / 62.9 % residency; window 0 keeps the flat 3584 MiB -> arena 17977.5 MiB / 55.1 %. +2550 MiB of arena, +7.8 points. Fixed on the way: * src/llama-memory-hybrid.cpp passed its attention cache to the extended ctor positionally, so after upstream inserted `is_indexer` before `v_enabled` the delivery's `kv_pool` landed in `v_enabled`: the cache allocated NO V tensor and llama_kv_cache::cpy_v null-dereferenced on the first graph build (every hybrid/GDN model segfaulted at load; the dense 4B arm died before generating). `is_indexer` is now named explicitly. The other ctor call sites were audited: hybrid-idx already named it, model.cpp stops at `share`, and dsa/dsa-iswa/msa/dsv4 are upstream's and correct. * ggml/src/ggml-cuda/indexer-score.cu is NOT an R16 drift but a latent R12 defect (b1b0fa807): the fused GGML_OP_INDEXER_SCORE node called ggml_rope_get_truncate(dst), and upstream's ggml-org#30206 added an assert that the argument is a ROPE/ROPE_BACK node. Every qwen4exp sparse QSA decode run has aborted on this tree since R12 (no R12-R15 gate reaches that arm -- the coherence arms and both qwen4exp gates run the dense arm; block 15's residency gate reaches it because its `pref` arm sets LLAMA_QSA_DENSE_DECODE_UNTIL=0, and aborted after 63 generated tokens at ggml.c:4648). Both call sites now pass /*truncate*/ true, which is the graph's own rope node default (ggml_rope_impl initialises no_trunc 0 and nothing calls ggml_rope_set_truncate on the indexer-key node) and the pre-ggml-org#30206 5-argument helper's unconditional floor/ceil, i.e. pre-re-base numerics. Coherence (same session, same commands, this build family): dense 4B 1de99b7e6ee6, 30B-A3B 4b4d56191368, 35B-A3B 3 GPU tensor rccl 86b7f9b5aa80, Flash-Next GSQ 7a8734a9f1a6 -- all four unchanged from R13. Gates: * gate-kv-residency.sh PASS. Window: wref == wres == wspill be904e86f248, wres 0 flips / 0 MiB host-backed, wspill 16 flips / 64 MiB, every slide on the map grid. Pool: pref == pres == pfloor f260d1824ab3, bad 0, 8192 pages (408.0 MiB) on pres vs 4104 (204.4 MiB) on pfloor, 252 resolves both, claims 137.7 -> 217.1 per resolve, hits 91.02 -> 89.63 %. Multi-device (-sm layer 0,1): pmref == pmres == pmfloor f260d1824ab3, one mirror/pool/counter block per device, 2 counter blocks summed, 117.8 -> 268.1 claims per resolve. * gate-kv-window-split.sh PASS, 38/38: one region per device on a 3-device 4B, a 27B at -c 524288 sliding on BOTH devices (32 flips each), -c 1048576 windowed, 1-device unchanged, -nkvo still declines, all five fit arms (fixed/auto/ram/ram-drop/off), and win2mtp == ref2mtp with identical acceptance 0.46154 whose batched state save takes the region path. * gate-spec-draft-window.sh PASS: LLAMA_SPEC_DRAFT_WINDOW=1024 gives "1024 cells per sequence, cache 3072 cells ((win + 512) x 2)" and all six requests across both slots are byte-identical to win 0, acceptance identical (0.47222 / 17-36, 1.0 / 23-23). * check-gpu-faults.sh --since the session start: clean.
…W (Goal A) and an attendance POOL (Goal B), both opt-in Re-based onto a691b23 (r236) The rung collided with everything the streamed KV binds to: the memory instances (ggml-org#31141 no_alloc, ggml-org#31200 n_pad removed, ggml-org#31142), the KV cache internals (ggml-org#30541 on-device state copy sizes, ggml-org#31073 the rotation constants moved into a per-cache buffer, ggml-org#31570 kv_rows), the Meta (tensor-split) device (ggml-org#31447) and the qwen4exp rewrite. 8 files conflicted / 12 hunks (9 expected: src/models/qwen4exp.cpp auto-merged, the D3 residue did not conflict this time and its 59/-7 lines all landed). A distinctive-added-line check over the 25 auto-merged files found no dropped delivery code. D13 (memory instances) -- re-derived, not carried: * llama_memory_params keeps upstream's `no_alloc` and adds the delivery's `kv_pool` (llama-context.cpp's designated init passes both); the three `hparams.no_alloc` reads the block added follow ggml-org#31141 out of the hparams and become the ctor's `no_alloc`. * memory_breakdown() is re-derived over `ctxs_bufs.bufs` + `ctxs_bufs.no_alloc` instead of the old per-cache loop: upstream moved the no_alloc/plain accounting into llama_memory_bufs and added attn_rot_bufs (ggml-org#31073), whose bytes are summed on top. The pool's mirror-to-host-bucket and the window's resident/spill split accounting are unchanged. * the MTP draft window's llama_kv_cache construction drops the `n_pad` argument (ggml-org#31200), and the pool's cell count is rounded to whole PAGES (it used to round to the cache's n_pad, which no longer exists as a parameter -- n_ctx is unpadded now). * create_memory() takes upstream's `params` name back (the delivery-side `params_l` rename is gone; the body was upstream's everywhere but two lines). * src/llama-ext.h keeps upstream's classifier-free-guidance declaration, src/llama-memory.h keeps upstream's llama_memory_bufs struct, ggml-backend-meta.cpp keeps upstream's view-slab helpers next to ggml_backend_meta_kv_region_grow. src/llama-context.cpp takes upstream's readback-sync hunk -- the delivery side of it was stale F1 code (layer_inp_host_fill, deleted at R13). D12 (quantized-KV state, rotation) -- the provider still binds at the BUFFER TYPE and no kernel addresses cells differently: the rotation constants are a per-cache, per-layer buffer (attn_rot_bufs), not cell-indexed, so they are outside the region; state_write/state_read keep going through the region buffer's own copy. Proven by the gates below, whose spilling arms really spill (16 mapping flips, 64 MiB host-backed) and whose state arm (win2mtp) takes the region path. The r193 draft reserve is preserved (r236 absorbed the fit plumbing): common/common.cpp takes upstream's common_fit_apply() call, and block 15's mtp_shared branch is folded into common_draft_reserve_derive() -- the one function both `--fit` and the MoE preflight call. Measured, 35B-A3B Q8_0 1 GPU -ncmoe 48 -c 262144 with --spec-type draft-mtp: window auto derives "draft CONTEXT 1102 MiB (kv 142 + compute 768 + slack 192)" -> arena 20527.5 MiB / 62.9 % residency; window 0 keeps the flat 3584 MiB -> arena 17977.5 MiB / 55.1 %. +2550 MiB of arena, +7.8 points. Fixed on the way: * src/llama-memory-hybrid.cpp passed its attention cache to the extended ctor positionally, so after upstream inserted `is_indexer` before `v_enabled` the delivery's `kv_pool` landed in `v_enabled`: the cache allocated NO V tensor and llama_kv_cache::cpy_v null-dereferenced on the first graph build (every hybrid/GDN model segfaulted at load; the dense 4B arm died before generating). `is_indexer` is now named explicitly. The other ctor call sites were audited: hybrid-idx already named it, model.cpp stops at `share`, and dsa/dsa-iswa/msa/dsv4 are upstream's and correct. * ggml/src/ggml-cuda/indexer-score.cu is NOT an R16 drift but a latent R12 defect (b1b0fa807): the fused GGML_OP_INDEXER_SCORE node called ggml_rope_get_truncate(dst), and upstream's ggml-org#30206 added an assert that the argument is a ROPE/ROPE_BACK node. Every qwen4exp sparse QSA decode run has aborted on this tree since R12 (no R12-R15 gate reaches that arm -- the coherence arms and both qwen4exp gates run the dense arm; block 15's residency gate reaches it because its `pref` arm sets LLAMA_QSA_DENSE_DECODE_UNTIL=0, and aborted after 63 generated tokens at ggml.c:4648). Both call sites now pass /*truncate*/ true, which is the graph's own rope node default (ggml_rope_impl initialises no_trunc 0 and nothing calls ggml_rope_set_truncate on the indexer-key node) and the pre-ggml-org#30206 5-argument helper's unconditional floor/ceil, i.e. pre-re-base numerics. Coherence (same session, same commands, this build family): dense 4B 1de99b7e6ee6, 30B-A3B 4b4d56191368, 35B-A3B 3 GPU tensor rccl 86b7f9b5aa80, Flash-Next GSQ 7a8734a9f1a6 -- all four unchanged from R13. Gates: * gate-kv-residency.sh PASS. Window: wref == wres == wspill be904e86f248, wres 0 flips / 0 MiB host-backed, wspill 16 flips / 64 MiB, every slide on the map grid. Pool: pref == pres == pfloor f260d1824ab3, bad 0, 8192 pages (408.0 MiB) on pres vs 4104 (204.4 MiB) on pfloor, 252 resolves both, claims 137.7 -> 217.1 per resolve, hits 91.02 -> 89.63 %. Multi-device (-sm layer 0,1): pmref == pmres == pmfloor f260d1824ab3, one mirror/pool/counter block per device, 2 counter blocks summed, 117.8 -> 268.1 claims per resolve. * gate-kv-window-split.sh PASS, 38/38: one region per device on a 3-device 4B, a 27B at -c 524288 sliding on BOTH devices (32 flips each), -c 1048576 windowed, 1-device unchanged, -nkvo still declines, all five fit arms (fixed/auto/ram/ram-drop/off), and win2mtp == ref2mtp with identical acceptance 0.46154 whose batched state save takes the region path. * gate-spec-draft-window.sh PASS: LLAMA_SPEC_DRAFT_WINDOW=1024 gives "1024 cells per sequence, cache 3072 cells ((win + 512) x 2)" and all six requests across both slots are byte-identical to win 0, acceptance identical (0.47222 / 17-36, 1.0 / 23-23). * check-gpu-faults.sh --since the session start: clean.
…W (Goal A) and an attendance POOL (Goal B), both opt-in Re-based onto a691b23 (r236) The rung collided with everything the streamed KV binds to: the memory instances (ggml-org#31141 no_alloc, ggml-org#31200 n_pad removed, ggml-org#31142), the KV cache internals (ggml-org#30541 on-device state copy sizes, ggml-org#31073 the rotation constants moved into a per-cache buffer, ggml-org#31570 kv_rows), the Meta (tensor-split) device (ggml-org#31447) and the qwen4exp rewrite. 8 files conflicted / 12 hunks (9 expected: src/models/qwen4exp.cpp auto-merged, the D3 residue did not conflict this time and its 59/-7 lines all landed). A distinctive-added-line check over the 25 auto-merged files found no dropped delivery code. D13 (memory instances) -- re-derived, not carried: * llama_memory_params keeps upstream's `no_alloc` and adds the delivery's `kv_pool` (llama-context.cpp's designated init passes both); the three `hparams.no_alloc` reads the block added follow ggml-org#31141 out of the hparams and become the ctor's `no_alloc`. * memory_breakdown() is re-derived over `ctxs_bufs.bufs` + `ctxs_bufs.no_alloc` instead of the old per-cache loop: upstream moved the no_alloc/plain accounting into llama_memory_bufs and added attn_rot_bufs (ggml-org#31073), whose bytes are summed on top. The pool's mirror-to-host-bucket and the window's resident/spill split accounting are unchanged. * the MTP draft window's llama_kv_cache construction drops the `n_pad` argument (ggml-org#31200), and the pool's cell count is rounded to whole PAGES (it used to round to the cache's n_pad, which no longer exists as a parameter -- n_ctx is unpadded now). * create_memory() takes upstream's `params` name back (the delivery-side `params_l` rename is gone; the body was upstream's everywhere but two lines). * src/llama-ext.h keeps upstream's classifier-free-guidance declaration, src/llama-memory.h keeps upstream's llama_memory_bufs struct, ggml-backend-meta.cpp keeps upstream's view-slab helpers next to ggml_backend_meta_kv_region_grow. src/llama-context.cpp takes upstream's readback-sync hunk -- the delivery side of it was stale F1 code (layer_inp_host_fill, deleted at R13). D12 (quantized-KV state, rotation) -- the provider still binds at the BUFFER TYPE and no kernel addresses cells differently: the rotation constants are a per-cache, per-layer buffer (attn_rot_bufs), not cell-indexed, so they are outside the region; state_write/state_read keep going through the region buffer's own copy. Proven by the gates below, whose spilling arms really spill (16 mapping flips, 64 MiB host-backed) and whose state arm (win2mtp) takes the region path. The r193 draft reserve is preserved (r236 absorbed the fit plumbing): common/common.cpp takes upstream's common_fit_apply() call, and block 15's mtp_shared branch is folded into common_draft_reserve_derive() -- the one function both `--fit` and the MoE preflight call. Measured, 35B-A3B Q8_0 1 GPU -ncmoe 48 -c 262144 with --spec-type draft-mtp: window auto derives "draft CONTEXT 1102 MiB (kv 142 + compute 768 + slack 192)" -> arena 20527.5 MiB / 62.9 % residency; window 0 keeps the flat 3584 MiB -> arena 17977.5 MiB / 55.1 %. +2550 MiB of arena, +7.8 points. Fixed on the way: * src/llama-memory-hybrid.cpp passed its attention cache to the extended ctor positionally, so after upstream inserted `is_indexer` before `v_enabled` the delivery's `kv_pool` landed in `v_enabled`: the cache allocated NO V tensor and llama_kv_cache::cpy_v null-dereferenced on the first graph build (every hybrid/GDN model segfaulted at load; the dense 4B arm died before generating). `is_indexer` is now named explicitly. The other ctor call sites were audited: hybrid-idx already named it, model.cpp stops at `share`, and dsa/dsa-iswa/msa/dsv4 are upstream's and correct. * ggml/src/ggml-cuda/indexer-score.cu is NOT an R16 drift but a latent R12 defect (b1b0fa807): the fused GGML_OP_INDEXER_SCORE node called ggml_rope_get_truncate(dst), and upstream's ggml-org#30206 added an assert that the argument is a ROPE/ROPE_BACK node. Every qwen4exp sparse QSA decode run has aborted on this tree since R12 (no R12-R15 gate reaches that arm -- the coherence arms and both qwen4exp gates run the dense arm; block 15's residency gate reaches it because its `pref` arm sets LLAMA_QSA_DENSE_DECODE_UNTIL=0, and aborted after 63 generated tokens at ggml.c:4648). Both call sites now pass /*truncate*/ true, which is the graph's own rope node default (ggml_rope_impl initialises no_trunc 0 and nothing calls ggml_rope_set_truncate on the indexer-key node) and the pre-ggml-org#30206 5-argument helper's unconditional floor/ceil, i.e. pre-re-base numerics. Coherence (same session, same commands, this build family): dense 4B 1de99b7e6ee6, 30B-A3B 4b4d56191368, 35B-A3B 3 GPU tensor rccl 86b7f9b5aa80, Flash-Next GSQ 7a8734a9f1a6 -- all four unchanged from R13. Gates: * gate-kv-residency.sh PASS. Window: wref == wres == wspill be904e86f248, wres 0 flips / 0 MiB host-backed, wspill 16 flips / 64 MiB, every slide on the map grid. Pool: pref == pres == pfloor f260d1824ab3, bad 0, 8192 pages (408.0 MiB) on pres vs 4104 (204.4 MiB) on pfloor, 252 resolves both, claims 137.7 -> 217.1 per resolve, hits 91.02 -> 89.63 %. Multi-device (-sm layer 0,1): pmref == pmres == pmfloor f260d1824ab3, one mirror/pool/counter block per device, 2 counter blocks summed, 117.8 -> 268.1 claims per resolve. * gate-kv-window-split.sh PASS, 38/38: one region per device on a 3-device 4B, a 27B at -c 524288 sliding on BOTH devices (32 flips each), -c 1048576 windowed, 1-device unchanged, -nkvo still declines, all five fit arms (fixed/auto/ram/ram-drop/off), and win2mtp == ref2mtp with identical acceptance 0.46154 whose batched state save takes the region path. * gate-spec-draft-window.sh PASS: LLAMA_SPEC_DRAFT_WINDOW=1024 gives "1024 cells per sequence, cache 3072 cells ((win + 512) x 2)" and all six requests across both slots are byte-identical to win 0, acceptance identical (0.47222 / 17-36, 1.0 / 23-23). * check-gpu-faults.sh --since the session start: clean.
…W (Goal A) and an attendance POOL (Goal B), both opt-in Re-based onto a691b23 (r236) The rung collided with everything the streamed KV binds to: the memory instances (ggml-org#31141 no_alloc, ggml-org#31200 n_pad removed, ggml-org#31142), the KV cache internals (ggml-org#30541 on-device state copy sizes, ggml-org#31073 the rotation constants moved into a per-cache buffer, ggml-org#31570 kv_rows), the Meta (tensor-split) device (ggml-org#31447) and the qwen4exp rewrite. 8 files conflicted / 12 hunks (9 expected: src/models/qwen4exp.cpp auto-merged, the D3 residue did not conflict this time and its 59/-7 lines all landed). A distinctive-added-line check over the 25 auto-merged files found no dropped delivery code. D13 (memory instances) -- re-derived, not carried: * llama_memory_params keeps upstream's `no_alloc` and adds the delivery's `kv_pool` (llama-context.cpp's designated init passes both); the three `hparams.no_alloc` reads the block added follow ggml-org#31141 out of the hparams and become the ctor's `no_alloc`. * memory_breakdown() is re-derived over `ctxs_bufs.bufs` + `ctxs_bufs.no_alloc` instead of the old per-cache loop: upstream moved the no_alloc/plain accounting into llama_memory_bufs and added attn_rot_bufs (ggml-org#31073), whose bytes are summed on top. The pool's mirror-to-host-bucket and the window's resident/spill split accounting are unchanged. * the MTP draft window's llama_kv_cache construction drops the `n_pad` argument (ggml-org#31200), and the pool's cell count is rounded to whole PAGES (it used to round to the cache's n_pad, which no longer exists as a parameter -- n_ctx is unpadded now). * create_memory() takes upstream's `params` name back (the delivery-side `params_l` rename is gone; the body was upstream's everywhere but two lines). * src/llama-ext.h keeps upstream's classifier-free-guidance declaration, src/llama-memory.h keeps upstream's llama_memory_bufs struct, ggml-backend-meta.cpp keeps upstream's view-slab helpers next to ggml_backend_meta_kv_region_grow. src/llama-context.cpp takes upstream's readback-sync hunk -- the delivery side of it was stale F1 code (layer_inp_host_fill, deleted at R13). D12 (quantized-KV state, rotation) -- the provider still binds at the BUFFER TYPE and no kernel addresses cells differently: the rotation constants are a per-cache, per-layer buffer (attn_rot_bufs), not cell-indexed, so they are outside the region; state_write/state_read keep going through the region buffer's own copy. Proven by the gates below, whose spilling arms really spill (16 mapping flips, 64 MiB host-backed) and whose state arm (win2mtp) takes the region path. The r193 draft reserve is preserved (r236 absorbed the fit plumbing): common/common.cpp takes upstream's common_fit_apply() call, and block 15's mtp_shared branch is folded into common_draft_reserve_derive() -- the one function both `--fit` and the MoE preflight call. Measured, 35B-A3B Q8_0 1 GPU -ncmoe 48 -c 262144 with --spec-type draft-mtp: window auto derives "draft CONTEXT 1102 MiB (kv 142 + compute 768 + slack 192)" -> arena 20527.5 MiB / 62.9 % residency; window 0 keeps the flat 3584 MiB -> arena 17977.5 MiB / 55.1 %. +2550 MiB of arena, +7.8 points. Fixed on the way: * src/llama-memory-hybrid.cpp passed its attention cache to the extended ctor positionally, so after upstream inserted `is_indexer` before `v_enabled` the delivery's `kv_pool` landed in `v_enabled`: the cache allocated NO V tensor and llama_kv_cache::cpy_v null-dereferenced on the first graph build (every hybrid/GDN model segfaulted at load; the dense 4B arm died before generating). `is_indexer` is now named explicitly. The other ctor call sites were audited: hybrid-idx already named it, model.cpp stops at `share`, and dsa/dsa-iswa/msa/dsv4 are upstream's and correct. * ggml/src/ggml-cuda/indexer-score.cu is NOT an R16 drift but a latent R12 defect (b1b0fa807): the fused GGML_OP_INDEXER_SCORE node called ggml_rope_get_truncate(dst), and upstream's ggml-org#30206 added an assert that the argument is a ROPE/ROPE_BACK node. Every qwen4exp sparse QSA decode run has aborted on this tree since R12 (no R12-R15 gate reaches that arm -- the coherence arms and both qwen4exp gates run the dense arm; block 15's residency gate reaches it because its `pref` arm sets LLAMA_QSA_DENSE_DECODE_UNTIL=0, and aborted after 63 generated tokens at ggml.c:4648). Both call sites now pass /*truncate*/ true, which is the graph's own rope node default (ggml_rope_impl initialises no_trunc 0 and nothing calls ggml_rope_set_truncate on the indexer-key node) and the pre-ggml-org#30206 5-argument helper's unconditional floor/ceil, i.e. pre-re-base numerics. Coherence (same session, same commands, this build family): dense 4B 1de99b7e6ee6, 30B-A3B 4b4d56191368, 35B-A3B 3 GPU tensor rccl 86b7f9b5aa80, Flash-Next GSQ 7a8734a9f1a6 -- all four unchanged from R13. Gates: * gate-kv-residency.sh PASS. Window: wref == wres == wspill be904e86f248, wres 0 flips / 0 MiB host-backed, wspill 16 flips / 64 MiB, every slide on the map grid. Pool: pref == pres == pfloor f260d1824ab3, bad 0, 8192 pages (408.0 MiB) on pres vs 4104 (204.4 MiB) on pfloor, 252 resolves both, claims 137.7 -> 217.1 per resolve, hits 91.02 -> 89.63 %. Multi-device (-sm layer 0,1): pmref == pmres == pmfloor f260d1824ab3, one mirror/pool/counter block per device, 2 counter blocks summed, 117.8 -> 268.1 claims per resolve. * gate-kv-window-split.sh PASS, 38/38: one region per device on a 3-device 4B, a 27B at -c 524288 sliding on BOTH devices (32 flips each), -c 1048576 windowed, 1-device unchanged, -nkvo still declines, all five fit arms (fixed/auto/ram/ram-drop/off), and win2mtp == ref2mtp with identical acceptance 0.46154 whose batched state save takes the region path. * gate-spec-draft-window.sh PASS: LLAMA_SPEC_DRAFT_WINDOW=1024 gives "1024 cells per sequence, cache 3072 cells ((win + 512) x 2)" and all six requests across both slots are byte-identical to win 0, acceptance identical (0.47222 / 17-36, 1.0 / 23-23). * check-gpu-faults.sh --since the session start: clean.
…W (Goal A) and an attendance POOL (Goal B), both opt-in Re-based onto a691b23 (r236) The rung collided with everything the streamed KV binds to: the memory instances (ggml-org#31141 no_alloc, ggml-org#31200 n_pad removed, ggml-org#31142), the KV cache internals (ggml-org#30541 on-device state copy sizes, ggml-org#31073 the rotation constants moved into a per-cache buffer, ggml-org#31570 kv_rows), the Meta (tensor-split) device (ggml-org#31447) and the qwen4exp rewrite. 8 files conflicted / 12 hunks (9 expected: src/models/qwen4exp.cpp auto-merged, the D3 residue did not conflict this time and its 59/-7 lines all landed). A distinctive-added-line check over the 25 auto-merged files found no dropped delivery code. D13 (memory instances) -- re-derived, not carried: * llama_memory_params keeps upstream's `no_alloc` and adds the delivery's `kv_pool` (llama-context.cpp's designated init passes both); the three `hparams.no_alloc` reads the block added follow ggml-org#31141 out of the hparams and become the ctor's `no_alloc`. * memory_breakdown() is re-derived over `ctxs_bufs.bufs` + `ctxs_bufs.no_alloc` instead of the old per-cache loop: upstream moved the no_alloc/plain accounting into llama_memory_bufs and added attn_rot_bufs (ggml-org#31073), whose bytes are summed on top. The pool's mirror-to-host-bucket and the window's resident/spill split accounting are unchanged. * the MTP draft window's llama_kv_cache construction drops the `n_pad` argument (ggml-org#31200), and the pool's cell count is rounded to whole PAGES (it used to round to the cache's n_pad, which no longer exists as a parameter -- n_ctx is unpadded now). * create_memory() takes upstream's `params` name back (the delivery-side `params_l` rename is gone; the body was upstream's everywhere but two lines). * src/llama-ext.h keeps upstream's classifier-free-guidance declaration, src/llama-memory.h keeps upstream's llama_memory_bufs struct, ggml-backend-meta.cpp keeps upstream's view-slab helpers next to ggml_backend_meta_kv_region_grow. src/llama-context.cpp takes upstream's readback-sync hunk -- the delivery side of it was stale F1 code (layer_inp_host_fill, deleted at R13). D12 (quantized-KV state, rotation) -- the provider still binds at the BUFFER TYPE and no kernel addresses cells differently: the rotation constants are a per-cache, per-layer buffer (attn_rot_bufs), not cell-indexed, so they are outside the region; state_write/state_read keep going through the region buffer's own copy. Proven by the gates below, whose spilling arms really spill (16 mapping flips, 64 MiB host-backed) and whose state arm (win2mtp) takes the region path. The r193 draft reserve is preserved (r236 absorbed the fit plumbing): common/common.cpp takes upstream's common_fit_apply() call, and block 15's mtp_shared branch is folded into common_draft_reserve_derive() -- the one function both `--fit` and the MoE preflight call. Measured, 35B-A3B Q8_0 1 GPU -ncmoe 48 -c 262144 with --spec-type draft-mtp: window auto derives "draft CONTEXT 1102 MiB (kv 142 + compute 768 + slack 192)" -> arena 20527.5 MiB / 62.9 % residency; window 0 keeps the flat 3584 MiB -> arena 17977.5 MiB / 55.1 %. +2550 MiB of arena, +7.8 points. Fixed on the way: * src/llama-memory-hybrid.cpp passed its attention cache to the extended ctor positionally, so after upstream inserted `is_indexer` before `v_enabled` the delivery's `kv_pool` landed in `v_enabled`: the cache allocated NO V tensor and llama_kv_cache::cpy_v null-dereferenced on the first graph build (every hybrid/GDN model segfaulted at load; the dense 4B arm died before generating). `is_indexer` is now named explicitly. The other ctor call sites were audited: hybrid-idx already named it, model.cpp stops at `share`, and dsa/dsa-iswa/msa/dsv4 are upstream's and correct. * ggml/src/ggml-cuda/indexer-score.cu is NOT an R16 drift but a latent R12 defect (b1b0fa807): the fused GGML_OP_INDEXER_SCORE node called ggml_rope_get_truncate(dst), and upstream's ggml-org#30206 added an assert that the argument is a ROPE/ROPE_BACK node. Every qwen4exp sparse QSA decode run has aborted on this tree since R12 (no R12-R15 gate reaches that arm -- the coherence arms and both qwen4exp gates run the dense arm; block 15's residency gate reaches it because its `pref` arm sets LLAMA_QSA_DENSE_DECODE_UNTIL=0, and aborted after 63 generated tokens at ggml.c:4648). Both call sites now pass /*truncate*/ true, which is the graph's own rope node default (ggml_rope_impl initialises no_trunc 0 and nothing calls ggml_rope_set_truncate on the indexer-key node) and the pre-ggml-org#30206 5-argument helper's unconditional floor/ceil, i.e. pre-re-base numerics. Coherence (same session, same commands, this build family): dense 4B 1de99b7e6ee6, 30B-A3B 4b4d56191368, 35B-A3B 3 GPU tensor rccl 86b7f9b5aa80, Flash-Next GSQ 7a8734a9f1a6 -- all four unchanged from R13. Gates: * gate-kv-residency.sh PASS. Window: wref == wres == wspill be904e86f248, wres 0 flips / 0 MiB host-backed, wspill 16 flips / 64 MiB, every slide on the map grid. Pool: pref == pres == pfloor f260d1824ab3, bad 0, 8192 pages (408.0 MiB) on pres vs 4104 (204.4 MiB) on pfloor, 252 resolves both, claims 137.7 -> 217.1 per resolve, hits 91.02 -> 89.63 %. Multi-device (-sm layer 0,1): pmref == pmres == pmfloor f260d1824ab3, one mirror/pool/counter block per device, 2 counter blocks summed, 117.8 -> 268.1 claims per resolve. * gate-kv-window-split.sh PASS, 38/38: one region per device on a 3-device 4B, a 27B at -c 524288 sliding on BOTH devices (32 flips each), -c 1048576 windowed, 1-device unchanged, -nkvo still declines, all five fit arms (fixed/auto/ram/ram-drop/off), and win2mtp == ref2mtp with identical acceptance 0.46154 whose batched state save takes the region path. * gate-spec-draft-window.sh PASS: LLAMA_SPEC_DRAFT_WINDOW=1024 gives "1024 cells per sequence, cache 3072 cells ((win + 512) x 2)" and all six requests across both slots are byte-identical to win 0, acceptance identical (0.47222 / 17-36, 1.0 / 23-23). * check-gpu-faults.sh --since the session start: clean.
…W (Goal A) and an attendance POOL (Goal B), both opt-in Re-based onto a691b23 (r236) The rung collided with everything the streamed KV binds to: the memory instances (ggml-org#31141 no_alloc, ggml-org#31200 n_pad removed, ggml-org#31142), the KV cache internals (ggml-org#30541 on-device state copy sizes, ggml-org#31073 the rotation constants moved into a per-cache buffer, ggml-org#31570 kv_rows), the Meta (tensor-split) device (ggml-org#31447) and the qwen4exp rewrite. 8 files conflicted / 12 hunks (9 expected: src/models/qwen4exp.cpp auto-merged, the D3 residue did not conflict this time and its 59/-7 lines all landed). A distinctive-added-line check over the 25 auto-merged files found no dropped delivery code. D13 (memory instances) -- re-derived, not carried: * llama_memory_params keeps upstream's `no_alloc` and adds the delivery's `kv_pool` (llama-context.cpp's designated init passes both); the three `hparams.no_alloc` reads the block added follow ggml-org#31141 out of the hparams and become the ctor's `no_alloc`. * memory_breakdown() is re-derived over `ctxs_bufs.bufs` + `ctxs_bufs.no_alloc` instead of the old per-cache loop: upstream moved the no_alloc/plain accounting into llama_memory_bufs and added attn_rot_bufs (ggml-org#31073), whose bytes are summed on top. The pool's mirror-to-host-bucket and the window's resident/spill split accounting are unchanged. * the MTP draft window's llama_kv_cache construction drops the `n_pad` argument (ggml-org#31200), and the pool's cell count is rounded to whole PAGES (it used to round to the cache's n_pad, which no longer exists as a parameter -- n_ctx is unpadded now). * create_memory() takes upstream's `params` name back (the delivery-side `params_l` rename is gone; the body was upstream's everywhere but two lines). * src/llama-ext.h keeps upstream's classifier-free-guidance declaration, src/llama-memory.h keeps upstream's llama_memory_bufs struct, ggml-backend-meta.cpp keeps upstream's view-slab helpers next to ggml_backend_meta_kv_region_grow. src/llama-context.cpp takes upstream's readback-sync hunk -- the delivery side of it was stale F1 code (layer_inp_host_fill, deleted at R13). D12 (quantized-KV state, rotation) -- the provider still binds at the BUFFER TYPE and no kernel addresses cells differently: the rotation constants are a per-cache, per-layer buffer (attn_rot_bufs), not cell-indexed, so they are outside the region; state_write/state_read keep going through the region buffer's own copy. Proven by the gates below, whose spilling arms really spill (16 mapping flips, 64 MiB host-backed) and whose state arm (win2mtp) takes the region path. The r193 draft reserve is preserved (r236 absorbed the fit plumbing): common/common.cpp takes upstream's common_fit_apply() call, and block 15's mtp_shared branch is folded into common_draft_reserve_derive() -- the one function both `--fit` and the MoE preflight call. Measured, 35B-A3B Q8_0 1 GPU -ncmoe 48 -c 262144 with --spec-type draft-mtp: window auto derives "draft CONTEXT 1102 MiB (kv 142 + compute 768 + slack 192)" -> arena 20527.5 MiB / 62.9 % residency; window 0 keeps the flat 3584 MiB -> arena 17977.5 MiB / 55.1 %. +2550 MiB of arena, +7.8 points. Fixed on the way: * src/llama-memory-hybrid.cpp passed its attention cache to the extended ctor positionally, so after upstream inserted `is_indexer` before `v_enabled` the delivery's `kv_pool` landed in `v_enabled`: the cache allocated NO V tensor and llama_kv_cache::cpy_v null-dereferenced on the first graph build (every hybrid/GDN model segfaulted at load; the dense 4B arm died before generating). `is_indexer` is now named explicitly. The other ctor call sites were audited: hybrid-idx already named it, model.cpp stops at `share`, and dsa/dsa-iswa/msa/dsv4 are upstream's and correct. * ggml/src/ggml-cuda/indexer-score.cu is NOT an R16 drift but a latent R12 defect (b1b0fa807): the fused GGML_OP_INDEXER_SCORE node called ggml_rope_get_truncate(dst), and upstream's ggml-org#30206 added an assert that the argument is a ROPE/ROPE_BACK node. Every qwen4exp sparse QSA decode run has aborted on this tree since R12 (no R12-R15 gate reaches that arm -- the coherence arms and both qwen4exp gates run the dense arm; block 15's residency gate reaches it because its `pref` arm sets LLAMA_QSA_DENSE_DECODE_UNTIL=0, and aborted after 63 generated tokens at ggml.c:4648). Both call sites now pass /*truncate*/ true, which is the graph's own rope node default (ggml_rope_impl initialises no_trunc 0 and nothing calls ggml_rope_set_truncate on the indexer-key node) and the pre-ggml-org#30206 5-argument helper's unconditional floor/ceil, i.e. pre-re-base numerics. Coherence (same session, same commands, this build family): dense 4B 1de99b7e6ee6, 30B-A3B 4b4d56191368, 35B-A3B 3 GPU tensor rccl 86b7f9b5aa80, Flash-Next GSQ 7a8734a9f1a6 -- all four unchanged from R13. Gates: * gate-kv-residency.sh PASS. Window: wref == wres == wspill be904e86f248, wres 0 flips / 0 MiB host-backed, wspill 16 flips / 64 MiB, every slide on the map grid. Pool: pref == pres == pfloor f260d1824ab3, bad 0, 8192 pages (408.0 MiB) on pres vs 4104 (204.4 MiB) on pfloor, 252 resolves both, claims 137.7 -> 217.1 per resolve, hits 91.02 -> 89.63 %. Multi-device (-sm layer 0,1): pmref == pmres == pmfloor f260d1824ab3, one mirror/pool/counter block per device, 2 counter blocks summed, 117.8 -> 268.1 claims per resolve. * gate-kv-window-split.sh PASS, 38/38: one region per device on a 3-device 4B, a 27B at -c 524288 sliding on BOTH devices (32 flips each), -c 1048576 windowed, 1-device unchanged, -nkvo still declines, all five fit arms (fixed/auto/ram/ram-drop/off), and win2mtp == ref2mtp with identical acceptance 0.46154 whose batched state save takes the region path. * gate-spec-draft-window.sh PASS: LLAMA_SPEC_DRAFT_WINDOW=1024 gives "1024 cells per sequence, cache 3072 cells ((win + 512) x 2)" and all six requests across both slots are byte-identical to win 0, acceptance identical (0.47222 / 17-36, 1.0 / 23-23). * check-gpu-faults.sh --since the session start: clean.
…W (Goal A) and an attendance POOL (Goal B), both opt-in Re-based onto a691b23 (r236) The rung collided with everything the streamed KV binds to: the memory instances (ggml-org#31141 no_alloc, ggml-org#31200 n_pad removed, ggml-org#31142), the KV cache internals (ggml-org#30541 on-device state copy sizes, ggml-org#31073 the rotation constants moved into a per-cache buffer, ggml-org#31570 kv_rows), the Meta (tensor-split) device (ggml-org#31447) and the qwen4exp rewrite. 8 files conflicted / 12 hunks (9 expected: src/models/qwen4exp.cpp auto-merged, the D3 residue did not conflict this time and its 59/-7 lines all landed). A distinctive-added-line check over the 25 auto-merged files found no dropped delivery code. D13 (memory instances) -- re-derived, not carried: * llama_memory_params keeps upstream's `no_alloc` and adds the delivery's `kv_pool` (llama-context.cpp's designated init passes both); the three `hparams.no_alloc` reads the block added follow ggml-org#31141 out of the hparams and become the ctor's `no_alloc`. * memory_breakdown() is re-derived over `ctxs_bufs.bufs` + `ctxs_bufs.no_alloc` instead of the old per-cache loop: upstream moved the no_alloc/plain accounting into llama_memory_bufs and added attn_rot_bufs (ggml-org#31073), whose bytes are summed on top. The pool's mirror-to-host-bucket and the window's resident/spill split accounting are unchanged. * the MTP draft window's llama_kv_cache construction drops the `n_pad` argument (ggml-org#31200), and the pool's cell count is rounded to whole PAGES (it used to round to the cache's n_pad, which no longer exists as a parameter -- n_ctx is unpadded now). * create_memory() takes upstream's `params` name back (the delivery-side `params_l` rename is gone; the body was upstream's everywhere but two lines). * src/llama-ext.h keeps upstream's classifier-free-guidance declaration, src/llama-memory.h keeps upstream's llama_memory_bufs struct, ggml-backend-meta.cpp keeps upstream's view-slab helpers next to ggml_backend_meta_kv_region_grow. src/llama-context.cpp takes upstream's readback-sync hunk -- the delivery side of it was stale F1 code (layer_inp_host_fill, deleted at R13). D12 (quantized-KV state, rotation) -- the provider still binds at the BUFFER TYPE and no kernel addresses cells differently: the rotation constants are a per-cache, per-layer buffer (attn_rot_bufs), not cell-indexed, so they are outside the region; state_write/state_read keep going through the region buffer's own copy. Proven by the gates below, whose spilling arms really spill (16 mapping flips, 64 MiB host-backed) and whose state arm (win2mtp) takes the region path. The r193 draft reserve is preserved (r236 absorbed the fit plumbing): common/common.cpp takes upstream's common_fit_apply() call, and block 15's mtp_shared branch is folded into common_draft_reserve_derive() -- the one function both `--fit` and the MoE preflight call. Measured, 35B-A3B Q8_0 1 GPU -ncmoe 48 -c 262144 with --spec-type draft-mtp: window auto derives "draft CONTEXT 1102 MiB (kv 142 + compute 768 + slack 192)" -> arena 20527.5 MiB / 62.9 % residency; window 0 keeps the flat 3584 MiB -> arena 17977.5 MiB / 55.1 %. +2550 MiB of arena, +7.8 points. Fixed on the way: * src/llama-memory-hybrid.cpp passed its attention cache to the extended ctor positionally, so after upstream inserted `is_indexer` before `v_enabled` the delivery's `kv_pool` landed in `v_enabled`: the cache allocated NO V tensor and llama_kv_cache::cpy_v null-dereferenced on the first graph build (every hybrid/GDN model segfaulted at load; the dense 4B arm died before generating). `is_indexer` is now named explicitly. The other ctor call sites were audited: hybrid-idx already named it, model.cpp stops at `share`, and dsa/dsa-iswa/msa/dsv4 are upstream's and correct. * ggml/src/ggml-cuda/indexer-score.cu is NOT an R16 drift but a latent R12 defect (b1b0fa807): the fused GGML_OP_INDEXER_SCORE node called ggml_rope_get_truncate(dst), and upstream's ggml-org#30206 added an assert that the argument is a ROPE/ROPE_BACK node. Every qwen4exp sparse QSA decode run has aborted on this tree since R12 (no R12-R15 gate reaches that arm -- the coherence arms and both qwen4exp gates run the dense arm; block 15's residency gate reaches it because its `pref` arm sets LLAMA_QSA_DENSE_DECODE_UNTIL=0, and aborted after 63 generated tokens at ggml.c:4648). Both call sites now pass /*truncate*/ true, which is the graph's own rope node default (ggml_rope_impl initialises no_trunc 0 and nothing calls ggml_rope_set_truncate on the indexer-key node) and the pre-ggml-org#30206 5-argument helper's unconditional floor/ceil, i.e. pre-re-base numerics. Coherence (same session, same commands, this build family): dense 4B 1de99b7e6ee6, 30B-A3B 4b4d56191368, 35B-A3B 3 GPU tensor rccl 86b7f9b5aa80, Flash-Next GSQ 7a8734a9f1a6 -- all four unchanged from R13. Gates: * gate-kv-residency.sh PASS. Window: wref == wres == wspill be904e86f248, wres 0 flips / 0 MiB host-backed, wspill 16 flips / 64 MiB, every slide on the map grid. Pool: pref == pres == pfloor f260d1824ab3, bad 0, 8192 pages (408.0 MiB) on pres vs 4104 (204.4 MiB) on pfloor, 252 resolves both, claims 137.7 -> 217.1 per resolve, hits 91.02 -> 89.63 %. Multi-device (-sm layer 0,1): pmref == pmres == pmfloor f260d1824ab3, one mirror/pool/counter block per device, 2 counter blocks summed, 117.8 -> 268.1 claims per resolve. * gate-kv-window-split.sh PASS, 38/38: one region per device on a 3-device 4B, a 27B at -c 524288 sliding on BOTH devices (32 flips each), -c 1048576 windowed, 1-device unchanged, -nkvo still declines, all five fit arms (fixed/auto/ram/ram-drop/off), and win2mtp == ref2mtp with identical acceptance 0.46154 whose batched state save takes the region path. * gate-spec-draft-window.sh PASS: LLAMA_SPEC_DRAFT_WINDOW=1024 gives "1024 cells per sequence, cache 3072 cells ((win + 512) x 2)" and all six requests across both slots are byte-identical to win 0, acceptance identical (0.47222 / 17-36, 1.0 / 23-23). * check-gpu-faults.sh --since the session start: clean.
…W (Goal A) and an attendance POOL (Goal B), both opt-in Re-based onto a691b23 (r236) The rung collided with everything the streamed KV binds to: the memory instances (ggml-org#31141 no_alloc, ggml-org#31200 n_pad removed, ggml-org#31142), the KV cache internals (ggml-org#30541 on-device state copy sizes, ggml-org#31073 the rotation constants moved into a per-cache buffer, ggml-org#31570 kv_rows), the Meta (tensor-split) device (ggml-org#31447) and the qwen4exp rewrite. 8 files conflicted / 12 hunks (9 expected: src/models/qwen4exp.cpp auto-merged, the D3 residue did not conflict this time and its 59/-7 lines all landed). A distinctive-added-line check over the 25 auto-merged files found no dropped delivery code. D13 (memory instances) -- re-derived, not carried: * llama_memory_params keeps upstream's `no_alloc` and adds the delivery's `kv_pool` (llama-context.cpp's designated init passes both); the three `hparams.no_alloc` reads the block added follow ggml-org#31141 out of the hparams and become the ctor's `no_alloc`. * memory_breakdown() is re-derived over `ctxs_bufs.bufs` + `ctxs_bufs.no_alloc` instead of the old per-cache loop: upstream moved the no_alloc/plain accounting into llama_memory_bufs and added attn_rot_bufs (ggml-org#31073), whose bytes are summed on top. The pool's mirror-to-host-bucket and the window's resident/spill split accounting are unchanged. * the MTP draft window's llama_kv_cache construction drops the `n_pad` argument (ggml-org#31200), and the pool's cell count is rounded to whole PAGES (it used to round to the cache's n_pad, which no longer exists as a parameter -- n_ctx is unpadded now). * create_memory() takes upstream's `params` name back (the delivery-side `params_l` rename is gone; the body was upstream's everywhere but two lines). * src/llama-ext.h keeps upstream's classifier-free-guidance declaration, src/llama-memory.h keeps upstream's llama_memory_bufs struct, ggml-backend-meta.cpp keeps upstream's view-slab helpers next to ggml_backend_meta_kv_region_grow. src/llama-context.cpp takes upstream's readback-sync hunk -- the delivery side of it was stale F1 code (layer_inp_host_fill, deleted at R13). D12 (quantized-KV state, rotation) -- the provider still binds at the BUFFER TYPE and no kernel addresses cells differently: the rotation constants are a per-cache, per-layer buffer (attn_rot_bufs), not cell-indexed, so they are outside the region; state_write/state_read keep going through the region buffer's own copy. Proven by the gates below, whose spilling arms really spill (16 mapping flips, 64 MiB host-backed) and whose state arm (win2mtp) takes the region path. The r193 draft reserve is preserved (r236 absorbed the fit plumbing): common/common.cpp takes upstream's common_fit_apply() call, and block 15's mtp_shared branch is folded into common_draft_reserve_derive() -- the one function both `--fit` and the MoE preflight call. Measured, 35B-A3B Q8_0 1 GPU -ncmoe 48 -c 262144 with --spec-type draft-mtp: window auto derives "draft CONTEXT 1102 MiB (kv 142 + compute 768 + slack 192)" -> arena 20527.5 MiB / 62.9 % residency; window 0 keeps the flat 3584 MiB -> arena 17977.5 MiB / 55.1 %. +2550 MiB of arena, +7.8 points. Fixed on the way: * src/llama-memory-hybrid.cpp passed its attention cache to the extended ctor positionally, so after upstream inserted `is_indexer` before `v_enabled` the delivery's `kv_pool` landed in `v_enabled`: the cache allocated NO V tensor and llama_kv_cache::cpy_v null-dereferenced on the first graph build (every hybrid/GDN model segfaulted at load; the dense 4B arm died before generating). `is_indexer` is now named explicitly. The other ctor call sites were audited: hybrid-idx already named it, model.cpp stops at `share`, and dsa/dsa-iswa/msa/dsv4 are upstream's and correct. * ggml/src/ggml-cuda/indexer-score.cu is NOT an R16 drift but a latent R12 defect (b1b0fa807): the fused GGML_OP_INDEXER_SCORE node called ggml_rope_get_truncate(dst), and upstream's ggml-org#30206 added an assert that the argument is a ROPE/ROPE_BACK node. Every qwen4exp sparse QSA decode run has aborted on this tree since R12 (no R12-R15 gate reaches that arm -- the coherence arms and both qwen4exp gates run the dense arm; block 15's residency gate reaches it because its `pref` arm sets LLAMA_QSA_DENSE_DECODE_UNTIL=0, and aborted after 63 generated tokens at ggml.c:4648). Both call sites now pass /*truncate*/ true, which is the graph's own rope node default (ggml_rope_impl initialises no_trunc 0 and nothing calls ggml_rope_set_truncate on the indexer-key node) and the pre-ggml-org#30206 5-argument helper's unconditional floor/ceil, i.e. pre-re-base numerics. Coherence (same session, same commands, this build family): dense 4B 1de99b7e6ee6, 30B-A3B 4b4d56191368, 35B-A3B 3 GPU tensor rccl 86b7f9b5aa80, Flash-Next GSQ 7a8734a9f1a6 -- all four unchanged from R13. Gates: * gate-kv-residency.sh PASS. Window: wref == wres == wspill be904e86f248, wres 0 flips / 0 MiB host-backed, wspill 16 flips / 64 MiB, every slide on the map grid. Pool: pref == pres == pfloor f260d1824ab3, bad 0, 8192 pages (408.0 MiB) on pres vs 4104 (204.4 MiB) on pfloor, 252 resolves both, claims 137.7 -> 217.1 per resolve, hits 91.02 -> 89.63 %. Multi-device (-sm layer 0,1): pmref == pmres == pmfloor f260d1824ab3, one mirror/pool/counter block per device, 2 counter blocks summed, 117.8 -> 268.1 claims per resolve. * gate-kv-window-split.sh PASS, 38/38: one region per device on a 3-device 4B, a 27B at -c 524288 sliding on BOTH devices (32 flips each), -c 1048576 windowed, 1-device unchanged, -nkvo still declines, all five fit arms (fixed/auto/ram/ram-drop/off), and win2mtp == ref2mtp with identical acceptance 0.46154 whose batched state save takes the region path. * gate-spec-draft-window.sh PASS: LLAMA_SPEC_DRAFT_WINDOW=1024 gives "1024 cells per sequence, cache 3072 cells ((win + 512) x 2)" and all six requests across both slots are byte-identical to win 0, acceptance identical (0.47222 / 17-36, 1.0 / 23-23). * check-gpu-faults.sh --since the session start: clean.
…W (Goal A) and an attendance POOL (Goal B), both opt-in Re-based onto a691b23 (r236) The rung collided with everything the streamed KV binds to: the memory instances (ggml-org#31141 no_alloc, ggml-org#31200 n_pad removed, ggml-org#31142), the KV cache internals (ggml-org#30541 on-device state copy sizes, ggml-org#31073 the rotation constants moved into a per-cache buffer, ggml-org#31570 kv_rows), the Meta (tensor-split) device (ggml-org#31447) and the qwen4exp rewrite. 8 files conflicted / 12 hunks (9 expected: src/models/qwen4exp.cpp auto-merged, the D3 residue did not conflict this time and its 59/-7 lines all landed). A distinctive-added-line check over the 25 auto-merged files found no dropped delivery code. D13 (memory instances) -- re-derived, not carried: * llama_memory_params keeps upstream's `no_alloc` and adds the delivery's `kv_pool` (llama-context.cpp's designated init passes both); the three `hparams.no_alloc` reads the block added follow ggml-org#31141 out of the hparams and become the ctor's `no_alloc`. * memory_breakdown() is re-derived over `ctxs_bufs.bufs` + `ctxs_bufs.no_alloc` instead of the old per-cache loop: upstream moved the no_alloc/plain accounting into llama_memory_bufs and added attn_rot_bufs (ggml-org#31073), whose bytes are summed on top. The pool's mirror-to-host-bucket and the window's resident/spill split accounting are unchanged. * the MTP draft window's llama_kv_cache construction drops the `n_pad` argument (ggml-org#31200), and the pool's cell count is rounded to whole PAGES (it used to round to the cache's n_pad, which no longer exists as a parameter -- n_ctx is unpadded now). * create_memory() takes upstream's `params` name back (the delivery-side `params_l` rename is gone; the body was upstream's everywhere but two lines). * src/llama-ext.h keeps upstream's classifier-free-guidance declaration, src/llama-memory.h keeps upstream's llama_memory_bufs struct, ggml-backend-meta.cpp keeps upstream's view-slab helpers next to ggml_backend_meta_kv_region_grow. src/llama-context.cpp takes upstream's readback-sync hunk -- the delivery side of it was stale F1 code (layer_inp_host_fill, deleted at R13). D12 (quantized-KV state, rotation) -- the provider still binds at the BUFFER TYPE and no kernel addresses cells differently: the rotation constants are a per-cache, per-layer buffer (attn_rot_bufs), not cell-indexed, so they are outside the region; state_write/state_read keep going through the region buffer's own copy. Proven by the gates below, whose spilling arms really spill (16 mapping flips, 64 MiB host-backed) and whose state arm (win2mtp) takes the region path. The r193 draft reserve is preserved (r236 absorbed the fit plumbing): common/common.cpp takes upstream's common_fit_apply() call, and block 15's mtp_shared branch is folded into common_draft_reserve_derive() -- the one function both `--fit` and the MoE preflight call. Measured, 35B-A3B Q8_0 1 GPU -ncmoe 48 -c 262144 with --spec-type draft-mtp: window auto derives "draft CONTEXT 1102 MiB (kv 142 + compute 768 + slack 192)" -> arena 20527.5 MiB / 62.9 % residency; window 0 keeps the flat 3584 MiB -> arena 17977.5 MiB / 55.1 %. +2550 MiB of arena, +7.8 points. Fixed on the way: * src/llama-memory-hybrid.cpp passed its attention cache to the extended ctor positionally, so after upstream inserted `is_indexer` before `v_enabled` the delivery's `kv_pool` landed in `v_enabled`: the cache allocated NO V tensor and llama_kv_cache::cpy_v null-dereferenced on the first graph build (every hybrid/GDN model segfaulted at load; the dense 4B arm died before generating). `is_indexer` is now named explicitly. The other ctor call sites were audited: hybrid-idx already named it, model.cpp stops at `share`, and dsa/dsa-iswa/msa/dsv4 are upstream's and correct. * ggml/src/ggml-cuda/indexer-score.cu is NOT an R16 drift but a latent R12 defect (b1b0fa807): the fused GGML_OP_INDEXER_SCORE node called ggml_rope_get_truncate(dst), and upstream's ggml-org#30206 added an assert that the argument is a ROPE/ROPE_BACK node. Every qwen4exp sparse QSA decode run has aborted on this tree since R12 (no R12-R15 gate reaches that arm -- the coherence arms and both qwen4exp gates run the dense arm; block 15's residency gate reaches it because its `pref` arm sets LLAMA_QSA_DENSE_DECODE_UNTIL=0, and aborted after 63 generated tokens at ggml.c:4648). Both call sites now pass /*truncate*/ true, which is the graph's own rope node default (ggml_rope_impl initialises no_trunc 0 and nothing calls ggml_rope_set_truncate on the indexer-key node) and the pre-ggml-org#30206 5-argument helper's unconditional floor/ceil, i.e. pre-re-base numerics. Coherence (same session, same commands, this build family): dense 4B 1de99b7e6ee6, 30B-A3B 4b4d56191368, 35B-A3B 3 GPU tensor rccl 86b7f9b5aa80, Flash-Next GSQ 7a8734a9f1a6 -- all four unchanged from R13. Gates: * gate-kv-residency.sh PASS. Window: wref == wres == wspill be904e86f248, wres 0 flips / 0 MiB host-backed, wspill 16 flips / 64 MiB, every slide on the map grid. Pool: pref == pres == pfloor f260d1824ab3, bad 0, 8192 pages (408.0 MiB) on pres vs 4104 (204.4 MiB) on pfloor, 252 resolves both, claims 137.7 -> 217.1 per resolve, hits 91.02 -> 89.63 %. Multi-device (-sm layer 0,1): pmref == pmres == pmfloor f260d1824ab3, one mirror/pool/counter block per device, 2 counter blocks summed, 117.8 -> 268.1 claims per resolve. * gate-kv-window-split.sh PASS, 38/38: one region per device on a 3-device 4B, a 27B at -c 524288 sliding on BOTH devices (32 flips each), -c 1048576 windowed, 1-device unchanged, -nkvo still declines, all five fit arms (fixed/auto/ram/ram-drop/off), and win2mtp == ref2mtp with identical acceptance 0.46154 whose batched state save takes the region path. * gate-spec-draft-window.sh PASS: LLAMA_SPEC_DRAFT_WINDOW=1024 gives "1024 cells per sequence, cache 3072 cells ((win + 512) x 2)" and all six requests across both slots are byte-identical to win 0, acceptance identical (0.47222 / 17-36, 1.0 / 23-23). * check-gpu-faults.sh --since the session start: clean.
…W (Goal A) and an attendance POOL (Goal B), both opt-in Re-based onto a691b23 (r236) The rung collided with everything the streamed KV binds to: the memory instances (ggml-org#31141 no_alloc, ggml-org#31200 n_pad removed, ggml-org#31142), the KV cache internals (ggml-org#30541 on-device state copy sizes, ggml-org#31073 the rotation constants moved into a per-cache buffer, ggml-org#31570 kv_rows), the Meta (tensor-split) device (ggml-org#31447) and the qwen4exp rewrite. 8 files conflicted / 12 hunks (9 expected: src/models/qwen4exp.cpp auto-merged, the D3 residue did not conflict this time and its 59/-7 lines all landed). A distinctive-added-line check over the 25 auto-merged files found no dropped delivery code. D13 (memory instances) -- re-derived, not carried: * llama_memory_params keeps upstream's `no_alloc` and adds the delivery's `kv_pool` (llama-context.cpp's designated init passes both); the three `hparams.no_alloc` reads the block added follow ggml-org#31141 out of the hparams and become the ctor's `no_alloc`. * memory_breakdown() is re-derived over `ctxs_bufs.bufs` + `ctxs_bufs.no_alloc` instead of the old per-cache loop: upstream moved the no_alloc/plain accounting into llama_memory_bufs and added attn_rot_bufs (ggml-org#31073), whose bytes are summed on top. The pool's mirror-to-host-bucket and the window's resident/spill split accounting are unchanged. * the MTP draft window's llama_kv_cache construction drops the `n_pad` argument (ggml-org#31200), and the pool's cell count is rounded to whole PAGES (it used to round to the cache's n_pad, which no longer exists as a parameter -- n_ctx is unpadded now). * create_memory() takes upstream's `params` name back (the delivery-side `params_l` rename is gone; the body was upstream's everywhere but two lines). * src/llama-ext.h keeps upstream's classifier-free-guidance declaration, src/llama-memory.h keeps upstream's llama_memory_bufs struct, ggml-backend-meta.cpp keeps upstream's view-slab helpers next to ggml_backend_meta_kv_region_grow. src/llama-context.cpp takes upstream's readback-sync hunk -- the delivery side of it was stale F1 code (layer_inp_host_fill, deleted at R13). D12 (quantized-KV state, rotation) -- the provider still binds at the BUFFER TYPE and no kernel addresses cells differently: the rotation constants are a per-cache, per-layer buffer (attn_rot_bufs), not cell-indexed, so they are outside the region; state_write/state_read keep going through the region buffer's own copy. Proven by the gates below, whose spilling arms really spill (16 mapping flips, 64 MiB host-backed) and whose state arm (win2mtp) takes the region path. The r193 draft reserve is preserved (r236 absorbed the fit plumbing): common/common.cpp takes upstream's common_fit_apply() call, and block 15's mtp_shared branch is folded into common_draft_reserve_derive() -- the one function both `--fit` and the MoE preflight call. Measured, 35B-A3B Q8_0 1 GPU -ncmoe 48 -c 262144 with --spec-type draft-mtp: window auto derives "draft CONTEXT 1102 MiB (kv 142 + compute 768 + slack 192)" -> arena 20527.5 MiB / 62.9 % residency; window 0 keeps the flat 3584 MiB -> arena 17977.5 MiB / 55.1 %. +2550 MiB of arena, +7.8 points. Fixed on the way: * src/llama-memory-hybrid.cpp passed its attention cache to the extended ctor positionally, so after upstream inserted `is_indexer` before `v_enabled` the delivery's `kv_pool` landed in `v_enabled`: the cache allocated NO V tensor and llama_kv_cache::cpy_v null-dereferenced on the first graph build (every hybrid/GDN model segfaulted at load; the dense 4B arm died before generating). `is_indexer` is now named explicitly. The other ctor call sites were audited: hybrid-idx already named it, model.cpp stops at `share`, and dsa/dsa-iswa/msa/dsv4 are upstream's and correct. * ggml/src/ggml-cuda/indexer-score.cu is NOT an R16 drift but a latent R12 defect (b1b0fa807): the fused GGML_OP_INDEXER_SCORE node called ggml_rope_get_truncate(dst), and upstream's ggml-org#30206 added an assert that the argument is a ROPE/ROPE_BACK node. Every qwen4exp sparse QSA decode run has aborted on this tree since R12 (no R12-R15 gate reaches that arm -- the coherence arms and both qwen4exp gates run the dense arm; block 15's residency gate reaches it because its `pref` arm sets LLAMA_QSA_DENSE_DECODE_UNTIL=0, and aborted after 63 generated tokens at ggml.c:4648). Both call sites now pass /*truncate*/ true, which is the graph's own rope node default (ggml_rope_impl initialises no_trunc 0 and nothing calls ggml_rope_set_truncate on the indexer-key node) and the pre-ggml-org#30206 5-argument helper's unconditional floor/ceil, i.e. pre-re-base numerics. Coherence (same session, same commands, this build family): dense 4B 1de99b7e6ee6, 30B-A3B 4b4d56191368, 35B-A3B 3 GPU tensor rccl 86b7f9b5aa80, Flash-Next GSQ 7a8734a9f1a6 -- all four unchanged from R13. Gates: * gate-kv-residency.sh PASS. Window: wref == wres == wspill be904e86f248, wres 0 flips / 0 MiB host-backed, wspill 16 flips / 64 MiB, every slide on the map grid. Pool: pref == pres == pfloor f260d1824ab3, bad 0, 8192 pages (408.0 MiB) on pres vs 4104 (204.4 MiB) on pfloor, 252 resolves both, claims 137.7 -> 217.1 per resolve, hits 91.02 -> 89.63 %. Multi-device (-sm layer 0,1): pmref == pmres == pmfloor f260d1824ab3, one mirror/pool/counter block per device, 2 counter blocks summed, 117.8 -> 268.1 claims per resolve. * gate-kv-window-split.sh PASS, 38/38: one region per device on a 3-device 4B, a 27B at -c 524288 sliding on BOTH devices (32 flips each), -c 1048576 windowed, 1-device unchanged, -nkvo still declines, all five fit arms (fixed/auto/ram/ram-drop/off), and win2mtp == ref2mtp with identical acceptance 0.46154 whose batched state save takes the region path. * gate-spec-draft-window.sh PASS: LLAMA_SPEC_DRAFT_WINDOW=1024 gives "1024 cells per sequence, cache 3072 cells ((win + 512) x 2)" and all six requests across both slots are byte-identical to win 0, acceptance identical (0.47222 / 17-36, 1.0 / 23-23). * check-gpu-faults.sh --since the session start: clean.
Overview
Only CPU and CUDA are currently supported, changes to other backends are to mark as unsupported.
YaRN calculates correction intervals to switch frequency interpolation methods, but the setting to not round the boundaries of these intervals to integers (
truncate=false) was not supported.Models that use
truncate=falseinclude gpt-oss and some PLaMo-3 models; to support those models correctly, the GGML operations and CPU/CUDA backends are modified to handle calculations without rounding. The default behavior istruncate=true, and existing calls not explicitly configured will maintain their previous behavior.Additional information
truncate=falseRequirements