feat(codegen): validate carry op family - #2187
Conversation
📝 WalkthroughWalkthroughThe PR formalizes carry-aware tile arithmetic for ChangesCarry arithmetic operations
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant TestCarryFamily
participant tile.addc
participant MemoryReuse
TestCarryFamily->>tile.addc: execute carry arithmetic with valid_shapes
tile.addc-->>TestCarryFamily: produce and validate output
MemoryReuse->>tile.addc: reuse dead src0 buffer
tile.addc-->>MemoryReuse: bind destination to src0 MemRef
Possibly related PRs
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.
🧹 Nitpick comments (1)
src/ir/op/tile_ops/elementwise.cpp (1)
71-75: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueCarry contract duplicates the pre-existing tdiv contract machinery.
IsCarryDataType(71-75) is identical toIsTDivDataType(66-69) — same four dtypes, same body. AndCheckCarryTileMatches(717-748) reimplements the exact dtype/shape-rank/shape-extent/valid-shape-rank/valid-shape-extent sequence already inlined inDeduceTileOpElementwiseBinaryType'srequire_tdiv_contractbranch (lines ~137-175), instead of extracting/reusing one shared helper for both contracts. Since these two contracts happen to coincide today, a future divergence in one path without updating the other would silently break parity.♻️ Suggested consolidation
-static bool IsCarryDataType(DataType dtype) { - return dtype == DataType::INT16 || dtype == DataType::INT32 || dtype == DataType::FP16 || - dtype == DataType::FP32; -} +// Carry ops (addc/subc/addsc/subsc) currently share the same dtype union as +// the tdiv contract; reuse it explicitly instead of duplicating the list. +static bool IsCarryDataType(DataType dtype) { return IsTDivDataType(dtype); }And in
DeduceTileOpElementwiseBinaryType'srequire_tdiv_contractbranch, replace the inline dtype/shape/valid-shape checks with a call toCheckCarryTileMatches(tile_type1, tile_type2, "src1", op_name)(after hoisting its declaration above this function), removing the duplicate block.Also applies to: 717-748
🤖 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/op/tile_ops/elementwise.cpp` around lines 71 - 75, Consolidate the duplicated carry and tdiv contract logic in IsCarryDataType, CheckCarryTileMatches, and DeduceTileOpElementwiseBinaryType: reuse one shared dtype predicate and hoist CheckCarryTileMatches so the require_tdiv_contract branch calls it instead of duplicating dtype, shape, rank, extent, and valid-shape checks. Preserve the existing contract validation behavior and diagnostics for both paths.
🤖 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 `@src/ir/op/tile_ops/elementwise.cpp`:
- Around line 71-75: Consolidate the duplicated carry and tdiv contract logic in
IsCarryDataType, CheckCarryTileMatches, and DeduceTileOpElementwiseBinaryType:
reuse one shared dtype predicate and hoist CheckCarryTileMatches so the
require_tdiv_contract branch calls it instead of duplicating dtype, shape, rank,
extent, and valid-shape checks. Preserve the existing contract validation
behavior and diagnostics for both paths.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 1fb6fd8a-dbf2-44ed-83fc-2caffafd8650
📒 Files selected for processing (11)
docs/en/dev/codegen/00-pto_codegen.mddocs/en/dev/ptoas-op-status.mddocs/zh-cn/dev/codegen/00-pto_codegen.mddocs/zh-cn/dev/ptoas-op-status.mdpython/pypto/ir/op/tile_ops.pypython/pypto/language/op/tile_ops.pysrc/backend/common/pto_ops_elementwise.cppsrc/ir/op/tile_ops/elementwise.cpptests/st/runtime/ops/test_carry.pytests/ut/ir/operators/test_tile_ops.pytests/ut/ir/transforms/test_memory_reuse.py
|
Review follow-up: I am keeping the carry contract local rather than reusing the division helper. Carry ops have a third carry operand and different output/reuse semantics; coupling them to the division-specific helper would broaden the refactor and make future changes to either instruction family less isolated, without fixing a correctness issue. |
Summary
tile.addc,tile.subc,tile.addsc, andtile.subscwith the current native PTO-ISA dtype, shape, valid-region, scalar, layout, and carry semanticssrc0 - src1/scalar + carry, and emit the four canonical PTOAS ops with exact operand orderValidation
git diff --check: passed/data/chenshenai/test2: passed.ptofiles contain exactpto.taddc,pto.tsubc,pto.taddsc, andpto.tsubscoperand orderThe runtime cases cover carry values 0/1, add/subtract, tile/scalar forms, INT32 overflow/borrow behavior, and narrowed
valid_shape. A5 hardware validation remains pending and is documented in the status matrix.