Skip to content

[PIPELINE] Support non-power-of-two TLE pipe capacities - #990

Draft
Prophet-Hongyi wants to merge 1 commit into
flagos-ai:mainfrom
Prophet-Hongyi:codex/tle-memory-descriptor-shapes
Draft

[PIPELINE] Support non-power-of-two TLE pipe capacities#990
Prophet-Hongyi wants to merge 1 commit into
flagos-ai:mainfrom
Prophet-Hongyi:codex/tle-memory-descriptor-shapes

Conversation

@Prophet-Hongyi

Copy link
Copy Markdown

Summary

Allow TLE memory-backed descriptors and pipe state to use arbitrary positive
static capacities, including 3, 5, and 6.

The failure had two independent compiler layers:

  1. buffered_tensor_type and barrier_type inherited tl.block_type, so
    memory descriptors incorrectly received Triton's register-tensor
    power-of-two shape validation.
  2. TleLowerPipeToNvws initialized all close tags through a distributed
    tensor<capacity x 1>. Even after fixing the Python type hierarchy, that
    register tensor reintroduced the same restriction during native lowering.

This change introduces a memory-descriptor base type with positive static
shape validation and initializes close tags one scalar memdesc slot at a time.
On H20, a real FlagGems FP8 einsum kernel forced to a six-stage typed pipe now
compiles and executes through the updated native library.

Review map

  1. Review memory_descriptor_type in gpu/types.py: memory-backed shape,
    element type, size, and scalar properties are separated from register
    tl.block_type validation.
  2. Review buffered_tensor_type and barrier_type: both adopt the new base;
    buffered-tensor equality also includes element type and storage, and
    with_element_ty preserves descriptor metadata.
  3. Review createPipeState in TleLowerPipeToNvws.cpp: close tags remain in
    shared memory, but initialization no longer materializes a
    tensor<capacity x 1> register value.
  4. Review the Python, GPU slot, and MLIR tests for the two regression layers.

Supported contract

Surface This PR
Descriptor shapes Non-empty static list/tuple of positive integer dimensions
New capability Non-power-of-two leading pipeline capacities, including capacity 6
Register tensors Unchanged; tl.block_type continues to reject invalid register-block shapes
Allocation space Existing SMEM/TMEM descriptor storage and layout behavior
Pipe close tags Same shared-memory state and initial false value, initialized per scalar slot
Public kernel behavior No automatic schedule or stage-count change
Fallback/compatibility Existing power-of-two capacities and register tl.block_type behavior remain unchanged

Root cause and solution

Before this change, a six-stage memory buffer was rejected because its type was
modeled as a register block:

buffered_tensor_type / barrier_type
                  -> tl.block_type
                  -> validate_block_shape
                  -> reject leading dimension 6

Changing only that Python inheritance was insufficient. Native pipe lowering
still built a distributed tensor<6x1xi32> to initialize close tags, which was
again subject to the register-block restriction.

The new representation keeps the distinction explicit:

memory-backed descriptor shape
                  -> memory_descriptor_type
                  -> memdesc<capacity x ...>
                  -> scalar local_store per close-tag slot

The register-tensor validator is preserved for actual register blocks.

Validation

Current Draft source identity:
d817794488017d8bcbfc408d8b52128ab44f6537 based on
df824d72097a31b4dca479ddfb7f480a470b7d66.

The H20 and native gates below ran on pre-rebase commit
0dfeca539a7bf57551e25d6380f51bdf8060e6ce. Before publication, the single
feature commit was replayed onto the current base and its stable patch ID
remained unchanged; the two intervening upstream commits do not touch this
PR's files. The device results are therefore patch-identical pre-rebase
evidence, not an exact-current-commit H20 rerun.

Gate Location Result What it proves
TLE Python/unit and GPU-slot tests NVIDIA H20 historical PASS — 46 passed Descriptor validation and a [6, BLOCK] SMEM slot lower and execute
test_tle_lower_pipe_to_nvws.mlir Native triton-opt historical PASS Capacity 6 lowers to memdesc<6x1>, emits six scalar stores, and does not create tensor<6x1>
Real fp8_einsum stage-6 compile/execute NVIDIA H20 historical PASS pro_b1, w4/s6/tile0 traverses both the Python and native fixes
Pre-commit hooks Local, current Draft head PASS ruff, yapf, clang-format, mypy, syntax, whitespace, and repository checks passed

The native library used by the stage-6 gate had SHA-256
8ca85dfc84da45c2198c7a8743fb2864202fb7bc97eab2c72eab298717b1deda.
The real-kernel gate selected six stages and produced finite output. It is an
expressibility/execution gate; it is not a stage-6 performance claim and does
not by itself establish full numerical equivalence for every workload.

Focused regression coverage — invariants exercised by the added tests
  • [6, 1, 64, 128] buffered descriptor construction succeeds while the
    equivalent tl.block_type construction remains rejected.
  • Zero dimensions and non-integer dimensions remain rejected.
  • Buffered-descriptor equality distinguishes dtype and storage space.
  • A capacity-6 barrier descriptor reports shape (6, 1) and is not a block.
  • A GPU kernel indexes slot 5 of [6, 64] SMEM, stores, reloads, and returns
    exact integer values.
  • The MLIR regression checks six ttg.local_store operations and
    nvws.create_token with numBuffers = 6.

Performance evidence

Baseline: current upstream rejects the tested capacity-6 descriptor or
pipe before the real kernel can run.

Evidence boundary: this is a compiler correctness and expressibility PR.
No latency in ms or throughput improvement is claimed; the performance-relevant result is that a
previously unavailable six-stage schedule becomes compilable for later,
independent tuning.

Files changed

  • python/triton/experimental/tle/language/gpu/types.py
    — memory-descriptor type hierarchy and equality.
  • python/test/tle/unit/test_tle.py
    — shape, validation, equality, and barrier unit tests.
  • python/test/tle/unit/test_tle_gpu_slot.py
    — H20 non-power-of-two SMEM slot execution test.
  • third_party/tle/dialect/lib/Transforms/TleLowerPipeToNvws.cpp
    — scalar close-tag slot initialization.
  • third_party/tle/test/GPU/test_tle_lower_pipe_to_nvws.mlir
    — native capacity-6 lowering regression.

Known limits

  • This PR makes non-power-of-two capacities expressible; it does not claim that
    capacity 6 is optimal for any kernel or add it to an autotuning space.
  • The full TLE suite and product-wide benchmarks were not run. Validation is
    focused on the affected type, slot, pipe-lowering, and real-kernel paths.
  • Schedule selection and any FlagGems stage-6 enablement belong in separate
    changes with their own correctness and performance evidence.

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.

1 participant