-
Notifications
You must be signed in to change notification settings - Fork 771
mpl: improved notches #9282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
mpl: improved notches #9282
Conversation
There was a problem hiding this 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 an improved notch detection algorithm for penalty calculation, along with debug visualization for the detected notches. The core logic changes are in SACoreSoftMacro::calNotchPenalty. My review focuses on enhancing the performance and maintainability of this new algorithm. I've identified a significant performance bottleneck due to redundant computations and suggest a fix. Additionally, I've provided recommendations for refactoring to reduce code duplication, replacing magic numbers with constants, and removing a non-standard header for better portability.
src/mpl/src/SACoreSoftMacro.cpp
Outdated
|
|
||
| #include "SACoreSoftMacro.h" | ||
|
|
||
| #include <bits/ranges_algo.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/mpl/src/SACoreSoftMacro.cpp
Outdated
| std::vector<int> x_coords; | ||
| int epsilon = outline_.dx() / 100; | ||
| for (size_t i = 0; i < x_point.size(); i++) { | ||
| if (i + 1 < x_point.size() | ||
| && std::abs(x_point[i + 1] - x_point[i]) <= epsilon) { | ||
| continue; | ||
| } | ||
| x_point.insert(macro.getX()); | ||
| x_point.insert(macro.getX() + macro.getWidth()); | ||
| y_point.insert(macro.getY()); | ||
| y_point.insert(macro.getY() + macro.getHeight()); | ||
| x_coords.push_back(x_point[i]); | ||
| } | ||
|
|
||
| std::vector<int> y_coords; | ||
| epsilon = outline_.dy() / 100; | ||
| for (size_t i = 0; i < y_point.size(); i++) { | ||
| if (i + 1 < y_point.size() | ||
| && std::abs(y_point[i + 1] - y_point[i]) <= epsilon) { | ||
| continue; | ||
| } | ||
| y_coords.push_back(y_point[i]); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value 100 is used as a magic number in two places to calculate epsilon. It would be better to define it as a single named constant (e.g., constexpr int kCoordEpsilonDivisor = 100;) at a suitable scope to improve readability, maintainability, and ensure consistency.
References
- Define tunable parameters as named constants instead of using hardcoded magic numbers.
src/mpl/src/SACoreSoftMacro.cpp
Outdated
| if (n.total() == 4) { | ||
| notch_penalty_ += calSingleNotchPenalty(block_->dbuToMicrons(width), | ||
| block_->dbuToMicrons(height)); | ||
| if (graphics_) { | ||
| graphics_->addNotch(odb::Rect(x_coords[start_col], | ||
| y_coords[start_row], | ||
| x_coords[end_col + 1], | ||
| y_coords[end_row + 1])); | ||
| } | ||
| } else if (n.top && n.bottom) { | ||
| if (height < notch_h_th_) { | ||
| notch_penalty_ += calSingleNotchPenalty(block_->dbuToMicrons(width), | ||
| block_->dbuToMicrons(height)); | ||
| if (graphics_) { | ||
| graphics_->addNotch(odb::Rect(x_coords[start_col], | ||
| y_coords[start_row], | ||
| x_coords[end_col + 1], | ||
| y_coords[end_row + 1])); | ||
| } | ||
| } | ||
| } else if (n.left && n.right) { | ||
| if (width < notch_v_th_) { | ||
| notch_penalty_ += calSingleNotchPenalty(block_->dbuToMicrons(width), | ||
| block_->dbuToMicrons(height)); | ||
| if (graphics_) { | ||
| graphics_->addNotch(odb::Rect(x_coords[start_col], | ||
| y_coords[start_row], | ||
| x_coords[end_col + 1], | ||
| y_coords[end_row + 1])); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code block for calculating the notch penalty and adding the notch for visualization is duplicated in three places within the if-else if structure. This can be refactored to improve maintainability and reduce redundancy.
You could determine if a notch should be penalized using a boolean flag, and then have a single block of code that performs the penalty calculation and graphics update.
bool is_notch = false;
if (n.total() == 4) {
is_notch = true;
} else if (n.top && n.bottom) {
if (height < notch_h_th_) {
is_notch = true;
}
} else if (n.left && n.right) {
if (width < notch_v_th_) {
is_notch = true;
}
}
if (is_notch) {
notch_penalty_ += calSingleNotchPenalty(block_->dbuToMicrons(width),
block_->dbuToMicrons(height));
if (graphics_) {
graphics_->addNotch(odb::Rect(x_coords[start_col],
y_coords[start_row],
x_coords[end_col + 1],
y_coords[end_row + 1]));
}
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clang-tidy made some suggestions
src/mpl/src/SACoreSoftMacro.cpp
Outdated
| #include <cmath> | ||
| #include <iterator> | ||
| #include <limits> | ||
| #include <ranges> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: included header limits is not used directly [misc-include-cleaner]
| #include <ranges> | |
| #include <ranges> |
| #include <iterator> | ||
| #include <limits> | ||
| #include <ranges> | ||
| #include <set> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: included header ranges is not used directly [misc-include-cleaner]
| #include <set> | |
| #include <set> |
src/mpl/src/SACoreSoftMacro.cpp
Outdated
|
|
||
| if (graphics_) { | ||
| graphics_->setNotchPenalty( | ||
| {"Notch", notch_weight_, notch_penalty_, norm_notch_penalty_}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: use designated initializer list to initialize 'PenaltyData' [modernize-use-designated-initializers]
| {"Notch", notch_weight_, notch_penalty_, norm_notch_penalty_}); | |
| {.name="Notch", .weight=notch_weight_, .value=notch_penalty_, .normalization_factor=norm_notch_penalty_}); |
Additional context
src/mpl/src/mpl-util.h:89: aggregate type is defined here
struct PenaltyData
^
src/mpl/src/SACoreSoftMacro.cpp
Outdated
|
|
||
| std::vector<int> x_coords; | ||
| int epsilon = outline_.dx() / 100; | ||
| for (size_t i = 0; i < x_point.size(); i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: no header providing "size_t" is directly included [misc-include-cleaner]
src/mpl/src/SACoreSoftMacro.cpp:9:
- #include <iterator>
+ #include <cstddef>
+ #include <iterator>|
clang-tidy review says "All clean, LGTM! 👍" |
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
94f3969 to
407f91a
Compare
|
clang-tidy review says "All clean, LGTM! 👍" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that the notch function is too big and should be broken into smaller pieces, that's why most of the comments. We've been making a large effort to a more granular code and it has been proven to be a very helpful thing.
I tend to prefer functions over lambdas if it starts to get too big. I think it does depend on the context (it looks that the idea here was to keep the notch detection code well encapsulated), but for concision and readability, let's keep things smaller. We can have a "section" of methods only for notch penalty.
A question: are the notches being erased when rendering after MPL is done? (see eraseDrawing).
src/mpl/src/SACoreSoftMacro.cpp
Outdated
| bool left = true; | ||
| bool right = true; | ||
|
|
||
| int total() { return top + bottom + left + right; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of implicit casting. However the logic here is sound. @maliberty would you have an opinion on it?
src/mpl/src/SACoreSoftMacro.cpp
Outdated
| for (int col = 0; col < num_x; col++) { | ||
| if (grid[row][col]) { | ||
| continue; | ||
| auto neighbors = [&](int row1, int col1, int row2, int col2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be a function `findNeighbors".
src/mpl/src/SACoreSoftMacro.cpp
Outdated
| int end_row = start_row; | ||
| int end_col = start_col; | ||
|
|
||
| Neighbors n = neighbors(start_row, start_col, end_row, end_col); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, avoid this type of abbreviation.
src/mpl/src/SACoreSoftMacro.cpp
Outdated
| return neighbors; | ||
| }; | ||
|
|
||
| auto valid = [&](int row1, int col1, int row2, int col2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should also be a function. Validity doesn't feel like the best quality here. Perhaps expansionOverlapped or something in this sense? I'm not attached to my suggestion.
src/mpl/src/SACoreSoftMacro.cpp
Outdated
| return; | ||
| } | ||
|
|
||
| struct Neighbors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be a member of the annealer itself. I also think we should have a comment explaining what are Neighbors (seeing a boolean in the code doesn't tell us much).
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
Signed-off-by: João Mai <jmai@precisioninno.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
src/mpl/src/graphics.cpp
Outdated
| painter.drawRect(rect); | ||
| } | ||
|
|
||
| // notches_.clear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leftover?
Signed-off-by: João Mai <jmai@precisioninno.com>
|
clang-tidy review says "All clean, LGTM! 👍" |
This PR improves the notch detection for the notch penalty calculation. It achieves it by considering closely aligned macros as aligned (in order to generate a more meaningful grid) and merging cells in order to find the notches actual size and amount.
It also enhances the debug visualization, showing the notches when using the mpl::mpl_debug command.