Skip to content

odb: refactor 3dblox checkOverlappingChips#9469

Open
ahmed532 wants to merge 2 commits intoThe-OpenROAD-Project:masterfrom
ahmed532:feat/3dblox-checker-checkOverlappingChips
Open

odb: refactor 3dblox checkOverlappingChips#9469
ahmed532 wants to merge 2 commits intoThe-OpenROAD-Project:masterfrom
ahmed532:feat/3dblox-checker-checkOverlappingChips

Conversation

@ahmed532
Copy link

@ahmed532 ahmed532 commented Feb 14, 2026

refactors the 3DBlox checkOverlappingChips

Significantly improve performance.

Changes:

  • Logic Fix: Relaxed Checker::isValid to allow INTERNAL_EXT connections between different parent chips, provided their Z-ranges intersect.
  • Use a line sweep algorithm for overlap checking for better performance.
  • Testing: Added comprehensive test cases to Test3DBloxChecker covering:
    • Complex multi-chip overlap scenarios.

Validation

Passed all tests in Test3DBloxChecker.
Verified that existing functionality for floating chips and simple overlaps remains correct.

Related to: #9291

Allow overlapping embedded chips.
Use a line sweep algorithm and connection map for better performance.
Create more tests.

Signed-off-by: Ahmed R. Mohamed <ahmed@precisioninno.com>
@ahmed532 ahmed532 self-assigned this Feb 14, 2026
Copy link
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 refactors the checkOverlappingChips function to improve performance and support overlapping embedded chips. The changes include using a sweep-line algorithm for faster overlap detection and relaxing the validation for INTERNAL_EXT connections to handle embedded chip scenarios. The code is cleaner and more modern. The addition of comprehensive test cases is a great way to ensure the new logic is correct. Overall, this is a solid improvement, with a suggestion for minor readability and performance enhancement by moving a lambda definition outside a loop.

Comment on lines 191 to 228
{
auto overlap = chip1->cuboid.intersect(chip2->cuboid);
Rect overlap_rect(
overlap.xMin(), overlap.yMin(), overlap.xMax(), overlap.yMax());

const auto* c1 = chip1;
const auto* c2 = chip2;
if (c1 > c2) {
std::swap(c1, c2);
}

auto it = connection_map.find({c1, c2});
if (it == connection_map.end()) {
return false;
}

for (const auto* conn_ptr : it->second) {
const auto& conn = *conn_ptr;
// We already know parent chips match c1/c2 due to map validation
if (!isValid(conn)) {
continue;
}
auto* r1 = conn.top_region;
auto* r2 = conn.bottom_region;
auto valid = [&](auto* r) {
return r->isInternalExt()
&& Rect(r->cuboid.xMin(),
r->cuboid.yMin(),
r->cuboid.xMax(),
r->cuboid.yMax())
.contains(overlap_rect);
};
if (valid(r1) || valid(r2)) {
return true;
}
}
return false;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For improved readability and to avoid recreating the lambda in each iteration of the loop, you can define the valid lambda before the loop starts.

{
  auto overlap = chip1->cuboid.intersect(chip2->cuboid);
  Rect overlap_rect(
      overlap.xMin(), overlap.yMin(), overlap.xMax(), overlap.yMax());

  const auto* c1 = chip1;
  const auto* c2 = chip2;
  if (c1 > c2) {
    std::swap(c1, c2);
  }

  auto it = connection_map.find({c1, c2});
  if (it == connection_map.end()) {
    return false;
  }

  auto valid = [&](const auto* r) {
    return r->isInternalExt()
           && Rect(r->cuboid.xMin(),
                   r->cuboid.yMin(),
                   r->cuboid.xMax(),
                   r->cuboid.yMax())
                  .contains(overlap_rect);
  };

  for (const auto* conn_ptr : it->second) {
    const auto& conn = *conn_ptr;
    // We already know parent chips match c1/c2 due to map validation
    if (!isValid(conn)) {
      continue;
    }
    auto* r1 = conn.top_region;
    auto* r2 = conn.bottom_region;
    if (valid(r1) || valid(r2)) {
      return true;
    }
  }
  return false;
}

Copy link
Member

Choose a reason for hiding this comment

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

please define externally in a namespace

@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Member

@osamahammad21 osamahammad21 left a comment

Choose a reason for hiding this comment

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

I feel that using connections to verify overlap violations is an overkill. It is simply a violation if 2 chiplets overlap at any condition.

Comment on lines 191 to 228
{
auto overlap = chip1->cuboid.intersect(chip2->cuboid);
Rect overlap_rect(
overlap.xMin(), overlap.yMin(), overlap.xMax(), overlap.yMax());

const auto* c1 = chip1;
const auto* c2 = chip2;
if (c1 > c2) {
std::swap(c1, c2);
}

auto it = connection_map.find({c1, c2});
if (it == connection_map.end()) {
return false;
}

for (const auto* conn_ptr : it->second) {
const auto& conn = *conn_ptr;
// We already know parent chips match c1/c2 due to map validation
if (!isValid(conn)) {
continue;
}
auto* r1 = conn.top_region;
auto* r2 = conn.bottom_region;
auto valid = [&](auto* r) {
return r->isInternalExt()
&& Rect(r->cuboid.xMin(),
r->cuboid.yMin(),
r->cuboid.xMax(),
r->cuboid.yMax())
.contains(overlap_rect);
};
if (valid(r1) || valid(r2)) {
return true;
}
}
return false;
}
Copy link
Member

Choose a reason for hiding this comment

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

please define externally in a namespace

Comment on lines 223 to 225
if (valid(r1) || valid(r2)) {
return true;
}
Copy link
Member

Choose a reason for hiding this comment

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

why would this be valid?

Copy link
Author

Choose a reason for hiding this comment

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

The spec allows it like in the diagram on page 18 cases 1 and 3. We define the internal_ext region to span the whole chip z (for now) and this check ensure that it's x and y span the whole overlap (embedded chip).

@ahmed532
Copy link
Author

The spec allows embedded chiplets connected via internal_ext. That means one chiplet completely inside another -- an overlap. But that is not a violation if the internal_ext region covers the overlap. You can find examples in the tests.

Signed-off-by: Ahmed R. Mohamed <ahmed@precisioninno.com>
@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

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