PAPI 7.1.0.0
Loading...
Searching...
No Matches
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
15typedef struct {
16 double init;
17 double pcpVal;
19
20//-----------------------------------------------------------------------------
21// qsort comparison to sort benchData array into ascending order of Init.
22//-----------------------------------------------------------------------------
23int 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//-----------------------------------------------------------------------------
36int 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//-----------------------------------------------------------------------------
52double 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//-----------------------------------------------------------------------------
65double 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
76void 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
91int 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 i
double median_BDPCP(BenchData_t *fRec, int count)
Definition: benchStats.c:65
int sortAscBDPCP(const void *vA, const void *vB)
Definition: benchStats.c:36
int sortAscBDInit(const void *vA, const void *vB)
Definition: benchStats.c:23
void histogram(int *BinCount, int bins, int total, double minVal, double width)
Definition: benchStats.c:76
double median_BDInit(BenchData_t *fRec, int count)
Definition: benchStats.c:52
static long count
Return codes and api definitions.
FILE * stderr
int fclose(FILE *__stream)
int main()
Definition: pernode.c:20
static int total
Definition: rapl_overflow.c:9
double init
Definition: benchStats.c:16
double pcpVal
Definition: benchStats.c:17