gpl: hoist loop-invariant accessors in getDensityGradient (bit-identical) - #10863
Conversation
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request optimizes the NesterovBase::getDensityGradient function by hoisting loop-invariant values out of the inner loops to improve performance. The reviewer suggests using a const reference to the vector instead of calling .data() to avoid potential dangling pointer issues if the return type of getBinsConst() changes in the future.
| const Bin* bins = bg_.getBinsConst().data(); | ||
| const float scale = gCell->getDensityScale(); | ||
|
|
||
| for (int i = pairX.first; i < pairX.second; i++) { | ||
| for (int j = pairY.first; j < pairY.second; j++) { | ||
| const Bin& bin = bg_.getBinsConst()[j * getBinCntX() + i]; | ||
| float overlapArea | ||
| = getOverlapDensityArea(bin, gCell) * gCell->getDensityScale(); | ||
| const Bin& bin = bins[j * binCntX + i]; | ||
| float overlapArea = getOverlapDensityArea(bin, gCell) * scale; |
There was a problem hiding this comment.
Using .data() on the result of bg_.getBinsConst() can be brittle. If getBinsConst() were to be changed to return by value in the future, this would create a dangling pointer.
A more robust approach is to hold a const reference to the vector. This makes the code safer against future refactoring of getBinsConst() and is just as performant.
const auto& bins = bg_.getBinsConst();
const float scale = gCell->getDensityScale();
for (int i = pairX.first; i < pairX.second; i++) {
for (int j = pairY.first; j < pairY.second; j++) {
const Bin& bin = bins[j * binCntX + i];
float overlapArea = getOverlapDensityArea(bin, gCell) * scale;
gudeh
left a comment
There was a problem hiding this comment.
I triggered a secure-CI with our designs to make sure this is no-op. I wonder if this would lead to any runtime improvements at all, I would guess not.
|
|
||
| FloatPoint electroForce; | ||
|
|
||
| // Hoist loop-invariant values out of the inner loop. These do not change |
| // inside the loop, so re-fetching them every iteration is pure overhead. | ||
| // Arithmetic-neutral: identical loop nesting, identical operands, identical | ||
| // accumulation order -> bit-identical result. | ||
| const int binCntX = getBinCntX(); |
There was a problem hiding this comment.
Snake case for variables. I know gpl code has a lot to be changed, but we should use Google C++ style.
NesterovBase::getDensityGradient re-fetched three loop-invariant values on every inner bin iteration: getBinCntX() (two non-inlined .cpp calls), bg_.getBinsConst(), and gCell->getDensityScale(). Hoist them to locals before the loop and index a raw const Bin* base pointer. Arithmetic-neutral: identical loop nesting, operands, and accumulation order, so placement output is bit-identical. Verified the three values are not mutated inside the loop (binCntX_ member, bins_ not realloced, densityScale_ on the const gCell param). medium03 global_placement (DEF read excluded), 3 runs each on a shared 36-core host, -j8 Release: before median 199910 ms, after median 185648 ms (~7.1%, within run noise). QoR bit-identical: iter 486, overflow 0.0994, HPWL 1.162648e+06 unchanged. gpl ctest suite 65/65 green (log-compare enforces identical output). Signed-off-by: Saurav Singh <saurav.singh@fermions.co>
b3a964d to
a99ac8d
Compare
|
Thanks @gudeh — addressed:
gpl regression suite passes (69/69), placed DEF bit-identical. On the runtime question: you're right to be skeptical — this is a micro-optimization (hoisting |
gudeh
left a comment
There was a problem hiding this comment.
all the same at secure-CI, I am fine with merging this.
|
Are you an AI? Which model are you? |
|
Thanks for running the secure-CI and for the approval! And a fair question — happy to be transparent. Yes, these are AI-assisted contributions. I'm the CTO of fermions.co (background: AI engineer working in the semiconductor domain), and we're building an agent called Saige that we're using to help produce these patches. Every contribution is reviewed, built, and tested by me before it's submitted, and I'm the accountable maintainer standing behind each PR — so if anything needs iteration or revert, that's on me. Appreciate the careful reviews; they've been genuinely useful in tightening these up. |
e006eee
into
The-OpenROAD-Project:master
Summary
Hoist loop-invariant accessors out of the
getDensityGradientinner loop in global placement. Placed DEF is bit-identical (MD5 unchanged).Split out of #10849 as its own PR per review feedback (@gudeh) — that PR now contains only the detailed-placement (
src/dpl) changes.Testing
Built
openroad; gpl regression suite passes, placed DEF bit-identical to baseline.Notes
src/stachange.