PAPI  5.3.2.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sdsc4.c
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Test example for multiplex functionality, originally
5  * provided by Timothy Kaiser, SDSC. It was modified to fit the
6  * PAPI test suite by Nils Smeds, <smeds@pdc.kth.se>.
7  *
8  * This example verifies the adding and removal of multiplexed
9  * events in an event set.
10  */
11 
12 #include "papi_test.h"
13 #include <stdio.h>
14 #include <math.h>
15 #include <assert.h>
16 
17 #define MAXEVENTS 9
18 #define REPEATS (MAXEVENTS * 4)
19 #define SLEEPTIME 100
20 #define MINCOUNTS 100000
21 
22 static double dummy3( double x, int iters );
23 
24 int
25 main( int argc, char **argv )
26 {
27  PAPI_event_info_t info;
28  char name2[PAPI_MAX_STR_LEN];
29  int i, j, retval, idx, repeats;
30  int iters = NUM_FLOPS;
31  double x = 1.1, y, dtmp;
32  long long t1, t2;
33  long long values[MAXEVENTS], refvals[MAXEVENTS];
34  int nsamples[MAXEVENTS], truelist[MAXEVENTS], ntrue;
35 #ifdef STARTSTOP
36  long long dummies[MAXEVENTS];
37 #endif
38  int sleep_time = SLEEPTIME;
39  double valsample[MAXEVENTS][REPEATS];
40  double valsum[MAXEVENTS];
41  double avg[MAXEVENTS];
42  double spread[MAXEVENTS];
43  int nevents = MAXEVENTS, nev1;
44  int eventset = PAPI_NULL;
45  int events[MAXEVENTS];
46  int eventidx[MAXEVENTS];
47  int eventmap[MAXEVENTS];
48  int fails;
49 
50  events[0] = PAPI_FP_INS;
51  events[1] = PAPI_TOT_CYC;
52  events[2] = PAPI_TOT_INS;
53  events[3] = PAPI_TOT_IIS;
54  events[4] = PAPI_INT_INS;
55  events[5] = PAPI_STL_CCY;
56  events[6] = PAPI_BR_INS;
57  events[7] = PAPI_SR_INS;
58  events[8] = PAPI_LD_INS;
59 
60  for ( i = 0; i < MAXEVENTS; i++ ) {
61  values[i] = 0;
62  valsum[i] = 0;
63  nsamples[i] = 0;
64  }
65 
66  if ( argc > 1 ) {
67  if ( !strcmp( argv[1], "TESTS_QUIET" ) )
68  tests_quiet( argc, argv );
69  else {
70  sleep_time = atoi( argv[1] );
71  if ( sleep_time <= 0 )
72  sleep_time = SLEEPTIME;
73  }
74  }
75 
76  if ( !TESTS_QUIET ) {
77  printf( "\nFunctional check of multiplexing routines.\n" );
78  printf( "Adding and removing events from an event set.\n\n" );
79  }
80 
81  if ( ( retval =
83  test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
84 
85 #ifdef MPX
86  init_multiplex( );
87 #endif
88  if ( ( retval = PAPI_create_eventset( &eventset ) ) )
89  test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
90 
91 #ifdef MPX
92 
93  /* In Component PAPI, EventSets must be assigned a component index
94  before you can fiddle with their internals.
95  0 is always the cpu component */
96  retval = PAPI_assign_eventset_component( eventset, 0 );
97  if ( retval != PAPI_OK )
98  test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component",
99  retval );
100 
101  if ( ( retval = PAPI_set_multiplex( eventset ) ) ) {
102  if ( retval == PAPI_ENOSUPP) {
103  test_skip(__FILE__, __LINE__, "Multiplex not supported", 1);
104  }
105 
106  test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval );
107  }
108 #endif
109 
110  /* What does this code even do */
111  nevents = MAXEVENTS;
112  for ( i = 0; i < nevents; i++ ) {
113  if ( ( retval = PAPI_add_event( eventset, events[i] ) ) ) {
114  for ( j = i; j < MAXEVENTS-1; j++ )
115  events[j] = events[j + 1];
116  nevents--;
117  i--;
118  }
119  }
120  if ( nevents < 3 )
121  test_skip( __FILE__, __LINE__, "Not enough events left...", 0 );
122 
123  /* Find a reasonable number of iterations (each
124  * event active 20 times) during the measurement
125  */
126  t2 = 10000 * 20 * nevents; /* Target: 10000 usec/multiplex, 20 repeats */
127  if ( t2 > 30e6 )
128  test_skip( __FILE__, __LINE__, "This test takes too much time",
129  retval );
130 
131  /* Measure one run */
132  t1 = PAPI_get_real_usec( );
133  y = dummy3( x, iters );
134  t1 = PAPI_get_real_usec( ) - t1;
135 
136  if ( t2 > t1 ) /* Scale up execution time to match t2 */
137  iters = iters * ( int ) ( t2 / t1 );
138  else if ( t1 > 30e6 ) /* Make sure execution time is < 30s per repeated test */
139  test_skip( __FILE__, __LINE__, "This test takes too much time",
140  retval );
141 
142  j = nevents;
143  for ( i = 1; i < nevents; i = i + 2 )
144  eventidx[--j] = i;
145  for ( i = 0; i < nevents; i = i + 2 )
146  eventidx[--j] = i;
147  assert( j == 0 );
148  for ( i = 0; i < nevents; i++ )
149  eventmap[i] = i;
150 
151  x = 1.0;
152 
153  if ( !TESTS_QUIET )
154  printf( "\nReference run:\n" );
155 
156  t1 = PAPI_get_real_usec( );
157  if ( ( retval = PAPI_start( eventset ) ) )
158  test_fail( __FILE__, __LINE__, "PAPI_start", retval );
159  y = dummy3( x, iters );
160  PAPI_read( eventset, refvals );
161  t2 = PAPI_get_real_usec( );
162 
163  ntrue = nevents;
164  PAPI_list_events( eventset, truelist, &ntrue );
165  if ( !TESTS_QUIET ) {
166  printf( "\tOperations= %.1f Mflop", y * 1e-6 );
167  printf( "\t(%g Mflop/s)\n\n", ( y / ( double ) ( t2 - t1 ) ) );
168  printf( "%20s %16s %-15s %-15s\n", "PAPI measurement:",
169  "Acquired count", "Expected event", "PAPI_list_events" );
170  }
171 
172  if ( !TESTS_QUIET ) {
173  for ( j = 0; j < nevents; j++ ) {
174  PAPI_get_event_info( events[j], &info );
175  PAPI_event_code_to_name( truelist[j], name2 );
176  if ( !TESTS_QUIET )
177  printf( "%20s = %16lld %-15s %-15s %s\n", info.short_descr,
178  refvals[j], info.symbol, name2, strcmp( info.symbol,
179  name2 ) ?
180  "*** MISMATCH ***" : "" );
181  }
182  printf( "\n" );
183  }
184 
185  nev1 = nevents;
186  repeats = nevents * 4;
187  for ( i = 0; i < repeats; i++ ) {
188  if ( ( i % nevents ) + 1 == nevents )
189  continue;
190 
191  if ( !TESTS_QUIET )
192  printf( "\nTest %d (of %d):\n", i + 1 - i / nevents, repeats - 4 );
193 
194  if ( ( retval = PAPI_stop( eventset, values ) ) )
195  test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
196 
197  j = eventidx[i % nevents];
198 
199  if ( ( i / nevents ) % 2 == 0 ) {
200  PAPI_get_event_info( events[j], &info );
201  if ( !TESTS_QUIET )
202  printf( "Removing event[%d]: %s\n", j, info.short_descr );
203  if ( ( retval = PAPI_remove_event( eventset, events[j] ) ) )
204  test_fail( __FILE__, __LINE__, "PAPI_remove_event", retval );
205  nev1--;
206  for ( idx = 0; eventmap[idx] != j; idx++ );
207  for ( j = idx; j < nev1; j++ )
208  eventmap[j] = eventmap[j + 1];
209  } else {
210  PAPI_get_event_info( events[j], &info );
211  if ( !TESTS_QUIET )
212  printf( "Adding event[%d]: %s\n", j, info.short_descr );
213  if ( ( retval = PAPI_add_event( eventset, events[j] ) ) )
214  test_fail( __FILE__, __LINE__, "PAPI_add_event", retval );
215  eventmap[nev1] = j;
216  nev1++;
217  }
218  if ( ( retval = PAPI_start( eventset ) ) )
219  test_fail( __FILE__, __LINE__, "PAPI_start", retval );
220 
221  x = 1.0;
222 #ifndef STARTSTOP
223  if ( ( retval = PAPI_reset( eventset ) ) )
224  test_fail( __FILE__, __LINE__, "PAPI_reset", retval );
225 #else
226  if ( ( retval = PAPI_stop( eventset, dummies ) ) )
227  test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
228  if ( ( retval = PAPI_start( eventset ) ) )
229  test_fail( __FILE__, __LINE__, "PAPI_start", retval );
230 #endif
231 
232  t1 = PAPI_get_real_usec( );
233  y = dummy3( x, iters );
234  PAPI_read( eventset, values );
235  t2 = PAPI_get_real_usec( );
236 
237  if ( !TESTS_QUIET ) {
238  printf( "\n(calculated independent of PAPI)\n" );
239  printf( "\tOperations= %.1f Mflop", y * 1e-6 );
240  printf( "\t(%g Mflop/s)\n\n", ( y / ( double ) ( t2 - t1 ) ) );
241  printf( "%20s %16s %-15s %-15s\n", "PAPI measurement:",
242  "Acquired count", "Expected event", "PAPI_list_events" );
243  }
244 
245  ntrue = nev1;
246  PAPI_list_events( eventset, truelist, &ntrue );
247  for ( j = 0; j < nev1; j++ ) {
248  idx = eventmap[j];
249  /* printf("Mapping: Counter %d -> slot %d.\n",j,idx); */
250  PAPI_get_event_info( events[idx], &info );
251  PAPI_event_code_to_name( truelist[j], name2 );
252  if ( !TESTS_QUIET )
253  printf( "%20s = %16lld %-15s %-15s %s\n", info.short_descr,
254  values[j], info.symbol, name2, strcmp( info.symbol,
255  name2 ) ?
256  "*** MISMATCH ***" : "" );
257  dtmp = ( double ) values[j];
258  valsum[idx] += dtmp;
259  valsample[idx][nsamples[idx]] = dtmp;
260  nsamples[idx]++;
261  }
262  if ( !TESTS_QUIET )
263  printf( "\n" );
264  }
265 
266  if ( ( retval = PAPI_stop( eventset, values ) ) )
267  test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
268 
269  if ( !TESTS_QUIET ) {
270  printf( "\n\nEstimated variance relative to average counts:\n" );
271  for ( j = 0; j < nev1; j++ )
272  printf( " Event %.2d", j );
273  printf( "\n" );
274  }
275 
276  fails = nevents;
277  /* Due to limited precision of floating point cannot really use
278  typical standard deviation compuation for large numbers with
279  very small variations. Instead compute the std devation
280  problems with precision.
281  */
282  for ( j = 0; j < nev1; j++ ) {
283  avg[j] = valsum[j] / nsamples[j];
284  spread[j] = 0;
285  for ( i = 0; i < nsamples[j]; ++i ) {
286  double diff = ( valsample[j][i] - avg[j] );
287  spread[j] += diff * diff;
288  }
289  spread[j] = sqrt( spread[j] / nsamples[j] ) / avg[j];
290  if ( !TESTS_QUIET )
291  printf( "%9.2g ", spread[j] );
292  /* Make sure that NaN get counted as errors */
293  if ( spread[j] < MPX_TOLERANCE )
294  fails--;
295  else if ( values[j] < MINCOUNTS ) /* Neglect inprecise results with low counts */
296  fails--;
297  }
298  if ( !TESTS_QUIET ) {
299  printf( "\n\n" );
300  for ( j = 0; j < nev1; j++ ) {
301  PAPI_get_event_info( events[j], &info );
302  printf( "Event %.2d: mean=%10.0f, sdev/mean=%7.2g nrpt=%2d -- %s\n",
303  j, avg[j], spread[j], nsamples[j], info.short_descr );
304  }
305  printf( "\n\n" );
306  }
307 
308  if ( fails )
309  test_fail( __FILE__, __LINE__, "Values differ from reference", fails );
310  else
311  test_pass( __FILE__, NULL, 0 );
312 
313  return 0;
314 }
315 
316 static double
317 dummy3( double x, int iters )
318 {
319  int i;
320  double w, y, z, a, b, c, d, e, f, g, h;
321  double one;
322  one = 1.0;
323  w = x;
324  y = x;
325  z = x;
326  a = x;
327  b = x;
328  c = x;
329  d = x;
330  e = x;
331  f = x;
332  g = x;
333  h = x;
334  for ( i = 1; i <= iters; i++ ) {
335  w = w * 1.000000000001 + one;
336  y = y * 1.000000000002 + one;
337  z = z * 1.000000000003 + one;
338  a = a * 1.000000000004 + one;
339  b = b * 1.000000000005 + one;
340  c = c * 0.999999999999 + one;
341  d = d * 0.999999999998 + one;
342  e = e * 0.999999999997 + one;
343  f = f * 0.999999999996 + one;
344  g = h * 0.999999999995 + one;
345  h = h * 1.000000000006 + one;
346  }
347  return 2.0 * ( a + b + c + d + e + f + w + x + y + z + g + h );
348 }
#define PAPI_INT_INS
Definition: fpapi.h:186
int atoi()
int PAPI_stop(int EventSet, long long *values)
Definition: papi.c:2232
#define NUM_FLOPS
#define PAPI_LD_INS
Definition: fpapi.h:188
double f(double a)
Definition: cpi.c:23
int PAPI_add_event(int EventSet, int EventCode)
Definition: papi.c:1604
int PAPI_reset(int EventSet)
Definition: papi.c:2377
#define PAPI_NULL
Definition: fpapi.h:13
#define REPEATS
Definition: sdsc4.c:18
#define PAPI_MAX_STR_LEN
Definition: fpapi.h:43
int PAPI_remove_event(int EventSet, int EventCode)
Definition: papi.c:1699
void test_skip(char *file, int line, char *call, int retval)
Definition: test_utils.c:614
#define PAPI_TOT_INS
Definition: fpapi.h:185
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:961
return PAPI_OK
Definition: linux-nvml.c:458
volatile double t2
tests_quiet(argc, argv)
#define printf
Definition: papi_test.h:125
volatile double t1
double c
Definition: multiplex.c:22
void init_multiplex(void)
Definition: test_utils.c:888
static double
Definition: fileop.c:1281
test_pass(__FILE__, NULL, 0)
int int argc
Definition: iozone.c:1609
static double a[MATRIX_SIZE][MATRIX_SIZE]
Definition: rapl_basic.c:37
int PAPI_get_event_info(int EventCode, PAPI_event_info_t *info)
Definition: papi.c:844
#define PAPI_BR_INS
Definition: fpapi.h:190
int TESTS_QUIET
Definition: test_utils.c:11
char ** argv
Definition: iozone.c:1610
test_fail(__FILE__, __LINE__,"PAPI_library_init", retval)
int PAPI_library_init(int version)
Definition: papi.c:495
long long y
Definition: iozone.c:1335
int i
Definition: fileop.c:140
#define PAPI_ENOSUPP
Definition: fpapi.h:123
#define PAPI_TOT_CYC
Definition: fpapi.h:194
#define PAPI_SR_INS
Definition: fpapi.h:189
int one
char short_descr[PAPI_MIN_STR_LEN]
Definition: papi.h:962
#define PAPI_VER_CURRENT
Definition: fpapi.h:14
char events[MAX_EVENTS][BUFSIZ]
#define PAPI_FP_INS
Definition: fpapi.h:187
int PAPI_assign_eventset_component(int EventSet, int cidx)
Definition: papi.c:1467
int PAPI_create_eventset(int *EventSet)
Definition: papi.c:1406
int PAPI_event_code_to_name(int EventCode, char *out)
Definition: papi.c:924
static double dummy3(double x, int iters)
Definition: sdsc4.c:317
#define MINCOUNTS
Definition: sdsc4.c:20
static double b[MATRIX_SIZE][MATRIX_SIZE]
Definition: rapl_basic.c:38
#define PAPI_TOT_IIS
Definition: fpapi.h:184
#define MPX_TOLERANCE
Definition: test_utils.h:15
long long PAPI_get_real_usec(void)
Definition: papi.c:6138
int
Definition: iozone.c:18528
int x
Definition: fileop.c:78
#define PAPI_STL_CCY
Definition: fpapi.h:174
int PAPI_set_multiplex(int EventSet)
Definition: papi.c:3241
int PAPI_read(int EventSet, long long *values)
Definition: papi.c:2476
int PAPI_start(int EventSet)
Definition: papi.c:2026
long j
Definition: iozone.c:19135
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
#define MAXEVENTS
Definition: sdsc4.c:17
ssize_t retval
Definition: libasync.c:338
#define SLEEPTIME
Definition: sdsc4.c:19
int main(int argc, char **argv)
List all appio events codes and names.
int PAPI_list_events(int EventSet, int *Events, int *number)
Definition: papi.c:5876