From 8288bc4567b77390d80ed7a73ee1d58d7b764d5c Mon Sep 17 00:00:00 2001 From: bong-water-water-bong Date: Tue, 10 Nov 2026 19:44:00 -0400 Subject: [PATCH 1/2] tests: hrx-backend-test compiles again after the alias_miss field (#262) #262 added ValueMap's alias_miss field before the optional buffer binding. Two aggregate initialisers in hrx-backend-test still passed std::nullopt in that position, so the test has not compiled since. They now pass AliasMiss::None. Co-Authored-By: Claude Fable 5.2 --- tests/hrx-backend-test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/hrx-backend-test.cpp b/tests/hrx-backend-test.cpp index 8fffb7d6f07f..d1d487788356 100644 --- a/tests/hrx-backend-test.cpp +++ b/tests/hrx-backend-test.cpp @@ -8375,7 +8375,7 @@ static void run_alias_value_import_checks() { value_map .add_snapshot_value({ ggml::hrx::ValueId(0), ggml::hrx::ValueKind::External, ggml::hrx::ValueStorageId(0), ggml::hrx::ValueId(0), ggml::hrx::ValueId(), 0, 8 * sizeof(float), GGML_TYPE_F32, ne, - nb, 8, 8 * sizeof(float), true, nullptr, std::nullopt }) + nb, 8, 8 * sizeof(float), true, nullptr, ggml::hrx::AliasMiss::None, std::nullopt }) .success()); REQUIRE(value_map.add_snapshot_storage({ ggml::hrx::ValueStorageId(1), ggml::hrx::ValueId(1), 8 * sizeof(float) }) .success()); @@ -8383,7 +8383,7 @@ static void run_alias_value_import_checks() { value_map .add_snapshot_value({ ggml::hrx::ValueId(1), ggml::hrx::ValueKind::Transient, ggml::hrx::ValueStorageId(1), ggml::hrx::ValueId(1), ggml::hrx::ValueId(), 0, 8 * sizeof(float), GGML_TYPE_F32, ne, - nb, 8, 8 * sizeof(float), true, nullptr, std::nullopt }) + nb, 8, 8 * sizeof(float), true, nullptr, ggml::hrx::AliasMiss::None, std::nullopt }) .success()); REQUIRE(value_map.alias_storage(ggml::hrx::ValueId(1), ggml::hrx::ValueId(0)).success()); const ggml::hrx::Value * aliased_value = value_map.find(ggml::hrx::ValueId(1)); From 2136dd642be31a99dce7e2ed9405ae29f207143f Mon Sep 17 00:00:00 2001 From: bong-water-water-bong Date: Tue, 10 Nov 2026 19:55:27 -0400 Subject: [PATCH 2/2] tests: hrx-backend-test expects the transposed V's spread pitch (engine #1989) qwen_flash_attention_dispatch still required the transposed V to be keys x columns long with value_layout 1. Since llama.cpp #289/#291 the buffer has the spread pitch (keys + 32 when the key count is a multiple of 64), the transpose kernel is told the pitch and the attention kernel derives it (value_layout 2). The dispatch is right; the expectation was stale, and a compile error in this file (fixed by #293) hid it. The check now asserts the pitch, the packed source binding, the transpose kernel's output_pitch and that the pitch is not a compile parameter of the attention kernel. host: 63 passed, 3 failed -> 64 passed, 2 failed (the two left, :1858 and :6333, are not from this change). Co-Authored-By: Claude Fable 5.2 --- tests/hrx-backend-test.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/hrx-backend-test.cpp b/tests/hrx-backend-test.cpp index d1d487788356..38abc3c83b63 100644 --- a/tests/hrx-backend-test.cpp +++ b/tests/hrx-backend-test.cpp @@ -4119,8 +4119,15 @@ static void schedule_flash_attention_command(ggml_context * ctx, REQUIRE(copy.bindings.size() == 2); REQUIRE(copy.bindings[1].value == dispatch.bindings[2].value); REQUIRE(copy.bindings[0].value != copy.bindings[1].value); - REQUIRE(copy.bindings[1].length == static_cast(key_value_token_count * key_value_head_count * value_head_size) * sizeof(ggml_fp16_t)); - require_compile_parameter(dispatch, "ggml.flash_attention.value_layout", "1"); + // engine #1989: the transposed V has the spread pitch - keys + 32 when the key count is a multiple of 64 - which + // the transpose kernel is told and the attention kernel derives from its key count (value_layout 2). The source + // binding stays the packed V. + const int64_t transposed_pitch = key_value_token_count % 64 == 0 ? key_value_token_count + 32 : key_value_token_count; + REQUIRE(copy.bindings[0].length == static_cast(key_value_token_count * key_value_head_count * value_head_size) * sizeof(ggml_fp16_t)); + REQUIRE(copy.bindings[1].length == static_cast(transposed_pitch * key_value_head_count * value_head_size) * sizeof(ggml_fp16_t)); + require_compile_parameter(copy, "ggml.copy_transpose_f16.output_pitch", std::to_string(transposed_pitch)); + require_compile_parameter(dispatch, "ggml.flash_attention.value_layout", "2"); + REQUIRE(dispatch.kernel.compile_parameters.count("ggml.flash_attention.value_transposed_pitch") == 0); } else { REQUIRE(dispatch.kernel.compile_parameters.count("ggml.flash_attention.value_layout") == 0); }