Skip to content

fix: preserve singleton broadcast dims in SplitVectorKernel#976

Closed
ndleslx wants to merge 1 commit intohw-native-sys:mainfrom
ndleslx:fix/split-vector-singleton-broadcast
Closed

fix: preserve singleton broadcast dims in SplitVectorKernel#976
ndleslx wants to merge 1 commit intohw-native-sys:mainfrom
ndleslx:fix/split-vector-singleton-broadcast

Conversation

@ndleslx
Copy link
Copy Markdown

@ndleslx ndleslx commented Apr 12, 2026

Summary

  • preserve singleton split-axis dimensions in SplitVectorKernel instead of halving them unconditionally
  • only adjust offsets and tracked split metadata when the split is actually applied
  • add a regression test for [1, 128] broadcast tile loads used by col_expand_mul under SplitMode.UP_DOWN

Repro

This fixes the failure where split AIV kernels hit:

SplitVectorKernel requires an even split dimension, got 1

for broadcast tile loads such as Tile[[1, 128], ...] on the split axis.

Testing

  • pip install -e ".[dev]"
  • python -m pytest tests/ut/ir/transforms/test_split_vector_kernel.py -k singleton_broadcast -v

Closes #975

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 45e7c288-5c6e-4227-a38a-ebf7b90ee8fd

📥 Commits

Reviewing files that changed from the base of the PR and between 53d9f93 and 8574ef1.

📒 Files selected for processing (2)
  • src/ir/transforms/split_vector_kernel_pass.cpp
  • tests/ut/ir/transforms/test_split_vector_kernel.py

📝 Walkthrough

Walkthrough

Modified the split_vector_kernel_pass.cpp to preserve singleton dimensions on the split axis instead of unconditionally halving them. Introduced ComputeSplitDimInfo() function returning both the computed dimension and a split_applied flag, gating offset adjustments and tile tracking on actual splits. Added regression test validating singleton broadcast tile preservation.

Changes

Cohort / File(s) Summary
Split Vector Kernel Pass Core Logic
src/ir/transforms/split_vector_kernel_pass.cpp
Introduced ComputeSplitDimInfo() function that returns both computed dimension expression and split_applied flag. Updated HalveTileShape() and HalveTupleElement() to accept preserve_singleton parameter. Modified ProcessStmt() to conditionally apply offset adjustments and tile-variable tracking only when split_applied is true, while preserving singleton dimensions (e.g., [1, N]) in broadcast tiles.
Regression Test
tests/ut/ir/transforms/test_split_vector_kernel.py
Added test_load_preserves_singleton_broadcast_dim test validating that split_vector_kernel() preserves singleton broadcast tiles under SplitMode.UP_DOWN, ensuring split dimension (e.g., [1, 128]) remains unchanged while normal tiles (e.g., [16, 128][8, 128]) are correctly halved.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • lyfne123

Poem

🐰 A tile so small, with just one in its way,
No need to halve it—let it stay!
While siblings split right down the seam,
The broadcast singleton achieves its dream. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% 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 title clearly and concisely describes the main change: preserving singleton broadcast dimensions in SplitVectorKernel instead of halving them unconditionally.
Description check ✅ Passed The description is well-organized with Summary, Repro, and Testing sections that directly relate to the changeset and issue being fixed.
Linked Issues check ✅ Passed The code changes fully implement the requirements from issue #975: preserving singleton dimensions, conditional offset/metadata adjustments, and adding a regression test for [1,128] broadcast tiles.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing singleton broadcast dimension handling in SplitVectorKernel; no unrelated modifications were introduced.

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

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 introduces a mechanism to preserve singleton dimensions during vector kernel splitting for AIV operations by replacing the ComputeHalfDimSize function with ComputeSplitDimInfo. This allows the transformation to skip splitting for dimensions of size 1 when the preserve_singleton flag is enabled, preventing potential value errors. The logic was updated for tile.load, tile.full, and tile.create operations, and a new unit test was added to verify the behavior. Feedback points out that the tile.tpop_from_aic operation was not fully updated to use this new logic, which could lead to crashes or incorrect offset adjustments for singleton tiles.

std::make_shared<Var>(assign->var_->name_hint_, new_call->GetType(), assign->var_->span_);
if (tt && split_dim < static_cast<int>(tt->shape_.size())) {
TileInfo info{ComputeHalfDimSize(tt->shape_[split_dim])};
TileInfo info{ComputeSplitDimInfo(tt->shape_[split_dim]).dim_size};
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.

high

The tile.tpop_from_aic operation handling is incomplete and will still crash when encountering a singleton dimension on the split axis.

  1. This line calls ComputeSplitDimInfo with the default preserve_singleton=false, which will throw a ValueError for dimensions of size 1.
  2. Additionally, tile_vars should only be updated if the split was actually applied (split_applied == true). Otherwise, subsequent tile.store operations will incorrectly adjust offsets for the non-split singleton tile.
  3. The helper RebuildTpopWithHalvedShape (called at line 296) also needs to be updated to support and pass the preserve_singleton flag to HalveTileShape to avoid a similar crash during type reconstruction.
References
  1. When an AIV operation produces a TileType, ensure that any shape-related arguments within the Call itself are also updated (e.g., halved) to maintain type consistency and prevent failures in subsequent passes or codegen.

@lyfne123 lyfne123 self-assigned this Apr 13, 2026
lyfne123 added a commit to lyfne123/pypto that referenced this pull request Apr 13, 2026
Redesign the split decision algorithm in SplitVectorKernel to be
op-semantics-aware instead of unconditionally halving all tile dims:

- Add IsSingletonDim check: tiles with split-axis extent == 1 (e.g.
  broadcast [1, 128] under UP_DOWN) are now preserved as-is without
  halving shape, adjusting offsets, or tracking in tile_vars
- Add IsReduceOnSplitAxis detection: reduce ops (tile.sum/max/min,
  tile.row_sum/max/min) that reduce on the split axis are rejected
  with a clear error, since partial reduction is semantically incorrect
- Add regression tests for both UP_DOWN and LEFT_RIGHT singleton
  broadcast scenarios, plus a reduce-on-split-axis rejection test

Fixes hw-native-sys#976
Closes hw-native-sys#975

Made-with: Cursor
lyfne123 added a commit to lyfne123/pypto that referenced this pull request Apr 13, 2026
Redesign the split decision algorithm in SplitVectorKernel to be
op-semantics-aware instead of unconditionally halving all tile dims:

- Add IsSingletonDim check: tiles with split-axis extent == 1 (e.g.
  broadcast [1, 128] under UP_DOWN) are now preserved as-is without
  halving shape, adjusting offsets, or tracking in tile_vars
- Add IsReduceOnSplitAxis detection: reduce ops (tile.sum/max/min,
  tile.row_sum/max/min) that reduce on the split axis are rejected
  with a clear error, since partial reduction is semantically incorrect
- Add regression tests for both UP_DOWN and LEFT_RIGHT singleton
  broadcast scenarios, plus a reduce-on-split-axis rejection test

Fixes hw-native-sys#976
Closes hw-native-sys#975

Made-with: Cursor
Crystal-wzy pushed a commit to Crystal-wzy/pypto that referenced this pull request Apr 13, 2026
…-native-sys#984)

## Summary

- Redesign the split decision algorithm in `SplitVectorKernel` to be op-semantics-aware instead of unconditionally halving all tile dimensions on the split axis
- Add `IsSingletonDim` check: tiles with split-axis extent == 1 (e.g. broadcast `[1, 128]` under `UP_DOWN`) are preserved as-is without halving, offset adjustment, or tile tracking
- Add `IsReduceOnSplitAxis` detection: reduce ops (`tile.sum/max/min`, `tile.row_sum/max/min`) that reduce on the split axis are rejected with a clear error since partial reduction is semantically incorrect
- Add regression tests for UP_DOWN and LEFT_RIGHT singleton broadcast scenarios, plus a reduce-on-split-axis rejection test

Fixes hw-native-sys#976
Closes hw-native-sys#975

## Test plan

- [x] All 15 `test_split_vector_kernel.py` tests pass (12 existing + 3 new)
- [x] All 980 `tests/ut/ir/transforms/` tests pass with no regressions
- [x] Pre-commit hooks pass (clang-format, cpplint, ruff, pyright)
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.

[Pass Bug]SplitVectorKernel fails on singleton broadcast tile loads in split AIV kernels

2 participants