Skip to content

[Refactor] Simplify logic in the CompleteBufferFragment#1226

Merged
LeiWang1999 merged 3 commits intotile-ai:mainfrom
LeiWang1999:parallel_fix_1111
Nov 11, 2025
Merged

[Refactor] Simplify logic in the CompleteBufferFragment#1226
LeiWang1999 merged 3 commits intotile-ai:mainfrom
LeiWang1999:parallel_fix_1111

Conversation

@LeiWang1999
Copy link
Member

@LeiWang1999 LeiWang1999 commented Nov 11, 2025

This pull request simplifies the logic in the CompleteBufferFragment function in src/op/parallel.cc by removing a pre-check for bijective mapping and its fallback logic. The function now directly computes the inverse layout without checking for non-bijective mappings, streamlining the code.

Code simplification:

  • Removed the cardinality check that guarded against non-bijective mappings after appending rep_b, along with the associated fallback logic for non-bijective cases. The function now always computes the inverse layout directly.

Summary by CodeRabbit

  • Refactor

    • Simplified parallel operation handling by removing fallback checks and streamlining the computation path, reducing internal complexity without changing outward behavior.
  • Chore

    • Reduced noisy warnings: a shape-related warning is now emitted only in debug builds, so fewer warnings appear in normal (non-debug) runs.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 11, 2025

Walkthrough

Removed a non-bijective pre-check and fallback in CompleteBufferFragment (src/op/parallel.cc), now directly inverting the bijective indices to compute replication extents; changed a persistent LOG(WARNING) to DLOG(WARNING) in LayoutNode::InverseWithLevel (src/layout/layout.cc).

Changes

Cohort / File(s) Summary
Bijective inversion simplification
src/op/parallel.cc
Removed non-bijective mapping pre-check and fallback in CompleteBufferFragment; compute ind_inv directly as inverse of Layout(loop_vars_, bijective_indice) and derive indice_rep_extent / thd_b without prior conditional guards.
Debug logging reduction
src/layout/layout.cc
Replaced LOG(WARNING) with DLOG(WARNING) in LayoutNode::InverseWithLevel for non-static shapes so the warning is emitted only in debug builds.

Sequence Diagram(s)

sequenceDiagram
  participant Caller as CompleteBufferFragment
  participant Layout as Layout(loop_vars_)
  participant Inv as ind_inv
  participant Rep as RepExtentCalc

  Note over Caller,Layout: OLD FLOW (with pre-check & fallback)
  Caller->>Layout: compute bijective_indice
  Layout-->>Caller: bijective_indice
  Caller->>Caller: construct layout_before_inv
  alt layout_before_inv not bijective
    Caller->>Rep: fallback to no-rep inversion
    Rep-->>Caller: fallback result
  else bijective
    Caller->>Layout: inverse Layout(loop_vars_, bijective_indice)
    Layout-->>Inv: ind_inv
    Caller->>Rep: derive indice_rep_extent, compute thd_b
    Rep-->>Caller: rep results
  end
Loading
sequenceDiagram
  participant Caller as CompleteBufferFragment
  participant Layout as Layout(loop_vars_)
  participant Inv as ind_inv
  participant Rep as RepExtentCalc

  Note over Caller,Layout: NEW FLOW (direct inversion)
  Caller->>Layout: compute bijective_indice
  Layout-->>Caller: bijective_indice
  Caller->>Layout: inverse Layout(loop_vars_, bijective_indice)
  Layout-->>Inv: ind_inv
  Caller->>Rep: derive indice_rep_extent, compute thd_b
  Rep-->>Caller: rep results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Areas to check:
    • src/op/parallel.cc: ensure removal of the non-bijective pre-check is safe for all callers and that non-bijective inputs are impossible or handled elsewhere.
    • Correctness of ind_inv computation and downstream use of indice_rep_extent / thd_b.
    • src/layout/layout.cc: confirm reducing logging severity is acceptable for release diagnostics.

Possibly related PRs

Poem

🐰
I hopped through loops and indices neat,
Removed the checks, made inversion fleet,
Warnings now whisper in debug light,
Rep extents compute and everything's tight,
A small carrot for cleaner sight 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: simplifying logic in CompleteBufferFragment by removing the bijective mapping pre-check and fallback logic.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3349d8d and 4f6e654.

📒 Files selected for processing (1)
  • src/layout/layout.cc (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Test for Python 3.12 with ROCm-6.3 (on self-hosted-amd)
  • GitHub Check: Test for Python 3.12 with Metal (on macos-latest)
🔇 Additional comments (1)
src/layout/layout.cc (1)

253-255: Changing LOG(WARNING) to DLOG(WARNING) is acceptable but verify the trade-off.

The warning about using NoCheck level is only visible in debug builds now, not production. However, actual runtime validation is preserved—DetectIterMap still throws NormalizeIterException if it encounters errors (lines 259–262), regardless of the DLOG change.

Additionally, callers like loop_partition.cc (lines 83–84) check the returned IterMapLevel and add runtime guards when the level is not Bijective, so the safety net exists even with the silenced warning.

The trade-off is reduced production observability of the decision to fall back to NoCheck level in favor of less noisy logs. If this visibility is valuable for debugging or operational monitoring, consider keeping LOG(WARNING) or adding metrics/alerts for symbolic layout inversions.


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.

@github-actions
Copy link

👋 Hi! Thank you for contributing to the TileLang project.

Please remember to run pre-commit run --all-files in the root directory of the project to ensure your changes are properly linted and formatted. This will help ensure your contribution passes the format check.

We appreciate you taking this step! Our team will review your contribution, and we look forward to your awesome work! 🚀

Copy link
Contributor

@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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 67cc861 and 3349d8d.

📒 Files selected for processing (1)
  • src/op/parallel.cc (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/op/parallel.cc (1)
src/layout/layout.cc (2)
  • Layout (58-70)
  • Layout (72-75)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Quick Lint

std::nullopt)
->CondenseReplicateVar();
}
Layout ind_inv = Layout(loop_vars_, bijective_indice)->Inverse();
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify that bijective mapping is guaranteed before unconditional inversion.

The removal of the pre-check for bijective mapping and the fallback logic means that Layout::Inverse() is now called unconditionally on line 652. If bijective_indice (created by appending rep_b from DivideUnusedIterators) is not actually bijective, this could lead to runtime failures or incorrect layout computations.

Potential risks:

  • Layout::Inverse() may fail or produce incorrect results for non-bijective mappings
  • Error messages may be less clear without the pre-check
  • Silent correctness issues if the inverse is computed incorrectly

Please verify that DivideUnusedIterators guarantees a bijective mapping in all cases. Run the following script to check for existing test coverage of edge cases:

Additionally, consider:

  1. Adding explicit checks or assertions that validate bijectivity before inversion
  2. Documenting why the unconditional inversion is safe (if it is proven to be)
  3. Adding test cases that exercise non-trivial index patterns to ensure correctness

🏁 Script executed:

#!/bin/bash
# Description: Check for test coverage of CompleteBufferFragment and bijective mapping edge cases

# Search for tests related to CompleteBufferFragment
echo "=== Tests for CompleteBufferFragment ==="
rg -n "CompleteBufferFragment" --type=cpp --type=py

# Search for tests involving DivideUnusedIterators
echo -e "\n=== Tests for DivideUnusedIterators ==="
rg -n "DivideUnusedIterators" --type=cpp --type=py

# Search for bijective-related tests in parallel operations
echo -e "\n=== Bijective mapping tests ==="
rg -nC3 "bijective.*parallel|parallel.*bijective" --type=cpp --type=py -g '!*.md'

# Look for any comments or documentation about bijective guarantees
echo -e "\n=== Documentation about bijective guarantees ==="
rg -nC2 "DivideUnusedIterators" --type=cpp -A5 -B5

Length of output: 4531


🏁 Script executed:

#!/bin/bash
# Check the implementation of DivideUnusedIterators and MakeFlattenedExpression
echo "=== DivideUnusedIterators implementation ==="
sed -n '122,160p' src/layout/utils.cc

echo -e "\n=== MakeFlattenedExpression signature ==="
rg -A10 "^PrimExpr MakeFlattenedExpression" src/layout/utils.cc

echo -e "\n=== Layout::Inverse() function ==="
rg -n "Inverse()" src/layout/layout.h

echo -e "\n=== Layout::Inverse() implementation ==="
rg -A20 "Layout.*::Inverse()" src/layout/layout.cc

echo -e "\n=== Check for bijective-related comments or checks ==="
rg -nC3 "bijective" src/op/parallel.cc

echo -e "\n=== Look for any error handling or assertions around Inverse ==="
rg -B5 -A5 "->Inverse()" src/op/parallel.cc

Length of output: 995


🏁 Script executed:

#!/bin/bash
# Check the implementation of DivideUnusedIterators and MakeFlattenedExpression
echo "=== DivideUnusedIterators implementation ==="
sed -n '122,160p' src/layout/utils.cc

echo -e "\n=== MakeFlattenedExpression signature ==="
rg -A10 "^PrimExpr MakeFlattenedExpression" src/layout/utils.cc

echo -e "\n=== Layout::Inverse() function ==="
rg -n "Inverse()" src/layout/layout.h

echo -e "\n=== Layout::Inverse() implementation ==="
rg -A20 "Layout.*::Inverse()" src/layout/layout.cc

echo -e "\n=== Check for bijective-related comments or checks ==="
rg -nC3 "bijective" src/op/parallel.cc

echo -e "\n=== Look for error handling or assertions around Inverse in parallel.cc ==="
rg -B5 -A5 "Inverse" src/op/parallel.cc | head -50

Length of output: 9042


🏁 Script executed:

#!/bin/bash
# Check the git history of the file to see what was removed
echo "=== Git history of line 652 changes ==="
git log --oneline -n 20 src/op/parallel.cc

echo -e "\n=== Check if InverseWithLevel has parameters for handling non-bijective ==="
rg -A30 "LayoutNode::InverseWithLevel()" src/layout/layout.cc | head -40

echo -e "\n=== Check what level parameter means in DetectIterMap ==="
rg -B3 "IterMapLevel" src/layout/layout.cc | head -30

echo -e "\n=== Check if there's any old fallback code in git ==="
git log -p --follow -S "pre-check\|fallback" src/op/parallel.cc | head -100

Length of output: 3546


🏁 Script executed:

#!/bin/bash
# Get the full diff of the most relevant commit
echo "=== Full diff of commit 2957afc ==="
git show 2957afc -- src/op/parallel.cc | head -200

echo -e "\n=== Look for InverseWithLevel usage in the same file ==="
rg -n "InverseWithLevel\|Inverse()" src/op/parallel.cc

Length of output: 4193


Remove unconditional Inverse() call or restore bijectivity pre-check and fallback handling.

The current code at line 652 removes critical safety mechanisms that were previously in place. The git history (commit 2957afc) shows the code previously included:

  1. Pre-check for bijectivity: CanProveEqual(in_prod, out_prod) to verify the combined mapping was bijective
  2. Fallback path: If the check failed, it would use Layout(loop_vars_, indice_map_[buffer])->Inverse() without rep_b

Without these safeguards, calling Inverse() unconditionally can fail if bijective_indice is not actually bijective (for example, if DivideUnusedIterators output combined with the original indices creates a non-bijective mapping). The 2D path (lines 626–632) validates bijectivity explicitly before inversion; the fallback path should too.

Options:

  • Restore the cardinality pre-check and fallback handling
  • Or add explicit error handling around the Inverse() call with recovery logic
  • Or document why bijectivity is now guaranteed

@LeiWang1999 LeiWang1999 merged commit 7045f1d into tile-ai:main Nov 11, 2025
5 of 6 checks passed
RubiaCx pushed a commit to RubiaCx/tilelang that referenced this pull request Nov 24, 2025
* fix

* Fix logging level in LayoutNode::InverseWithLevel method from WARNING to DLOG for symbolic layout fallback.

* lint fix

---------

Co-authored-by: Zhiwen Mo <zm125@ic.ac.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants