From 691202d15dd3ed1125fb1ca4939966f92bae9a90 Mon Sep 17 00:00:00 2001 From: Thomas Brasser Date: Tue, 18 Aug 2026 22:22:27 +0200 Subject: [PATCH] test(BACKEND-ROCM): the block-size contract is enforced at its production call site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `CheckKvCacheShape` is well tested in isolation (test_attn_backend_registry / test_common_attn_metadata), but its install inside `GPUModelRunner::initialize_kv_cache` had no test: deleting it left every gate green (the #1065 Owed item). A runner built with a non-multiple-of-16 block size now asserts the throw at construction, from the FLASH_ATTN backend's own `get_kv_cache_shape` — the executable statement of the contract the server's `--block-size` validation and the bench rounding exist to prevent at the entry points. Validated on gfx1151 (Strix Halo) as part of the M3 battery: test_runner 20/20, 544 assertions. Issue: #41 FOLLOWING_AGENTS_PROTOCOL Following-Agents-Protocol: true AI-Assisted: true Assisted-by: Buffy:assistant [Freebuff] --- tests/vllm/v1/worker/test_runner.cpp | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/vllm/v1/worker/test_runner.cpp b/tests/vllm/v1/worker/test_runner.cpp index 107f2e8a9..2b5fd5cca 100644 --- a/tests/vllm/v1/worker/test_runner.cpp +++ b/tests/vllm/v1/worker/test_runner.cpp @@ -1527,3 +1527,32 @@ TEST_CASE("runner: full-attention-only step skips GDN metadata build (no OOB)") doctest::Contains("qwen3_5 dense paged forward"), std::runtime_error); } + +// ─── M3: THE BLOCK-SIZE CONTRACT AT ITS PRODUCTION CALL SITE ───────────────── +// +// `CheckKvCacheShape` is well tested in isolation (test_attn_backend_registry / +// test_common_attn_metadata), but its PRODUCTION call site — the install inside +// `GPUModelRunner::initialize_kv_cache` — was not: no test drove the runner +// with a non-multiple-of-16 block size, so deleting that install left every +// gate green (the #1065 Owed item). The FLASH_ATTN backend's own +// `get_kv_cache_shape` refuses block_size % 16 != 0, and the runner resolves +// FLASH_ATTN for the CPU device, so construction must throw the backend's +// `invalid_argument` from init — the same failure the server's --block-size +// validation and the bench rounding exist to prevent at the entry points. +TEST_CASE("runner: initialize_kv_cache refuses a non-multiple-of-16 block size") { + const HfConfig c = MakeDenseOnlyConfig(); + const Qwen3_5DenseWeights w = MakeDenseOnlyWeights(c); + + KVCacheConfig kv = MakeFaOnlyKvConfig(c); + kv.kv_cache_groups[0].kv_cache_spec = std::make_shared( + /*block_size=*/8, static_cast(c.num_key_value_heads), + static_cast(c.head_dim), vllm::v1::ResolveKvCacheDType()); + + auto make_runner = [&]() { + GPUModelRunner runner(c, w, kv, Q(), /*max_num_reqs=*/8, kMaxModelLen, + /*max_num_batched_tokens=*/64); + }; + CHECK_THROWS_WITH_AS(make_runner(), + doctest::Contains("Block size must be a multiple of 16"), + std::invalid_argument); +}