-
Notifications
You must be signed in to change notification settings - Fork 740
AI Generated DPL PR v1 #8873
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?
AI Generated DPL PR v1 #8873
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -17,6 +17,7 @@ | |||||||||
| #include "Padding.h" | ||||||||||
| #include "boost/polygon/polygon.hpp" | ||||||||||
| #include "dpl/Opendp.h" | ||||||||||
| #include "network.h" | ||||||||||
| #include "odb/db.h" | ||||||||||
| #include "odb/dbShape.h" | ||||||||||
| #include "odb/dbTransform.h" | ||||||||||
|
|
@@ -781,4 +782,209 @@ DbuY Grid::rowHeight(GridY index) | |||||||||
| return row_index_to_pixel_height_.at(index.v); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| void Grid::computeUtilizationMap(Network* network, | ||||||||||
| float area_weight, | ||||||||||
| float pin_weight) | ||||||||||
| { | ||||||||||
| // Get grid dimensions | ||||||||||
| const int grid_size = row_count_.v * row_site_count_.v; | ||||||||||
|
|
||||||||||
| if (grid_size == 0) { | ||||||||||
| return; // No grid to work with | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // Store weights for incremental updates | ||||||||||
| area_weight_ = area_weight; | ||||||||||
| pin_weight_ = pin_weight; | ||||||||||
|
|
||||||||||
| // Initialize member vectors for area and pin density accumulation | ||||||||||
| total_area_.assign(grid_size, 0.0f); | ||||||||||
| total_pins_.assign(grid_size, 0.0f); | ||||||||||
| utilization_density_.assign(grid_size, 0.0f); | ||||||||||
|
|
||||||||||
| // Iterate through all movable nodes in the network | ||||||||||
| for (const auto& node_ptr : network->getNodes()) { | ||||||||||
| Node* node = node_ptr.get(); | ||||||||||
| if (!node || node->isFixed() || node->getType() != Node::Type::CELL) { | ||||||||||
| continue; // Skip fixed cells and non-standard cells | ||||||||||
| } | ||||||||||
|
|
||||||||||
| const float cell_area | ||||||||||
| = static_cast<float>(node->getWidth().v * node->getHeight().v); | ||||||||||
| const int num_pins = node->getNumPins(); | ||||||||||
|
|
||||||||||
| // Count pixels covered by this cell first | ||||||||||
| int cell_pixel_count = 0; | ||||||||||
| GridRect cell_grid = gridCovering(node); | ||||||||||
|
|
||||||||||
| for (GridY y = cell_grid.ylo; y < cell_grid.yhi; y++) { | ||||||||||
| for (GridX x = cell_grid.xlo; x < cell_grid.xhi; x++) { | ||||||||||
| Pixel* pixel = gridPixel(x, y); | ||||||||||
| if (pixel && pixel->is_valid) { | ||||||||||
| cell_pixel_count++; | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| if (cell_pixel_count == 0) { | ||||||||||
| continue; // Cell doesn't cover any valid pixels | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // Distribute cell's contribution across its pixels | ||||||||||
| const float area_per_pixel | ||||||||||
| = cell_area / static_cast<float>(cell_pixel_count); | ||||||||||
| const float pins_per_pixel = static_cast<float>(num_pins) | ||||||||||
| / static_cast<float>(cell_pixel_count); | ||||||||||
|
Comment on lines
+836
to
+837
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it suffices to cast just one of these. |
||||||||||
|
|
||||||||||
| for (GridY y = cell_grid.ylo; y < cell_grid.yhi; y++) { | ||||||||||
| for (GridX x = cell_grid.xlo; x < cell_grid.xhi; x++) { | ||||||||||
| Pixel* pixel = gridPixel(x, y); | ||||||||||
| if (pixel && pixel->is_valid) { | ||||||||||
| const int pixel_idx = y.v * row_site_count_.v + x.v; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
Suggested change
|
||||||||||
| if (pixel_idx >= 0 && pixel_idx < grid_size) { | ||||||||||
| total_area_[pixel_idx] += area_per_pixel; | ||||||||||
| total_pins_[pixel_idx] += pins_per_pixel; | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| normalizeUtilization(); | ||||||||||
| utilization_dirty_ = false; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| void Grid::normalizeUtilization() | ||||||||||
| { | ||||||||||
| const int grid_size = total_area_.size(); | ||||||||||
| if (grid_size == 0) { | ||||||||||
| return; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // Find maximum values for normalization | ||||||||||
| float max_area = 0.0f; | ||||||||||
| float max_pins = 0.0f; | ||||||||||
|
|
||||||||||
| // We iterate manually to find max to avoid multiple passes or copies | ||||||||||
| for(float v : total_area_) { | ||||||||||
| if(v > max_area) max_area = v; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: use
Suggested change
|
||||||||||
| } | ||||||||||
| for(float v : total_pins_) { | ||||||||||
| if(v > max_pins) max_pins = v; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: use
Suggested change
|
||||||||||
| } | ||||||||||
|
|
||||||||||
| // Avoid division by zero | ||||||||||
| if (max_area == 0.0f) | ||||||||||
| max_area = 1.0f; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
Comment on lines
+876
to
+878
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok for safety but it is an impossible condition and should be an error instead. Likewise max_pins == 0. |
||||||||||
| if (max_pins == 0.0f) | ||||||||||
| max_pins = 1.0f; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
|
||||||||||
|
|
||||||||||
| // Calculate weighted power density for each pixel | ||||||||||
| float max_util_density = 0.0f; | ||||||||||
| for (int i = 0; i < grid_size; i++) { | ||||||||||
| const float normalized_area = total_area_[i] / max_area; | ||||||||||
| const float normalized_pins = total_pins_[i] / max_pins; | ||||||||||
| float val = area_weight_ * normalized_area | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
Suggested change
|
||||||||||
| + pin_weight_ * normalized_pins; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
Suggested change
|
||||||||||
| utilization_density_[i] = val; | ||||||||||
| if(val > max_util_density) max_util_density = val; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: use
Suggested change
|
||||||||||
| } | ||||||||||
|
|
||||||||||
| // Final normalization of power density to [0, 1] range | ||||||||||
| if (max_util_density > 0.0f) { | ||||||||||
| for (float& density : utilization_density_) { | ||||||||||
| density /= max_util_density; | ||||||||||
| } | ||||||||||
| } | ||||||||||
| utilization_dirty_ = false; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| void Grid::updateUtilizationMap(Node* node, DbuX x, DbuY y, bool add) | ||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This largely duplicates logic from computeUtilizationMap. Common code should be refactored out. |
||||||||||
| { | ||||||||||
| if (!node || node->isFixed() || node->getType() != Node::Type::CELL) { | ||||||||||
| return; // Skip invalid, fixed, or non-standard cells | ||||||||||
| } | ||||||||||
|
|
||||||||||
| const float cell_area | ||||||||||
| = static_cast<float>(node->getWidth().v * node->getHeight().v); | ||||||||||
| const int num_pins = node->getNumPins(); | ||||||||||
|
|
||||||||||
| // Calculate grid rectangle for the cell at the given position | ||||||||||
| const GridX grid_x = gridX(x); | ||||||||||
| const GridY grid_y = gridSnapDownY(y); | ||||||||||
| const GridX grid_x_end = grid_x + gridWidth(node); | ||||||||||
| const GridY grid_y_end = gridEndY(y + node->getHeight()); | ||||||||||
|
|
||||||||||
| // Count valid pixels for this cell | ||||||||||
| int cell_pixel_count = 0; | ||||||||||
| for (GridY gy = grid_y; gy < grid_y_end; gy++) { | ||||||||||
| for (GridX gx = grid_x; gx < grid_x_end; gx++) { | ||||||||||
| Pixel* pixel = gridPixel(gx, gy); | ||||||||||
| if (pixel && pixel->is_valid) { | ||||||||||
| cell_pixel_count++; | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| if (cell_pixel_count == 0) { | ||||||||||
| return; // Cell doesn't cover any valid pixels | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // Calculate per-pixel contributions | ||||||||||
| const float area_per_pixel | ||||||||||
| = cell_area / static_cast<float>(cell_pixel_count); | ||||||||||
| const float pins_per_pixel = static_cast<float>(num_pins) | ||||||||||
| / static_cast<float>(cell_pixel_count); | ||||||||||
| const float sign = add ? 1.0f : -1.0f; | ||||||||||
|
|
||||||||||
| // Update raw totals for affected pixels | ||||||||||
| for (GridY gy = grid_y; gy < grid_y_end; gy++) { | ||||||||||
| for (GridX gx = grid_x; gx < grid_x_end; gx++) { | ||||||||||
| Pixel* pixel = gridPixel(gx, gy); | ||||||||||
| if (pixel && pixel->is_valid) { | ||||||||||
| const int pixel_idx = gy.v * row_site_count_.v + gx.v; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]
Suggested change
|
||||||||||
| if (pixel_idx >= 0 | ||||||||||
| && pixel_idx < static_cast<int>(total_area_.size())) { | ||||||||||
| total_area_[pixel_idx] += sign * area_per_pixel; | ||||||||||
| total_pins_[pixel_idx] += sign * pins_per_pixel; | ||||||||||
|
|
||||||||||
| // Ensure non-negative values (floating point precision safety) | ||||||||||
| if (total_area_[pixel_idx] < 0.0f) | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements] if (total_area_[pixel_idx] < 0.0f)
^this fix will not be applied because it overlaps with another fix |
||||||||||
| total_area_[pixel_idx] = 0.0f; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: use
Suggested change
|
||||||||||
| if (total_pins_[pixel_idx] < 0.0f) | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements] if (total_pins_[pixel_idx] < 0.0f)
^this fix will not be applied because it overlaps with another fix |
||||||||||
| total_pins_[pixel_idx] = 0.0f; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: use
Suggested change
|
||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| utilization_dirty_ = true; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| float Grid::getUtilizationDensity(int pixel_idx) const | ||||||||||
| { | ||||||||||
| // Ideally we would normalize here if dirty, but this is a const method | ||||||||||
| // and we want to avoid mutexes/mutable. | ||||||||||
| // The optimization loop should call normalizeUtilization() explicitly | ||||||||||
| // periodically if it needs fresh normalized values, OR we accept | ||||||||||
| // that we are using slightly stale normalized values based on fresh raw data | ||||||||||
| // (which is what we are doing here - we don't re-normalize on every read). | ||||||||||
| // | ||||||||||
| // However, to respect the expert advice: "Only call normalize... once per | ||||||||||
| // outer pass". | ||||||||||
| // So we return the value from the `utilization_density_` vector which might | ||||||||||
| // be stale relative to `total_area_`. | ||||||||||
| // To make this work better without re-normalizing, we could return | ||||||||||
| // the raw value scaled by the *old* max, but that's complex. | ||||||||||
|
Comment on lines
+977
to
+978
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it that complex? |
||||||||||
| // | ||||||||||
| // For now, return the stored (potentially stale) normalized value. | ||||||||||
| // The user of this class is responsible for calling normalizeUtilization() | ||||||||||
| // when they want to "commit" the raw updates to the normalized view. | ||||||||||
|
|
||||||||||
| if (pixel_idx >= 0 && pixel_idx < utilization_density_.size()) { | ||||||||||
| return utilization_density_[pixel_idx]; | ||||||||||
| } | ||||||||||
| return 0.0f; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| } // namespace dpl | ||||||||||
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.
Somewhat inaccurate as the cell may fully cover some pixels and partially cover others. Probably not a huge effect.