From e1677a18c43ddf5f8791a9e9c28ca31baaeff0da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81rp=C3=A1d=20B=C5=B1rmen?= Date: Mon, 23 Dec 2024 09:08:51 +0100 Subject: [PATCH 1/2] Per-device load timing support. --- src/frontend/resource.c | 18 +++++++++++++++++- src/include/ngspice/optdefs.h | 4 ++++ src/spicelib/analysis/cktdest.c | 2 ++ src/spicelib/analysis/cktload.c | 17 ++++++++++++++++- src/spicelib/devices/cktinit.c | 3 +++ 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/frontend/resource.c b/src/frontend/resource.c index 60cd0d620..4f0478d07 100644 --- a/src/frontend/resource.c +++ b/src/frontend/resource.c @@ -14,6 +14,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice/ngspice.h" #include "ngspice/cpdefs.h" #include "ngspice/ftedefs.h" +#include "ngspice/devdefs.h" #include "circuits.h" #include "resource.h" @@ -325,7 +326,22 @@ printres(char *name) /* Now get all the spice resource stuff. */ if (ft_curckt && ft_curckt->ci_ckt) { - + if (name && eq(name, "devtimes")) { + /* Per-device timings */ + for(int i=0; i<=DEVmaxnum; i++) { + if (ft_curckt->ci_ckt->CKTstat->devCounts[i]==0) { + continue; + } + fprintf(cp_out, "%s: t=%f n=%ld t/n=%e\n", + (i==DEVmaxnum ? "\noverhead" : DEVices[i]->DEVpublic.name), + ft_curckt->ci_ckt->CKTstat->devTimes[i], + ft_curckt->ci_ckt->CKTstat->devCounts[i], + ft_curckt->ci_ckt->CKTstat->devTimes[i]/(double)(ft_curckt->ci_ckt->CKTstat->devCounts[i]) + ); + } + } + yy = TRUE; + #ifdef CIDER /* begin cider integration */ if (!name || eq(name, "circuit") || eq(name, "task")) diff --git a/src/include/ngspice/optdefs.h b/src/include/ngspice/optdefs.h index 6e8a5549f..3455a2454 100644 --- a/src/include/ngspice/optdefs.h +++ b/src/include/ngspice/optdefs.h @@ -7,6 +7,8 @@ Modified: 2000 AlansFixes #ifndef ngspice_OPTDEFS_H #define ngspice_OPTDEFS_H +#include + /* structure used to describe the statistics to be collected */ typedef struct sSTATdevList { @@ -46,6 +48,8 @@ typedef struct { double STATacLoadTime; /* time spent in AC device loading */ double STATacSyncTime; /* time spent in transient sync'ing */ STATdevList *STATdevNum; /* PN: Number of instances and models for each device */ + double *devTimes; /* Per-device load times, last entry is overhead */ + size_t *devCounts; /* Per-device load counts, last entry is overhead */ } STATistics; enum { diff --git a/src/spicelib/analysis/cktdest.c b/src/spicelib/analysis/cktdest.c index 24ed208d8..8a868a5f4 100644 --- a/src/spicelib/analysis/cktdest.c +++ b/src/spicelib/analysis/cktdest.c @@ -98,6 +98,8 @@ CKTdestroy(CKTcircuit *ckt) #endif FREE(ckt->CKTstat->STATdevNum); + FREE(ckt->CKTstat->devCounts); + FREE(ckt->CKTstat->devTimes); FREE(ckt->CKTstat); FREE(ckt->CKThead); diff --git a/src/spicelib/analysis/cktload.c b/src/spicelib/analysis/cktload.c index b56f7e255..3088efcfa 100644 --- a/src/spicelib/analysis/cktload.c +++ b/src/spicelib/analysis/cktload.c @@ -27,12 +27,13 @@ Modified: 2000 AlansFixes static int ZeroNoncurRow(SMPmatrix *matrix, CKTnode *nodes, int rownum); +// #define PER_DEVICE_STATS int CKTload(CKTcircuit *ckt) { int i; int size; - double startTime; + double startTime, td0; CKTnode *node; int error; #ifdef STEPDEBUG @@ -49,6 +50,13 @@ CKTload(CKTcircuit *ckt) /* gtri - begin - Put resistors to ground at all nodes */ #endif + td0 = SPfrontEnd->IFseconds(); + +#ifdef PER_DEVICE_STATS + ckt->CKTstat->devTimes[DEVmaxnum] += SPfrontEnd->IFseconds() - td0; + ckt->CKTstat->devCounts[DEVmaxnum]++; +#endif + startTime = SPfrontEnd->IFseconds(); size = SMPmatSize(ckt->CKTmatrix); for (i = 0; i <= size; i++) { @@ -61,7 +69,14 @@ CKTload(CKTcircuit *ckt) for (i = 0; i < DEVmaxnum; i++) { if (DEVices[i] && DEVices[i]->DEVload && ckt->CKThead[i]) { +#ifdef PER_DEVICE_STATS + td0 = SPfrontEnd->IFseconds(); +#endif error = DEVices[i]->DEVload (ckt->CKThead[i], ckt); +#ifdef PER_DEVICE_STATS + ckt->CKTstat->devTimes[i] += SPfrontEnd->IFseconds() - td0; + ckt->CKTstat->devCounts[i]++; +#endif if (ckt->CKTnoncon) ckt->CKTtroubleNode = 0; #ifdef STEPDEBUG diff --git a/src/spicelib/devices/cktinit.c b/src/spicelib/devices/cktinit.c index ea4ed0c29..ad1cce399 100644 --- a/src/spicelib/devices/cktinit.c +++ b/src/spicelib/devices/cktinit.c @@ -82,6 +82,9 @@ CKTinit(CKTcircuit **ckt) /* new circuit to create */ sckt->CKTstat->STATdevNum = TMALLOC(STATdevList, DEVmaxnum); if(sckt->CKTstat->STATdevNum == NULL) return(E_NOMEM); + /* Per-device timings */ + sckt->CKTstat->devTimes = TMALLOC(double, DEVmaxnum+1); + sckt->CKTstat->devCounts = TMALLOC(size_t, DEVmaxnum+1); sckt->CKTtroubleNode = 0; sckt->CKTtroubleElt = NULL; sckt->CKTtimePoints = NULL; From 9693e304eaaf9439eab5bbd4d449dc27fe2abd7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81rp=C3=A1d=20B=C5=B1rmen?= Date: Tue, 7 Jan 2025 13:13:49 +0100 Subject: [PATCH 2/2] initializeLimiting -> iniLim, reorder sim_params for faster OSDI device evaluation. --- .gitignore | 3 +++ src/osdi/osdiload.c | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 62177c06b..b9eec8a42 100644 --- a/.gitignore +++ b/.gitignore @@ -90,3 +90,6 @@ src/spicelib/parser/inpptree-parser.h test_cases/diode/__pycache__/* test_cases/diode/test_osdi/* test_cases/diode/test_built_in/* + +build*/ +prof/ \ No newline at end of file diff --git a/src/osdi/osdiload.c b/src/osdi/osdiload.c index a36673d62..3180d5f31 100644 --- a/src/osdi/osdiload.c +++ b/src/osdi/osdiload.c @@ -25,8 +25,8 @@ #define NUM_SIM_PARAMS 10 char *sim_params[NUM_SIM_PARAMS + 1] = { - "gdev", "gmin", "tnom", - "simulatorVersion", "sourceScaleFactor", "initializeLimiting", + "iniLim", "gmin", "gdev", "tnom", + "simulatorVersion", "sourceScaleFactor", "epsmin", "reltol", "vntol", "abstol", NULL}; char *sim_params_str[1] = {NULL}; @@ -44,7 +44,7 @@ OsdiSimParas get_simparams(const CKTcircuit *ckt) { double sim_param_vals_[NUM_SIM_PARAMS] = { // Verilog-A tnom is in degrees Celsius - gdev, gmin, ckt->CKTnomTemp-CONSTCtoK, simulatorVersion, sourceScaleFactor, initializeLimiting, + initializeLimiting, gmin, gdev, ckt->CKTnomTemp-CONSTCtoK, simulatorVersion, sourceScaleFactor, ckt->CKTepsmin, ckt->CKTreltol, ckt->CKTvoltTol, ckt->CKTabstol }; memcpy(&sim_param_vals, &sim_param_vals_, sizeof(double) * NUM_SIM_PARAMS); OsdiSimParas sim_params_ = {.names = sim_params,