Skip to content

fix: support composite shape dims in function parameter types#1765

Open
YunjiQin wants to merge 5 commits into
hw-native-sys:mainfrom
YunjiQin:composite-shape-param-ut
Open

fix: support composite shape dims in function parameter types#1765
YunjiQin wants to merge 5 commits into
hw-native-sys:mainfrom
YunjiQin:composite-shape-param-ut

Conversation

@YunjiQin

Copy link
Copy Markdown
Contributor

Summary

A function parameter whose tensor shape carries a composite dim — e.g.
pl.Tensor[[M * 2, N], pl.FP32] where M is a pl.dynamic var, so the dim
is a Mul(Var, ConstInt) expression rather than a bare Var — failed to
compile. Two independent bugs were on the critical path:

  • SSA verifier registered dynamic shape vars from parameter/return
    TensorType shapes by matching bare Var dims only, so the inner M of a
    composite dim was never registered. Any reference to it — including the
    verifier walking the parameter type itself — reported "used outside its defining scope". Fixed by recursively collecting every Var leaf through
    BinaryExpr/UnaryExpr shape expressions.

  • PTO codegen flushed the function's constants section before rendering the
    tensor-view/alloc prologue, so a constant that appears only inside a shape
    expression (the 2 in M * 2) was declared after the section was written
    out — leaving the emitted arith.muli referencing an undeclared
    %c2_index (invalid MLIR). Fixed by rendering the prologue into a buffer
    before finalizing the constants section.

Docs (en + zh-cn) updated to describe the constant-ordering behavior for
composite shape dims.

Testing

  • UT: TestCompositeShapeDimVerification (verifier) and
    test_add_kernel_composite_dim_constant_declared (codegen) — confirmed to
    fail before the fixes, pass after.
  • ST on real NPU via task-submit: single-device
    (tests/st/runtime/control_flow/test_composite_shape_dim.py) and 2-device L3
    distributed (tests/st/distributed/test_l3_composite_shape_dim.py), both
    executing a composite-dim kernel end-to-end with correct output.
  • Full UT suites for the verifier, dynamic-shape codegen, and distributed
    codegen pass.

YunjiQin added 5 commits June 12, 2026 15:50
The SSA verifier registered dynamic shape variables from parameter and
return TensorType shapes by matching bare Var dims only. A composite dim
such as M * 2 is a BinaryExpr, so its inner Var was never registered and
any reference to it — including the verifier walking the parameter type
itself — reported 'used outside its defining scope'.

Collect every Var leaf recursively through BinaryExpr/UnaryExpr trees so
composite shape dims in parameter and return types verify cleanly.

Add regression tests covering a bare-var baseline, a composite parameter
dim, and a composite dim whose inner var is also used in the body.
PTOCodegen flushed the function's constants section to the output stream
before rendering make_tensor_view and extra alloc-tile prologues. Those
emitters call GetOrEmitConstant, so a constant first needed by a tensor
view shape expression — such as the 2 in a composite parameter dim M * 2
— was appended to the constants section after it had already been
written out, leaving the emitted arith.muli referencing an undeclared
%c2_index and producing invalid MLIR.

Render the prologue into a temporary buffer first so the constants
section is fully populated, then emit constants, prologue, and body in
order. Parameter tensor-view names are bound before the body is visited,
so buffering the prologue emission is purely textual and changes no
bindings.

Add a regression test asserting the composite dim factor is declared
before use.
Add a runtime system test that submits an add kernel whose parameter
shapes use the composite dim M * 2, exercising the SSA-verifier and PTO
codegen fixes together end-to-end through the task-submit runtime.
Document that the tensor-view/alloc prologue is rendered before the
constants block is finalized, so constants unique to a composite shape or
stride expression (e.g. the 2 in M * 2) are still declared before use, in
both the en and zh-cn PTO codegen docs. Condense the inline comments added
with the composite-dim fixes.
Add an L3 distributed system test that runs two independent chip tasks on
two devices (device=0 -> a+b, device=1 -> a-b), with every InCore and
chip-orch parameter type carrying the composite dim M * 2. Validates the
SSA-verifier and PTO codegen composite-shape-dim fixes end-to-end under a
2-device distributed compile + execute.
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR enables support for composite (binary expression) shape dimensions in tensor types by enhancing IR verification to register dynamic variables within nested expressions, reordering code generation to emit constants before prologue, and adding comprehensive regression tests at unit and system levels.

Changes

Composite Shape Dimension Support

Layer / File(s) Summary
SSA verifier composite shape var registration
src/ir/verifier/verify_ssa_pass.cpp
Extends RegisterTypeVars with recursive RegisterShapeExprVars helper to traverse binary/unary shape expressions and register all contained dynamic vars, not just bare Var nodes.
Codegen prologue and constants emission reordering
src/codegen/pto/pto_codegen.cpp
Refactors GenerateFunction to buffer prologue into a temporary string, then emit constants followed by prologue, ensuring constants referenced in shape/stride expressions are declared before use.
Codegen unit test for composite dimension constant ordering
tests/ut/codegen/test_dynamic_shape.py
Adds AddKernelCompositeDim program and test_add_kernel_composite_dim_constant_declared asserting generated MLIR contains arith.muli using a properly declared %c2_index constant declared before its use.
SSA verifier unit tests for composite shape dimensions
tests/ut/ir/transforms/test_verify_ssa_pass.py
Introduces TestCompositeShapeDimVerification with tests for bare dynamic vars, composite dimension expressions, and composite dimensions referenced in function body, all verifying SSA conversion and verification succeed.
Runtime end-to-end test for composite shape dimensions
tests/st/runtime/control_flow/test_composite_shape_dim.py
Adds CompositeDimAddTestCase exercising in-core kernel with M * 2 typed parameters, task-submit runtime execution, and correctness validation via element-wise addition.
Distributed multi-device system test for composite shape dimensions
tests/st/distributed/test_l3_composite_shape_dim.py
Adds 2-device distributed test executing add/sub kernels on separate devices with M * 2 composite shape, using DistributedConfig and validating results on full 128×128 tensors.
Documentation updates for composite shape dimensions
docs/en/dev/codegen/00-pto_codegen.md, docs/zh-cn/dev/codegen/00-pto_codegen.md
Clarifies codegen emission ordering (prologue buffering before constants finalization) and explains tensor-view constant auto-generation for composite dimensions with arithmetic lowering examples.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

bug

Poem

A composite shape takes flight,
M * 2 shines bright and clear,
Prologue before constants right,
Vars nested, variables dear,
Distributed tensors cheer! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title clearly summarizes the main change: adding support for composite shape dimensions in function parameter types.
Description check ✅ Passed The pull request description is comprehensive and directly related to the changeset, explaining the two bugs fixed and the testing performed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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 and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for composite shape dimensions (such as M * 2) in function parameter types. Key changes include updating the SSA verifier to recursively register dynamic shape variables nested within composite expressions, and modifying the PTO codegen to render the tensor-view and allocation prologue before finalizing the constants block, ensuring constant factors are declared before use. Comprehensive documentation, unit tests, and end-to-end distributed runtime tests have been added to verify these fixes. No review comments were provided, so there is no additional feedback to address.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/st/distributed/test_l3_composite_shape_dim.py (1)

133-134: 💤 Low value

Consider using the standard pytest.main pattern for consistency.

The distributed test adds *sys.argv[1:] to forward additional arguments, while the single-device test in test_composite_shape_dim.py uses the exact pattern pytest.main([__file__, "-v"]). Based on learnings, the standard pattern across test files is pytest.main([__file__, "-v"]) unless there's a compelling reason for custom handling.

If argument forwarding is essential for distributed test configuration, the current implementation is acceptable. Otherwise, consider removing *sys.argv[1:] for consistency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/st/distributed/test_l3_composite_shape_dim.py` around lines 133 - 134,
The pytest invocation in the __main__ guard uses pytest.main([__file__, "-v",
*sys.argv[1:]]) which deviates from the standard pattern used elsewhere; change
the call in the if __name__ == "__main__" block to pytest.main([__file__, "-v"])
to match other tests (remove the "*sys.argv[1:]" forwarding), or if argument
forwarding is required for distributed setup, keep it but add a short comment
explaining why this file uses custom forwarding; locate the pytest.main call and
the __main__ guard to make the change.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/st/distributed/test_l3_composite_shape_dim.py`:
- Around line 133-134: The pytest invocation in the __main__ guard uses
pytest.main([__file__, "-v", *sys.argv[1:]]) which deviates from the standard
pattern used elsewhere; change the call in the if __name__ == "__main__" block
to pytest.main([__file__, "-v"]) to match other tests (remove the
"*sys.argv[1:]" forwarding), or if argument forwarding is required for
distributed setup, keep it but add a short comment explaining why this file uses
custom forwarding; locate the pytest.main call and the __main__ guard to make
the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3d71de94-bd44-43aa-b6dc-4846e78b74dd

📥 Commits

Reviewing files that changed from the base of the PR and between 1eec39f and ee82d96.

📒 Files selected for processing (8)
  • docs/en/dev/codegen/00-pto_codegen.md
  • docs/zh-cn/dev/codegen/00-pto_codegen.md
  • src/codegen/pto/pto_codegen.cpp
  • src/ir/verifier/verify_ssa_pass.cpp
  • tests/st/distributed/test_l3_composite_shape_dim.py
  • tests/st/runtime/control_flow/test_composite_shape_dim.py
  • tests/ut/codegen/test_dynamic_shape.py
  • tests/ut/ir/transforms/test_verify_ssa_pass.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant