From 4c3c017f7aac58df9574088b6bbf775729a64a3b Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Wed, 12 Aug 2026 15:23:10 +0000 Subject: [PATCH 1/2] dcalc: reserve per column slack in PrimaDelayCalc::stampEqns Signed-off-by: dsengupta0628 --- dcalc/PrimaDelayCalc.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dcalc/PrimaDelayCalc.cc b/dcalc/PrimaDelayCalc.cc index a5ea608c..a23d417f 100644 --- a/dcalc/PrimaDelayCalc.cc +++ b/dcalc/PrimaDelayCalc.cc @@ -590,6 +590,17 @@ PrimaDelayCalc::stampEqns() C_.setZero(); B_.setZero(); + // The stamps below insert into G_/C_ in parasitic traversal order, which is + // unrelated to the node indices assigned by findNodeCount(). coeffRef() on a + // packed sparse column has no free slot for an out of order insert, so it + // shifts the remaining values over, making stampEqns() quadratic in the node + // count. Reserving slack per column gives the inserts somewhere to land. + // Node degree in an RC network is small; stamp_slack covers the diagonal, the + // resistor and coupling capacitor off diagonals and the driver row. + constexpr int stamp_slack = 8; + G_.reserve(Eigen::VectorXi::Constant(order_, stamp_slack)); + C_.reserve(Eigen::VectorXi::Constant(order_, stamp_slack)); + NetSet drvr_nets(network_); for (ArcDcalcArg &dcalc_arg : *dcalc_args_) { const Net *net = dcalc_arg.drvrNet(network_); From e8af2e8ad9fadfa431adfc54860d2e73fc8ce12b Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Wed, 12 Aug 2026 19:28:15 +0000 Subject: [PATCH 2/2] make same as upstream Signed-off-by: dsengupta0628 --- dcalc/PrimaDelayCalc.cc | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/dcalc/PrimaDelayCalc.cc b/dcalc/PrimaDelayCalc.cc index a23d417f..51f16237 100644 --- a/dcalc/PrimaDelayCalc.cc +++ b/dcalc/PrimaDelayCalc.cc @@ -590,16 +590,12 @@ PrimaDelayCalc::stampEqns() C_.setZero(); B_.setZero(); - // The stamps below insert into G_/C_ in parasitic traversal order, which is - // unrelated to the node indices assigned by findNodeCount(). coeffRef() on a - // packed sparse column has no free slot for an out of order insert, so it - // shifts the remaining values over, making stampEqns() quadratic in the node - // count. Reserving slack per column gives the inserts somewhere to land. - // Node degree in an RC network is small; stamp_slack covers the diagonal, the - // resistor and coupling capacitor off diagonals and the driver row. - constexpr int stamp_slack = 8; - G_.reserve(Eigen::VectorXi::Constant(order_, stamp_slack)); - C_.reserve(Eigen::VectorXi::Constant(order_, stamp_slack)); + // The stamps below do not visit the nodes in index order. Reserve room in + // each column so an out of order coeffRef() insert does not shift the packed + // array to make room, which makes stamping quadratic in the node count. + constexpr int non_zero_entry_count = 8; + G_.reserve(Eigen::VectorXi::Constant(order_, non_zero_entry_count)); + C_.reserve(Eigen::VectorXi::Constant(order_, non_zero_entry_count)); NetSet drvr_nets(network_); for (ArcDcalcArg &dcalc_arg : *dcalc_args_) {