Commit e56f006ed for llama.cpp

commit e56f006ed6b416ae8b7ccb5243b204743f09df1e
Author: Hongqiang Wang <wangh@qti.qualcomm.com>
Date:   Wed Nov 4 18:31:01 2026 -0800

    llama : fix on-device state copy sizes for quantized KV caches (#30541)

    * llama : fix on-device state copy sizes for quantized KV caches

    The on-device sequence state copies (LLAMA_STATE_SEQ_FLAGS_ON_DEVICE) computed
    their element count as size / ggml_element_size(). For a quantized type such as
    q8_0 or q4_0 that is the number of blocks, not elements, so only part of each
    range was copied: the restored state was wrong, or the copy crashed.

    Compute the count as size / ggml_type_size() * ggml_blck_size() for the save,
    the restore and the copy between differently chunked ranges, and assert that
    each range covers whole blocks.

    * llama : drop the one-line comments

    * llama : drop the redundant cast in the state copy size

diff --git a/src/llama-context.cpp b/src/llama-context.cpp
index 85c32c995..63b203201 100644
--- a/src/llama-context.cpp
+++ b/src/llama-context.cpp
@@ -3350,7 +3350,8 @@ public:
         for (const auto & winfo : winfos) {
             auto * buft = ggml_backend_buffer_get_type(winfo.tensor->buffer);

-            const int64_t n = winfo.size/ggml_element_size(winfo.tensor);
+            GGML_ASSERT(winfo.size % ggml_type_size(winfo.tensor->type) == 0);
+            const int64_t n = winfo.size/ggml_type_size(winfo.tensor->type)*ggml_blck_size(winfo.tensor->type);

             auto & mbuf = mbufs_new[buft];

@@ -3481,7 +3482,8 @@ public:
         for (const auto & rinfo : rinfos) {
             auto * buft = ggml_backend_buffer_get_type(rinfo.tensor->buffer);

-            const int64_t n = rinfo.size/ggml_element_size(rinfo.tensor);
+            GGML_ASSERT(rinfo.size % ggml_type_size(rinfo.tensor->type) == 0);
+            const int64_t n = rinfo.size/ggml_type_size(rinfo.tensor->type)*ggml_blck_size(rinfo.tensor->type);

             auto & mbuf = mbufs_new[buft];

@@ -3553,8 +3555,8 @@ public:

                 const size_t n_copy = std::min(src_size - src_off, dst_size - dst_off);

-                const size_t   el   = ggml_element_size(src_t);
-                const int64_t n_el = (int64_t) (n_copy / el);
+                GGML_ASSERT(n_copy % ggml_type_size(src_t->type) == 0);
+                const int64_t n_el = n_copy / ggml_type_size(src_t->type) * ggml_blck_size(src_t->type);

                 auto * src_v = ggml_view_1d(ctx_scratch, src_t, n_el, src_off);
                 ggml_backend_view_init(src_v);