Statistics patch: added netlist loading and parsing time in acct command.

Added devhelp command to obtain information about available devices and device parameters
Added inventory command to print the number of instances per device.
This commit is contained in:
pnenzi 2011-08-09 18:41:36 +00:00
parent 11de01c304
commit 5ba0b8b86c
16 changed files with 382 additions and 7 deletions

View File

@ -76,6 +76,7 @@ libfte_la_SOURCES = \
control.h \
control.c \
ftehelp.h \
ftesopt.c \
hcomp.c \
hcomp.h \
init.c \
@ -129,6 +130,7 @@ libfte_la_SOURCES = \
inpcom.h \
interp.c \
interp.h \
inventory.c \
linear.c \
linear.h \
measure.c \

View File

@ -560,7 +560,16 @@ struct comm spcp_coms[] = {
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
NULL,
" [ vec ... ] : Convert plot into one with linear scale." } ,
{ 0, NULL, FALSE, FALSE, { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
{ "devhelp", com_devhelp, FALSE, FALSE,
{ 040000, 0400000, 040000, 040000 }, E_DEFHMASK, 0, 5 ,
NULL,
"devspecs : show device information." },
{ "inventory", com_inventory, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
NULL,
": Print circuit inventory" },
{ 0, NULL, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
NULL,
NULL }
};
@ -940,9 +949,16 @@ struct comm nutcp_coms[] = {
{ 040000, 040000, 040000, 040000 }, E_DEFHMASK, 0, LOTS,
NULL,
" [ vec ... ] : Convert plot into one with linear scale." } ,
{ 0, NULL, FALSE, FALSE, { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
{ "devhelp",NULL, FALSE, FALSE,
{ 040, 040, 040, 040 }, E_DEFHMASK, 0, 5 ,
NULL,
" devspecs : show device information." },
{ "inventory", NULL, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
NULL,
": Print circuit inventory" } ,
{ 0, NULL, FALSE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
NULL,
NULL }
} ;

View File

@ -26,6 +26,183 @@ static wordlist *devexpand(char *name);
static void all_show(wordlist *wl, int mode);
static void all_show_old(wordlist *wl, int mode);
/*
* devhelp: lists available devices and information on parameters
* devhelp : shows all available devices
* devhelp devname : shows all parameters of that model/instance
* devhelp devname parname : shows parameter meaning
* Options: -csv (comma separated value for generating docs)
*
*/
void com_devhelp(wordlist *wl)
{
/* Just a simple driver now */
devhelp(wl);
}
void devhelp(wordlist *wl)
{
int i, k = 0;
int devindex = -1, devInstParNo = 0 , devModParNo = 0;
bool found = FALSE;
bool csv = FALSE;
wordlist *wlist;
IFparm *plist;
/*First copy the base pointer */
wlist = wl;
/* If there are no arguments output the list of available devices */
if (!wlist) {
out_init();
out_printf("\nDevices available in the simulator\n\n");
for (k = 0; k < ft_sim->numDevices; k++) {
if (ft_sim->devices[k])
out_printf("%-*s:\t%s\n",
DEV_WIDTH, ft_sim->devices[k]->name,
ft_sim->devices[k]->description);
}
out_send("\n");
return;
}
/* The first argument must be the csv option or a device name */
if (wlist && wlist->wl_word && eq(wlist->wl_word, "-csv")) {
csv = TRUE;
if (wlist->wl_next)
wlist = wlist->wl_next;
else
return;
}
/* This argument, if exists, must be the device name */
if (wlist && wlist->wl_word) {
while (k < ft_sim->numDevices && !found) {
if (ft_sim->devices[k])
if (strcasecmp(ft_sim->devices[k]->name, wlist->wl_word) == 0) {
devindex = k;
if (ft_sim->devices[devindex]->numInstanceParms)
devInstParNo = *(ft_sim->devices[devindex]->numInstanceParms);
else
devInstParNo = 0;
if (ft_sim->devices[devindex]->numModelParms)
devModParNo = *(ft_sim->devices[devindex]->numModelParms);
else
devModParNo = 0;
wlist = wlist->wl_next;
found = TRUE;
}
k++;
}
if (!found) {
fprintf(cp_out, "Error: Device %s not found\n", wlist->wl_word);
return;
}
}
/* At this point, found is TRUE and we have found the device.
* Now we have to scan the model and instance parameters to print
* the string
*/
found = FALSE;
if (wlist && wlist->wl_word) {
plist = ft_sim->devices[devindex]->modelParms;
for (i = 0; i < devModParNo; i++) { /* Scan model parameters first */
if (strcasecmp(plist[i].keyword, wlist->wl_word) == 0) {
found = TRUE;
out_init();
printdesc(plist[i], csv);
out_send("\n");
}
}
if (!found) {
plist = ft_sim->devices[devindex]->instanceParms;
for (i = 0; i < devInstParNo; i++) { /* Scan instance parameters then */
if (strcasecmp(plist[i].keyword, wlist->wl_word) == 0) {
found = TRUE;
out_init();
printdesc(plist[i], csv);
out_send("\n");
}
}
}
if (!found)
fprintf(cp_out, "Error: Parameter %s not found\n", wlist->wl_word);
return;
}
/* No arguments - we want all the parameters*/
out_init();
out_printf("%s - %s\n\n", ft_sim->devices[devindex]->name, ft_sim->devices[devindex]->description);
out_printf("Model Parameters\n");
if (csv)
out_printf("id#, Name, Dir, Description\n");
else
out_printf("%5s\t %-10s\t Dir\t Description\n", "id#", "Name");
plist = ft_sim->devices[devindex]->modelParms;
for (i = 0; i < devModParNo; i++)
printdesc(plist[i], csv);
out_printf("\n");
out_printf("Instance Parameters\n");
if (csv)
out_printf("id#, Name, Dir, Description\n");
else
out_printf("%5s\t %-10s\t Dir\t Description\n", "id#", "Name");
plist = ft_sim->devices[devindex]->instanceParms;
for (i = 0; i < devInstParNo; i++)
printdesc(plist[i], csv);
out_send("\n");
}
/*
* Pretty print parameter descriptions
* This function prints description of device parameters
*/
void printdesc(IFparm p, bool csv)
{
char sep;
int spacer1, spacer2;
/* First we indentify the separator */
if (csv) {
sep = ',';
spacer1 = 0;
spacer2 = 0;
} else {
sep = '\t';
spacer1 = 5;
spacer2 = 10;
}
out_printf("%*d%c %-*s%c ", spacer1, p.id, sep, spacer2, p.keyword, sep);
if (p.dataType & IF_SET)
if (p.dataType & IF_ASK)
out_printf("inout%c ", sep);
else
out_printf("in%c ", sep);
else
out_printf("out%c ", sep);
if (p.description)
out_printf("%s\n", p.description);
else
out_printf("n.a.\n");
}
/*
* show: list device operating point info
* show

View File

@ -21,6 +21,10 @@ int printvals(dgen *dg, IFparm *p, int i);
int printvals_old(dgen *dg, IFparm *p, int i);
void old_show(wordlist *wl);
/* DEVHELP*/
void devhelp(wordlist *wl);
void printdesc(IFparm p, bool csv);

View File

@ -26,6 +26,7 @@ $Id$
#include "breakp2.h"
#include "../misc/util.h" /* ngdirname() */
#include "../misc/mktemp.h"
#include "../misc/misc_time.h"
#include "subckt.h"
#include "spiceif.h"
#include "error.h" /* controlled_exit() */
@ -323,9 +324,14 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
FILE *lastin, *lastout, *lasterr;
double temperature_value;
double startTime, endTime;
/* read in the deck from a file */
char *filename_dup = ( filename == NULL ) ? strdup(".") : strdup(filename);
startTime = seconds();
inp_readall(fp, &deck, 0, ngdirname(filename_dup), comfile);
endTime = seconds();
tfree(filename_dup);
/* if nothing came back from inp_readall, just close fp and return to caller */
@ -585,6 +591,8 @@ inp_spsource(FILE *fp, bool comfile, char *filename)
if (ft_curckt) {
ft_curckt->ci_param = NULL;
ft_curckt->ci_meas = NULL;
/* PN add here stats*/
ft_curckt->FTEstats->FTESTATnetLoadTime = endTime - startTime;
}
for (dd = deck; dd; dd = dd->li_next) {
@ -711,6 +719,8 @@ inp_dodeck(
bool noparse, ii;
int print_listing;
double startTime;
/* First throw away any old error messages there might be and fix
the case of the lines. */
for (dd = deck; dd; dd = dd->li_next) {
@ -729,6 +739,9 @@ inp_dodeck(
NULL);
}
ft_curckt = ct = alloc(struct circ);
/*PN FTESTATS*/
ft_curckt->FTEstats = TMALLOC(FTESTATistics, 1);
}
noparse = cp_getvar("noparse", CP_BOOL, NULL);
@ -785,18 +798,23 @@ inp_dodeck(
* if_inpdeck which takes the deck and returns a
* a pointer to the circuit ckt.
*---------------------------------------------------*/
if (!noparse)
if (!noparse) {
startTime = seconds();
ckt = if_inpdeck(deck, &tab);
else
ft_curckt->FTEstats->FTESTATnetParseTime = seconds() - startTime;
} else
ckt = NULL;
out_init();
ft_curckt->FTEstats->FTESTATdeckNumLines = 0;
/*----------------------------------------------------
* Now run through the deck and look to see if there are
* errors on any line.
*---------------------------------------------------*/
for (dd = deck; dd; dd = dd->li_next) {
ft_curckt->FTEstats->FTESTATdeckNumLines += 1;
#ifdef TRACE
/* SDB debug statement */

52
src/frontend/inventory.c Normal file
View File

@ -0,0 +1,52 @@
/**********
Copyright 2010 Paolo Nenzi. All rights reserved.
Author: 2010 Paolo Nenzi
**********/
#include "ngspice.h"
#include "cktdefs.h"
#include "cpdefs.h"
#include "ftedefs.h"
#include "optdefs.h"
#include "dvec.h"
#include "ftehelp.h"
#include "hlpdefs.h"
#include "circuits.h"
#include "where.h"
/*
The inventory command shows the number of instances for each device
in the current circuit.
*/
void
com_inventory(wordlist *wl)
{
CKTcircuit *circuit = NULL;
STATistics *stat = NULL;
STATdevList *devList = NULL;
int k;
NG_IGNORE(wl);
if (!ft_curckt) {
fprintf(cp_err, "There is no current circuit\n");
return;
}
circuit = ft_curckt->ci_ckt;
stat = circuit->CKTstat;
devList = stat->STATdevNum;
out_init();
out_send("Circuit Inventory\n\n");
for (k = 0; k < ft_sim->numDevices; k++) {
if (ft_sim->devices[k])
out_printf("%s: %d\n",
ft_sim->devices[k]->name,
devList[k].instNum);
}
out_send("\n");
return;
}

View File

@ -49,6 +49,9 @@ com_removecirc(wordlist *wl)
tfree(v);
}
/* PN FTESTATS*/
tfree(ct->FTEstats);
ct->ci_vars = NULL;
caux=ft_circuits;
namecircuit = strdup(ft_curckt->ci_name);

View File

@ -395,6 +395,36 @@ printres(char *name)
#endif
}
/* PN Now get all the frontend resource stuff */
if (ft_curckt) {
if (name && eq(name, "task")) {
vfree = v = ft_getstat(ft_curckt, NULL);
} else {
vfree = v = ft_getstat(ft_curckt, name);
}
if (name && v) {
fprintf(cp_out, "%s= ", v->va_name);
wl_print(cp_varwl(v), cp_out);
(void)putc('\n', cp_out);
yy = TRUE;
} else if (v) {
(void) putc('\n', cp_out);
while (v) {
wordlist *wlpr = cp_varwl(v);
fprintf(cp_out, "%s = ", v->va_name);
wl_print(wlpr, cp_out);
wl_free(wlpr);
(void) putc('\n', cp_out);
v = v->va_next;
}
yy = TRUE;
}
}
if(vfree)
free_struct_variable(vfree);
/* Now get all the spice resource stuff. */
if (ft_curckt && ft_curckt->ci_ckt) {

View File

@ -39,6 +39,7 @@ noinst_HEADERS = \
ftedbgra.h \
ftedebug.h \
ftedefs.h \
fteoptdefs.h \
ftedev.h \
fteext.h \
fteinp.h \

View File

@ -15,6 +15,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#define IPOINTMIN 20 /* When we start plotting incremental plots. */
#include "fteparse.h"
#include "fteinp.h"
#include "fteoptdefs.h"
struct save_info {
char *name;
@ -48,6 +49,8 @@ struct circ {
JOB *ci_specOpt; /* the special options anal. for command line jobs */
JOB *ci_curOpt; /* the most recent options anal. for the circuit */
char *ci_last_an; /* name of last analysis run */
FTESTATistics *FTEstats; /* Statistics for the front end */
} ;

View File

@ -123,6 +123,10 @@ extern void *cx_group_delay(void *, short int , int , int *, short int *, struct
extern struct pnode *ft_substdef(const char *name, struct pnode *args);
extern void ft_pnode(struct pnode *pn);
/* DEVHELP*/
extern void com_devhelp(wordlist *wl);
extern void com_inventory(wordlist *wl);
/* dotcards.c */
extern bool ft_acctprint;
@ -151,6 +155,9 @@ extern void externalerror(char *);
extern struct dvec *ft_evaluate(struct pnode *node);
/* ftesopt.c */
extern struct variable *ft_getstat(struct circ *, char *);
/* ginterface.c
extern bool gi_init();

25
src/include/fteoptdefs.h Normal file
View File

@ -0,0 +1,25 @@
/**********
Author: 2010 Paolo Nenzi
**********/
#ifndef FTEOPT
#define FTEOPT
/* Structure used to describe the frontend statistics to be collected */
/* This is similar to the STATististics in optdefs.h but collects */
/* statistics pertaining to ngspice frontend */
typedef struct sFTESTATistics {
int FTESTATdeckNumLines; /* number of lines in spice deck */
double FTESTATnetLoadTime; /* total time required to load the spice deck */
double FTESTATnetParseTime; /* total time required to parse the netlist */
} FTESTATistics;
#define FTEOPT_NLDECK 1
#define FTEOPT_NLT 2
#define FTEOPT_NPT 3
#endif /*FTEOPT*/

View File

@ -9,6 +9,12 @@ Modified: 2000 AlansFixes
/* structure used to describe the statistics to be collected */
typedef struct sSTATdevList {
struct sSTATdevList *STATnextDev;
int modNum;
int instNum;
} STATdevList;
typedef struct {
int STATnumIter; /* number of total iterations performed */
@ -20,6 +26,8 @@ typedef struct {
int STATaccepted; /* number of timepoints accepted */
int STATrejected; /* number of timepoints rejected */
int STATtotalDev; /* PN: number of total devices in the netlist */
double STATtotAnalTime; /* total time for all analysis */
double STATloadTime; /* total time spent in device loading */
double STATdecompTime; /* total time spent in LU decomposition */
@ -40,7 +48,7 @@ typedef struct {
double STATacLoadTime; /* time spent in AC device loading */
double STATacCombTime; /* time spent in AC combining */
double STATacSyncTime; /* time spent in transient sync'ing */
STATdevList *STATdevNum; /* PN: Number of instances and models for each device */
} STATistics;
#define OPT_GMIN 1
@ -130,4 +138,6 @@ typedef struct {
/* gtri - end - wbk - add new options */
#endif
#define OPT_TOTALDEV 200 /* Total devices in the netlist */
#endif /*OPT*/

View File

@ -49,6 +49,15 @@ CKTcrtElt(CKTcircuit *ckt, GENmodel *modPtr, GENinstance **inInstPtr, IFuid name
if (instPtr == NULL)
return E_NOMEM;
/* PN: adding instance number for statistical purpose */
ckt->CKTstat->STATdevNum[type].instNum ++;
ckt->CKTstat->STATtotalDev ++;
#if 0
printf("device: %s number %d\n",
DEVices[type]->DEVpublic.name, ckt->CKTstat->STATdevNum[type].instNum);
#endif
instPtr->GENname = name;
instPtr->GENmodPtr = modPtr;

View File

@ -74,7 +74,13 @@ CKTinit(CKTcircuit **ckt) /* new circuit to create */
sckt->CKTdefaultMosAS = 0;
sckt->CKTsrcFact=1;
sckt->CKTdiagGmin=0;
/* PN: additions for circuit inventory */
sckt->CKTstat = TMALLOC(STATistics, 1);
if(sckt->CKTstat == NULL)
return(E_NOMEM);
sckt->CKTstat->STATdevNum = TMALLOC(STATdevList, DEVmaxnum);
if(sckt->CKTstat->STATdevNum == NULL)
return(E_NOMEM);
sckt->CKTtroubleNode = 0;
sckt->CKTtroubleElt = NULL;
sckt->CKTtimePoints = NULL;

View File

@ -1941,6 +1941,10 @@
RelativePath="..\src\include\ftedefs.h"
>
</File>
<File
RelativePath="..\src\include\fteoptdefs.h"
>
</File>
<File
RelativePath="..\src\include\ftedev.h"
>
@ -5685,6 +5689,10 @@
RelativePath="..\src\misc\hash.c"
>
</File>
<File
RelativePath="..\src\frontend\ftesopt.c"
>
</File>
<File
RelativePath="..\src\frontend\hcomp.c"
>
@ -6309,6 +6317,10 @@
RelativePath="..\src\frontend\interp.c"
>
</File>
<File
RelativePath="..\src\frontend\inventory.c"
>
</File>
<File
RelativePath="..\src\maths\poly\interpolate.c"
>