Repository navigation
[ROCm][Perf][DSv4.1] Build the SWA decode metadata in one launch - #63885
AndreasKaratzas merged 7 commits into
Conversation
| return False | ||
| from vllm.platforms.rocm import on_mi3xx | ||
|
|
||
| return on_mi3xx() |
There was a problem hiding this comment.
Don't gate this on mi3xx_enabled() / on_mi3xx(). Check the CDNA version or the gfx arch with get_cdna_version() or on_gfx942() / on_gfx950(). #63994 already does the second in swa_decode_meta_enabled()
There was a problem hiding this comment.
@frida-andersson Done in 768a354. swa_decode_meta.build now checks swa_decode_meta_enabled() from #63994, which is --monokernel and on_gfx942() or on_gfx950(). The gate test fakes on_gfx950 instead of on_mi3xx, so on MI355X it also fails if the gate goes back to on_mi3xx().
|
@frida-andersson Converged with #63994 here, as proposed. The second commit takes #63994's
|
| return False | ||
| from vllm.platforms.rocm import on_gfx942, on_gfx950 | ||
|
|
||
| return on_gfx942() or on_gfx950() |
There was a problem hiding this comment.
can we check for cdna 3 or 4 instead? that way we won't need to add additional imports as we go forward
dllehr-amd
left a comment
There was a problem hiding this comment.
This also looks good, thanks @okorzh-amd
|
✅ @okorzh-amd, CI is now available for this PR.
|
|
Hi @okorzh-amd, the pre-commit checks have failed. Please run: uv pip install pre-commit>=4.5.1
pre-commit install
pre-commit run --all-filesThen, commit the changes and push to your branch. For future commits, |
…fx950 with --monokernel swa_decode_meta (vllm-project#60731) builds a decode batch's SWA metadata with one Triton launch instead of the 8 small launches of vLLM's build, for every causal SWA group of the target and every non-causal group of the DSpark draft. vllm-project#60731 gated it with the other gfx942 helpers on ops.enabled(), so on gfx950 every group still runs the 8-launch build in front of each decode graph. The kernel has no arch-specific code and writes the same tensors, including the ragged views whose length the gfx950 split selector reads, so the metadata is identical. It now runs with --monokernel on gfx942 and gfx950 (ops.mi3xx_enabled(), on on_mi3xx()); the other helpers keep the gfx942-only gate. DeepSeek-V4.1-Flash TP4 with --monokernel and DSpark k=6 on MI355X, 32k/1k, on nightly 83c078d plus five open DSv4.1 PRs that do not touch this path (the changed code is the same on main), one unswapped run per arm: decode step -2.0% at concurrency 1 (-103 us) and -0.9% at concurrency 2 (inside the base's cross-round drift). Both need an ABBA re-measure on main. A CPU test checks that a decode batch takes the one launch with --monokernel on gfx942 and gfx950, and keeps vLLM's build without the flag or on another arch. The MI355 mono numerics job now also runs the kernel's comparison with vLLM's ops. Signed-off-by: Oxana Korzh <okorzh@amd.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AndreasKaratzas
left a comment
There was a problem hiding this comment.
Test def looks good, but i m trying to make sure that the UT is also looking good. Let's not skip the NITs all the time . I can merge it rn but @okorzh-amd could you first lmk any comments on the lines i highlighted?
|
|
||
| monkeypatch.setattr(ops, "current_platform", SimpleNamespace(is_rocm=lambda: True)) | ||
| monkeypatch.setattr(rocm_platform, "on_gfx942", lambda: arch == "gfx942") | ||
| cdna = {"gfx90a": 2, "gfx942": 3, "gfx950": 4}[arch] |
There was a problem hiding this comment.
this looks a bit suboptimal, if you choose cdna def then why not parametrize it like that ? Also what are we testing on gfx90a here?
There was a problem hiding this comment.
@AndreasKaratzas Agreed, thanks. Done in 67aec3e and d331b82
Review: - The gate test runs on CDNA3 and CDNA4, the versions the gate checks, instead of on gfx942, gfx950 and gfx90a. - The SWA metadata kernel test moves from tests/kernels/models/amd/test_dsv41_gfx942_decode_meta.py to tests/models/test_dsv41_mono_numerics.py, so that it runs on gfx950 as well as gfx942 with no Buildkite change. The MI355 DeepSeek-V4.1 Mono Decode Numerics and MI300 gfx942 Mono Decode Layers steps already run that file. The models_basic.yaml hunk is dropped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Oxana Korzh <okorzh@amd.com>
Head branch was pushed to by a user without write access
Review: minimize the test changes. The kernel test goes back to tests/kernels/models/amd/test_dsv41_gfx942_decode_meta.py unchanged, so the PR's only test change is the CDNA3/CDNA4 gate test in tests/models/test_dsv41_mono_decode.py, with no Buildkite change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Oxana Korzh <okorzh@amd.com>
|
/ci run |
|
✅ Triggered Buildkite CI #98447 for commit ℹ️ This PR is 79 commits behind upstream |
…h --monokernel With --monokernel on gfx942, ops/fused_markov.py (vllm-project#60731) samples each DSpark draft position in one launch (k + 1 launches a decode step) instead of vLLM's loop of about 9 kernels a position: the Markov embedding, the 66 MB markov_w2 GEMV, the add, the Gumbel sample with its argmax and gather, and the draft_tokens copy. vllm-project#60731 gated it with the other gfx942 helpers on ops.enabled(), so gfx950 still runs the loop. The kernel is plain Triton with vLLM's own Gumbel helpers and nothing gfx942-specific. fused_markov now runs under the gate of swa_decode_meta (vllm-project#63885), --monokernel on CDNA3 (gfx942) or CDNA4 (gfx950), renamed from swa_decode_meta_enabled() to ops.mi3xx_enabled() since both helpers use it; the other helpers keep ops.enabled(). On gfx950 it takes steps of at most 5 rows (MAX_ROWS_GFX950): from 6 rows on, vLLM's loop is faster there, because its Markov GEMV leaves wvSplitK. Both archs launch the step kernel at 4 warps, which on gfx950 is as fast as 8 at 1-2 rows and faster at 3-5. As on gfx942, a bias value may differ from the GEMV's in its last bf16 bit, which can change a draft token but not the distribution of the target's output, since rejection sampling verifies every draft token. test_dspark_draft_model_samples_with_fused_markov now runs fused_markov's gate with stub kernels: with --monokernel the fused launches take a 5-row step on gfx950 and an 8-row step on gfx942, and vLLM's loop takes a 6-row step on gfx950 and any step without the flag. The gfx942 kernel test clears the new gate's cache with the old one's. Signed-off-by: Oxana Korzh <okorzh@amd.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…m-project#63885) Signed-off-by: Oxana Korzh <okorzh@amd.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Carl Persson <carl.persson@amd.com> Co-authored-by: vllm-agent <claw@inferact.ai> Signed-off-by: Dao Le <Dao007forever@gmail.com>
…h --monokernel With --monokernel on gfx942, ops/fused_markov.py (vllm-project#60731) samples each DSpark draft position in one launch (k + 1 launches a decode step) instead of vLLM's loop of about 9 kernels a position: the Markov embedding, the 66 MB markov_w2 GEMV, the add, the Gumbel sample with its argmax and gather, and the draft_tokens copy. vllm-project#60731 gated it with the other gfx942 helpers on ops.enabled(), so gfx950 still runs the loop. The kernel is plain Triton with vLLM's own Gumbel helpers and nothing gfx942-specific. fused_markov now runs under ops.fused_markov_enabled(), --monokernel on CDNA3 (gfx942) or CDNA4 (gfx950). It shares one cached check with swa_decode_meta_enabled() (vllm-project#63885); the other helpers keep ops.enabled(). On gfx950 it takes steps of at most 5 rows (MAX_ROWS_GFX950): from 6 rows on, vLLM's loop is faster there, because its Markov GEMV leaves wvSplitK. Both archs launch the step kernel at 4 warps, which on gfx950 is as fast as 8 at 1-2 rows and faster at 3-5. As on gfx942, a bias value may differ from the GEMV's in its last bf16 bit, which can change a draft token but not the distribution of the target's output, since rejection sampling verifies every draft token. test_dspark_draft_model_samples_with_fused_markov now runs fused_markov's gate with stub kernels: with --monokernel the fused launches take a 5-row step on gfx950 and an 8-row step on gfx942, and vLLM's loop takes a 6-row step on gfx950 and any step without the flag. The gfx942 kernel test clears the new gate's cache with the old one's. Signed-off-by: Oxana Korzh <okorzh@amd.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h --monokernel With --monokernel on gfx942, ops/fused_markov.py (vllm-project#60731) samples each DSpark draft position in one launch (k + 1 launches a decode step) instead of vLLM's loop of about 9 kernels a position: the Markov embedding, the 66 MB markov_w2 GEMV, the add, the Gumbel sample with its argmax and gather, and the draft_tokens copy. vllm-project#60731 gated it with the other gfx942 helpers on ops.enabled(), so gfx950 still runs the loop. The kernel is plain Triton with vLLM's own Gumbel helpers and nothing gfx942-specific. fused_markov now runs under ops.fused_markov_enabled(), --monokernel on CDNA3 (gfx942) or CDNA4 (gfx950). It shares one cached check with swa_decode_meta_enabled() (vllm-project#63885); the other helpers keep ops.enabled(). On gfx950 it takes steps of at most 5 rows (MAX_ROWS_GFX950): from 6 rows on, vLLM's loop is faster there, because its Markov GEMV leaves wvSplitK. Both archs launch the step kernel at 4 warps, which on gfx950 is as fast as 8 at 1-2 rows and faster at 3-5. As on gfx942, a bias value may differ from the GEMV's in its last bf16 bit, which can change a draft token but not the distribution of the target's output, since rejection sampling verifies every draft token. test_dspark_draft_model_samples_with_fused_markov now runs fused_markov's gate with stub kernels: with --monokernel the fused launches take a 5-row step on gfx950 and an 8-row step on gfx942, and vLLM's loop takes a 6-row step on gfx950 and any step without the flag. The gfx942 kernel test clears the new gate's cache with the old one's. Signed-off-by: Oxana Korzh <okorzh@amd.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h --monokernel With --monokernel on gfx942, ops/fused_markov.py (vllm-project#60731) samples each DSpark draft position in one launch (k + 1 launches a decode step) instead of vLLM's loop of about 9 kernels a position: the Markov embedding, the 66 MB markov_w2 GEMV, the add, the Gumbel sample with its argmax and gather, and the draft_tokens copy. vllm-project#60731 gated it with the other gfx942 helpers on ops.enabled(), so gfx950 still runs the loop. The kernel is plain Triton with vLLM's own Gumbel helpers and nothing gfx942-specific. fused_markov now runs under ops.fused_markov_enabled(), --monokernel on CDNA3 (gfx942) or CDNA4 (gfx950). It shares one cached check with swa_decode_meta_enabled() (vllm-project#63885); the other helpers keep ops.enabled(). On gfx950 it takes steps of at most 5 rows (MAX_ROWS_GFX950): from 6 rows on, vLLM's loop is faster there, because its Markov GEMV leaves wvSplitK. Both archs launch the step kernel at 4 warps, which on gfx950 is as fast as 8 at 1-2 rows and faster at 3-5. As on gfx942, a bias value may differ from the GEMV's in its last bf16 bit, which can change a draft token but not the distribution of the target's output, since rejection sampling verifies every draft token. test_dspark_draft_model_samples_with_fused_markov now runs fused_markov's gate with stub kernels: with --monokernel the fused launches take a 5-row step on gfx950 and an 8-row step on gfx942, and vLLM's loop takes a 6-row step on gfx950 and any step without the flag. The gfx942 kernel test clears the new gate's cache with the old one's. Signed-off-by: Oxana Korzh <okorzh@amd.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h --monokernel With --monokernel on gfx942, ops/fused_markov.py (vllm-project#60731) samples each DSpark draft position in one launch (k + 1 launches a decode step) instead of vLLM's loop of about 9 kernels a position: the Markov embedding, the 66 MB markov_w2 GEMV, the add, the Gumbel sample with its argmax and gather, and the draft_tokens copy. vllm-project#60731 gated it with the other gfx942 helpers on ops.enabled(), so gfx950 still runs the loop. The kernel is plain Triton with vLLM's own Gumbel helpers and nothing gfx942-specific. fused_markov now runs under ops.fused_markov_enabled(), --monokernel on CDNA3 (gfx942) or CDNA4 (gfx950). It shares one cached check with swa_decode_meta_enabled() (vllm-project#63885); the other helpers keep ops.enabled(). On gfx950 it takes steps of at most 5 rows (MAX_ROWS_GFX950): from 6 rows on, vLLM's loop is faster there, because its Markov GEMV leaves wvSplitK. Both archs launch the step kernel at 4 warps, which on gfx950 is as fast as 8 at 1-2 rows and faster at 3-5. As on gfx942, a bias value may differ from the GEMV's in its last bf16 bit, which can change a draft token but not the distribution of the target's output, since rejection sampling verifies every draft token. test_dspark_draft_model_samples_with_fused_markov now runs fused_markov's gate with stub kernels: with --monokernel the fused launches take a 5-row step on gfx950 and an 8-row step on gfx942, and vLLM's loop takes a 6-row step on gfx950 and any step without the flag. The gfx942 kernel test clears the new gate's cache with the old one's. Signed-off-by: Oxana Korzh <okorzh@amd.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h --monokernel With --monokernel on gfx942, ops/fused_markov.py (vllm-project#60731) samples each DSpark draft position in one launch (k + 1 launches a decode step) instead of vLLM's loop of about 9 kernels a position: the Markov embedding, the 66 MB markov_w2 GEMV, the add, the Gumbel sample with its argmax and gather, and the draft_tokens copy. vllm-project#60731 gated it with the other gfx942 helpers on ops.enabled(), so gfx950 still runs the loop. The kernel is plain Triton with vLLM's own Gumbel helpers and nothing gfx942-specific. fused_markov now runs under ops.fused_markov_enabled(), --monokernel on CDNA3 (gfx942) or CDNA4 (gfx950). It shares one cached check with swa_decode_meta_enabled() (vllm-project#63885); the other helpers keep ops.enabled(). On gfx950 it takes steps of at most 5 rows (MAX_ROWS_GFX950): from 6 rows on, vLLM's loop is faster there, because its Markov GEMV leaves wvSplitK. Both archs launch the step kernel at 4 warps, which on gfx950 is as fast as 8 at 1-2 rows and faster at 3-5. As on gfx942, a bias value may differ from the GEMV's in its last bf16 bit, which can change a draft token but not the distribution of the target's output, since rejection sampling verifies every draft token. test_dspark_draft_model_samples_with_fused_markov now runs fused_markov's gate with stub kernels: with --monokernel the fused launches take a 5-row step on gfx950 and an 8-row step on gfx942, and vLLM's loop takes a 6-row step on gfx950 and any step without the flag. The gfx942 kernel test clears the new gate's cache with the old one's. Signed-off-by: Oxana Korzh <okorzh@amd.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…h --monokernel With --monokernel on gfx942, ops/fused_markov.py (vllm-project#60731) samples each DSpark draft position in one launch (k + 1 launches a decode step) instead of vLLM's loop of about 9 kernels a position: the Markov embedding, the 66 MB markov_w2 GEMV, the add, the Gumbel sample with its argmax and gather, and the draft_tokens copy. vllm-project#60731 gated it with the other gfx942 helpers on ops.enabled(), so gfx950 still runs the loop. The kernel is plain Triton with vLLM's own Gumbel helpers and nothing gfx942-specific. fused_markov now runs under ops.monokernel_cdna3_or_4(), --monokernel on CDNA3 (gfx942) or CDNA4 (gfx950), the check that swa_decode_meta (vllm-project#63885) now uses too, in place of swa_decode_meta_enabled(); the other helpers keep ops.enabled(). On gfx950 it takes steps of at most 5 rows (MAX_ROWS_GFX950): from 6 rows on, vLLM's loop is faster there, because its Markov GEMV leaves wvSplitK. Both archs launch the step kernel at 4 warps, which on gfx950 is as fast as 8 at 1-2 rows and faster at 3-5. As on gfx942, a bias value may differ from the GEMV's in its last bf16 bit, which can change a draft token but not the distribution of the target's output, since rejection sampling verifies every draft token. test_dspark_draft_model_samples_with_fused_markov now runs fused_markov's gate with stub kernels: with --monokernel the fused launches take a 5-row step on gfx950 and an 8-row step on gfx942, and vLLM's loop takes a 6-row step on gfx950 and any step without the flag. The gfx942 kernel test clears the new check's cache with the old one's. Signed-off-by: Oxana Korzh <okorzh@amd.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Overview
With
--monokernelon gfx950 (MI355X), DeepSeek-V4.1 decode batches of up to 32 rows now build their SWA metadata withswa_decode_meta's single Triton launch (#60731). Before, they took vLLM's 8 launches per SWA group. #60731 enabled the kernel only on gfx942, but the kernel has no arch-specific code. This PR converges with #63994: it takes #63994's gate,swa_decode_meta_enabled()(on_gfx942() or on_gfx950()), and adds the gate test, the MI355 CI step and the GPU validation below.Claims
--monokernel, DSpark k=6 (synthetic AL 3.87, AV off), 32k in / 1k out, onmainnightly 5d35ce3.cache_saltis 3.577 in both arms.--monokernel, other arches, and prefill, mixed or >32-row batches. The gate test covers arch x flag; the row and prefill guards are [ROCm][Perf][DSv4.1] Mono decode on MI300X and MI325X (gfx942) #60731's and untouched. There is no new flag.Validation
Tests (MI355X, gfx950)
tests/kernels/models/amd/test_dsv41_gfx942_decode_meta.py: kernel vs vLLM's ops, 300 random batches per case-k swa_decode_meta: 2 passed; whole file: 3 passedtests/models/test_dsv41_mono_decode.py, with the new gate test (arch x--monokernel)[gfx950-True]assert [] == [False]-k swa_decode_meta) is added to:amd: (MI355) DeepSeek-V4.1 Mono Decode Numerics. Until now CI ran it only in the MI300 (gfx942) kernels step.(MI355) Basic Models (Other)mirror. It stubslaunchand the platform, so no CI job runsbuild()with the real kernel on gfx950. The trace and the GSM8K runs below cover that path outside CI.on_mi3xx()in place of the arch check, gfx942 only, any ROCm arch, no--monokernelcheck, nocache_clear(), andbuild()back onenabled().main.Performance. DeepSeek-V4.1-Flash on MI355X, one TP4 server per half of the node. The servers run
--monokernelwith DSpark k=6, synthetic AL 3.87 and AV off. The workload is random 32k in / 1k out,--ignore-eos, 32 prompts per run, 3 runs per point on the same server. The decode step is ITL p50.vllm/vllm-openai-rocm:nightly-rocm100-5d35ce3934a7804b298559d2d99eec33792e1eb9. That is the PR base, which already has [Bugfix][ROCm][DSv4.1] Await krdy before K2's combine reads klen in index-source launches #63576, plus 23 commits.on_mi3xx()foron_gfx942() or on_gfx950(), which give the same value on gfx942 and gfx950 (_ON_MI3XXis exactly those two arches). The tests above ran on the second commit.Launch counts. These come from a torch-profiler trace of each arm: rank 0, c1, 133 decode steps each. The SWA-build kernel counts are the same on every step. The total, fill and copy counts below are the per-step mode; a few steps add the same extra launches in both arms. The PR is 49 launches lower on every step.
_compute_swa_indices_and_lens_kernel(target) and the draft's non-causal index kerneltorch.ge(compare_scalar_kernel<long>) /FillFunctor<int>_count_valid_row_entries_kernel/ rocprim scan /_compact_dense_row_to_ragged_kernel__amd_rocclr_copyBuffer_decode_swa_meta_kernel_token_request_mapping_kernel(control)_decode_swa_meta_kernel.Accuracy and AL (AV off unless noted). GSM8K-1319 is 8-shot at temperature 0, over
/v1/completions. AL is real block-rejection acceptance, read from/metrics.cache_salt(nothing cached). 8 runs per arm: 6 at 8 parallel, 2 at 4 parallel.cache_salt, so a text-identity check was not possible.--monokernel, mono consumes only the dense indices and lengths.indptrandis_valid_token.Sync check. One TP4 server per arm ran with
VLLM_GPU_SYNC_CHECK=error, which polices the worker'sexecute_modelandsample_tokensafter warmup. Each served c1 and c2 (8 requests each, 512 out), 300 GSM8K questions at 4 parallel requests, and 4 greedy probes. Neither arm reported a sync, logged an error or failed a request.Reproduction commands
Details
Change.
ops.swa_decode_meta_enabled(), the gate from #63994, returns true with--monokernelon ROCm whenon_gfx942()oron_gfx950()holds. Onlyswa_decode_meta.builduses it. The other gfx942 helpers keepops.enabled(). On gfx942 the two gates agree.Limits.
--monokerneldeployments now take this path. The AV-on round served without errors and matched base on accuracy and AL.Related PRs.
swa_decode_meta_enabled()gate, with Carl Persson as co-author of that commit. It adds the gate test, the MI355 CI step ([ROCm][Perf][DSv4.1] One-launch decode SWA metadata on gfx950 #63994 used the optionaltest-amd.yamlstep) and the GPU validation. [ROCm][Perf][DSv4.1] One-launch decode SWA metadata on gfx950 #63994 can be closed.models_basic.yaml,ops/__init__.py,rocm.pyandtest_dsv41_mono_decode.py.KernelConfig.monokernelandrecord_monokerneltospecialized_decode, and replacestest_dsv41_mono_decode.pywithtest_dsv41_specialized_decode.py._monokernelinswa_decode_meta_enabled()and move the gate test.test_dsv41_mono_decode.py. If it lands first, I drop themodels_basic.yamlhunk and move the gate test.--monokernel. It adds its ownmi3xx_enabled()onon_mi3xx(), and the same review applies to it. Both PRs touch the samemodels_basic.yamlstep and theops/__init__.pydocstring; the second to land merges those hunks.Why the metadata is the same, and who reads it
_decode_swa_meta_kernelis integer Triton with no arch intrinsics.[0, n)it writesis_valid_tokenand the dense window indices and lengths. It sets the lengths from rownto the end of the buffer to 0. It writesindptr[:n+1]and the ragged indices up toindptr[n].torch.ge, the length fill,_compute_swa_indices_and_lens_kernel(orComputeDSparkNoncausalSWAIndicesKernelfor the draft block),build_ragged_indices_from_denseand_copy_ragged_to_graph_buffersproduce.build()returns views of the same persistent buffers, with the same lengths: ragged[:max(n*width, 1)]andindptr[:n+1].--monokernel, every target and DSpark-draft layer runs mono on decode-only steps of 48 rows or fewer that replay a FULL graph or run eagerly. Mono reads only the dense indices and lengths,slot_mappingandtoken_to_req.VLLM_ROCM_USE_AITER_TRITON_SPARSE_MLA) reads the ragged indices betweenindptr[t]andindptr[t+1]. It sizes its splits from the ragged view'snumel(), which isn*widthon both paths.is_valid_tokenon compressed layers.indptr[n]. vLLM's build copies them from atorch.emptytensor; the kernel leaves the previous contents. No reader reads pastindptr.mainbut not in the measured image. It fuses inverse RoPE and the MXFP8 quant into the aiter sparse-MLA output, and does not change the index views that call reads. So this argument holds on currentmain.An AL caveat for anyone reproducing (affects
main, not this PR)On 4 of the 10 AV-off servers, AL fell from about 3.58 to 3.42-3.45 on GSM8K passes that repeated the same prompts. Those passes had about 96% prefix-cache hits, against about 89% on a first pass. The 4 servers were 2 base and 2 PR; one of the PR servers had mono forced off.
cache_salt, those passes stayed at 3.58.Compare AL on first or salted passes only. I will look into the drop separately.
Pull Request Checklist
I used vLLM's
/pr-checklistskill. (Mandatory for agents, optional for humans).AI assistance was used during the creation of this PR.
Design Fit: Minimizes impact on core components, reuses existing functionality, and justifies added complexity.
Testing and Validation: Validates the change and ensures any added tests are meaningful and reliable, with CI coverage or documented CI resource constraints and validation performed outside CI.
Code Quality and Style: Keeps code and comments clear and concise, and updates relevant documentation and examples.
Pull Request Contents: Includes a brief summary and relevant links, supports claims with evidence, explains root causes and implementation trade-offs, and follows the contributing guide.