OpenSTA/dcalc
Drew Lewis 832c62b579
Refactor DMP solver to use Eigen and implement Determinant Guarded solver (#450)
This commit refactors the Dartu-Menezes-Pileggi (DMP) effective capacitance
algorithm solver to use the Eigen library, and implements a Determinant Guarded
solver to handle singular and near-singular Jacobians safely and efficiently.

Key changes:
1. Refactored the DMP solver to use Eigen stack-based data structures,
   replacing the custom Crout LU decomposition and solver.
2. Extracted the linear solver logic into a dedicated helper function
   DmpAlg::solveNewtonStep.
3. Implemented a "Determinant Guarded" solver:
   - Manually checks the determinant of the Jacobian (safety guard).
   - Throws a DmpError if the determinant is dangerously close to zero (|det| < 1e-12),
     safely triggering the lumped capacitance fallback.
   - Otherwise, solves using Eigen's highly optimized analytical inverse (fast path).
4. Added documentation in the comments on how to easily swap back to LU
   decomposition with partial pivoting (PartialPivLU) if any numerical
   precision issues arise in the future.

Benchmark Results (Optimized Release Build, 5,288 DMP calls):

| Test Case | Calls | 1. Original (Crout LU) | 2. Eigen (PartialPivLU) | 3. Eigen (Determinant Guarded) | Speedup (3 vs 1) | Speedup (3 vs 2) |
| :--- | :---: | :---: | :---: | :---: | :---: | :---: |
| power | 2,608 | 1.8822 ms | 1.6791 ms | 1.2702 ms | +32.5% | +24.4% |
| power_vcd | 2,608 | 1.8729 ms | 1.6704 ms | 1.2768 ms | +31.8% | +23.6% |
| spef_parasitics | 24 | 0.0193 ms | 0.0187 ms | 0.0140 ms | +27.5% | +25.1% |
| mcmm3 | 48 | 0.0728 ms | 0.0756 ms | 0.0817 ms | -12.2% | -8.1% |
| Total DMP Time | 5,288 | 3.8472 ms | 3.4438 ms | 2.6427 ms | +31.3% | +23.3% |
2026-06-18 13:52:14 -07:00
..
ArcDcalcWaveforms.cc clang tidy 2026-04-15 09:38:10 -07:00
ArcDcalcWaveforms.hh tidy round1 2026-04-13 14:59:05 -07:00
ArcDelayCalc.cc clang tidy 2026-04-15 09:38:10 -07:00
Arnoldi.hh tidy 2026-04-21 17:30:35 -07:00
Arnoldi.txt arnoldi delay calculator 2018-10-24 14:22:21 -07:00
ArnoldiDelayCalc.cc copy() use copy constructors 2026-05-05 17:25:09 -07:00
ArnoldiDelayCalc.hh tidy round1 2026-04-13 14:59:05 -07:00
ArnoldiReduce.cc tidy 2026-04-21 17:30:35 -07:00
ArnoldiReduce.hh clang tidy 2026-04-15 09:38:10 -07:00
CcsCeffDelayCalc.cc copy() use copy constructors 2026-05-05 17:25:09 -07:00
CcsCeffDelayCalc.hh copy() use copy constructors 2026-05-05 17:25:09 -07:00
DcalcAnalysisPt.cc rel 3.0 2026-01-13 09:36:45 -07:00
Delay.cc clang tidy 2026-04-15 09:38:10 -07:00
DelayCalc.cc clang tidy 2026-04-15 09:38:10 -07:00
DelayCalc.i rm extra swig module dcls 2026-04-16 15:46:32 -07:00
DelayCalc.tcl use std::format squash 2026-03-16 15:01:38 -07:00
DelayCalcBase.cc clang tidy 2026-04-15 09:38:10 -07:00
DelayCalcBase.hh clang tidy 2026-04-15 09:38:10 -07:00
DelayNormal.cc untabify 2026-04-25 14:45:49 -07:00
DelayScalar.cc clang tidy 2026-04-15 09:38:10 -07:00
DelaySkewNormal.cc clang tidy 2026-04-15 09:38:10 -07:00
DmpCeff.cc Refactor DMP solver to use Eigen and implement Determinant Guarded solver (#450) 2026-06-18 13:52:14 -07:00
DmpCeff.hh Refactor DMP solver to use Eigen and implement Determinant Guarded solver (#450) 2026-06-18 13:52:14 -07:00
DmpDelayCalc.cc Dmp delay calc inline algs 2026-05-05 17:08:16 -07:00
DmpDelayCalc.hh tidy round1 2026-04-13 14:59:05 -07:00
FindRoot.cc clang tidy 2026-04-15 09:38:10 -07:00
FindRoot.hh clang tidy 2026-04-15 09:38:10 -07:00
GraphDelayCalc.cc sta_internal_bidirect_instance_paths_enabled use load->driver edges 2026-06-15 17:02:58 -07:00
LumpedCapDelayCalc.cc copy() use copy constructors 2026-05-05 17:25:09 -07:00
LumpedCapDelayCalc.hh clang tidy 2026-04-15 09:38:10 -07:00
NetCaps.cc clang tidy 2026-04-15 09:38:10 -07:00
NetCaps.hh clang tidy 2026-04-15 09:38:10 -07:00
ParallelDelayCalc.cc clang tidy 2026-04-15 09:38:10 -07:00
ParallelDelayCalc.hh clang tidy 2026-04-15 09:38:10 -07:00
PrimaDelayCalc.cc prima non-ccs report dcalc resolves #418 2026-04-16 15:13:28 -07:00
PrimaDelayCalc.hh clang tidy 2026-04-15 09:38:10 -07:00
UnitDelayCalc.cc copy() use copy constructors 2026-05-05 16:58:59 -07:00
UnitDelayCalc.hh tidy round1 2026-04-13 14:59:05 -07:00