Skip to content

[Triton/Gluon] [HIP] [CK] Read (B, next_n) context lengths in the paged MQA logits kernels - #9

Closed
amd-sriram wants to merge 11 commits into
mainfrom
rocm/paged-mqa-logits-2d-context-lens
Closed

amd-sriram wants to merge 11 commits into
mainfrom
rocm/paged-mqa-logits-2d-context-lens

Conversation

@amd-sriram

@amd-sriram amd-sriram commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

Motivation

vLLM's sparse indexer now builds context lengths as a 2D (B, next_n) per-row table for every caller ((B, 1) without MTP), the layout DeepGEMM's fp8_paged_mqa_logits takes. The AITER paged MQA-logits kernels read one length per sequence (load(context_len_ptr + pid_batch)) and rebuild the per-row bound themselves. With MTP on, the 2D table therefore gives the kernels the wrong lengths: silently for Gluon/Triton, and as a reshape error for FlyDSL.

vllm-project/vllm#59420 works around it on the vLLM side by copying the last column into a 1D tensor before each call. This makes the kernels read the 2D table directly, so vLLM can pass it as-is and nothing is copied.

Technical details

  • Each kernel reads sequence b's length at b * ContextLenStride + ContextLenStride - 1: element b of [B] (stride 1, today's code), or the last entry of row b of a contiguous (B, n) table (stride n). The per-row causal bound is still rebuilt from that length, unchanged.
  • Gluon (_gluon_deepgemm_fp8_paged_mqa_logits, _preshuffle, _preshuffle_varctx) and Triton (_deepgemm_fp8_paged_mqa_logits, _stage1, _varctx_schedule): new ContextLenStride constexpr, default 1, so the [B] path compiles to the same code as before.
  • FlyDSL flydsl_fp8_paged_mqa_logits: new runtime ctx_stride kernel argument. A [B, n] table must be contiguous. A strided [B] is now made contiguous: before, reshape(batch_size) kept the strided view and the kernel read it as dense.
  • Wrappers derive the stride from the tensor (_context_len_stride); a 2D table must be contiguous.
  • AOT Gluon (Triton < 3.4): a stride other than 1 adds _S<n> to the kernel name, so a missing prebuilt binary fails loudly instead of running the 1D one.
  • The ragged-K variants take prefix_sum_context_lens and are unchanged.
  • Contract: the per-row table is the standard one, row j of a sequence of length L seeing L - next_n + 1 + j tokens, which is what vLLM builds.

Test Plan

  • New test_paged_mqa_logits_2d_context_lens in op_tests/test_pa_mqa_logits_offset.py: for Gluon plain, Gluon preshuffle and FlyDSL (gfx950), a (B, next_n) table must give exactly the logits of the per-sequence lengths. Mixed lengths (3000, 257, 64, 3), next_n=3, KVBlockSize 64.
  • Full op_tests/test_pa_mqa_logits_offset.py, 10 times.
  • Kernel time, 1D vs 2D, cold cache (run_perftest rotates inputs), GLM-5 indexer shape, 8k context.
  • Stage1 and the varctx schedule: 2D vs 1D over 100 repeated calls.

Test Result

MI355X, AITER 48b1365 with this change applied (the touched files are identical to main), Triton 3.8, FlyDSL 0.3.4.1:

  • FlyDSL [B] input: a strided tensor now gives the same logits as a contiguous one; (B, 1) matches [B].
  • Without the change the new test fails for every entry point. With it: test_pa_mqa_logits_offset.py 108/108, 10/10 runs.
  • Raw 2D table vs per-sequence lengths, varied lengths, B=16, next_n=3: bit-identical for Gluon and FlyDSL. Stage1 and varctx: 100/100 calls identical.
  • No copy and no measurable cost:
path B next_n 1D us 2D us delta
Gluon preshuffle 16 3 10.02 10.01 -0.1%
Gluon preshuffle 128 3 47.61 47.42 -0.4%
Gluon preshuffle 16 5 14.49 14.47 -0.1%
Gluon preshuffle 128 5 70.50 70.00 -0.7%
FlyDSL 16 3 14.96 15.10 +0.9%
FlyDSL 128 3 45.33 45.24 -0.2%
FlyDSL 16 5 19.22 19.50 +1.5%
FlyDSL 128 5 60.06 60.52 +0.8%
  • Not tested: the AOT Gluon path (needs Triton < 3.4).

Found while testing (not changed here)

With the new test's inputs, two paths are not reproducible run to run even with 1D lengths, so the test leaves them out:

  • deepgemm_fp8_paged_mqa_logits_stage1: 11/11 repeated calls with identical inputs gave a different -inf mask from the first, on rows 1 and 3, columns 0..71.
  • Gluon preshuffle with VarCtxSchedule: up to 5/200 repeated call pairs differ (the schedule value itself is stable at 1).

Neither is on the vLLM gfx942/gfx950 decode path. Worth a separate issue.

Gluon, Triton stage1/schedule and FlyDSL wrappers take the last column of a 2D table, the layout DeepGEMM takes and vLLM passes.

Signed-off-by: Sriram Kumar <sriramkumar.kishorekumar@amd.com>
@coderabbitai

coderabbitai Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: f82d757f-364f-4366-b17e-ebc8a181c2d0
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Oct 4, 2026

Copy link
Copy Markdown

🏷️ CI Guide

Runs automatically on every PR:

  • ✅ Pre-checks (submodule verification, code formatting)
  • ✅ Aiter op tests (gfx942 + gfx950)
  • ✅ Triton tests on MI35X (only when aiter/ops/triton/** or related paths are changed)

Extended tests (opt-in via labels):

Label Tests
ci:gfx1250-ffm-triton Run the five-shard gfx1250 FFM Triton test suite
ci:triton-300x Run an additional Triton test job on MI300X in PRs (added automatically when gfx942 configs change); main branch always runs both MI35X and MI300X
ci:triton-355 Run the full Triton test suite on MI35X, not only the tests the change affects
multigpu Aiter multi-GPU tests on the 8-GPU runner
ci:sglang SGLang integration tests: DeepSeek-R1-MXFP4 accuracy, Qwen 3.5 accuracy
ci:atom ATOM benchmark: DeepSeek-R1-0528, GPT-OSS-120B
ci:atom_full ATOM accuracy suite for PR and main models from ATOM models_accuracy.json
ci:vllm vLLM benchmark: GPT-OSS-120B, DeepSeek-R1-0528, Kimi-K2.5
ci:all All standard extended tests (excludes ci:atom_full)

Only add ci:atom_full for FlyDSL or Triton upgrades.
Add labels via the sidebar or gh pr edit 9 --add-label <label>

One backend per PR:
A PR changes one kernel backend: [Triton/Gluon] (Triton and Gluon count as one), [HIP], [ASM], [CK], [OPUS] or [FlyDSL]. If the title ends up with two backend tags, split the PR -- as stacked pull requests when one part cannot merge without the other.

PR title tags & labels:
Component tags ([Triton/Gluon], [HIP], [CK], [ASM], ...) are added to the PR title and as PR labels automatically from the changed files and re-synced on every push — change-type tags like [fix]/[Perf], op tags like [MLA], and human labels (ci:*) are left untouched. Add the no-auto-title label to stop the title rewrites; labels stay in sync either way.

@github-actions github-actions Bot changed the title [Triton][FlyDSL] Accept (B, next_n) context lengths in paged MQA logits [Triton/Gluon] [FlyDSL] Accept (B, next_n) context lengths in paged MQA logits Oct 4, 2026
@amd-sriram amd-sriram self-assigned this Oct 4, 2026
…copy

Replaces the wrapper-side slice with a ContextLenStride the Gluon, Triton and FlyDSL kernels index with.

Signed-off-by: Sriram Kumar <sriramkumar.kishorekumar@amd.com>
@amd-sriram amd-sriram changed the title [Triton/Gluon] [FlyDSL] Accept (B, next_n) context lengths in paged MQA logits [Triton][FlyDSL] Read (B, next_n) context lengths in the paged MQA logits kernels Oct 4, 2026
yhl-amd and others added 6 commits October 5, 2026 19:52
…cast race fix (ROCm#6127)

* perf(mega): MegaMoEV2 opt-in combine masking and tuning hooks

- combine_no_stage1 can take the top-k ids and skip slots whose id is -1.
  Those slots are never dispatched, so their partial is whatever an earlier
  call left in the shared combine buffer. MegaMoEV2.forward(
  mask_invalid_slots=True) enables it for callers that pad with -1 ids (DP pad
  rows come back as exact zeros, partially masked rows are correct);
  supports_combine_mask advertises the argument. The id check costs ~1 us per
  decode layer but 9-12% of a prefill layer (8 x MI355X, compact MTPR 16384:
  1550 -> 1683 us at 2048 tokens/rank, 4678 -> 5248 at 8192), so it is off
  by default (AITER_MEGA_COMBINE_MASK=1 turns it on for every call).
- AITER_MEGA_CFG_OVERRIDE: per-path/per-bucket Stage1/Stage2 config overrides
  (JSON) for tuning, e.g. persistent Stage2 for the fixed-slot buckets 1..64
  (the default launches ~86k mostly empty CTAs; -10..-12 us/layer at 7..28
  tokens/rank).
- AITER_MEGA_FIXED_SLOT_MAX_MTPR=511 admits a fixed-slot MTPR-256 instance
  (224 tokens/rank: 436 us/layer vs 589 on the 16384 compact path, with a
  BF16 instead of FP8 combine wire).
- AITER_MEGA_S1_LAUNCH_HANDSHAKE=0 drops the fixed-slot LAUNCH_READY round
  trip, which the combine barrier already orders when every Stage1 is followed
  by Stage2 + combine_no_stage1 (-1..-2 us/layer).
- AITER_MEGA_COMBINE_GEOM: combine launch geometry by token count (tuning
  knob; without masking the tuning table is within 0.5% of the best measured).
- AITER_MEGA_TRACE=1: per-CTA s_memrealtime timeline of prepare, Stage1,
  Stage2 and combine (debug aid).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* fix(mega): key the single-variant Stage1 launcher on its kernel; lighter fixed-slot sync knobs

- compile_mega_moe_stage1()'s launch() closed over a _Stage1KernelSpec object,
  which FlyDSL's JIT cache key does not inspect, so every Stage1 config shared
  one key and a cached launcher of another config could be reused. The
  launcher now captures the kernel's own cache key and launch geometry.
- AITER_MEGA_S1_OWNER_LIGHT=1: the fixed-slot owner publishes its counter
  resets with one agent release and a relaxed gate store instead of two agent
  releases plus a system-scope release store (each writes back L2).
- AITER_MEGA_S1_PRODUCER_FENCE=0: fixed-slot producers rely on store
  acknowledgement and only the last producer of a group issues the system
  release before COUNT_DONE.
  Both are correct (8 x MI355X, pad rows exactly 0) but worth only ~1 us per
  layer (T=56: 331.9 -> 331.3 us), so they stay off by default.
- AITER_MEGA_TRACE also records the owner's reset phase and each producer's
  atomic/copy completion.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* perf(mega): 8-column GEMM1 quant epilogue; Stage2 scatter width knob

SiluQuantEpilogue's store pass handled 2 columns per lane: a 16-lane
shuffle-max per pair of values and one 16-bit store. With 8 columns per lane a
1x32 group spans 4 lanes (2 shuffles) and each lane stores its 8 FP8 values
at once; scales and rounding are unchanged (outputs bit-identical). 8 x MI355X
compact MTPR 16384: 1550 -> 1535 us/layer at 2048 tokens/rank, 2473 -> 2436 at
4096, 4685 -> 4623 at 8192; decode unchanged. AITER_MEGA_S1_EPI_EVEC=2 restores
the old pass.

AITER_MEGA_S2_SCATTER_VEC (8 default, or 16) sets the values per lane in the
Stage2 peer scatter; 16 measured neutral at prefill.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* perf(mega): opt-in Stage1/Stage2 experiment knobs (all default off)

AITER_MEGA_DISPATCH_FAST_COPY (compact producers keep two rows in flight),
AITER_MEGA_S2_FAST_FP8 (DPP group max, one packed scale store per row),
AITER_MEGA_S2_STATIC_K (fully unrolled GEMM2 K loop) and AITER_MEGA_S2_WPE
(Stage2 waves-per-EU hint). Only the fast copy paid off (next commit turns it
on); the others measured neutral or slower and stay off.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* perf(mega): compact dispatch fast copy on by default

Producers read two route ids back to back and keep both rows' loads in flight.
Prefill -0.5..-1.2% per layer (4096: 2436->2423 us, 8192: 4623->4577 us); decode (fixed-slot) unaffected.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* perf(mega): persistent Stage2 (128 CTAs) for fixed-slot buckets below 128

The non-persistent grid is sized for the MTPR capacity; its idle CTAs delay the
real tiles. T=7/14/28: -10..-11 us/layer, T=56 -1; --check PASS.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* perf(mega): paired K loop + LDS-DMA A for small fixed-slot GEMM1 buckets

The rolled GEMM1 K loop copied the prefetched B tile into loop-carried
registers, which forced a vmcnt drain of the prefetch every K step; with
register A copies the A load was also waited for in the same step. Fixed-slot
tiles with async A now run the K loop two steps per iteration (ping-pong B
registers; VGPR 138/174), and buckets <= 8 use async A. T=3 -11, T=7 -2
us/layer; 14..112 and compact prefill unchanged; --check PASS.
AITER_MEGA_S1_UNROLL_K (0/1/2) stays as an experiment override.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* fix(mega): Stage1 block broadcasts get dedicated LDS slots

The consumer loop broadcast first_work, then scheduled_first (ready-order
path), through pool[0], which the A-tile LDS DMA and the GEMM1 C tile also
overwrite. A wave that had not yet read the broadcast value then read the next
value or A bytes as its tile index and loaded W13 from a garbage expert
(memory access fault). Needed skewed routing (ready-order scheduling: DSV4 hash
layers on identical warmup tokens) plus a timing shift; the 8-column epilogue
made it reliable in ATOM warmup. first_work, scheduled_first and the
fixed-slot ticket now use their own LDS slots (+48 B, occupancy unchanged).
Also bound the 8-column epilogue's full-output view like the 2-column path.
Same-expert routing: 150 back-to-back calls x 4 sizes clean; prefill 2048/4096/
8192 1534/2415/4512 us, decode MTPR 256 --check PASS.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* perf(mega): non-temporal W2 loads for the fixed-slot 256 bucket

C128 decode graphs are DP-padded to 224 rows/rank with ~84 real: Stage2 with
use_nt -14 us/layer (364 -> 350); fully real 224 rows -2 us; 160/56 unchanged;
--check PASS. persist_cu (64..256) made no difference.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* style(mega): black the MegaMoE files this series touches

Formatting only; the pre-checks black job flags them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* test(mega): check whole -1 rows under mask_invalid_slots; fixed-slot to MTPR 1024

test_mega_moe_v2.py --pad-tail-rows N routes each rank's last N rows to -1
after the unmasked passes (so the combine input still holds their values) and
checks that forward(mask_invalid_slots=True) returns those rows as exact
zeros, keeps the real rows within rtol of the reference, and replays the same
output from a CUDA graph. This is the shape ATOM's DP pad-row mask produces.

Note in mega_moe_config that AITER_MEGA_FIXED_SLOT_MAX_MTPR=1023 / 2047 extends
fixed-slot to the 512 / 1024-token capacities: on EP8 v4_pro, bs 1..1024,
uniform and skewed per-rank counts, and with -1 tail rows, the fixed-slot
output matches the reference with the same relL2 as the compact path, and CUDA
graph replay is exact.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* style(mega): satisfy ruff on the MegaMoE files this series touches

Sort the trace imports, merge the two persist_cu=128 arms, and mark the
nested `if const_expr(TRACE_BASE)` / runtime-`if` guards `noqa: SIM102` as
elsewhere in the FlyDSL kernels: the outer test is resolved at trace time and
the inner one is a device branch, so they must stay separate statements.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* refactor(mega): drop the experiment and tuning env knobs

None of them is set by any caller, and each was measured neutral, slower or
within noise, or its finding is already the default:

- AITER_MEGA_S2_FAST_FP8, AITER_MEGA_S2_STATIC_K, AITER_MEGA_S2_WPE: neutral
  or slower; removes the DPP scale path, the unrolled GEMM2 K loop and the
  waves-per-EU hint (gemm2.py is back to main).
- AITER_MEGA_S1_UNROLL_K: the paired K loop the fixed-slot buckets use stays;
  only the env override and the fully unrolled mode it alone reached go.
- AITER_MEGA_S1_LAUNCH_HANDSHAKE, AITER_MEGA_S1_PRODUCER_FENCE,
  AITER_MEGA_S1_OWNER_LIGHT: within noise; the handshake, fences and owner
  resets are main's again (the handshake-free variant also relied on every
  Stage1 being followed by combine).
- AITER_MEGA_CFG_OVERRIDE: its finding (persistent fixed-slot Stage2) is the
  default now.
- AITER_MEGA_COMBINE_GEOM and the per-call combine geometry: the tuning table
  is already within noise of the best geometry, and the op's cfg can pin one.
- AITER_MEGA_S2_SCATTER_VEC: 16 was neutral; the scatter width is 8 again.

With the knobs unset the kernels and their cache keys are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* refactor(mega): drop the AITER_MEGA_TRACE timestamp instrumentation

The per-CTA s_memrealtime timeline was a debugging aid for tuning the
series. Remove trace.py and its hooks in prepare, Stage1, the fixed-slot
dispatch, Stage2 and the fused combine; mega_moe_prepare.py and
mega_moe_stage2.py are back to main. With tracing off (the default) the
kernels and their cache keys are unchanged.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* refactor(mega): read MegaMoEV2's environment variables from one module

mega_moe/envs.py lists every AITER_MEGA_* variable MegaMoEV2 reads, with its
default and what it does; config, Stage1, GEMM1 and MegaMoEV2 read them
through it instead of os.environ. Values are still read when accessed, so
each keeps its point of effect (import, Stage1 compile, instance build).

GEMM1's epilogue width is now a build_fused_gemm1() argument that Stage1
passes from the same read it keys the kernel on, instead of a second
os.environ read inside GEMM1.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* style(mega): trim comments, the env table and the pad-row test helpers

- Comments state the mechanism without benchmark numbers.
- envs.py names each variable once: name -> (parser, default).
- test_mega_moe_v2.py: one _rel_l2() helper for the relL2 check in
  _run_size and _check_pad_tail (which also guards an all-zero reference),
  and _check_pad_tail's rank-wide flags go through _reduce_float.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* refactor(mega): pass the combine mask ids instead of keeping them on the instance

- forward() hands the top-k ids to combine as an argument through
  _run_stage2 / _run_fused_stage2 / _run_aligned_pair_stage2. Nothing is
  kept between calls, so a direct Stage2 call no longer inherits the mask of
  the previous forward and the instance holds no reference to the caller's
  ids.
- supports_combine_mask is a class attribute.
- One loop preloads both combine variants.
- _run_combine_kernel takes the tok_map value; its signature is main's again
  apart from the new argument.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

* refactor(mega): simplify Stage1/GEMM1 plumbing and share the epilogue store helpers

- The single-variant Stage1 launcher closes over its kernel and launch ints
  instead of the opaque spec, so FlyDSL keys it itself; the hand-built
  _key_kernel / _key_geometry tuple goes.
- Stage1 knobs: FAST_COPY already folds in compact dispatch and PAIR_K is a
  bool (was k_unroll 0/2); kernel names are unchanged.
- One GEMM1 output descriptor in the epilogue's store width instead of an
  Int16 one plus out_vec_rsrc; evec is a required argument, and standalone
  compile_gemm1 states it (8 with a tile resource, else 2), replacing the
  silent override in SiluQuantEpilogue.
- The 2- and 8-column store passes share _tile_out, _row_target,
  _group_absmax and _e8m0_scale.
- emit_dispatch_payload: fast_copy is required and the two-row store is a
  _store_token helper next to _load_token.

Compile-only build of every MegaMoE AOT bundle (MTPR 128/512/1024/16384), the
single-variant Stage1 launchers and standalone GEMM1, against the previous
head: the final ISA is identical, with and without the fallback env knobs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: yihonglie <hyi@amd.com>

---------

Signed-off-by: yihonglie <hyi@amd.com>
Co-authored-by: Honglie Yi <hyi@crsuse2-m2m-v2-020.us-east2-a.compute.internal>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…block-table capacity bounds) (ROCm#5600)

The two-step addressing (pool coord -> block column + offset) that this
branch originally carried is already on main via ROCm#5749, together with
64-bit addressing, the negative-prologue clamp and the preshuffle tail
store -- so this commit drops the duplicate and keeps only the mask
hardening that ROCm#5749 does not have:

1. Prologue prefetch masks bound BOTH directions: the existing >= 0
   lower bound, plus context_length and the block-table row capacity
   (max_block_len * KVBlockSize pools) as upper bounds. ROCm#5749 only
   guards the lower bound, so a first split shorter than ChunkK can
   prefetch past the row's valid kv_indices columns.

2. In-loop prefetch masks + out-of-window lanes forced to block 0.
   ROCm#5749's in-loop buffer_load is unmasked and relies solely on the
   loop bound; with the masks, an out-of-contract context_length (which
   the wrapper does not validate) can only ever read block 0, never a
   garbage block id dereferenced into KV_buffer.

In-contract the window tops out at split_context_length, so the new
bounds never mask a valid lane; they only fire for out-of-contract
callers. This also answers the Copilot review's block_col bound finding.

Co-authored-by: beast <beast@vector4d.cn>
Signed-off-by: Sriram Kumar <sriramkumar.kishorekumar@amd.com>
@github-actions github-actions Bot changed the title [Triton][FlyDSL] Read (B, next_n) context lengths in the paged MQA logits kernels [Triton/Gluon] [FlyDSL] Read (B, next_n) context lengths in the paged MQA logits kernels Oct 5, 2026
amd-sriram and others added 3 commits October 5, 2026 19:45
Make a strided [B] contiguous, reject a 2D table that is not contiguous or has fewer than B rows.

Signed-off-by: Sriram Kumar <sriramkumar.kishorekumar@amd.com>
…weights (ROCm#6092)

* Fix Triton Conv2D/Conv3D caching for inference tensor weights

* Review 1
Simplify inference-tensor weight handling

* Update Conv2D test inventory count
@github-actions github-actions Bot changed the title [Triton/Gluon] [FlyDSL] Read (B, next_n) context lengths in the paged MQA logits kernels [Triton/Gluon] [HIP] [CK] Read (B, next_n) context lengths in the paged MQA logits kernels Oct 5, 2026
@amd-sriram amd-sriram closed this Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants