fix(auto-tile): Add M/N tiling for loop-carried matmul_acc - #2262
fix(auto-tile): Add M/N tiling for loop-carried matmul_acc#2262tonibohnlein wants to merge 11 commits into
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThe PR adds ChangesTile metadata and representation
Physical L0C allocation and tiling
AutoTileMatmulL0 split-K tiling
Validation and control-flow safety
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related issues
Possibly related PRs
Suggested labels: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (4)
src/ir/transforms/init_memref.cpp (1)
803-813: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRemove the shadowing
ctxre-declaration at line 822.This change introduces
const auto* ctx = PassContext::Current();at line 803. Line 822 declares a secondctxwith the same initializer inside the declared-allocation check. The inner declaration shadows the outer one and adds no behavior. Reuse the outerctx.♻️ Proposed cleanup at line 822
if (!declared_allocs.empty()) { - const auto* ctx = PassContext::Current(); CHECK(ctx == nullptr || ctx->GetMemoryPlanner() != MemoryPlanner::PtoAS)🤖 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 `@src/ir/transforms/init_memref.cpp` around lines 803 - 813, Remove the inner ctx declaration in the declared-allocation check and reuse the existing ctx initialized from PassContext::Current(). Keep the surrounding DeclaredAllocCollector initialization and backend-handler behavior unchanged.src/ir/transforms/utils/l0_tile_chooser.cpp (1)
538-542: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueReport the physical footprint in the L0c capacity failure message.
The message prints the logical minimum tile
min_m x min_n. Withbox_align_*orl0c_align_mset, the rejected footprint is*min_c_elements, which can be much larger. Include that value so a caller can see why the logical minimum does not fit.♻️ Proposed message change
CHECK(min_c_elements && *min_c_elements <= static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) && C0_base >= static_cast<int64_t>(*min_c_elements)) << "ChooseL0Tile: L0c capacity " << C0_base << " elements is too small to fit the minimum tile (" - << cfg.min_m << " x " << cfg.min_n << ")"; + << cfg.min_m << " x " << cfg.min_n << "), whose physical footprint after box/L0C-row alignment is " + << (min_c_elements ? std::to_string(*min_c_elements) : std::string("unrepresentable")) << " elements";🤖 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 `@src/ir/transforms/utils/l0_tile_chooser.cpp` around lines 538 - 542, Update the failure message in the ChooseL0Tile validation to include the physical minimum L0c footprint from min_c_elements, alongside the existing logical min_m x min_n dimensions, so aligned configurations report the actual rejected capacity requirement.src/ir/transforms/auto_tile_matmul_l0_pass.cpp (2)
1486-1496: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueHoist the loop-invariant
out_tylookup out of the grid loop.
out_tyat line 1490 depends only onmatch.matmul, so it does not change across grid steps. Compute it once before thenjloop.♻️ Proposed change
+ auto out_ty = As<TileType>(match.matmul->var_->GetType()); + INTERNAL_CHECK_SPAN(out_ty, match.matmul->span_) + << "Internal error: canonical split-K matmul result is not a TileType"; int step = 0; for (int64_t nj = 0; nj < num_n; ++nj) { @@ const std::string suffix = "_mn" + std::to_string(step); - auto out_ty = As<TileType>(match.matmul->var_->GetType()); const auto window = BuildCanonicalOutputWindow(match, m_eff, n_eff, *output_box_alignment);🤖 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 `@src/ir/transforms/auto_tile_matmul_l0_pass.cpp` around lines 1486 - 1496, Move the loop-invariant TileType lookup for out_ty out of the nested grid loops, computing it once before the nj loop while keeping the existing match.matmul source and all subsequent uses unchanged.
1017-1020: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueReuse
PreserveCallAttrsinstead of duplicating the attribute rebuild.Lines 1018-1020 rebuild the deduced
Callwith the original attributes.PreserveCallAttrsat line 1340 performs the identical rebuild. MovePreserveCallAttrsaboveDirectGmPlacerand call it here, so the attribute-preservation rule has one definition.♻️ Proposed refactor
auto deduced = reg.Create("tile.store", {sub, offs, chain_in}, kwargs_, sp_); - auto scall = attrs_.empty() ? deduced - : std::make_shared<Call>(deduced->op_, deduced->args_, deduced->kwargs_, - attrs_, deduced->GetType(), deduced->span_); + auto scall = attrs_.empty() + ? deduced + : std::make_shared<Call>(deduced->op_, deduced->args_, deduced->kwargs_, attrs_, + deduced->GetType(), deduced->span_);Then replace the body with a shared helper once
PreserveCallAttrsis declared before this class.🤖 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 `@src/ir/transforms/auto_tile_matmul_l0_pass.cpp` around lines 1017 - 1020, Extract or move PreserveCallAttrs before DirectGmPlacer so it is available at this call site, then replace the inline attrs_.empty() conditional and Call reconstruction in the tile.store creation path with that helper. Remove the duplicate attribute-preservation implementation while keeping the resulting Call attributes unchanged.
🤖 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 `@python/pypto/ir/builder.py`:
- Around line 692-693: In the ir.TileView signature, move the compact parameter
after span so existing eighth-position positional calls continue passing ir.Span
to span. Preserve the current compact default and all other parameter behavior.
In `@src/backend/common/pto_ops_elementwise.cpp`:
- Around line 570-572: Update the same_layout compatibility check in the
elementwise operation to also require src_view.pad == dst_view.pad before taking
the no-op aliasing path. Preserve the existing tmov behavior for any layout or
padding mismatch.
In `@src/ir/transforms/memory_reuse_pass.cpp`:
- Around line 602-622: Add a regression test in
tests/ut/ir/transforms/test_memory_reuse.py covering an Acc initializer whose
seed passes through tile.set_validshape with padding. Assert the initializer and
accumulator coalesce to the same Acc allocation, while the resulting logical
valid_shape remains unchanged.
---
Nitpick comments:
In `@src/ir/transforms/auto_tile_matmul_l0_pass.cpp`:
- Around line 1486-1496: Move the loop-invariant TileType lookup for out_ty out
of the nested grid loops, computing it once before the nj loop while keeping the
existing match.matmul source and all subsequent uses unchanged.
- Around line 1017-1020: Extract or move PreserveCallAttrs before DirectGmPlacer
so it is available at this call site, then replace the inline attrs_.empty()
conditional and Call reconstruction in the tile.store creation path with that
helper. Remove the duplicate attribute-preservation implementation while keeping
the resulting Call attributes unchanged.
In `@src/ir/transforms/init_memref.cpp`:
- Around line 803-813: Remove the inner ctx declaration in the
declared-allocation check and reuse the existing ctx initialized from
PassContext::Current(). Keep the surrounding DeclaredAllocCollector
initialization and backend-handler behavior unchanged.
In `@src/ir/transforms/utils/l0_tile_chooser.cpp`:
- Around line 538-542: Update the failure message in the ChooseL0Tile validation
to include the physical minimum L0c footprint from min_c_elements, alongside the
existing logical min_m x min_n dimensions, so aligned configurations report the
actual rejected capacity requirement.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 987a1dd7-4946-4742-8775-6b68222d0107
📒 Files selected for processing (71)
docs/en/dev/backend/00-backend_handler.mddocs/en/dev/codegen/00-pto_codegen.mddocs/en/dev/ir/02-types.mddocs/en/dev/ir/04-serialization.mddocs/en/dev/language/00-python_syntax.mddocs/en/dev/passes/15-auto_tile_matmul_l0.mddocs/en/dev/passes/31-memory_reuse.mddocs/zh/dev/backend/00-backend_handler.mddocs/zh/dev/codegen/00-pto_codegen.mddocs/zh/dev/ir/02-types.mddocs/zh/dev/ir/04-serialization.mddocs/zh/dev/language/00-python_syntax.mddocs/zh/dev/passes/15-auto_tile_matmul_l0.mddocs/zh/dev/passes/31-memory_reuse.mdinclude/pypto/backend/910B/backend_910b_handler.hinclude/pypto/backend/common/backend_handler.hinclude/pypto/codegen/pto/pto_type_utils.hinclude/pypto/ir/tile_view_semantics.hinclude/pypto/ir/transforms/passes.hinclude/pypto/ir/transforms/utils/l0_tile_chooser.hinclude/pypto/ir/transforms/utils/l0c_footprint.hinclude/pypto/ir/transforms/utils/memref_utils.hinclude/pypto/ir/transforms/utils/tile_buf_signature.hinclude/pypto/ir/type.hinclude/pypto/ir/type_inference.hpython/bindings/modules/backend.cpppython/bindings/modules/ir.cpppython/bindings/modules/passes.cpppython/pypto/ir/builder.pypython/pypto/ir/type.pypython/pypto/language/__init__.pypython/pypto/language/parser/ast_parser.pypython/pypto/language/parser/type_resolver.pypython/pypto/pypto_core/backend.pyipython/pypto/pypto_core/ir.pyipython/pypto/pypto_core/passes.pyisrc/backend/common/pto_ops_datamove.cppsrc/backend/common/pto_ops_elementwise.cppsrc/backend/common/pto_ops_shared.cppsrc/codegen/pto/pto_codegen.cppsrc/codegen/pto/pto_type_utils.cppsrc/ir/op/tile_ops/matmul.cppsrc/ir/op/tile_ops/transform.cppsrc/ir/op/type_inference.cppsrc/ir/serialization/deserializer.cppsrc/ir/serialization/serializer.cppsrc/ir/transforms/auto_tile_matmul_l0_pass.cppsrc/ir/transforms/flatten_tile_nd_to_2d/rewrite.cppsrc/ir/transforms/infer_tile_memory_space_pass.cppsrc/ir/transforms/init_memref.cppsrc/ir/transforms/memory_reuse_pass.cppsrc/ir/transforms/python_printer.cppsrc/ir/transforms/structural_equal.cppsrc/ir/transforms/structural_hash.cppsrc/ir/transforms/utils/l0_tile_chooser.cppsrc/ir/type.cpptests/st/runtime/ops/test_auto_tile_matmul.pytests/ut/backend/test_backend_910b.pytests/ut/backend/test_backend_950.pytests/ut/codegen/test_pto_codegen_ops.pytests/ut/ir/core/test_tile_view_equality.pytests/ut/ir/memory/test_memref.pytests/ut/ir/operators/test_tile_ops.pytests/ut/ir/transforms/test_allocate_memory_addr_pass.pytests/ut/ir/transforms/test_auto_tile_matmul_acc_mn.pytests/ut/ir/transforms/test_auto_tile_matmul_l0.pytests/ut/ir/transforms/test_init_memref.pytests/ut/ir/transforms/test_l0_tile_chooser.pytests/ut/ir/transforms/test_memory_reuse.pytests/ut/ir/transforms/test_serialization.pytests/ut/language/parser/test_type_resolver.py
- preserve the positional IRBuilder tile_view span API - retain tile moves when pad representations differ - add focused padded-accumulator reuse coverage and review cleanups
Use backend-aware physical L0C footprints consistently in tile selection, double-buffer planning, and memory allocation. Rewrite canonical loop-carried split-K accumulators before dbC planning so each output tile completes its K reduction without materializing an oversized Acc.\n\nAdd host and device regressions for issue hw-native-sys#2232, including physically padded INT32 accumulators.
Box-align canonical split-K boundary loads and accumulators while preserving their logical valid shapes through matmul and matmul_acc. This keeps partial stores logical and prevents PTOAS from rejecting narrow Mat boxes.
Account for boxed Mat layouts before selecting L0 tiles. Preserve logical valid shapes through nested K tiling. Reject unsupported divergent L0C accumulator copies.
Represent PTO compact mode in TileView and propagate it through IR transformations, serialization, and PTO codegen. Infer the valid-aware normal mode for partial Left/Right tile.extract results so padded INT8 boundary operands do not copy box padding as data after AutoTile's secondary K split.
- preserve the positional IRBuilder tile_view span API - retain tile moves when pad representations differ - add focused padded-accumulator reuse coverage and review cleanups
Access the legacy module-level null alias dynamically and narrow the optional tile-view start offset before checking its source span.
10ff4d1 to
bf1d998
Compare
Allow PTO matmul valid regions to use containment while preserving exact physical-box checks. Normalize partial no-split Acc-to-Vec FIFO transfers to the physical box and restore their logical valid shape on both sides. Add operator and PTO codegen regressions for the affected asymmetric cases.
Summary
Fixes #2232 by adding real M/N tiling for the canonical loop-carried split-K
matmul/matmul_accform. The rewrite moves the output grid outside the K reduction, so each legal L0C sub-tile completes every source K block and is stored before the next sub-tile begins; the oversized full accumulator is never materialized.The change also:
valid_shape, then propagates that physical/valid distinction throughmatmul,matmul_acc, and stores;TileViewand automatically marks partial Left/Righttile.extractresults as compact, so TEXTRACT copies only valid INT8 tail data;tile.set_validshapeaccumulator initializers with the in-place reduction buffer and rejects irreconcilable distinct Acc-to-Acc copies before codegen; andPH-AT-006for non-canonical, caller-owned oversizedmatmul_accforms that still cannot be safely retiled.Validation
cmake --build build --parallel 2main(one untouched current-main parser assertion that expectsNameErrorbut receivesParserTypeErroron local Python 3.14 was excluded)[16, 1152]and the padded M/N boundary case[272, 144]under both PyPTO and PTOAS memory planners[32, 1152]accumulatorThe device run used the feature-equivalent pre-rebase tip
d2526fc6; the final rebase preserved the feature patches, integrated the new singularvalid_shapeAPI and fractal-byte documentation frommain, and was rebuilt and host-revalidated at the PR head.