00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 # include <stdio.h>
00055 # include <stdlib.h>
00056
00057 # include <math.h>
00058 # include <errno.h>
00059 # include <string.h>
00060 # include <iostream.h>
00061 # include <stdlib.h>
00062 # include <unistd.h>
00063 # include <string.h>
00064 # include <fcntl.h>
00065 # include <map.h>
00066
00067 #ifdef IPPL_TFLOP
00068 extern "C" int getopt(int, char *const *, const char *);
00069 extern char *optarg;
00070 extern int optind, opterr, optopt;
00071 #endif
00072
00073
00074
00075 # ifndef TRUE
00076 # define FALSE 0
00077 # define TRUE 1
00078 # endif
00079
00080 # if defined(ultrix) || defined(sequent) || defined(butterfly)
00081 double fmod (double x, double y)
00082 {
00083 return ( x - floor(x/y) * y );
00084 }
00085 # endif
00086
00087 static struct p_func_descr {
00088 #ifdef USE_LONG
00089 long numcalls;
00090 long numsubrs;
00091 #else // DEFAULT double
00092 double numcalls;
00093 double numsubrs;
00094 #endif // USE_LONG
00095 double usec;
00096 double cumusec;
00097 double stddeviation;
00098 } *p_func_list = 0;
00099
00100 static struct p_prof_elem {
00101 char *name;
00102 int tag;
00103 #ifdef USE_LONG
00104 long numcalls;
00105 long numsubrs;
00106 #else // DEFAULT double
00107 double numcalls;
00108 double numsubrs;
00109 #endif //USE_LONG
00110 double usec;
00111 double cumusec;
00112 double stddeviation;
00113 } *p_prof_tbl = 0,
00114 *p_min_tbl = 0,
00115 *p_max_tbl = 0,
00116 *p_total_tbl = 0;
00117
00118
00119 int top_level_function;
00120 double max_thread_cumusec = 0.0;
00121 static struct p_coll_descr {
00122 int numelem;
00123 int dim;
00124 int size;
00125 int localacs;
00126 int remoteacs;
00127 char *collname;
00128 char *elemname;
00129 char *varname;
00130 } *p_coll_list = 0,
00131 *p_coll_tbl = 0;
00132
00133 #define MAX_COUNTERS 1024
00134 #define SIZE_OF_LINE 64*1024
00135 #define SIZE_OF_FILENAME 1024
00136
00137 static struct p_aggr_descr {
00138 int numelem;
00139 int dim;
00140 int size;
00141 long counters[MAX_COUNTERS];
00142 long total_events;
00143 char *container_name;
00144 char *container_type;
00145 char *var_name;
00146 } *p_aggr_list = 0,
00147 *p_aggr_tbl = 0;
00148
00149 static int numfunc;
00150 static int filledDBThr, filledDBCtx = 0;
00151 static char *depfile;
00152 static char proffile[256];
00153 static char **funcnamebuf;
00154 static int *functagbuf;
00155 static int numcoll;
00156 static char **eventnamebuf = 0;
00157 static int numevents;
00158 static int numaggr;
00159 static double total_total;
00160 static double min_total;
00161 static double max_total;
00162 static int nodeprint = TRUE;
00163 static int dump = FALSE;
00164 static int dumpminmax = FALSE;
00165 static int list = FALSE;
00166 static char lbuf[256];
00167 static char sbuf[128];
00168 static int hpcxx_flag = FALSE;
00169 static int hwcounters = false;
00170 static int profilestats = false;
00171 static int files_processed = 0;
00172
00173
00174
00175 int FunctionSummaryInfo(int no, int ctx, int thr, int max);
00176 static char *strsave (const char *s);
00177 static int MsecCmp (const void *left, const void *right);
00178 static int CumMsecCmp (const void *left, const void *right);
00179 static int StdDevCmp (const void *left, const void *right);
00180 static int CallCmp (const void *left, const void *right);
00181 static void DumpFuncTab (struct p_prof_elem *tab, char *id_str, double total,
00182 int max, char *order);
00183 static void PrintFuncTab (struct p_prof_elem *tab, double total, int max);
00184
00185 static int (* compar)(const void *, const void *) = CumMsecCmp;
00186
00187
00188 struct ltstr
00189 {
00190 bool operator()(const char* s1, const char* s2) const
00191 {
00192 return strcmp(s1, s2) < 0;
00193 }
00194 };
00195
00196 class FunctionData {
00197 public :
00198 #ifdef USE_LONG
00199 long numcalls;
00200 long numsubrs;
00201 #else // DEFAULT double
00202 double numcalls;
00203 double numsubrs;
00204 #endif // USE_LONG
00205 double excl;
00206 double incl;
00207 double stddeviation;
00208 #ifdef USE_LONG
00209 FunctionData(long nc, long ns, double ex, double in, double sigma)
00210 : numcalls(nc), numsubrs(ns), excl(ex), incl(in), stddeviation(sigma) { }
00211 #else // DEFAULT double
00212 FunctionData(double nc, double ns, double ex, double in, double sigma)
00213 : numcalls(nc), numsubrs(ns), excl(ex), incl(in), stddeviation(sigma) { }
00214 #endif // USE_LONG
00215 FunctionData() {
00216 numcalls = numsubrs = 0;
00217 excl = incl = stddeviation = 0;
00218 }
00219 FunctionData(const FunctionData& X) {
00220 numcalls = X.numcalls;
00221 numsubrs = X.numsubrs;
00222 excl = X.excl;
00223 incl = X.incl;
00224 stddeviation = X.stddeviation;
00225 }
00226 FunctionData& operator= (const FunctionData& X) {
00227 numcalls = X.numcalls;
00228 numsubrs = X.numsubrs;
00229 excl = X.excl;
00230 incl = X.incl;
00231 stddeviation = X.stddeviation;
00232 return *this;
00233 }
00234 FunctionData& operator+= (const FunctionData& X) {
00235 numcalls += X.numcalls;
00236 numsubrs += X.numsubrs;
00237 excl += X.excl;
00238 incl += X.incl;
00239 stddeviation += X.stddeviation;
00240 return *this;
00241 }
00242 ~FunctionData() { }
00243 };
00244
00245 map<const char*, FunctionData, ltstr> funcDB;
00246
00247 bool IsDynamicProfiling(char *filename)
00248 {
00249 FILE *fp;
00250 char error_msg[SIZE_OF_FILENAME], version[64];
00251 int numberOfFunctions;
00252
00253 if ((fp = fopen(filename, "r")) == NULL) {
00254 sprintf(error_msg,"Error: Could not open %s",filename);
00255 perror(error_msg);
00256 return false;
00257 }
00258 if (fscanf(fp, "%d %s",&numberOfFunctions, version) == EOF) {
00259 printf("Error: fscanf returns EOF file %s", filename);
00260 return false;
00261 }
00262 fclose(fp);
00263
00264 if (strcmp(version,"templated_functions") == 0) {
00265 hwcounters = false;
00266 return true;
00267 }
00268 else {
00269 if (strcmp(version,"templated_functions_hw_counters") == 0) {
00270 hwcounters = true;
00271 return true;
00272 }
00273 else
00274 return false;
00275 }
00276 }
00277
00278
00279 int InitFuncNameBuf(void)
00280 {
00281 int i;
00282 map<const char*, FunctionData, ltstr>::iterator it;
00283
00284 funcnamebuf = (char **) malloc (numfunc * sizeof(char *));
00285 if (funcnamebuf == NULL)
00286 {
00287 perror("Error: Out of Memory : malloc returns NULL ");
00288 exit (1);
00289 }
00290 functagbuf = (int *) malloc (numfunc * sizeof(int));
00291 if (functagbuf == NULL)
00292 {
00293 perror("Error: Out of Memory : malloc returns NULL ");
00294 exit (1);
00295 }
00296
00297 for(it=funcDB.begin(), i = 0; it!=funcDB.end(); it++, i++)
00298 {
00299 funcnamebuf[i] = strsave((*it).first);
00300 functagbuf[i] = i;
00301
00302 }
00303
00304 return TRUE;
00305 }
00306
00307
00308
00309 int FillFunctionDB(int node, int ctx, int thr, char *prefix)
00310 {
00311 char line[SIZE_OF_LINE];
00312 char func[SIZE_OF_LINE];
00313 char version[64],filename[SIZE_OF_FILENAME];
00314 int numberOfFunctions, i, j, k;
00315 char header[256], trailer[256];
00316 int hlen, tlen;
00317 #ifdef USE_LONG
00318 long numcalls,numsubrs,numinvocations;
00319 #else // DEFAULT double
00320 double numcalls;
00321 double numsubrs;
00322 double numinvocations;
00323 #endif // USE_LONG
00324 double excl, incl, exclthiscall, inclthiscall, sumexclsqr;
00325 bool dontread = false;
00326 FILE *fp;
00327 char *functionName;
00328 map<const char*, FunctionData, ltstr>::iterator it;
00329
00330
00331
00332 sprintf(filename,"%s.%d.%d.%d",prefix, node, ctx, thr);
00333
00334 #ifdef DEBUG
00335 printf("Inside FillFunctionDB : Filename %s\n",filename);
00336 #endif
00337
00338 if ((fp = fopen(filename, "r")) == NULL) {
00339
00340 #ifdef DEBUG
00341 sprintf(line,"Error: Could not open file %s", filename);
00342 perror(line);
00343 #endif
00344 return 0;
00345 }
00346
00347 #ifdef DEBUG
00348 cout << "Inside FillFunctionDB n " << node << " c " << ctx << " thr " << thr << endl;
00349 #endif
00350 filledDBThr++;
00351 filledDBCtx++;
00352
00353 if (fgets(line, sizeof(line), fp) == NULL) {
00354 perror("Error: fgets returns NULL ");
00355 return 0;
00356 }
00357 sscanf(line,"%d %s", &numberOfFunctions, version);
00358
00359 if (strncmp(version,"templated_functions",strlen("templated_functions")) != 0 ) {
00360
00361 printf("Incorrect version in file %s : %s", filename, version);
00362 return 0;
00363 }
00364
00365
00366
00367 if (fgets(line, sizeof(line), fp) == NULL) {
00368 perror("Error: fgets returns NULL in format string ");
00369 return 0;
00370 }
00371 if (line[0] == '#') {
00372 sprintf(header,"# Name Calls Subrs Excl Incl ");
00373 hlen = strlen(header);
00374 if (strncmp(line, header, hlen) != 0) {
00375 printf("Error in reading Format String : Expected %s Got %s\n",
00376 header, line);
00377 exit(1);
00378 } else {
00379 sprintf(trailer,"SumExclSqr ProfileCalls");
00380 tlen = strlen(trailer);
00381 if (strncmp(line+hlen, trailer, tlen) == 0) {
00382 profilestats = true;
00383 } else {
00384 sprintf(trailer, "ProfileCalls");
00385 tlen = strlen(trailer);
00386 if (strncmp(line+hlen, trailer, tlen) == 0) {
00387 profilestats = false;
00388 } else {
00389 printf("Error in reading Format String : Got %s\n", line);
00390 exit(1);
00391 }
00392 }
00393 #ifdef DEBUG
00394 printf("Format String correct ProfileStats is %d\n", profilestats);
00395 #endif
00396 }
00397 }
00398 else {
00399 profilestats = false;
00400 dontread = true;
00401 }
00402
00403
00404
00405 for (i =0; i < numberOfFunctions; i++) {
00406 if((i == 0) && (dontread == true)) {
00407 } else {
00408 if (fgets(line, SIZE_OF_LINE, fp) == NULL) {
00409 perror("Error in fgets: Cannot read function table");
00410 return 0;
00411 }
00412 }
00413
00414 for (j=1; line[j] != '"'; j++) {
00415 func[j-1] = line[j];
00416 }
00417 func[j-1] = '\0';
00418
00419
00420 if (!profilestats) {
00421 #ifdef USE_LONG
00422 sscanf(&line[j+1], "%ld %ld %lG %lG %ld", &numcalls, &numsubrs, &excl, &incl, &numinvocations);
00423 #else // DEFAULT double
00424 sscanf(&line[j+1], "%lG %lG %lG %lG %lG", &numcalls, &numsubrs, &excl, &incl, &numinvocations);
00425 #endif // USE_LONG
00426 } else {
00427 #ifdef USE_LONG
00428 sscanf(&line[j+1], "%ld %ld %lG %lG %lG %ld", &numcalls, &numsubrs, &excl, &incl, &sumexclsqr, &numinvocations);
00429 #else // DEFAULT double
00430 sscanf(&line[j+1], "%lG %lG %lG %lG %lG %lG", &numcalls, &numsubrs, &excl, &incl, &sumexclsqr, &numinvocations);
00431 #endif // USE_LONG
00432 }
00433 #ifdef DEBUG
00434 cout << "func = "<< func << endl;
00435 cout << "numcalls = "<< numcalls << " numsubrs = "<< numsubrs << " excl = "<< excl <<" incl = " << incl << " no profiled invocations " << numinvocations << endl;
00436 #endif
00437
00438 functionName = new char[strlen(func)+1];
00439 strcpy(functionName,func);
00440
00441 if ((it = funcDB.find((const char *)functionName)) != funcDB.end()) {
00442 #ifdef DEBUG
00443 cout << "Found the name " << functionName << endl;
00444 #endif
00445 delete functionName;
00446 }
00447 else
00448 funcDB[(const char *)functionName] = FunctionData();
00449
00450
00451
00452 for(k = 0; k < numinvocations; k++) {
00453 if(fgets(line,SIZE_OF_LINE,fp) == NULL) {
00454 perror("Error in fgets: Cannot read invocation data ");
00455 return 0;
00456 }
00457
00458 sscanf(line, "%lG %lG", &exclthiscall, &inclthiscall);
00459 #ifdef DEBUG
00460 cout << "func = " << func << " ExclThisCall = " << exclthiscall << " InclThisCall = " << inclthiscall << endl;
00461 #endif
00462 }
00463 }
00464 fclose(fp);
00465 return 1;
00466 }
00467
00468
00469 int FillFunctionDBInContext(int node, int ctx, int thr, char *prefix)
00470 {
00471 #ifdef DEBUG
00472 cout << "FillFunctionDBInContext n" << node << " c " << ctx << " t " << thr << endl;
00473 #endif
00474 for(thr = 0,filledDBThr = 0; FillFunctionDB(node, ctx, thr, prefix); thr++);
00475 if (filledDBThr)
00476 return TRUE;
00477 else
00478 return FALSE;
00479 }
00480
00481 int FillFunctionDBInNode (int node, int ctx, int thr, char *prefix)
00482 {
00483 #ifdef DEBUG
00484 cout << "FillFunctionDBInNode n" << node << " c " << ctx << " t " << thr << endl;
00485 #endif
00486 for(ctx = 0, filledDBCtx = 0; FillFunctionDBInContext(node, ctx, thr, prefix); ctx ++);
00487 if (filledDBCtx)
00488 return TRUE;
00489 else
00490 return FALSE;
00491
00492 }
00493
00494
00495 int DumpFunctionNamesInDB(void)
00496 {
00497 map<const char*, FunctionData, ltstr>::iterator it;
00498
00499 for(it=funcDB.begin(); it != funcDB.end(); it++) {
00500 cout <<(*it).first << endl;
00501 }
00502 return 1;
00503 }
00504
00505 int DumpFtabFile(char *prefix)
00506 {
00507
00508 FILE *fp;
00509 char filename[SIZE_OF_FILENAME], error_msg[SIZE_OF_FILENAME];
00510 int i;
00511
00512
00513 sprintf(filename, "%s.ftab",prefix);
00514
00515
00516 if ((fp = fopen(filename, "r")) != NULL) {
00517 fclose (fp);
00518 return 1;
00519 }
00520 if (errno == ENOENT)
00521 fclose(fp);
00522
00523 if ((fp = fopen(filename, "w+")) == NULL) {
00524 sprintf(error_msg, "Error : Could not create %s", filename);
00525 perror(error_msg);
00526 return 0;
00527 }
00528
00529 fprintf(fp,"default.dep\n%d templated_functions\n",numfunc);
00530 for (i = 0; i < numfunc; i++) {
00531 fprintf(fp,"%d %s\n", functagbuf[i], funcnamebuf[i]);
00532 }
00533 fflush(fp);
00534 fclose (fp);
00535 return 1;
00536 }
00537
00538 int ProcessFileDynamic(int node, int ctx, int thr, int max, char *prefix)
00539 {
00540 char line[SIZE_OF_LINE];
00541 char func[SIZE_OF_LINE];
00542 char version[64],filename[SIZE_OF_FILENAME];
00543 int numberOfFunctions, i, j, k;
00544 #ifdef USE_LONG
00545 long numcalls, numsubrs, numinvocations;
00546 #else // DEFAULT double
00547 double numcalls, numsubrs, numinvocations;
00548 #endif // USE_LONG
00549 double excl, incl, exclthiscall, inclthiscall, sumexclsqr, stddev;
00550 bool dontread = false;
00551 FILE *fp;
00552 map<const char*, FunctionData, ltstr>::iterator it;
00553
00554
00555 sprintf(filename,"%s.%d.%d.%d",prefix, node, ctx, thr);
00556
00557
00558 if ((fp = fopen(filename, "r")) == NULL) {
00559
00560 #ifdef DEBUG
00561 sprintf(line,"Error: Could not open file %s", filename);
00562 perror(line);
00563 #endif
00564 return 0;
00565 }
00566
00567 #ifdef DEBUG
00568 printf("Inside ProcessFileDynamic : Filename %s\n",filename);
00569 #endif
00570
00571 filledDBThr++;
00572 filledDBCtx++;
00573
00574 if (fgets(line, sizeof(line), fp) == NULL) {
00575 perror("Error: fgets returns NULL ");
00576 return 0;
00577 }
00578 sscanf(line,"%d %s", &numberOfFunctions, version);
00579
00580 if (strncmp(version,"templated_functions",strlen("templated_functions")) != 0 ) {
00581
00582 printf("Incorrect version in file %s : %s", filename, version);
00583 return 0;
00584 }
00585
00586
00587
00588
00589
00590 if (fgets(line, sizeof(line), fp) == NULL) {
00591 perror("Error: fgets returns NULL in format string ");
00592 return 0;
00593 }
00594 if (line[0] != '#') {
00595 profilestats = false;
00596 dontread = true;
00597 }
00598
00599
00600
00601
00602
00603 for(it = funcDB.begin(); it != funcDB.end(); it++) {
00604 (*it).second = FunctionData();
00605 }
00606
00607
00608 for (i =0; i < numberOfFunctions; i++) {
00609 if ( (i==0) && (dontread == true)) {
00610 } else {
00611 if (fgets(line, SIZE_OF_LINE, fp) == NULL) {
00612 perror("Error in fgets: Cannot read function table");
00613 return 0;
00614 }
00615 }
00616
00617 for (j=1; line[j] != '"'; j++) {
00618 func[j-1] = line[j];
00619 }
00620 func[j-1] = '\0';
00621
00622
00623
00624 if (!profilestats) {
00625 #ifdef USE_LONG
00626 sscanf(&line[j+1], "%ld %ld %lG %lG %ld", &numcalls, &numsubrs, &excl, &incl, &numinvocations);
00627 #else // DEFAULT double
00628 sscanf(&line[j+1], "%lG %lG %lG %lG %lG", &numcalls, &numsubrs, &excl, &incl, &numinvocations);
00629 #endif // USE_LONG
00630 stddev = 0;
00631 } else {
00632 #ifdef USE_LONG
00633 sscanf(&line[j+1], "%ld %ld %lG %lG %lG %ld", &numcalls, &numsubrs, &excl, &incl, &sumexclsqr, &numinvocations);
00634 #else // DEFAULT double
00635 sscanf(&line[j+1], "%lG %lG %lG %lG %lG %lG", &numcalls, &numsubrs, &excl, &incl, &sumexclsqr, &numinvocations);
00636 #endif // USE_LONG
00637
00638 stddev = sqrt(fabs( (sumexclsqr/numcalls) - ((excl/numcalls) * (excl/numcalls))) );
00639 #ifdef DEBUG
00640 cout << "stddeviation = "<< stddev << " sumexclsqr = "<< sumexclsqr << " func : "<< " excl " << excl<< " calls " << numcalls << func<< endl;
00641 #endif
00642 }
00643
00644 #ifdef DEBUG
00645 cout << "func = "<< func << endl;
00646 cout << "numcalls = "<< numcalls <<" numsubrs = "<< numsubrs<< " excl = "<< excl <<" incl = " << incl << " num invocations profiled = " << numinvocations << endl;
00647 #endif
00648
00649 if ((it = funcDB.find((const char *)func)) == funcDB.end()) {
00650 cout << "ERROR : In second pass ProcessFileDynamic didn't find name " << func << " in file "<< filename << endl;
00651 return 0;
00652 }
00653 funcDB[func] += FunctionData(numcalls, numsubrs, excl, incl, stddev);
00654
00655
00656
00657
00658 for(k = 0; k < numinvocations; k++) {
00659 if(fgets(line,SIZE_OF_LINE,fp) == NULL) {
00660 perror("Error in fgets: Cannot read invocation data ");
00661 return 0;
00662 }
00663
00664 sscanf(line, "%lG %lG", &exclthiscall, &inclthiscall);
00665 #ifdef DEBUG
00666 cout << "func = " << func << " ExclThisCall = " << exclthiscall << " InclThisCall = " << inclthiscall << endl;
00667 #endif
00668 }
00669 }
00670
00671 p_func_list = (struct p_func_descr *) malloc(numfunc * sizeof(struct p_func_descr));
00672
00673
00674 for(it=funcDB.begin(), i = 0; it != funcDB.end(); it++, i++) {
00675 p_func_list[i].numcalls = (*it).second.numcalls;
00676 p_func_list[i].numsubrs = (*it).second.numsubrs;
00677 p_func_list[i].usec = (*it).second.excl;
00678 p_func_list[i].cumusec = (*it).second.incl;
00679 p_func_list[i].stddeviation = (*it).second.stddeviation;
00680
00681 if (p_func_list[i].cumusec > max_thread_cumusec) {
00682 top_level_function = i;
00683
00684 max_thread_cumusec = p_func_list[i].cumusec;
00685 }
00686 #ifdef DEBUG
00687 #ifdef USE_LONG
00688 printf("Func Id %d name %s numcalls %ld numsubrs %ld usec %lG cumusec %lG\n",i, funcnamebuf[i], p_func_list[i].numcalls, p_func_list[i].numsubrs, p_func_list[i].usec, p_func_list[i].cumusec);
00689 #else // DEFAULT double
00690 printf("Func Id %d name %s numcalls %lG numsubrs %lG usec %lG cumusec %lG\n",i, funcnamebuf[i], p_func_list[i].numcalls, p_func_list[i].numsubrs, p_func_list[i].usec, p_func_list[i].cumusec);
00691 #endif // USE_LONG
00692 #endif
00693 }
00694
00695 if ( fgets (line, 256, fp) == NULL ) {
00696 fprintf (stderr,
00697 "invalid proftablefile: cannot read number of collections\n");
00698 exit (1);
00699 }
00700 sscanf(line, "%d %s", &numcoll, version);
00701 if (strcmp(version, "aggregates") == 0)
00702 {
00703 if(numcoll) {
00704 }
00705 }
00706
00707
00708 fclose(fp);
00709 #ifdef DEBUG
00710 cout << "Closing file " << filename << endl;
00711 #endif
00712
00713
00714 FunctionSummaryInfo(node, ctx, thr, max);
00715
00716 return 1;
00717
00718 }
00719
00720 int FunctionSummaryInfo(int no, int ctx, int thr, int max)
00721 {
00722 int i, j;
00723 int active_counters=0;
00724 int numf;
00725 int numc;
00726 int numa;
00727 double total, ct;
00728 char ident_str[32];
00729
00730
00731
00732 numf = numfunc;
00733 numc = numa = numcoll;
00734 hpcxx_flag = TRUE;
00735
00736
00737 if ( !p_total_tbl ) {
00738 p_total_tbl = (struct p_prof_elem *) malloc (numf * sizeof(struct p_prof_elem));
00739 p_min_tbl = (struct p_prof_elem *) malloc (numf * sizeof(struct p_prof_elem));
00740 p_max_tbl = (struct p_prof_elem *) malloc (numf * sizeof(struct p_prof_elem));
00741 for (i=0; i<numf; i++) {
00742 p_total_tbl[i].tag = functagbuf[i];
00743 p_total_tbl[i].name = funcnamebuf[i];
00744 p_total_tbl[i].usec = 0.0;
00745 p_total_tbl[i].cumusec = 0.0;
00746 p_total_tbl[i].numcalls = 0;
00747 p_total_tbl[i].numsubrs = 0;
00748 p_total_tbl[i].stddeviation = 0;
00749
00750 p_max_tbl[i].tag = p_min_tbl[i].tag = p_total_tbl[i].tag;
00751 p_max_tbl[i].name = p_min_tbl[i].name = p_total_tbl[i].name;
00752 p_max_tbl[i].usec = p_min_tbl[i].usec = p_func_list[i].usec;
00753 p_max_tbl[i].cumusec = p_min_tbl[i].cumusec = p_func_list[i].cumusec;
00754 p_max_tbl[i].numcalls = p_min_tbl[i].numcalls = p_func_list[i].numcalls;
00755 p_max_tbl[i].numsubrs = p_min_tbl[i].numsubrs = p_func_list[i].numsubrs;
00756 p_max_tbl[i].stddeviation = p_min_tbl[i].stddeviation = p_func_list[i].stddeviation;
00757 #ifdef DEBUG
00758 #ifdef USE_LONG
00759 printf(" Func %d, min_tbl[i].numcalls %ld min_tbl[i].numsubrs %ld usec %lG, cumusec %lG\n",
00760 i, p_min_tbl[i].numcalls, p_min_tbl[i].numsubrs, p_min_tbl[i].usec, p_min_tbl[i].cumusec);
00761
00762 printf(" Func %d, max_tbl[i].numcalls %ld max_tbl[i].numsubrs %ld usec %lG, cumusec %lG\n",
00763 i, p_max_tbl[i].numcalls, p_max_tbl[i].numsubrs, p_max_tbl[i].usec, p_max_tbl[i].cumusec);
00764 #else // DEFAULT double
00765 printf(" Func %d, min_tbl[i].numcalls %lG min_tbl[i].numsubrs %lG usec %lG, cumusec %lG\n",
00766 i, p_min_tbl[i].numcalls, p_min_tbl[i].numsubrs, p_min_tbl[i].usec, p_min_tbl[i].cumusec);
00767
00768 printf(" Func %d, max_tbl[i].numcalls %lG max_tbl[i].numsubrs %lG usec %lG, cumusec %lG\n",
00769 i, p_max_tbl[i].numcalls, p_max_tbl[i].numsubrs, p_max_tbl[i].usec, p_max_tbl[i].cumusec);
00770 #endif // USE_LONG
00771 #endif
00772 }
00773 total_total = 0.0;
00774
00775
00776
00777 max_total = min_total = p_func_list[top_level_function].cumusec;
00778 }
00779
00780
00781
00782 p_prof_tbl = (struct p_prof_elem *) malloc (numf * sizeof(struct p_prof_elem));
00783 for (i=0; i<numf; i++) {
00784 p_prof_tbl[i].tag = p_total_tbl[i].tag;
00785 p_prof_tbl[i].name = p_total_tbl[i].name;
00786 p_total_tbl[i].usec += p_prof_tbl[i].usec = p_func_list[i].usec;
00787 p_total_tbl[i].cumusec += p_prof_tbl[i].cumusec = p_func_list[i].cumusec;
00788 p_total_tbl[i].numcalls += p_prof_tbl[i].numcalls = p_func_list[i].numcalls;
00789 p_total_tbl[i].numsubrs += p_prof_tbl[i].numsubrs = p_func_list[i].numsubrs;
00790 p_total_tbl[i].stddeviation += p_prof_tbl[i].stddeviation = p_func_list[i].stddeviation;
00791
00792 if ( p_min_tbl[i].usec > p_func_list[i].usec )
00793 p_min_tbl[i].usec = p_func_list[i].usec;
00794 if ( p_min_tbl[i].cumusec > p_func_list[i].cumusec )
00795 p_min_tbl[i].cumusec = p_func_list[i].cumusec;
00796 if ( p_min_tbl[i].numcalls > p_func_list[i].numcalls )
00797 p_min_tbl[i].numcalls = p_func_list[i].numcalls;
00798 if ( p_min_tbl[i].numsubrs > p_func_list[i].numsubrs )
00799 p_min_tbl[i].numsubrs = p_func_list[i].numsubrs;
00800 if ( p_min_tbl[i].stddeviation > p_func_list[i].stddeviation )
00801 p_min_tbl[i].stddeviation = p_func_list[i].stddeviation;
00802
00803 if ( p_max_tbl[i].usec < p_func_list[i].usec )
00804 p_max_tbl[i].usec = p_func_list[i].usec;
00805
00806 if ( p_max_tbl[i].cumusec < p_func_list[i].cumusec )
00807 p_max_tbl[i].cumusec = p_func_list[i].cumusec;
00808 if ( p_max_tbl[i].numcalls < p_func_list[i].numcalls )
00809 p_max_tbl[i].numcalls = p_func_list[i].numcalls;
00810 if ( p_max_tbl[i].numsubrs < p_func_list[i].numsubrs )
00811 p_max_tbl[i].numsubrs = p_func_list[i].numsubrs;
00812 if ( p_max_tbl[i].stddeviation < p_func_list[i].stddeviation )
00813 p_max_tbl[i].stddeviation = p_func_list[i].stddeviation;
00814 }
00815 #ifdef DEBUG
00816 for (i=0; i<numf; i++) {
00817 #ifdef USE_LONG
00818 printf(" Func %d, min_tbl[i].numcalls %ld numsubrs %ld usec %lG, cumusec %lG\n",
00819 i, p_min_tbl[i].numcalls, p_min_tbl[i].numsubrs, p_min_tbl[i].usec, p_min_tbl[i].cumusec);
00820
00821 printf(" Func %d, max_tbl[i].numcalls %ld numsubrs %ld usec %lG, cumusec %lG\n",
00822 i, p_max_tbl[i].numcalls, p_max_tbl[i].numsubrs, p_max_tbl[i].usec, p_max_tbl[i].cumusec);
00823 #else // DEFAULT double
00824 printf(" Func %d, min_tbl[i].numcalls %lG numsubrs %lG usec %lG, cumusec %lG\n",
00825 i, p_min_tbl[i].numcalls, p_min_tbl[i].numsubrs, p_min_tbl[i].usec, p_min_tbl[i].cumusec);
00826
00827 printf(" Func %d, max_tbl[i].numcalls %lG numsubrs %lG usec %lG, cumusec %lG\n",
00828 i, p_max_tbl[i].numcalls, p_max_tbl[i].numsubrs, p_max_tbl[i].usec, p_max_tbl[i].cumusec);
00829 #endif // USE_LONG
00830 }
00831 #endif
00832
00833
00834 #ifdef DEBUG
00835 printf("Top level function = %d in file %s\n", top_level_function, proffile);
00836 #endif
00837
00838
00839
00840
00841
00842 total_total += total = p_func_list[top_level_function].cumusec;
00843 if ( min_total > p_func_list[top_level_function].cumusec ) min_total = p_func_list[top_level_function].cumusec;
00844 if ( max_total < p_func_list[top_level_function].cumusec ) max_total = p_func_list[top_level_function].cumusec;
00845
00846 #ifdef DEBUG
00847 printf("%s : total = %5.1f top level = %5.1f\n", proffile, total, max_thread_cumusec);
00848 #endif
00849 if (hpcxx_flag == FALSE)
00850 {
00851 sprintf(ident_str,"%d", no);
00852 }
00853 else
00854 {
00855 sprintf(ident_str,"%d,%d,%d", no, ctx, thr);
00856 }
00857
00858
00859
00860 if ( nodeprint ) {
00861 if ( dump ) {
00862 qsort ((void *) p_prof_tbl, numf, sizeof(struct p_prof_elem), MsecCmp);
00863 DumpFuncTab (p_prof_tbl, ident_str, total, max, "excl");
00864 qsort ((void *) p_prof_tbl, numf, sizeof(struct p_prof_elem), CumMsecCmp);
00865 DumpFuncTab (p_prof_tbl, ident_str, total, max, "incl");
00866 }
00867 else {
00868 qsort ((void *) p_prof_tbl, numf, sizeof(struct p_prof_elem), compar);
00869 if (hpcxx_flag == FALSE)
00870 printf ("\nNODE %d: \n", no);
00871 else
00872 {
00873 printf ("\nNODE %d;", no);
00874 printf ("CONTEXT %d;", ctx);
00875 printf ("THREAD %d:\n", thr);
00876 }
00877
00878 PrintFuncTab (p_prof_tbl, total, max);
00879 }
00880 }
00881
00882 if ( numc ) {
00883 if ( hpcxx_flag == FALSE) {
00884 if ( nodeprint ) {
00885 if ( ! dump ) {
00886 printf ("\n local remote collection\n");
00887 printf ( "accesses accesses num name\n");
00888 }
00889 }
00890 for (i=0; i<numc; i++) {
00891 if ( nodeprint ) {
00892
00893 if ( dump ) {
00894 if ( ct = p_coll_list[i].localacs + p_coll_list[i].remoteacs ) {
00895 printf ("coll %d %d %d %4.2f %d %4.2f\n", no, i,
00896 p_coll_list[i].localacs, p_coll_list[i].localacs/ct*100.0,
00897 p_coll_list[i].remoteacs, p_coll_list[i].remoteacs/ct*100.0);
00898 }
00899 else {
00900 printf ("coll %d %d 0 0.0 0 0.0\n", no, i);
00901 }
00902 }
00903 else {
00904 printf ("%8d %8d %3d %s\n",
00905 p_coll_list[i].localacs, p_coll_list[i].remoteacs,
00906 i, p_coll_list[i].varname);
00907 }
00908 }
00909
00910
00911 p_coll_tbl[i].localacs += p_coll_list[i].localacs;
00912 p_coll_tbl[i].remoteacs += p_coll_list[i].remoteacs;
00913 }
00914 }
00915 else {
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925 for (i=0; i<numa; i++) {
00926 if ( nodeprint ) {
00927
00928 if ( dump ) {
00929 if ( p_aggr_list[i].total_events ) {
00930 active_counters = 0;
00931 for(j=0; j < MAX_COUNTERS; j++)
00932 {
00933 if (p_aggr_list[i].counters[j]) active_counters++ ;
00934 }
00935 printf("aggregates %d,%d,%d %d %d ",no, ctx, thr, i, active_counters);
00936
00937 for (j = 0; j < MAX_COUNTERS; j++)
00938 {
00939
00940 if ( p_aggr_list[i].counters[j])
00941 {
00942 if (eventnamebuf == NULL)
00943 {
00944 printf("%d NULL %d %4.2f ", j,
00945 p_aggr_list[i].counters[j],
00946 p_aggr_list[i].counters[j]*100.0/p_aggr_list[i].total_events);
00947 }
00948 else
00949 {
00950 printf("%d %s %d %4.2f ", j, eventnamebuf[j],
00951 p_aggr_list[i].counters[j],
00952 p_aggr_list[i].counters[j]*100.0/p_aggr_list[i].total_events);
00953 }
00954 }
00955 }
00956 printf("%s %s %s\n", p_aggr_list[i].container_name,
00957 p_aggr_list[i].container_type, p_aggr_list[i].var_name);
00958 }
00959 else
00960 {
00961 printf("aggregates %d,%d,%d %d 0 NULL 0 0.0 %s %s %s\n",
00962 no, ctx, thr, i, p_aggr_list[i].container_name,
00963 p_aggr_list[i].container_type, p_aggr_list[i].var_name);
00964
00965 }
00966 }
00967 else
00968 {
00969 printf("aggregates %s <%s> %s\n",p_aggr_list[i].container_name,
00970 p_aggr_list[i].container_type, p_aggr_list[i].var_name);
00971 for(j = 0; j < MAX_COUNTERS; j++)
00972 {
00973 if(p_aggr_list[i].counters[j])
00974 {
00975 if(eventnamebuf == NULL)
00976 {
00977 printf("Event id %d\t: %d %4.2f percent\n",
00978 j, p_aggr_list[i].counters[j],
00979 p_aggr_list[i].counters[j]*100.0/p_aggr_list[i].total_events);
00980 }
00981 else
00982 {
00983 printf("Event id %d name %s\t: %d %4.2f percent\n",
00984 j, eventnamebuf[j], p_aggr_list[i].counters[j],
00985 p_aggr_list[i].counters[j]*100.0/p_aggr_list[i].total_events);
00986 }
00987 }
00988 }
00989 }
00990 }
00991
00992 for (j = 0; j < MAX_COUNTERS; j++)
00993 {
00994 p_aggr_tbl[i].counters[j] += p_aggr_list[i].counters[j];
00995 }
00996 p_aggr_tbl[i].total_events += p_aggr_list[i].total_events;
00997 }
00998 }
00999 }
01000
01001 free (p_coll_list);
01002 free (p_func_list);
01003 free (p_prof_tbl);
01004 free (p_aggr_list);
01005 files_processed ++;
01006 return (TRUE);
01007 }
01008
01009 int ProcessFileDynamicInContext(int node, int ctx, int thr, int maxfuncs, char *prefix)
01010 {
01011 #ifdef DEBUG
01012 cout << "ProcessFileDynamicInContext n " << node << " c " << ctx << " t " << thr << endl;
01013 #endif
01014 for (thr =0, filledDBThr = 0; ProcessFileDynamic(node, ctx, thr, maxfuncs, prefix); thr++);
01015 if (filledDBThr)
01016 return TRUE;
01017 else
01018 return FALSE;
01019
01020 }
01021
01022 int ProcessFileDynamicInNode (int node, int ctx, int thr, int maxfuncs, char *prefix)
01023 {
01024 #ifdef DEBUG
01025 cout << "ProcessFileDynamicInNode n "<< node << " c "<< ctx << " t "<< thr<< endl;
01026 #endif
01027 for(ctx=0, filledDBCtx = 0; ProcessFileDynamicInContext(node, ctx, thr, maxfuncs, prefix); ctx++);
01028 if (filledDBCtx)
01029 return TRUE;
01030 else
01031 return FALSE;
01032
01033 }
01034
01035
01036
01037
01038
01039 static char *strsave (const char *s)
01040 {
01041 char *r;
01042
01043 if ( (r = (char *) malloc (strlen(s)+1)) == NULL ) {
01044 fprintf (stderr, "error: no more memory\n");
01045 exit (1);
01046 }
01047 strcpy (r, s);
01048 return r;
01049 }
01050
01051
01052
01053
01054
01055 static char *ToTimeStr (double ti, char timbuf[])
01056 {
01057 long msec, sec, min, hour;
01058
01059 if (hwcounters == false) {
01060 msec = fmod (ti / 1.0e3, 1.0e3);
01061 sec = fmod (ti / 1.0e6, 60.0);
01062 min = fmod (ti / 60.0e6, 60.0);
01063 hour = ti / 36.0e8;
01064
01065 if ( hour )
01066 sprintf (timbuf, "%2d:%02d:%02d.%03d", hour, min, sec, msec);
01067 else if ( min )
01068 sprintf (timbuf, " %2d:%02d.%03d", min, sec, msec);
01069 else if ( sec )
01070 sprintf (timbuf, " %2d,%03d", sec, msec);
01071 else
01072 sprintf (timbuf, " %3d", msec);
01073 if (ti < 1.0e3)
01074 sprintf (timbuf, " %9.3G",ti/1.0e3);
01075 } else {
01076 sprintf(timbuf,"%12.4G", ti);
01077 }
01078
01079 return (timbuf);
01080 }
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092 static int sign = 1;
01093
01094 static int MsecCmp (const void *left, const void *right)
01095 {
01096 double l = ((struct p_prof_elem *) left)->usec;
01097 double r = ((struct p_prof_elem *) right)->usec;
01098
01099 if ( l < r )
01100 return sign;
01101 else if ( l > r )
01102 return -sign;
01103 else
01104 return 0;
01105 }
01106
01107 static int CumMsecCmp (const void *left, const void *right)
01108 {
01109 double l = ((struct p_prof_elem *) left)->cumusec;
01110 double r = ((struct p_prof_elem *) right)->cumusec;
01111
01112 if ( l < r )
01113 return sign;
01114 else if ( l > r )
01115 return -sign;
01116 else
01117 return 0;
01118 }
01119
01120 static int CallCmp (const void *left, const void *right)
01121 {
01122 int l = ((struct p_prof_elem *) left)->numcalls;
01123 int r = ((struct p_prof_elem *) right)->numcalls;
01124
01125 if ( l < r )
01126 return sign;
01127 else if ( l > r )
01128 return -sign;
01129 else
01130 return 0;
01131 }
01132
01133 static int MsecPerCallCmp (const void *left, const void *right)
01134 {
01135 double l = ((struct p_prof_elem *) left) ->usec/ ((struct p_prof_elem *) left) ->numcalls;
01136 double r = ((struct p_prof_elem *) right) ->usec/ ((struct p_prof_elem *) right)->numcalls;
01137
01138 if ( l < r )
01139 return sign;
01140 else if (l > r)
01141 return -sign;
01142 else
01143 return 0;
01144 }
01145
01146 static int CumMsecPerCallCmp (const void *left, const void *right)
01147 {
01148 double l = ((struct p_prof_elem *) left) ->cumusec/ ((struct p_prof_elem *) left) ->numcalls;
01149 double r = ((struct p_prof_elem *) right) ->cumusec/ ((struct p_prof_elem *) right)->numcalls;
01150
01151 if ( l < r )
01152 return sign;
01153 else if (l > r)
01154 return -sign;
01155 else
01156 return 0;
01157 }
01158
01159 static int StdDevCmp (const void *left, const void *right)
01160 {
01161 double l = ((struct p_prof_elem *) left ) -> stddeviation;
01162 double r = ((struct p_prof_elem *) right) -> stddeviation;
01163
01164 if ( l < r )
01165 return sign;
01166 else if (l > r)
01167 return -sign;
01168 else
01169 return 0;
01170 }
01171
01172 static int SubrCmp (const void *left, const void *right)
01173 {
01174 int l = ((struct p_prof_elem *) left)->numsubrs;
01175 int r = ((struct p_prof_elem *) right)->numsubrs;
01176
01177 if ( l < r )
01178 return sign;
01179 else if ( l > r )
01180 return -sign;
01181 else
01182 return 0;
01183 }
01184
01185
01186
01187
01188
01189
01190
01191 static void PrintFuncTab (struct p_prof_elem *tab, double total, int max)
01192 {
01193 int i;
01194 #ifdef USE_LONG
01195 int o_numcalls = 0;
01196 int o_numsubrs = 0;
01197 #else // DEFAULT double
01198 double o_numcalls = 0.0;
01199 double o_numsubrs = 0.0;
01200 #endif // USE_LONG
01201 double o_usec = 0.0;
01202 double o_cumusec = 0.0;
01203 double o_stddeviation = 0.0;
01204 char buf1[20], buf2[20];
01205
01206 for (i=max; i<numfunc; i++) {
01207 o_numcalls += tab[i].numcalls;
01208 o_numsubrs += tab[i].numsubrs;
01209 o_usec += tab[i].usec;
01210 o_cumusec += tab[i].cumusec;
01211 o_stddeviation += tab[i].stddeviation;
01212 }
01213
01214 if (hwcounters == false) {
01215 printf ("---------------------------------------------------------------------------------------\n");
01216 printf ("%%Time Exclusive Inclusive #Call #Subrs Inclusive ");
01217 if (profilestats) printf("Standard ");
01218 printf("Name\n");
01219 printf (" msec total msec usec/call ");
01220 if (profilestats) printf("deviation ");
01221 printf("\n");
01222 printf ("---------------------------------------------------------------------------------------\n");
01223 }
01224 else {
01225 printf ("---------------------------------------------------------------------------------------\n");
01226 printf ("%%Time Exclusive Inclusive #Call #Subrs Count/Call ");
01227 if (profilestats) printf("Standard ");
01228 printf("Name\n");
01229 printf (" counts total counts ");
01230 if (profilestats) printf("deviation ");
01231 printf("\n");
01232 printf ("---------------------------------------------------------------------------------------\n");
01233
01234 }
01235
01236 for (i=0; i<numfunc && i<max; i++) {
01237 #ifdef DEBUG
01238 #ifdef USE_LONG
01239 printf(" PrintFuncTab name = %s, numcalls %ld, numsubrs %ld usec %lG, cumusec %lG \n",
01240 tab[i].name, tab[i].numcalls, tab[i].numsubrs, tab[i].usec, tab[i].cumusec);
01241 #else // DEFAULT double
01242 printf(" PrintFuncTab name = %s, numcalls %lG, numsubrs %lG usec %lG, cumusec %lG \n",
01243 tab[i].name, tab[i].numcalls, tab[i].numsubrs, tab[i].usec, tab[i].cumusec);
01244 #endif // USE_LONG
01245 #endif
01246
01247 if ( tab[i].numcalls > 0 ) {
01248 if ( tab[i].cumusec > 0.0 ) {
01249 if ( hwcounters == false) {
01250 #ifdef USE_LONG
01251 printf ("%5.1f %s %s %8ld %8ld %10.0f ",
01252 #else
01253 printf ("%5.1f %s %s %8G %8G %10.0f ",
01254 #endif
01255 tab[i].cumusec / total * 100.0,
01256 ToTimeStr (tab[i].usec, buf1),
01257 ToTimeStr (tab[i].cumusec, buf2),
01258 tab[i].numcalls,
01259 tab[i].numsubrs,
01260 tab[i].cumusec / tab[i].numcalls);
01261 if (profilestats) printf("%10.4G ", tab[i].stddeviation);
01262 printf("%s\n", tab[i].name);
01263 }
01264 else {
01265 #ifdef USE_LONG
01266 printf ("%5.1f %10.4G %10.4G %8ld %8ld %10.0f ",
01267 #else
01268 printf ("%5.1f %10.4G %10.4G %8G %8G %10.0f ",
01269 #endif
01270 tab[i].cumusec / total * 100.0,
01271 tab[i].usec,
01272 tab[i].cumusec,
01273 tab[i].numcalls,
01274 tab[i].numsubrs,
01275 tab[i].cumusec / tab[i].numcalls);
01276 if(profilestats) printf("%10.4G ", tab[i].stddeviation);
01277 printf("%s\n", tab[i].name);
01278 }
01279 }
01280 else {
01281 #ifdef USE_LONG
01282 printf (" 0.0 0 0 %8ld %8ld 0 ",
01283 #else
01284 printf (" 0.0 0 0 %8G %8G 0 ",
01285 #endif
01286 tab[i].numcalls,
01287 tab[i].numsubrs);
01288 if (profilestats) printf("%10.4G ", tab[i].stddeviation);
01289 printf("%s\n", tab[i].name);
01290
01291 }
01292 }
01293 }
01294
01295 if ( o_numcalls > 0 ) {
01296 if ( o_cumusec > 0.0 ) {
01297 if (hwcounters == false) {
01298 #ifdef USE_LONG
01299 printf ("%5.1f %s %s %8ld %8ld %10.0f ",
01300 #else
01301 printf ("%5.1f %s %s %8G %8G %10.0f ",
01302 #endif
01303 o_cumusec / total * 100.0,
01304 ToTimeStr (o_usec, buf1), ToTimeStr (o_cumusec, buf2),
01305 o_numcalls, o_numsubrs, o_cumusec / o_numcalls);
01306 if (profilestats) printf("%10.4G ",o_stddeviation);
01307 printf("-others-\n");
01308 }
01309 else {
01310 #ifdef USE_LONG
01311 printf ("%5.1f %10.4G %10.4G %8ld %8ld %10.0f ",
01312 #else
01313 printf ("%5.1f %10.4G %10.4G %8G %8G %10.0f ",
01314 #endif
01315 o_cumusec / total * 100.0,
01316 o_usec, o_cumusec,
01317 o_numcalls, o_numsubrs, o_cumusec / o_numcalls);
01318 if (profilestats) printf("%10.4G ",o_stddeviation);
01319 printf("-others-\n");
01320 }
01321 }
01322 else {
01323 #ifdef USE_LONG
01324 printf (" 0.0 0 0 %8ld %8ld 0 ",
01325 #else
01326 printf (" 0.0 0 0 %8G %8G 0 ",
01327 #endif
01328 o_numcalls, o_numsubrs);
01329 if (profilestats) printf("%10.4G ", o_stddeviation);
01330 printf("-others-\n");
01331 }
01332 }
01333 }
01334
01336 static void PrintFuncTabOrig (struct p_prof_elem *tab, double total, int max)
01337 {
01338 int i;
01339 #ifdef USE_LONG
01340 int o_numcalls = 0;
01341 int o_numsubrs = 0;
01342 #else // DEFAULT double
01343 double o_numcalls = 0.0;
01344 double o_numsubrs = 0.0;
01345 #endif // USE_LONG
01346
01347 double o_usec = 0.0;
01348 double o_cumusec = 0.0;
01349 char buf1[20], buf2[20];
01350
01351 for (i=max; i<numfunc; i++) {
01352 o_numcalls += tab[i].numcalls;
01353 o_numsubrs += tab[i].numsubrs;
01354 o_usec += tab[i].usec;
01355 o_cumusec += tab[i].cumusec;
01356 }
01357
01358 if (hwcounters == false) {
01359 printf ("---------------------------------------------------------------------------\n");
01360 printf ("%%time msec total msec #call #subrs usec/call name\n");
01361 printf ("---------------------------------------------------------------------------\n");
01362 }
01363 else {
01364 printf ("---------------------------------------------------------------------------\n");
01365 printf ("%%time exclusive inclusive #call #subrs count/call name\n");
01366 printf ("---------------------------------------------------------------------------\n");
01367 }
01368
01369 for (i=0; i<numfunc && i<max; i++) {
01370 #ifdef DEBUG
01371 #ifdef USE_LONG
01372 printf(" PrintFuncTab name = %s, numcalls %ld, numsubrs %ld usec %lG, cumusec %lG \n",
01373 tab[i].name, tab[i].numcalls, tab[i].numsubrs, tab[i].usec, tab[i].cumusec);
01374 #else // DEFAULT double
01375 printf(" PrintFuncTab name = %s, numcalls %lG, numsubrs %lG usec %lG, cumusec %lG \n",
01376 tab[i].name, tab[i].numcalls, tab[i].numsubrs, tab[i].usec, tab[i].cumusec);
01377 #endif // USE_LONG
01378 #endif
01379
01380 if ( tab[i].numcalls > 0 ) {
01381 if ( tab[i].cumusec > 0.0 ) {
01382 if ( hwcounters == false) {
01383 #ifdef USE_LONG
01384 printf ("%5.1f %s %s %8ld %8ld %10.0f %s\n",
01385 #else
01386 printf ("%5.1f %s %s %8G %8G %10.0f %s\n",
01387 #endif
01388 tab[i].cumusec / total * 100.0,
01389 ToTimeStr (tab[i].usec, buf1),
01390 ToTimeStr (tab[i].cumusec, buf2),
01391 tab[i].numcalls,
01392 tab[i].numsubrs,
01393 tab[i].cumusec / tab[i].numcalls,
01394 tab[i].name);
01395 }
01396 else {
01397 #ifdef USE_LONG
01398 printf ("%5.1f %10.4G %10.4G %8ld %8ld %10.0f %s\n",
01399 #else
01400 printf ("%5.1f %10.4G %10.4G %8G %8G %10.0f %s\n",
01401 #endif
01402 tab[i].cumusec / total * 100.0,
01403 tab[i].usec,
01404 tab[i].cumusec,
01405 tab[i].numcalls,
01406 tab[i].numsubrs,
01407 tab[i].cumusec / tab[i].numcalls,
01408 tab[i].name);
01409 }
01410 }
01411 else {
01412 #ifdef USE_LONG
01413 printf (" 0.0 0 0 %8ld %8ld 0 %s\n",
01414 #else
01415 printf (" 0.0 0 0 %8G %8G 0 %s\n",
01416 #endif
01417 tab[i].numcalls,
01418 tab[i].numsubrs,
01419 tab[i].name);
01420
01421 }
01422 }
01423 }
01424
01425 if ( o_numcalls > 0 ) {
01426 if ( o_cumusec > 0.0 ) {
01427 if (hwcounters == false) {
01428 #ifdef USE_LONG
01429 printf ("%5.1f %s %s %8ld %8ld %10.0f -others-\n",
01430 #else
01431 printf ("%5.1f %s %s %8G %8G %10.0f -others-\n",
01432 #endif
01433 o_cumusec / total * 100.0,
01434 ToTimeStr (o_usec, buf1), ToTimeStr (o_cumusec, buf2),
01435 o_numcalls, o_numsubrs, o_cumusec / o_numcalls);
01436 }
01437 else {
01438 #ifdef USE_LONG
01439 printf ("%5.1f %10.4G %10.4G %8ld %8ld %10.0f -others-\n",
01440 #else
01441 printf ("%5.1f %10.4G %10.4G %8G %8G %10.0f -others-\n",
01442 #endif
01443 o_cumusec / total * 100.0,
01444 o_usec, o_cumusec,
01445 o_numcalls, o_numsubrs, o_cumusec / o_numcalls);
01446 }
01447 }
01448 else {
01449 #ifdef USE_LONG
01450 printf (" 0.0 0 0 %8ld %8ld 0 -others-\n",
01451 #else
01452 printf (" 0.0 0 0 %8G %8G 0 -others-\n",
01453 #endif
01454 o_numcalls, o_numsubrs);
01455 }
01456 }
01457 }
01459
01460
01461 static void DumpFuncTab (struct p_prof_elem *tab, char *id_str, double total,
01462 int max, char *order)
01463 {
01464 int i;
01465 int printed_anything = 0;
01466 #ifdef USE_LONG
01467 long o_numcalls = 0;
01468 long o_numsubrs = 0;
01469 #else // DEFAULT double
01470 double o_numcalls = 0.0;
01471 double o_numsubrs = 0.0;
01472 #endif // USE_LONG
01473 double t = 0.0;
01474 double o_usec = 0.0;
01475 double o_cumusec = 0.0;
01476 char buf1[20], buf2[20];
01477
01478 for (i=0; i<numfunc; i++) {
01479 if ( tab[i].numcalls ) t += tab[i].usec;
01480 if ( i >= max ) {
01481 o_numcalls += tab[i].numcalls;
01482 o_numsubrs += tab[i].numsubrs;
01483 o_usec += tab[i].usec;
01484 o_cumusec += tab[i].cumusec;
01485 }
01486 }
01487
01488
01489
01490 for (i=0; i<numfunc && i<max; i++) {
01491 if ( tab[i].numcalls) {
01492 printf("%s ",id_str);
01493
01494
01495
01496 printf ("%d \"%s\" %s ", tab[i].tag, tab[i].name, order);
01497 if ( order[0] == 'e' )
01498 printf ("%.16G %4.2f\n", tab[i].usec, tab[i].usec / t * 100.0);
01499 else if ( order[0] == 'i' )
01500 printf ("%.16G %4.2f\n", tab[i].cumusec, tab[i].cumusec/total*100.0);
01501 if ( tab[i].cumusec > 0.0 ) {
01502 #ifdef USE_LONG
01503 printf ("%5.1f %s %s %8d %10.0f %s\n",
01504 #else
01505 printf ("%5.1f %s %s %8G %10.0f %s\n",
01506 #endif
01507 tab[i].cumusec / total * 100.0,
01508 ToTimeStr (tab[i].usec, buf1), ToTimeStr (tab[i].cumusec, buf2),
01509 tab[i].numcalls, tab[i].cumusec / tab[i].numcalls, tab[i].name);
01510 }
01511 else {
01512 #ifdef USE_LONG
01513 printf (" 0.0 0 0 %8d 0 %s\n",
01514 #else
01515 printf (" 0.0 0 0 %8G 0 %s\n",
01516 #endif
01517 tab[i].numcalls,
01518 tab[i].name);
01519 }
01520 printed_anything = 1;
01521 }
01522 }
01523
01524 if ( o_numcalls > 0) {
01525 printf("%s ",id_str);
01526
01527
01528
01529 printf (" -1 -others- %s ", order);
01530 if ( order[0] == 'e' )
01531 printf ("%.16G %4.2f\n", o_usec, o_usec / t * 100.0);
01532 else if ( order[0] == 'i' )
01533 printf ("%.16G %4.2f\n", o_cumusec, o_cumusec / total * 100.0);
01534 if ( o_cumusec > 0.0 ) {
01535 #ifdef USE_LONG
01536 printf ("%5.1f %s %s %8d %10.0f -others-\n",
01537 #else
01538 printf ("%5.1f %s %s %8G %10.0f -others-\n",
01539 #endif
01540 o_cumusec / total * 100.0,
01541 ToTimeStr (o_usec, buf1), ToTimeStr (o_cumusec, buf2),
01542 o_numcalls, o_cumusec / o_numcalls);
01543 }
01544 else {
01545 #ifdef USE_LONG
01546 printf (" 0.0 0 0 %8d 0 -others-\n",
01547 #else
01548 printf (" 0.0 0 0 %8G 0 -others-\n",
01549 #endif
01550 o_numcalls);
01551 }
01552 printed_anything = 1;
01553 }
01554
01555 if (!printed_anything) {
01556 printf("%s ", id_str);
01557 printf (" -1 -others- %s ", order);
01558
01559 if ( order[0] == 'e' )
01560 if (t > 0.0) {
01561 printf ("%.16G %4.2f\n", o_usec, o_usec / t * 100.0);
01562 }
01563 else {
01564 printf ("%.16G %4.2f\n", o_usec, o_usec );
01565 }
01566 else if ( order[0] == 'i' )
01567 printf ("%.16G %4.2f\n", o_cumusec, o_cumusec / total * 100.0);
01568 #ifdef USE_LONG
01569 printf (" 0.0 0 0 %8d 0 -others-\n",
01570 #else
01571 printf (" 0.0 0 0 %8G 0 -others-\n",
01572 #endif
01573 o_numcalls);
01574 }
01575 }
01576
01577
01578
01579
01580
01581
01582
01583 static void ReadNameTable (char file[])
01584 {
01585 int i, tag;
01586 FILE *in;
01587
01588 sprintf (proffile, "%s.ftab", file);
01589
01590 if ( (in = fopen (proffile, "r")) == NULL ) {
01591 perror (proffile);
01592 exit (1);
01593 }
01594
01595
01596 if ( fgets (lbuf, 256, in) == NULL ) {
01597 fprintf (stderr, "%s: cannot read function table\n", proffile);
01598 exit (1);
01599 }
01600 sscanf (lbuf, "%s", sbuf);
01601 depfile = strsave (sbuf);
01602
01603
01604 fgets (lbuf, 256, in);
01605 sscanf (lbuf, "%d", &numfunc);
01606
01607
01608 funcnamebuf = (char **) malloc (numfunc * sizeof(char *));
01609 functagbuf = (int *) malloc (numfunc * sizeof(int));
01610 for (i=0; i<numfunc; i++) {
01611 fgets (lbuf, 256, in);
01612 sscanf (lbuf, "%d %s", &tag, sbuf);
01613 if ( tag < 0 )
01614 funcnamebuf[i] = NULL;
01615 else
01616 funcnamebuf[i] = strsave (sbuf);
01617 functagbuf[i] = tag;
01618 }
01619 fclose (in);
01620 }
01621
01622 static void ReadEventTable (char file[])
01623 {
01624 int i, j, eventid;
01625 FILE *in;
01626
01627 sprintf (proffile, "%s.ctab", file);
01628
01629 if ( (in = fopen (proffile, "r")) == NULL ) {
01630 return ;
01631
01632 }
01633
01634
01635 if ( fgets (lbuf, 256, in) == NULL ) {
01636 fprintf (stderr, "%s: cannot read event table\n", proffile);
01637 exit (1);
01638 }
01639 sscanf (lbuf, "%d", &numevents);
01640
01641
01642 eventnamebuf = (char **) malloc (numevents * sizeof(char *));
01643 for (i=0; i<numevents; i++) {
01644 fgets (lbuf, 256, in);
01645 sscanf (lbuf, "%d", &eventid);
01646 j = 0;
01647 while((lbuf[j] != '"') && (j < strlen(lbuf))) j++;
01648 if ( j != strlen (lbuf))
01649 {
01650 strcpy(sbuf, &lbuf[j]);
01651 sbuf[strlen(sbuf) - 1] = '\0' ;
01652 }
01653 else
01654 {
01655 sscanf(lbuf, "%d %s",&eventid, sbuf);
01656 fprintf(stderr,"Warning : event id %d name %s should be in quotes in %s\n", eventid, sbuf, proffile);
01657 }
01658
01659 if ( eventid < 0 )
01660 eventnamebuf[i] = NULL;
01661 else
01662 eventnamebuf[eventid] = strsave (sbuf);
01663 }
01664 fclose (in);
01665
01666 if (numevents > MAX_COUNTERS)
01667 {
01668 fprintf(stderr,"Number of events in %s exceeds system limit \n",proffile);
01669 }
01670 #ifdef DEBUG
01671 for(i=0; i<numevents; i++)
01672 {
01673 printf("Event id %d name=%s\n",i,eventnamebuf[i]);
01674 }
01675 #endif
01676 return;
01677 }
01678
01679 static int ProcessFile (int no, int ctx, int thr, int longname, int max, char prefix[], int ignore)
01680 {
01681 int i, j, e, n, r, s, d, l, eid;
01682 int ret, active_counters=0;
01683 long count;
01684 int numf;
01685 int numc;
01686 int numa;
01687 FILE *in;
01688 double t1, t2;
01689 double total, ct;
01690 extern int errno;
01691 char s1[128], s2[128];
01692 char aggr_str[32],ident_str[32];
01693
01694 if (longname == FALSE)
01695 {
01696 sprintf (proffile, "%s.%d", prefix, no);
01697 }
01698 else
01699 {
01700 sprintf (proffile, "%s.%d.%d.%d", prefix, no, ctx, thr);
01701 }
01702
01703
01704
01705
01706 if ( (in = fopen (proffile, "r")) == NULL ) {
01707 if ( errno == ENOENT && ignore)
01708 return (FALSE);
01709 else {
01710 perror (proffile);
01711 exit (1);
01712 }
01713 }
01714
01715 #ifdef DEBUG
01716 printf("Reading %s\n", proffile);
01717 #endif
01718
01719 top_level_function = 0 ;
01720 max_thread_cumusec = 0.0 ;
01721
01722 if ( fgets (lbuf, 256, in) == NULL ) {
01723 fprintf (stderr,"invalid proftablefile: cannot read number of functions\n"); exit (1);
01724 }
01725 sscanf (lbuf, "%d", &numf);
01726
01727 if ( numf != numfunc ) {
01728 fprintf (stderr, "%s: number of functions does not match\n", proffile);
01729 exit (1);
01730 }
01731
01732 p_func_list = (struct p_func_descr *) malloc (numf * sizeof(struct p_func_descr));
01733 for (i=0; i<numf; i++) {
01734 fgets (lbuf, 256, in);
01735
01736 #ifdef __bsdi__
01737
01738 sscanf (lbuf, "%d %lf %lf", &n, &t1, &t2);
01739 #else
01740 sscanf (lbuf, "%d %lG %lG", &n, &t1, &t2);
01741 #endif
01742
01743 p_func_list[i].numcalls = n;
01744 p_func_list[i].usec = t1;
01745 p_func_list[i].cumusec = t2;
01746 if (p_func_list[i].cumusec > max_thread_cumusec) {
01747 top_level_function = i;
01748
01749 max_thread_cumusec = p_func_list[i].cumusec;
01750 }
01751 #ifdef DEBUG
01752 printf("Func Id %d numcalls %d usec %lG cumusec %lG\n",i, p_func_list[i].numcalls, p_func_list[i].usec, p_func_list[i].cumusec);
01753 #endif
01754 }
01755
01756
01757 if ( fgets (lbuf, 256, in) == NULL ) {
01758 fprintf (stderr,
01759 "invalid proftablefile: cannot read number of collections\n");
01760 exit (1);
01761 }
01762 sscanf (lbuf, "%d %s", &numc, aggr_str);
01763
01764 if(strcmp(aggr_str,"coll") == 0)
01765 {
01766
01767 if ( numc ) {
01768 p_coll_list = (struct p_coll_descr *) malloc (numc * sizeof(struct p_coll_descr));
01769
01770 for (i=0; i<numc; i++) {
01771 fgets (lbuf, 256, in);
01772 sscanf (lbuf,"%d %d %d %d %d %s %s %s", &n, &d, &s, &l, &r, sbuf, s1, s2);
01773
01774 p_coll_list[i].numelem = n;
01775 p_coll_list[i].dim = d;
01776 p_coll_list[i].size = s;
01777 p_coll_list[i].localacs = l;
01778 p_coll_list[i].remoteacs = r;
01779 p_coll_list[i].collname = strsave(sbuf);
01780 p_coll_list[i].elemname = strsave(s1);
01781 p_coll_list[i].varname = strsave(s2);
01782 }
01783
01784 if ( !p_coll_tbl ) {
01785 p_coll_tbl = (struct p_coll_descr *) malloc (numc * sizeof(struct p_coll_descr));
01786 for (i=0; i<numc; i++) {
01787 p_coll_tbl[i].numelem = p_coll_list[i].numelem;
01788 p_coll_tbl[i].dim = p_coll_list[i].dim;
01789 p_coll_tbl[i].size = p_coll_list[i].size;
01790 p_coll_tbl[i].localacs = 0;
01791 p_coll_tbl[i].remoteacs = 0;
01792 p_coll_tbl[i].collname = p_coll_list[i].collname;
01793 p_coll_tbl[i].elemname = p_coll_list[i].elemname;
01794 p_coll_tbl[i].varname = p_coll_list[i].varname;
01795 }
01796 numcoll = numc;
01797 }
01798 else if ( numc != numcoll ) {
01799 fprintf (stderr, "%s: number of collections does not match\n", proffile);
01800 exit (1);
01801 }
01802 }
01803 }
01804 else if (strcmp(aggr_str,"aggregates") == 0)
01805 {
01806 numa = numc;
01807 hpcxx_flag = TRUE;
01808
01809 if ( numa ) {
01810 p_aggr_list = (struct p_aggr_descr *) malloc (numa * sizeof(struct p_aggr_descr));
01811
01812 for (i=0; i<numa; i++) {
01813
01814
01815
01816
01817
01818
01819 if ((ret = fscanf(in, "%d %d %d %d ", &e, &n, &d, &s)) < 0)
01820 {
01821 perror("fscanf error:");
01822 exit(1);
01823 }
01824 #ifdef DEBUG
01825 printf("Got events %d no %d dim %d size %d\n", e,n,d,s);
01826 #endif
01827
01828 for(j =0; j < MAX_COUNTERS; j++)
01829 {
01830 p_aggr_list[i].counters[j] = 0L;
01831 }
01832 p_aggr_list[i].total_events = 0L;
01833
01834 p_aggr_list[i].numelem = n;
01835 p_aggr_list[i].dim = d;
01836 p_aggr_list[i].size = s;
01837 for(j = 0; j < e; j++)
01838 {
01839 fscanf(in,"%d %ld ", &eid, &count);
01840 #ifdef DEBUG
01841 printf(" <e %d c %ld> ", eid, count);
01842 #endif
01843 if ((eid < 0) || (eid > MAX_COUNTERS))
01844 {
01845 printf("Illegal event id %d \n", eid);
01846 exit(1);
01847 }
01848 p_aggr_list[i].counters[eid] = count;
01849 p_aggr_list[i].total_events += count;
01850 }
01851 fscanf(in, "%s %s %s", sbuf, s1, s2);
01852 p_aggr_list[i].container_name = strsave(sbuf);
01853 p_aggr_list[i].container_type = strsave(s1);
01854 p_aggr_list[i].var_name = strsave(s2);
01855 #ifdef DEBUG
01856 printf("\nReading %s %s %s\n", sbuf,s1, s2);
01857 #endif
01858 }
01859
01860 if ( !p_aggr_tbl ) {
01861 p_aggr_tbl = (struct p_aggr_descr *) malloc (numa * sizeof(struct p_aggr_descr));
01862 for (i=0; i<numa; i++) {
01863 p_aggr_tbl[i].numelem = p_aggr_list[i].numelem;
01864 p_aggr_tbl[i].dim = p_aggr_list[i].dim;
01865 p_aggr_tbl[i].size = p_aggr_list[i].size;
01866 p_aggr_tbl[i].container_name = p_aggr_list[i].container_name;
01867 p_aggr_tbl[i].container_type = p_aggr_list[i].container_type;
01868 p_aggr_tbl[i].var_name = p_aggr_list[i].var_name;
01869 for(j = 0; j < MAX_COUNTERS; j++)
01870 {
01871 p_aggr_tbl[i].counters[j] = 0L;
01872 p_aggr_tbl[i].total_events = 0L;
01873 }
01874 }
01875 numaggr = numa;
01876 }
01877 else if ( numa != numaggr ) {
01878 fprintf (stderr, "%s: number of aggregates does not match\n", proffile);
01879 exit (1);
01880 }
01881 }
01882 }
01883
01884
01885 fclose (in);
01886
01887
01888 if ( !p_total_tbl ) {
01889 p_total_tbl = (struct p_prof_elem *) malloc (numf * sizeof(struct p_prof_elem));
01890 p_min_tbl = (struct p_prof_elem *) malloc (numf * sizeof(struct p_prof_elem));
01891 p_max_tbl = (struct p_prof_elem *) malloc (numf * sizeof(struct p_prof_elem));
01892 for (i=0; i<numf; i++) {
01893 p_total_tbl[i].tag = functagbuf[i];
01894 p_total_tbl[i].name = funcnamebuf[i];
01895 p_total_tbl[i].usec = 0.0;
01896 p_total_tbl[i].cumusec = 0.0;
01897 p_total_tbl[i].numcalls = 0;
01898
01899 p_max_tbl[i].tag = p_min_tbl[i].tag = p_total_tbl[i].tag;
01900 p_max_tbl[i].name = p_min_tbl[i].name = p_total_tbl[i].name;
01901 p_max_tbl[i].usec = p_min_tbl[i].usec = p_func_list[i].usec;
01902 p_max_tbl[i].cumusec = p_min_tbl[i].cumusec = p_func_list[i].cumusec;
01903 p_max_tbl[i].numcalls = p_min_tbl[i].numcalls = p_func_list[i].numcalls;
01904 #ifdef DEBUG
01905 printf(" Func %d, min_tbl[i].numcalls %d usec %lG, cumusec %lG\n",
01906 i, p_min_tbl[i].numcalls, p_min_tbl[i].usec, p_min_tbl[i].cumusec);
01907
01908 printf(" Func %d, max_tbl[i].numcalls %d usec %lG, cumusec %lG\n",
01909 i, p_max_tbl[i].numcalls, p_max_tbl[i].usec, p_max_tbl[i].cumusec);
01910 #endif
01911 }
01912 total_total = 0.0;
01913
01914
01915
01916 max_total = min_total = p_func_list[top_level_function].cumusec;
01917 }
01918
01919
01920
01921 p_prof_tbl = (struct p_prof_elem *) malloc (numf * sizeof(struct p_prof_elem));
01922 for (i=0; i<numf; i++) {
01923 p_prof_tbl[i].tag = p_total_tbl[i].tag;
01924 p_prof_tbl[i].name = p_total_tbl[i].name;
01925 p_total_tbl[i].usec += p_prof_tbl[i].usec = p_func_list[i].usec;
01926 p_total_tbl[i].cumusec += p_prof_tbl[i].cumusec = p_func_list[i].cumusec;
01927 p_total_tbl[i].numcalls += p_prof_tbl[i].numcalls = p_func_list[i].numcalls;
01928
01929 if ( p_min_tbl[i].usec > p_func_list[i].usec )
01930 p_min_tbl[i].usec = p_func_list[i].usec;
01931 if ( p_min_tbl[i].cumusec > p_func_list[i].cumusec )
01932 p_min_tbl[i].cumusec = p_func_list[i].cumusec;
01933 if ( p_min_tbl[i].numcalls > p_func_list[i].numcalls )
01934 p_min_tbl[i].numcalls = p_func_list[i].numcalls;
01935
01936 if ( p_max_tbl[i].usec < p_func_list[i].usec )
01937 p_max_tbl[i].usec = p_func_list[i].usec;
01938 if ( p_max_tbl[i].cumusec < p_func_list[i].cumusec )
01939 p_max_tbl[i].cumusec = p_func_list[i].cumusec;
01940 if ( p_max_tbl[i].numcalls < p_func_list[i].numcalls )
01941 p_max_tbl[i].numcalls = p_func_list[i].numcalls;
01942 }
01943 #ifdef DEBUG
01944 for (i=0; i<numf; i++) {
01945 printf(" Func %d, min_tbl[i].numcalls %d usec %lG, cumusec %lG\n",
01946 i, p_min_tbl[i].numcalls, p_min_tbl[i].usec, p_min_tbl[i].cumusec);
01947
01948 printf(" Func %d, max_tbl[i].numcalls %d usec %lG, cumusec %lG\n",
01949 i, p_max_tbl[i].numcalls, p_max_tbl[i].usec, p_max_tbl[i].cumusec);
01950 }
01951 #endif
01952
01953
01954 #ifdef DEBUG
01955 printf("Top level function = %d in file %s\n", top_level_function, proffile);
01956 #endif
01957
01958
01959
01960
01961 total_total += total = p_func_list[top_level_function].cumusec;
01962 if ( min_total > p_func_list[top_level_function].cumusec ) min_total = p_func_list[top_level_function].cumusec;
01963 if ( max_total < p_func_list[top_level_function].cumusec ) max_total = p_func_list[top_level_function].cumusec;
01964
01965 #ifdef DEBUG
01966 printf("%s : total = %5.1f top level = %5.1f\n", proffile, total, max_thread_cumusec);
01967 #endif
01968 if (hpcxx_flag == FALSE)
01969 {
01970 sprintf(ident_str,"%d", no);
01971 }
01972 else
01973 {
01974 sprintf(ident_str,"%d,%d,%d", no, ctx, thr);
01975 }
01976
01977
01978
01979 if ( nodeprint ) {
01980 if ( dump ) {
01981 qsort ((void *) p_prof_tbl, numf, sizeof(struct p_prof_elem), MsecCmp);
01982 DumpFuncTab (p_prof_tbl, ident_str, total, max, "excl");
01983 qsort ((void *) p_prof_tbl, numf, sizeof(struct p_prof_elem), CumMsecCmp);
01984 DumpFuncTab (p_prof_tbl, ident_str, total, max, "incl");
01985 }
01986 else {
01987 qsort ((void *) p_prof_tbl, numf, sizeof(struct p_prof_elem), compar);
01988 if (hpcxx_flag == FALSE)
01989 printf ("\nNODE %d: \n", no);
01990 else
01991 {
01992 printf ("\nNODE %d;", no);
01993 printf ("CONTEXT %d;", ctx);
01994 printf ("THREAD %d:\n", thr);
01995 }
01996
01997 PrintFuncTab (p_prof_tbl, total, max);
01998 }
01999 }
02000
02001 if ( numc ) {
02002 if ( hpcxx_flag == FALSE) {
02003 if ( nodeprint ) {
02004 if ( ! dump ) {
02005 printf ("\n local remote collection\n");
02006 printf ( "accesses accesses num name\n");
02007 }
02008 }
02009 for (i=0; i<numc; i++) {
02010 if ( nodeprint ) {
02011
02012 if ( dump ) {
02013 if ( ct = p_coll_list[i].localacs + p_coll_list[i].remoteacs ) {
02014 printf ("coll %d %d %d %4.2f %d %4.2f\n", no, i,
02015 p_coll_list[i].localacs, p_coll_list[i].localacs/ct*100.0,
02016 p_coll_list[i].remoteacs, p_coll_list[i].remoteacs/ct*100.0);
02017 }
02018 else {
02019 printf ("coll %d %d 0 0.0 0 0.0\n", no, i);
02020 }
02021 }
02022 else {
02023 printf ("%8d %8d %3d %s\n",
02024 p_coll_list[i].localacs, p_coll_list[i].remoteacs,
02025 i, p_coll_list[i].varname);
02026 }
02027 }
02028
02029
02030 p_coll_tbl[i].localacs += p_coll_list[i].localacs;
02031 p_coll_tbl[i].remoteacs += p_coll_list[i].remoteacs;
02032 }
02033 }
02034 else {
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044 for (i=0; i<numa; i++) {
02045 if ( nodeprint ) {
02046
02047 if ( dump ) {
02048 if ( p_aggr_list[i].total_events ) {
02049 active_counters = 0;
02050 for(j=0; j < MAX_COUNTERS; j++)
02051 {
02052 if (p_aggr_list[i].counters[j]) active_counters++ ;
02053 }
02054 printf("aggregates %d,%d,%d %d %d ",no, ctx, thr, i, active_counters);
02055
02056 for (j = 0; j < MAX_COUNTERS; j++)
02057 {
02058
02059 if ( p_aggr_list[i].counters[j])
02060 {
02061 if (eventnamebuf == NULL)
02062 {
02063 printf("%d NULL %d %4.2f ", j,
02064 p_aggr_list[i].counters[j],
02065 p_aggr_list[i].counters[j]*100.0/p_aggr_list[i].total_events);
02066 }
02067 else
02068 {
02069 printf("%d %s %d %4.2f ", j, eventnamebuf[j],
02070 p_aggr_list[i].counters[j],
02071 p_aggr_list[i].counters[j]*100.0/p_aggr_list[i].total_events);
02072 }
02073 }
02074 }
02075 printf("%s %s %s\n", p_aggr_list[i].container_name,
02076 p_aggr_list[i].container_type, p_aggr_list[i].var_name);
02077 }
02078 else
02079 {
02080 printf("aggregates %d,%d,%d %d 0 NULL 0 0.0 %s %s %s\n",
02081 no, ctx, thr, i, p_aggr_list[i].container_name,
02082 p_aggr_list[i].container_type, p_aggr_list[i].var_name);
02083
02084 }
02085 }
02086 else
02087 {
02088 printf("aggregates %s <%s> %s\n",p_aggr_list[i].container_name,
02089 p_aggr_list[i].container_type, p_aggr_list[i].var_name);
02090 for(j = 0; j < MAX_COUNTERS; j++)
02091 {
02092 if(p_aggr_list[i].counters[j])
02093 {
02094 if(eventnamebuf == NULL)
02095 {
02096 printf("Event id %d\t: %d %4.2f percent\n",
02097 j, p_aggr_list[i].counters[j],
02098 p_aggr_list[i].counters[j]*100.0/p_aggr_list[i].total_events);
02099 }
02100 else
02101 {
02102 printf("Event id %d name %s\t: %d %4.2f percent\n",
02103 j, eventnamebuf[j], p_aggr_list[i].counters[j],
02104 p_aggr_list[i].counters[j]*100.0/p_aggr_list[i].total_events);
02105 }
02106 }
02107 }
02108 }
02109 }
02110
02111 for (j = 0; j < MAX_COUNTERS; j++)
02112 {
02113 p_aggr_tbl[i].counters[j] += p_aggr_list[i].counters[j];
02114 }
02115 p_aggr_tbl[i].total_events += p_aggr_list[i].total_events;
02116 }
02117 }
02118 }
02119
02120 free (p_coll_list);
02121 free (p_func_list);
02122 free (p_prof_tbl);
02123 free (p_aggr_list);
02124 files_processed ++;
02125 return (TRUE);
02126 }
02127
02128
02129
02130
02131
02132
02133 static void PrintFuncSummary (struct p_prof_elem *tab, double total,
02134 int max, char *message, char *ident)
02135 {
02136
02137 if ( dump ) {
02138 qsort ((void *) tab, numfunc, sizeof(struct p_prof_elem), MsecCmp);
02139 DumpFuncTab (tab, ident, total, max, "excl");
02140 qsort ((void *) tab, numfunc, sizeof(struct p_prof_elem), CumMsecCmp);
02141 DumpFuncTab (tab, ident, total, max, "incl");
02142 }
02143 else {
02144 qsort ((void *) tab, numfunc, sizeof(struct p_prof_elem), compar);
02145 printf ("\nFUNCTION SUMMARY (%s):\n", message);
02146 PrintFuncTab (tab, total, max);
02147 }
02148 }
02149
02150 static void PrintSummary (int max, int numproc)
02151 {
02152 int i,j,no_active_counters;
02153 double ct;
02154
02155 #ifdef DEBUG
02156 printf("PrintSummary: numproc = %d, dump = %d \n", numproc, dump);
02157 #endif
02158
02159 if ( (numproc > 1) || dump ) {
02160 PrintFuncSummary (p_total_tbl, total_total, max, "total", "t");
02161 if (dumpminmax) {
02162 PrintFuncSummary (p_min_tbl, min_total, max, "min", "<");
02163 PrintFuncSummary (p_max_tbl, max_total, max, "max", ">");
02164 }
02165
02166 #ifdef DEBUG
02167 for(i=0; i < numfunc; i++) {
02168 printf("p_total_tbl[i].numcalls = %d\n", p_total_tbl[i].numcalls);
02169 }
02170 #endif
02171
02172 for (i=0; i<numfunc; i++) {
02173 p_total_tbl[i].numcalls /= numproc;
02174 p_total_tbl[i].numsubrs /= numproc;
02175 p_total_tbl[i].usec /= numproc;
02176 p_total_tbl[i].cumusec /= numproc;
02177 }
02178 total_total /= numproc;
02179
02180 #ifdef DEBUG
02181 for (i=0; i < numfunc; i++) {
02182 printf("PrintSummary(Mean): Func %d p_total_tbl numcalls %d, usec %lG, cumusec %lg\n", i, p_total_tbl[i].numcalls, p_total_tbl[i].usec, p_total_tbl[i].cumusec);
02183 }
02184 #endif
02185
02186
02187 PrintFuncSummary (p_total_tbl, total_total, max, "mean", "m");
02188 }
02189
02190 if(hpcxx_flag == FALSE)
02191 {
02192 if ( numcoll ) {
02193 if ( dump ) {
02194 for (i=0; i<numcoll; i++) {
02195 ct = p_coll_tbl[i].localacs + p_coll_tbl[i].remoteacs;
02196 printf ("cinfo %d %s<%s> %s %d %d %d %d %4.2f %d %4.2f\n",
02197 i, p_coll_tbl[i].collname,
02198 p_coll_tbl[i].elemname, p_coll_tbl[i].varname,
02199 p_coll_tbl[i].numelem, p_coll_tbl[i].size, p_coll_tbl[i].dim,
02200 p_coll_tbl[i].localacs, p_coll_tbl[i].localacs/ct*100.0,
02201 p_coll_tbl[i].remoteacs, p_coll_tbl[i].remoteacs/ct*100.0);
02202 }
02203 }
02204 else {
02205 printf ("\nCOLLECTION SUMMARY:\n");
02206 printf ("------------------------------------------------------------\n");
02207 for (i=0; i<numcoll; i++) {
02208 printf ("%s<%s> %s, collection #%d\n", p_coll_tbl[i].collname,
02209 p_coll_tbl[i].elemname, p_coll_tbl[i].varname, i);
02210 printf ("\t%d elements of size %d, %d-dimensional\n",
02211 p_coll_tbl[i].numelem, p_coll_tbl[i].size, p_coll_tbl[i].dim);
02212 printf ("\t%8d local / %8d remote accesses\n",
02213 p_coll_tbl[i].localacs, p_coll_tbl[i].remoteacs);
02214 }
02215 }
02216 }
02217 }
02218 else
02219 {
02220
02221
02222 if ( numaggr ) {
02223 if ( dump ) {
02224 for (i=0; i<numaggr; i++) {
02225 no_active_counters = 0;
02226 for (j = 0; j < MAX_COUNTERS; j++)
02227 {
02228 if(p_aggr_tbl[i].counters[j]) no_active_counters ++;
02229 }
02230
02231 printf("ainfo %d %s %s %s %d %d %d %d ", i,
02232 p_aggr_tbl[i].container_name, p_aggr_tbl[i].container_type,
02233 p_aggr_tbl[i].var_name, p_aggr_tbl[i].numelem,
02234 p_aggr_tbl[i].size, p_aggr_tbl[i].dim, no_active_counters);
02235
02236 for(j = 0; j < MAX_COUNTERS; j++)
02237 {
02238 if (p_aggr_tbl[i].counters[j])
02239 {
02240 if (eventnamebuf == NULL)
02241 {
02242 printf("%d NULL %d %4.2f ", j,
02243 p_aggr_tbl[i].counters[j],
02244 p_aggr_tbl[i].counters[j]*100.0/p_aggr_tbl[i].total_events);
02245 }
02246 else
02247 {
02248 printf("%d %s %d %4.2f ", j, eventnamebuf[j],
02249 p_aggr_tbl[i].counters[j],
02250 p_aggr_tbl[i].counters[j]*100.0/p_aggr_tbl[i].total_events);
02251 }
02252 }
02253 }
02254 printf("\n");
02255 }
02256 }
02257 else {
02258 printf ("\nAGGREGATE SUMMARY:\n");
02259 printf ("------------------------------------------------------------\n");
02260 for (i=0; i<numaggr; i++) {
02261 printf ("%s<%s> %s, aggregate #%d\n",
02262 p_aggr_tbl[i].container_name,
02263 p_aggr_tbl[i].container_type, p_aggr_tbl[i].var_name, i);
02264 printf ("\t%d elements of size %d, %d-dimensional\n",
02265 p_aggr_tbl[i].numelem, p_aggr_tbl[i].size, p_aggr_tbl[i].dim);
02266 for(j = 0; j < MAX_COUNTERS; j++)
02267 {
02268 if(p_aggr_tbl[i].counters[j])
02269 {
02270 if(eventnamebuf == NULL)
02271 {
02272 printf("Event id %d\t: %d %4.2f percent\n",
02273 j, p_aggr_tbl[i].counters[j],
02274 p_aggr_tbl[i].counters[j]*100.0/p_aggr_tbl[i].total_events);
02275 }
02276 else
02277 {
02278 printf("Event id %d name %s\t: %d %4.2f percent\n",
02279 j, eventnamebuf[j], p_aggr_tbl[i].counters[j],
02280 p_aggr_tbl[i].counters[j]*100.0/p_aggr_tbl[i].total_events);
02281 }
02282 }
02283 }
02284 printf("\n");
02285 }
02286 }
02287 }
02288 }
02289 return;
02290 }
02291
02292 static int IsFilePresent(char *filename)
02293 {
02294 FILE *in;
02295
02296 if ( (in = fopen (filename, "r")) == NULL ) {
02297 return (FALSE);
02298 }
02299 else
02300 {
02301 fclose(in);
02302 return (TRUE);
02303 }
02304 }
02305
02306 static int ProcessFileInContext (int no, int ctx, int thr, int longname, int max, char prefix[], int ignore)
02307 {
02308
02309
02310 for (thr = 0;
02311 ProcessFile (no, ctx, thr, longname, max, prefix, ignore);
02312 thr ++)
02313 ;
02314 return (FALSE);
02315 }
02316
02317
02318 static int ProcessFileInNode (int no, int ctx, int thr, int longname, int max, char prefix[], int ignore)
02319 {
02320 for (ctx = 0;
02321 ProcessFileInContext(no, ctx, thr, longname, max, prefix, ignore);
02322 ctx ++)
02323 ;
02324 return (FALSE);
02325 }
02326
02327
02328
02329
02330 int main (int argc, char *argv[])
02331 {
02332 int argno, start;
02333 int ch;
02334 int i;
02335 int max = 999999999;
02336 int errflag;
02337 char *file = "profile";
02338 char proffile[SIZE_OF_FILENAME], *dir;
02339
02340 extern char *optarg;
02341 extern int optind;
02342
02343 dir = getenv("PROFILEDIR");
02344 if(dir != NULL) {
02345 file = strsave(strcat(strcat(dir,"/"),file));
02346 }
02347
02348
02349 errflag = FALSE;
02350 while ( (ch = getopt (argc, argv, "cbdf:lmeivn:rstx")) != EOF ) {
02351 switch ( ch ) {
02352 case 'c':
02353 compar = CallCmp;
02354 break;
02355 case 'b':
02356 compar = SubrCmp;
02357 break;
02358 case 'd':
02359 dump = TRUE;
02360 break;
02361 case 'f':
02362 file = optarg;
02363 break;
02364 case 'l':
02365 list = TRUE;
02366 break;
02367 case 'm':
02368 compar = MsecCmp;
02369 break;
02370 case 'e':
02371 compar = MsecPerCallCmp;
02372 break;
02373 case 'i':
02374 compar = CumMsecPerCallCmp;
02375 break;
02376 case 'n':
02377 max = atoi(optarg);
02378 break;
02379 case 'r':
02380 sign = -1;
02381 break;
02382 case 's':
02383 nodeprint = FALSE;
02384 break;
02385 case 't':
02386 compar = CumMsecCmp;
02387 break;
02388 case 'v':
02389 compar = StdDevCmp;
02390 break;
02391 case 'x':
02392 dumpminmax = TRUE;
02393 break;
02394 default:
02395 errflag = TRUE;
02396 break;
02397 }
02398 }
02399 if ( errflag ) {
02400 fprintf (stderr, "usage: %s [-c|-b|-m|-t|-e|-i|-v] [-r] [-s] [-n num] [-f filename] [-l] [node numbers]\n", argv[0]);
02401 fprintf(stderr," -c : Sort according to number of Calls \n");
02402 fprintf(stderr," -b : Sort according to number of suBroutines called by a function \n");
02403 fprintf(stderr," -m : Sort according to Milliseconds (exclusive time total)\n");
02404 fprintf(stderr," -t : Sort according to Total milliseconds (inclusive time total) (default)\n");
02405 fprintf(stderr," -e : Sort according to Exclusive time per call (msec/call)\n");
02406 fprintf(stderr," -i : Sort according to Inclusive time per call (total msec/call)\n");
02407 fprintf(stderr," -v : Sort according to Standard Deviation (excl usec)\n");
02408 fprintf(stderr," -r : Reverse sorting order\n");
02409 fprintf(stderr," -s : print only Summary profile information \n");
02410 fprintf(stderr," -n <num> : print only first <num> number of functions \n");
02411 fprintf(stderr," -f filename : specify full path and Filename without node ids\n");
02412 fprintf(stderr," -l : List all functions and exit\n");
02413 fprintf(stderr," [node numbers] : prints only info about all contexts/threads of given node numbers\n");
02414
02415
02416 exit (1);
02417 }
02418
02419
02420
02421
02422 if(optind == argc)
02423 start = 0;
02424 else
02425 start = atoi(argv[optind]);
02426
02427 sprintf(proffile,"%s.%d.0.0", file, start);
02428
02429 if (!dump) {
02430 printf("Reading Profile files in %s.*\n", file);
02431 }
02432
02433 if (IsDynamicProfiling(proffile)) {
02434
02435
02436 if ( optind == argc) {
02437
02438 for(argno = 0; FillFunctionDBInNode(argno, 0, 0, file); argno++) ;
02439 }
02440 else {
02441 for (argno = optind; argno < argc; argno++)
02442 FillFunctionDBInNode(atoi(argv[argno]), 0, 0, file);
02443 }
02444
02445 numfunc = funcDB.size();
02446
02447 InitFuncNameBuf();
02448
02449
02450 if (list) {
02451 DumpFunctionNamesInDB();
02452 exit(0);
02453 }
02454 else if (dump) {
02455
02456
02457 printf ("default.dep\n%d templated_functions\n", numfunc);
02458 }
02459
02460
02461
02462 if ( optind == argc ) {
02463 for (argno = 0; ProcessFileDynamicInNode(argno, 0, 0, max, file); argno++);
02464 }
02465 else {
02466 for (argno = optind; argno < argc; argno++)
02467 ProcessFileDynamicInNode (atoi(argv[argno]), 0, 0, max, file);
02468 argno -= optind;
02469 }
02470 if (files_processed > 0) PrintSummary (max, files_processed);
02471
02472 exit(0);
02473
02474 } else {
02475
02476 ReadNameTable (file);
02477
02478
02479 ReadEventTable (file);
02480 if ( list ) {
02481 printf ("%s:\n", depfile);
02482 for (i=0; i<numfunc; i++) {
02483 if ( functagbuf[i] > 0 )
02484 printf ("%5d %s\n", functagbuf[i], funcnamebuf[i]);
02485 }
02486 exit (0);
02487 } else if ( dump ) {
02488 printf ("%s\n%d functions\n", depfile, numfunc);
02489 }
02490 }
02491
02492
02493
02494 sprintf(proffile,"%s.%d", file,start);
02495 if(IsFilePresent(proffile))
02496 {
02497 if ( optind == argc ) {
02498 for (argno = 0; ProcessFile(argno, 0, 0, FALSE, max, file, TRUE); argno++);
02499 }
02500 else {
02501 for (argno = optind; argno < argc; argno++)
02502 ProcessFile (atoi(argv[argno]), 0, 0, FALSE, max, file, FALSE);
02503 argno -= optind;
02504 }
02505
02506 if ( argno ) PrintSummary (max, argno);
02507 }
02508 else
02509 {
02510 sprintf(proffile,"%s.%d.0.0", file, start);
02511 if (IsFilePresent(proffile))
02512 {
02513
02514
02515 if ( optind == argc ) {
02516 for (argno = 0; ProcessFileInNode(argno, 0, 0, TRUE, max, file, TRUE); argno++);
02517 }
02518 else {
02519 for (argno = optind; argno < argc; argno++)
02520 ProcessFileInNode (atoi(argv[argno]), 0, 0, TRUE, max, file, TRUE);
02521 argno -= optind;
02522
02523
02524 }
02525 if (files_processed > 0) PrintSummary (max, files_processed);
02526 }
02527 else
02528 {
02529
02530 printf("Error : profile file %s not found",proffile);
02531 exit(1);
02532 }
02533 }
02534
02535
02536 exit (0);
02537 }
02538
02539
02540
02541
02542
02543