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/3] 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/3] 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); } From 23342823be8206b980374e8d1466b8dfb2353357 Mon Sep 17 00:00:00 2001 From: bong-water-water-bong Date: Tue, 10 Nov 2026 20:06:28 -0400 Subject: [PATCH 3/3] tests: hrx-backend-test's two other stale host rows follow the backend (engine #2068) The test did not compile from #262 until #293, so host rows drifted from changes that were made on purpose. #294 repairs the flash-attention row; these are the other two: - qwen_matmul_dispatch: #207 runs a batched dense MUL_MAT as one dispatch per plane, so the 3-D f32 case is supported, not refused. - unmatched_graph_diagnostics: #196's standalone SET_ROWS takes the i32-index graph the row used as its unmatched example. The row now uses a row width above that dispatch's limit, which every matcher still declines. Co-Authored-By: Claude Fable 5.2 --- tests/hrx-backend-test.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/hrx-backend-test.cpp b/tests/hrx-backend-test.cpp index 38abc3c83b63..b255c738bc31 100644 --- a/tests/hrx-backend-test.cpp +++ b/tests/hrx-backend-test.cpp @@ -1835,8 +1835,11 @@ static void run_unmatched_graph_diagnostics_checks() { ggml_context * ctx = ggml_init(params); REQUIRE(ctx != nullptr); - ggml_tensor * cache = ggml_new_tensor_2d(ctx, GGML_TYPE_F16, 512, 512); - ggml_tensor * rows = ggml_new_tensor_2d(ctx, GGML_TYPE_F32, 512, 2); + // A SET_ROWS that no registration takes. The i32-index form at an ordinary row width used to be that graph; since + // llama.cpp #196 the standalone hip_set_rows dispatch runs it on the device. A row wider than that dispatch's 32,768 + // limit (and with i32 indices, which the two Loom writers decline) is still refused by every matcher. + ggml_tensor * cache = ggml_new_tensor_2d(ctx, GGML_TYPE_F16, 65536, 4); + ggml_tensor * rows = ggml_new_tensor_2d(ctx, GGML_TYPE_F32, 65536, 2); ggml_tensor * indices = ggml_new_tensor_1d(ctx, GGML_TYPE_I32, 2); REQUIRE(cache != nullptr); REQUIRE(rows != nullptr); @@ -6330,7 +6333,8 @@ static void run_qwen_matmul_dispatch_checks() { REQUIRE(input != nullptr); ggml_tensor * output = ggml_mul_mat(ctx, weight, input); REQUIRE(output != nullptr); - REQUIRE(!matmul_graph_is_supported(ctx, output)); + // llama.cpp #207: a batched dense MUL_MAT runs as one dispatch per plane; before it this graph was refused. + REQUIRE(matmul_graph_is_supported(ctx, output)); } {