Skip to content

fix(codegen): drop parent tile_view valid_shape in subview inference#1535

Merged
lyfne123 merged 4 commits into
hw-native-sys:mainfrom
lwDavid:issue-1507-tpop-valid-shape
May 27, 2026
Merged

fix(codegen): drop parent tile_view valid_shape in subview inference#1535
lyfne123 merged 4 commits into
hw-native-sys:mainfrom
lwDavid:issue-1507-tpop-valid-shape

Conversation

@lwDavid
Copy link
Copy Markdown
Contributor

@lwDavid lwDavid commented May 26, 2026

Summary

  • InferSubviewTileTypeComponents (src/backend/common/pto_ops_common.cpp:203) read source_tile_type.tile_view_.valid_shape to derive the subview result's static v_row / v_col.
  • ExtractTileTypeInfo (src/codegen/pto/pto_type_utils.cpp:142-145) renders every non-subview tile type as v_row=?, v_col=? regardless of what tile_view_.valid_shape holds in the IR. PTOAS therefore infers the subview result's static valid from the slice's sizes. Reading the sentinel [0, 0] that SplitVectorKernel's WithZeroValidShape (src/ir/transforms/split_vector_kernel_pass.cpp:228) stamps onto lane1 clones diverged from PTOAS: we emitted v_row=0, v_col=0 against a v_row=? parent and PTOAS rejected.
  • Switch the source-valid lookup to source_tile_type.shape_. For in-bounds slices this matches PTOAS's "infer from sizes" rule. Runtime valid is unchanged — pto.alloc_tile still reads valid_row / valid_col from TileType.tile_view_.valid_shape (pto_codegen.cpp:1078-1095), so lane1 elision still writes the [0, 0] sentinel where it should.

Why this fixes #1507 (and why the previous matmul attempt didn't)

The first attempt on this branch propagated operand valid_shape through DeduceTileMatMulType / MatMulAcc / MatMulBias. That broke hc_pre accuracy by 98–99% because pto.alloc_tile consumes tile_view.valid_shape as the physical write extent of the cube intrinsic — narrowing matmul output valid_shape clipped pto.tmatmul to the narrow region, leaving the rest of the Acc as garbage that downstream consumers still read.

The subview-inference fix only changes the static type string PTOAS verifies — it does not change pto.alloc_tile's runtime arguments, the cube/vec intrinsic's actual write extent, or any tile op's runtime semantics.

Testing

  • New regression test test_tile_slice_with_zero_valid_sentinel_parent_does_not_emit_zero_result_valid in tests/ut/codegen/test_pto_codegen_ops.py::TestTileSliceCodegen — materialises the lane1 sentinel via an explicit pl.TileView(valid_shape=[0, 0]) parent and asserts the pto.subview type string does NOT carry v_row=0 / v_col=0.
  • tests/ut/codegen/ + tests/ut/ir/transforms/test_split_vector_kernel.py — 359/359 pass.
  • Full tests/ut/ sweep — 5240 passed, 28 skipped, 0 failed.
  • pypto-lib-model (DSV4 hc_pre) accuracy via CI — must validate end-to-end.

Related Issues

Fixes #1507

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

InferSubviewTileTypeComponents now derives subview result-type source_valid directly from source tile shape, avoiding sentinel valid_shape=[0,0] propagation into invalid static dimensions. A regression test validates that sentinel parent valid_shape does not produce v_row=0, v_col=0 in the subview result type.

Changes

Subview tile type inference and sentinel valid_shape handling

Layer / File(s) Summary
Fix: source_valid derivation in subview type inference
src/backend/common/pto_ops_common.cpp
InferSubviewTileTypeComponents now references source_tile_type.shape_ directly instead of conditionally overwriting with tile_view_->valid_shape when present. Comments clarify this mirrors PTOAS static-result-type validation and prevents sentinel overrides from producing invalid v_row=0, v_col=0 instead of v_row=?, v_col=?.
Test: regression for sentinel valid_shape in parent tile
tests/ut/codegen/test_pto_codegen_ops.py
New test test_tile_slice_with_zero_valid_sentinel_parent_does_not_emit_zero_result_valid constructs a slice from a tile with parent TileView carrying valid_shape=[0, 0] sentinel, generates PTO MLIR, and asserts the pto.subview result type omits static v_row=0 and v_col=0.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

  • hw-native-sys/pypto#1267: The main change directly modifies InferSubviewTileTypeComponents to avoid using TileView.valid_shape and derive source_valid from source_tile_type.shape_, addressing the exact pto.subview result-type inference mismatch described in this issue.

Possibly related PRs

  • hw-native-sys/pypto#1217: Both target the same InferSubviewTileTypeComponents/tile.slice valid_shape propagation behavior and subview tile type inference logic.
  • hw-native-sys/pypto#1210: Both adjust pto.subview valid-shape/result-type generation in src/backend/common/pto_ops_common.cpp at the subview-valid typing/codegen level.
  • hw-native-sys/pypto#1505: Both address incorrect propagation/usage of TileView.valid_shape in subview/broadcast contexts.

Suggested reviewers

  • lyfne123
  • Hzfengsy

Poem

🐰 A sentinel tile once held shape [0, 0],
But subview drew them down, down, down—
Now source_valid springs straight from shape anew,
Whilst PTOAS smiles and plays no frown! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR partially addresses #1507 by fixing subview inference, but does not implement the full fix to propagate valid_shape through cube→vec bridge ops as requested in the issue. Review whether this narrower subview-inference fix adequately resolves #1507, or if the broader cube→vec bridge propagation changes are still required.
Docstring Coverage ⚠️ Warning Docstring coverage is 64.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly describes the main change: modifying subview inference to stop using parent tile_view valid_shape.
Description check ✅ Passed The PR description thoroughly explains the root cause, fix, rationale, testing, and connection to issue #1507.
Out of Scope Changes check ✅ Passed All changes are focused on fixing subview inference and adding a regression test, directly addressing the technical issue described in the PR.

✏️ 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.

@lwDavid lwDavid self-assigned this May 26, 2026
@lwDavid lwDavid moved this to In Progress in pto project May 26, 2026
Copy link
Copy Markdown
Contributor

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

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 addresses issue #1507 by ensuring that the matrix multiplication type deducers (DeduceTileMatMulType, DeduceTileMatMulAccType, and DeduceTileMatMulBiasType) correctly propagate the operand valid_shape (taking M from the left-hand side and N from the right-hand side) instead of defaulting to the full output shape. Corresponding unit tests have been added in test_tile_ops.py to verify this propagation behavior across tile.matmul, tile.matmul_acc, and tile.matmul_bias. I have no further feedback to provide as the changes are well-implemented and thoroughly tested.

@lwDavid lwDavid added the bug Something isn't working label May 26, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/ut/ir/operators/test_tile_ops.py (1)

1401-1475: ⚡ Quick win

Add one GEMV regression to lock the shared deducer contract.

These tests validate matmul/matmul_acc/matmul_bias propagation well, but tile.gemv* rely on separate op registrations even though they reuse the same deducers. A compact tile.gemv valid-shape assertion would catch wiring drift early.

Suggested test addition
+    def test_tile_gemv_propagates_operand_valid_shape(self):
+        """tile.gemv: output valid is [lhs.valid_M, rhs.valid_N] via shared matmul deducer."""
+        lhs = self._make_matmul_lhs_with_valid_m(m=1, k=32, valid_m=1)
+        rhs = self._make_matmul_rhs_with_valid_n(k=32, n=64, valid_n=24)
+        call = tile.gemv(lhs, rhs)
+        result_type = call.type
+        assert isinstance(result_type, ir.TileType)
+        assert result_type.tile_view is not None
+        valid_shape = result_type.tile_view.valid_shape
+        assert isinstance(valid_shape[0], ir.ConstInt) and valid_shape[0].value == 1
+        assert isinstance(valid_shape[1], ir.ConstInt) and valid_shape[1].value == 24
🤖 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/ut/ir/operators/test_tile_ops.py` around lines 1401 - 1475, Add a
compact regression test mirroring the matmul valid-shape checks: create lhs
using _make_matmul_lhs_with_valid_m(m=16,k=32,valid_m=8) and rhs using
_make_matmul_rhs_with_valid_n(k=32,n=64,valid_n=24), call tile.gemv(lhs, rhs),
get call.type, assert it's an ir.TileType with tile_view not None and that
tile_view.valid_shape has two ConstInt entries with values 8 and 24; name the
test e.g. test_tile_gemv_propagates_operand_valid_shape to lock the deducer
contract for tile.gemv.
🤖 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/ut/ir/operators/test_tile_ops.py`:
- Around line 1401-1475: Add a compact regression test mirroring the matmul
valid-shape checks: create lhs using
_make_matmul_lhs_with_valid_m(m=16,k=32,valid_m=8) and rhs using
_make_matmul_rhs_with_valid_n(k=32,n=64,valid_n=24), call tile.gemv(lhs, rhs),
get call.type, assert it's an ir.TileType with tile_view not None and that
tile_view.valid_shape has two ConstInt entries with values 8 and 24; name the
test e.g. test_tile_gemv_propagates_operand_valid_shape to lock the deducer
contract for tile.gemv.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 04fbe298-d290-4b73-996c-b139edda698d

📥 Commits

Reviewing files that changed from the base of the PR and between e7e41f5 and ff93864.

📒 Files selected for processing (2)
  • src/ir/op/tile_ops/matmul.cpp
  • tests/ut/ir/operators/test_tile_ops.py

@lwDavid lwDavid closed this May 26, 2026
@lwDavid lwDavid force-pushed the issue-1507-tpop-valid-shape branch from ff93864 to e7e41f5 Compare May 26, 2026 11:00
Fixes hw-native-sys#1507

InferSubviewTileTypeComponents read source_tile_type.tile_view_.valid_shape
to derive the subview result's static v_row / v_col. ExtractTileTypeInfo
in pto_type_utils.cpp always renders non-subview tile types as
v_row=?, v_col=? regardless of what valid_shape carries in the IR, so PTOAS
infers the subview result purely from the slice's `sizes`. Reading the
sentinel [0, 0] that SplitVectorKernel's WithZeroValidShape stamps onto
lane1 clones therefore diverged from PTOAS: we emitted v_row=0, v_col=0
against a v_row=? parent and PTOAS rejected.

Use source_tile_type.shape_ instead of tile_view.valid_shape. For
in-bounds slices this matches PTOAS's "infer from sizes" rule. Runtime
valid is unchanged — pto.alloc_tile still reads valid_row / valid_col from
TileType.tile_view_.valid_shape, so lane1 elision still writes the [0, 0]
sentinel where it should.

Add a codegen regression test that materialises the lane1 sentinel via an
explicit pl.TileView(valid_shape=[0, 0]) parent and asserts the resulting
pto.subview type string does not carry v_row=0 / v_col=0.
@lwDavid lwDavid reopened this May 26, 2026
@lwDavid lwDavid changed the title fix(ir): propagate operand valid_shape through matmul deducers fix(codegen): drop parent tile_view valid_shape in subview inference May 26, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@src/backend/common/pto_ops_common.cpp`:
- Around line 227-237: When initializing source_valid, special-case only the
zero-sentinel case instead of always using source_tile_type.shape_; detect if
source_tile_type.shape_ is the sentinel [0,0] (or equivalent zero-valid
sentinel) and only then set source_valid = source_tile_type.shape_, otherwise
preserve the parent's inferred static valid extents (e.g., use
source_tile_type.valid_shape or tile_view_.valid_shape) so nested subviews keep
their narrowed valid_box; update the assignment that creates source_valid to
branch on that sentinel check and pick the sentinel shape only when applicable.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f039cdc5-0e40-459b-8109-bceb75c6ba2b

📥 Commits

Reviewing files that changed from the base of the PR and between ff93864 and 484df88.

📒 Files selected for processing (2)
  • src/backend/common/pto_ops_common.cpp
  • tests/ut/codegen/test_pto_codegen_ops.py

Comment thread src/backend/common/pto_ops_common.cpp Outdated
lwDavid added 3 commits May 26, 2026 20:56
Previously the fix in 484df88 always replaced the parent's
`tile_view_.valid_shape` with `shape_` when inferring a subview's
static valid. CodeRabbit pointed out that this also discards genuine
narrow valid extents on parent subviews — when downstream propagation
populates a real `v_row/v_col`, nested subviews would now widen back
to `shape_` and mis-type their result valid.

Restore the existing inference for any non-zero parent valid, and only
fall through to `shape_` when the IR carries the all-zero lane1
sentinel (set by SplitVectorKernel's WithZeroValidShape). The original
issue hw-native-sys#1507 is still fixed because the sentinel detection covers the
exact case that PTOAS rejects.

Add a counterpart test for the non-sentinel narrow-valid path so the
preservation behaviour is locked in.
@lwDavid lwDavid moved this from In Progress to Done in pto project May 26, 2026
@lwDavid lwDavid requested a review from lyfne123 May 27, 2026 03:36
@lyfne123 lyfne123 merged commit dce520e into hw-native-sys:main May 27, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Pass Bug] tpop_from_aic (cube→vec bridge) drops matmul output valid_shape, breaking downstream vec subview

2 participants