PAPI  5.7.0.0
benchStats.c
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 // benchStats: Reads a CSV file of three columns; and produces various stats
3 // for each column.
4 //-----------------------------------------------------------------------------
5 
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <math.h>
11 #include <papi.h>
12 #include "papi_test.h"
13 #include <sys/time.h>
14 
15 typedef struct {
16  double init;
17  double pcpVal;
18 } BenchData_t;
19 
20 //-----------------------------------------------------------------------------
21 // qsort comparison to sort benchData array into ascending order of Init.
22 //-----------------------------------------------------------------------------
23 int sortAscBDInit(const void *vA, const void *vB) {
24  BenchData_t *sA=(BenchData_t*) vA; // recast to cmp type.
25  BenchData_t *sB=(BenchData_t*) vB; // ..
26 
27  if (sA->init < sB->init) return(-1); // move cA toward front of list.
28  if (sA->init > sB->init) return( 1); // move cA toward end of list.
29  return(0); // equality.
30 } // end routine.
31 
32 
33 //-----------------------------------------------------------------------------
34 // qsort comparison to sort benchData array into ascending order of pcpVal.
35 //-----------------------------------------------------------------------------
36 int sortAscBDPCP(const void *vA, const void *vB) {
37  BenchData_t *sA=(BenchData_t*) vA; // recast to cmp type.
38  BenchData_t *sB=(BenchData_t*) vB; // ..
39 
40  if (sA->pcpVal < sB->pcpVal) return(-1); // move cA toward front of list.
41  if (sA->pcpVal > sB->pcpVal) return( 1); // move cA toward end of list.
42  return(0); // equality.
43 } // end routine.
44 
45 
46 //-----------------------------------------------------------------------------
47 // median of sorted fRec init value array, for count elements.
48 // if count is odd, median is at (count/2). e.g. count=7, 7/2=3, a[3] is it.
49 // if count is even, median is average of (count/2)-1 and (count/2). e.g.
50 // count=8, a[3]+a[4] are two center values.
51 //-----------------------------------------------------------------------------
52 double median_BDInit(BenchData_t* fRec, int count) {
53  if ((count&1)) return fRec[(count>>1)].init; // median if count is odd.
54  return ( (fRec[(count>>1)-1].init +
55  fRec[(count>>1)].init)/2.0 ); // median if count is even.
56 } // end routine.
57 
58 
59 //-----------------------------------------------------------------------------
60 // median of sorted fRec pcp value array, for count elements.
61 // if count is odd, median is at (count/2). e.g. count=7, 7/2=3, a[3] is it.
62 // if count is even, median is average of (count/2)-1 and (count/2). e.g.
63 // count=8, a[3]+a[4] are two center values.
64 //-----------------------------------------------------------------------------
65 double median_BDPCP(BenchData_t* fRec, int count) {
66  if ((count&1)) return fRec[(count>>1)].pcpVal; // median if count is odd.
67  return ( (fRec[(count>>1)-1].pcpVal +
68  fRec[(count>>1)].pcpVal)/2.0 ); // median if count is even.
69 } // end routine.
70 
71 
72 //-----------------------------------------------------------------------------
73 // Write a rough ASCII histogram.
74 //-----------------------------------------------------------------------------
75 
76 void histogram(int *BinCount, int bins, int total, double minVal, double width) {
77  int i;
78  double ctr, pcnt;
79  for (i=0; i<bins; i++) {
80  ctr = minVal + ( (i+.5)*width); // compute bin center.
81  pcnt = (100.*BinCount[i]) / (total+0.0); // compute percentage of values.
82  printf("%8.1f, %8i, =%5.2f%%\n", ctr, BinCount[i], pcnt);
83  }
84 } // end routine.
85 
86 
87 //-----------------------------------------------------------------------------
88 // MAIN.
89 //-----------------------------------------------------------------------------
90 
91 int main(int argc, char **argv) { // args to set filename.
92  int i,j,ret;
93  FILE *Inp;
94  int Block = 64;
95  BenchData_t *fRec = calloc(Block, sizeof(BenchData_t)); // Make some initial space.
96  char title1[128], title2[128];
97  int count=0, size=Block; // records we have, size of malloc.
98 
99  if (argc != 2) { // progname inpfile
100  fprintf(stderr, "You must specify a CSV file on the command line.\n");
101  exit(-1);
102  }
103 
104  Inp =fopen(argv[1], "r"); // Open arg1 as input file.
105  if (Inp == NULL) { // In case of failure...
106  fprintf(stderr, "Error reading file %s.\n", argv[1]); // .. report it.
107  exit(-1); // .. exit.
108  }
109 
110  ret = fscanf(Inp, "%128[^,],%128[^\n]", title1, title2); // Read the three titles.
111  if (ret !=2) { // If we did not get 3,
112  fprintf(stderr, "File Format Error, read %i of 2 expected column titles in file '%s'.\n", ret, argv[1]);
113  fclose(Inp);
114  exit(-1);
115  }
116 
117  while (1) { // We break out of this.
118  ret = fscanf(Inp, "%lf,%*[ ]%lf\n", &fRec[count].init, &fRec[count].pcpVal); // read two values.
119  if (ret == EOF) break; // quiet break at EOF.
120  if (ret != 2) { // If we did not get 3 values,
121  fprintf(stderr, "File Format Error, read %i of 2 expected column values in file '%s', line %i.\n", ret, argv[1], count+2);
122  fclose(Inp);
123  free(fRec);
124  exit(-1);
125  }
126 
127  count++; // increment count of lines.
128  if (count == size) { // If that was last in size,
129  size += Block; // Need to add another chunk.
130  fRec = realloc(fRec, size*sizeof(BenchData_t)); // make more space.
131  if (fRec == NULL) {
132  fprintf(stderr, "Memory failure, failed to realloc(fRec, %i)\n", size);
133  fclose(Inp);
134  exit(-1);
135  }
136  } // end if realloc needed.
137  } // end of all reading.
138 
139  fclose(Inp); // Done with this file.
140  fprintf(stderr, "Read a total of %i data lines.\n", count);
141 
142  // We can go ahead and find the min, max, max-but-1 and average for both Init and PCP.
143  double minInit=fRec[0].init;
144  double maxInit=minInit;
145  double firstInit=minInit;
146  double avgInit=minInit;
147  double maxBut1Init = fRec[1].init; // start this at second value.
148 
149  double minPCP=fRec[0].pcpVal;
150  double maxPCP=minPCP;
151  double firstPCP=minPCP;
152  double avgPCP=minPCP;
153  double maxBut1PCP = fRec[1].pcpVal; // start this at second value.
154 
155  for (i=1; i<count; i++) { // check the rest.
156  double v;
157  v=fRec[i].init; // get it.
158  if (v > maxInit) maxInit=v;
159  if (v > maxBut1Init) maxBut1Init=v;
160  if (v < minInit) minInit=v;
161  avgInit += v; // build for average.
162 
163  v=fRec[i].pcpVal; // get it.
164  if (v > maxPCP) maxPCP=v;
165  if (v > maxBut1PCP) maxBut1PCP=v;
166  if (v < minPCP) minPCP=v;
167  avgPCP += v; // build for average.
168  }
169 
170  avgInit /= ((double) count); // compute average.
171  avgPCP /= ((double) count); // compute average.
172 
173 
174  // The mode: This is the highest value in a histogram of values;
175  // but that can be quite arbitary in picking the window size. We
176  // use as our # of bins the square root of the count; and make
177  // the bin size the (max-min)/#bins.
178 
179  int maxBin, *InitBins=NULL, *ReadBins=NULL; // counters for compute.
180  int bins = ceil(sqrtf((double) count));
181  int expCount = round(((count+0.0) / (bins+0.0))); // expected count per bin.
182 
183  // Mode for Init.
184  qsort(fRec, count, sizeof(BenchData_t), sortAscBDInit); // put in ascending order of Init time.
185 
186  double medInit = median_BDInit(fRec, count); // get the overall median.
187  double Initrange=(maxInit-minInit); // compute the range.
188  double Initbin=ceil(Initrange/bins); // bin size.
189  if (Initbin == 0.0) Initbin=1.0; // If all the same, just one bin.
190  InitBins = calloc(bins, sizeof(int)); // make counters for them.
191 
192  for (i=0; i<count; i++) { // for every record,
193  double v = fRec[i].init - minInit; // ..value to bin.
194  for (j=0; j<bins; j++) { // ..search for bin.
195  if (v < (j+1)*Initbin) break; // ..if we found the bin, break.
196  }
197 
198  InitBins[j]++; // Add to number in that bin.
199  }
200 
201  maxBin = 0; // first bin is beginning of max.
202  for (i=1; i<bins; i++) {
203  if (InitBins[i] > InitBins[maxBin]) maxBin=i; // remember index of max bin.
204  }
205 
206  double modeInit = minInit + ((maxBin+0.5) * Initbin); // find the mode as centerpoint.
207  int actInitCount = InitBins[maxBin]; // actual init count.
208 
209 
210  // Mode for PCP.
211  qsort(fRec, count, sizeof(BenchData_t), sortAscBDPCP); // put in ascending order of pcpVal.
212  double medPCP = median_BDPCP(fRec, count); // get the overall median.
213  double PCPrange=(maxPCP-minPCP); // compute the range.
214  double PCPbin=ceil(PCPrange/bins); // bin size.
215  if (PCPbin == 0.0) PCPbin=1.0; // If all the same, just one bin.
216  ReadBins = calloc(bins, sizeof(int)); // make counters for them.
217 
218  for (i=0; i<count; i++) { // for every record,
219  double v = fRec[i].pcpVal - minPCP; // ..value to bin.
220  for (j=0; j<bins; j++) { // ..search for bin.
221  if (v < (j+1)*PCPbin) break; // ..if we found the bin, break.
222  }
223 
224  ReadBins[j]++; // Add to number in that bin.
225  }
226 
227  maxBin = 0; // first bin is beginning of max.
228  for (i=1; i<bins; i++) {
229  if (ReadBins[i] > ReadBins[maxBin]) maxBin=i; // remember index of max bin.
230  }
231 
232  double modePCP = minPCP + ((maxBin+0.5) * PCPbin); // find the mode as centerpoint.
233  int actPCPCount = ReadBins[maxBin]; // actual init count.
234 
235 
236  // Stats for init.
237 
238  printf("Stats for Initialization time in file '%s'.\n" , argv[1] );
239  printf("Sample Values ,%8i\n" , count );
240  printf("Minimum uS ,%8.1f\n", minInit );
241  printf("Maximum uS ,%8.1f\n", maxInit );
242  printf("Average uS ,%8.1f\n", avgInit );
243  printf("Median uS ,%8.1f\n", medInit );
244  printf("First uS ,%8.1f\n", firstInit );
245  printf("Max w/o First ,%8.1f\n", maxBut1Init );
246  printf("Range uS ,%8.1f\n", Initrange );
247  printf("Histogram Bins chosen ,%8i\n" , bins );
248  printf("Bin width uS ,%8.1f\n", Initbin );
249  printf("Mode (center highest Bin Count),%8.1f\n", modeInit );
250  printf("Mode Bin Count ,%8i\n" , actInitCount );
251  printf("Bin Expected Count ,%8i\n" , expCount );
252  printf("\n");
253  printf("Initialization Histogram:\n"
254  "binCenter, Count, %% of Count\n");
255 
256  histogram(InitBins, bins, count, minInit, Initbin);
257 
258  printf("\n");
259  printf("Stats for PCP event read time in file '%s'.\n" , argv[1] );
260  printf("Sample Values ,%8i\n" , count );
261  printf("Minimum uS ,%8.1f\n", minPCP );
262  printf("Maximum uS ,%8.1f\n", maxPCP );
263  printf("Average uS ,%8.1f\n", avgPCP );
264  printf("Median uS ,%8.1f\n", medPCP );
265  printf("First uS ,%8.1f\n", firstPCP );
266  printf("Max w/o First ,%8.1f\n", maxBut1PCP );
267  printf("Range uS ,%8.1f\n", PCPrange );
268  printf("Histogram Bins chosen ,%8i\n" , bins );
269  printf("Bin width uS ,%8.1f\n", PCPbin );
270  printf("Mode (center highest Bin Count),%8.1f\n", modePCP );
271  printf("Mode Bin Count ,%8i\n" , actPCPCount );
272  printf("Bin Expected Count ,%8i\n" , expCount );
273  printf("\n");
274  printf("Read Event Histogram:\n"
275  "binCenter, Count, %% of Count\n");
276 
277  histogram(ReadBins, bins, count, minPCP, PCPbin);
278  printf("\n");
279  free(InitBins); InitBins=NULL; // Lose this version of InitBins array.
280  free(ReadBins); ReadBins=NULL; // Lose this version of ReadBins array.
281  free(fRec);
282 } // end main.
int main(int argc, char **argv)
Definition: benchStats.c:91
int sortAscBDInit(const void *vA, const void *vB)
Definition: benchStats.c:23
int sortAscBDPCP(const void *vA, const void *vB)
Definition: benchStats.c:36
Return codes and api definitions.
double pcpVal
Definition: benchStats.c:17
double init
Definition: benchStats.c:16
long long ret
Definition: iozone.c:1346
void histogram(int *BinCount, int bins, int total, double minVal, double width)
Definition: benchStats.c:76
static int total
Definition: rapl_overflow.c:9
double median_BDPCP(BenchData_t *fRec, int count)
Definition: benchStats.c:65
double median_BDInit(BenchData_t *fRec, int count)
Definition: benchStats.c:52
void exit()
static long count
int i
Definition: fileop.c:140