Add challenge 86: Paged KV-Cache Attention (Medium) - #225
Conversation
Implements decode-phase attention over a non-contiguous paged KV cache, modeled on the vLLM paged attention architecture. Teaches block-table indirection, online softmax across scattered memory pages, and the memory access patterns central to LLM serving workloads. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Redesign SVG: block_table as a proper table with column headers, cache pool as horizontal memory strip with color-coded blocks and sequence labels. Convert example and computation steps from HTML entities to LaTeX math notation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
|
||
| <h2>Implementation Requirements</h2> | ||
| <p> | ||
| Implement the function <code>solve(Q, K_cache, V_cache, block_table, context_lens, output, batch_size, num_heads, head_dim, block_size, max_blocks_per_seq)</code> |
There was a problem hiding this comment.
don't really have to say this in the implementation requirements. @claude change this to match the format of other challenge's implementation requirements
|
@claude change the implementation requirements to match the format of other challenge's implementation requirements. Specifically, you don't need to say "implement the function..." as it is obvious. |
1 similar comment
|
@claude change the implementation requirements to match the format of other challenge's implementation requirements. Specifically, you don't need to say "implement the function..." as it is obvious. |
- Migrate challenge.py to the current ChallengeBase contract: class-level metadata attributes instead of __init__, no device assertions, and device=self.device for every allocation so the challenge runs on XLA too. - Vectorize reference_impl (static-shape gather + masked softmax) instead of looping over the batch with .item() syncs. - Scatter each sequence's blocks through an over-allocated pool so a solution that ignores block_table and reads the cache contiguously no longer passes; the example now maps logical block 0 to physical block 1 for the same reason. - Add a partially-filled-trailing-block edge case (ctx_len 1/2/3, block_size 4). - Fix the head_dim constraint (tests use head_dim = 4, not a multiple of 8) and document max_blocks_per_seq, block_table padding, and unreferenced pool blocks. - JAX starter comment: "tensors on device". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Reviewed against the Issues found and fixed1. Tests didn't actually exercise paging (most significant). 2. 3. 4. Constraint contradicted the tests. The HTML said 5. Missing edge case. Added 6. JAX starter comment was Verification
Not verified: the live platform run. |



Summary
What makes this interesting for GPU programmers
block_tablethat maps logical block indices to physical block IDs in a shared pool — requires careful pointer arithmetic and strided access patternsFiles
challenge.py: reference implementation, 10 functional test cases (edge cases, power-of-2, non-power-of-2, variable-length batch, realistic sizes), performance test at LLaMA-3 scale (batch=8, heads=32, head_dim=128, block_size=16, ctx_len=2,048)challenge.html: full problem description with SVG block-table visualization, worked example, and constraintsTest plan
--action run) passed on NVIDIA TESLA T4pre-commit run --all-filespasses (black, isort, flake8, clang-format)🤖 Generated with Claude Code