PAPI  5.7.0.0
sdsc-mpx.c
Go to the documentation of this file.
1 /*
2  * Test example for multiplex functionality, originally
3  * provided by Timothy Kaiser, SDSC. It was modified to fit the
4  * PAPI test suite by Nils Smeds, <smeds@pdc.kth.se>.
5  *
6  * This example verifies the accuracy of multiplexed events
7  */
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <math.h>
13 
14 #include "papi.h"
15 #include "papi_test.h"
16 
17 #include "testcode.h"
18 
19 #define REPEATS 5
20 #define MAXEVENTS 14
21 #define SLEEPTIME 100
22 #define MINCOUNTS 100000
23 #define MPX_TOLERANCE 0.20
24 #define NUM_FLOPS 20000000
25 
26 void
27 check_values( int eventset, int *events, int nevents, long long *values,
28  long long *refvalues )
29 {
30  double spread[MAXEVENTS];
31  int i = nevents, j = 0;
32 
33  if ( !TESTS_QUIET ) {
34  printf( "\nRelative accuracy:\n" );
35  for ( j = 0; j < nevents; j++ )
36  printf( " Event %.2d", j + 1 );
37  printf( "\n" );
38  }
39 
40  for ( j = 0; j < nevents; j++ ) {
41  spread[j] = abs( (int) ( refvalues[j] - values[j] ) );
42  if ( values[j] )
43  spread[j] /= ( double ) values[j];
44  if ( !TESTS_QUIET )
45  printf( "%10.3g ", spread[j] );
46  /* Make sure that NaN get counted as errors */
47  if ( spread[j] < MPX_TOLERANCE ) {
48  i--;
49  }
50  else if ( refvalues[j] < MINCOUNTS ) { /* Neglect inprecise results with low counts */
51  i--;
52  }
53  else {
54  char buff[BUFSIZ];
55  if (!TESTS_QUIET) {
56  printf("reference = %lld, value = %lld, diff = %lld\n",
57  refvalues[j],values[j],refvalues[j] - values[j] );
58  }
59  sprintf(buff,"Error on %d, spread %lf > threshold %lf AND count %lld > minimum size threshold %d\n",j,spread[j],MPX_TOLERANCE,
60  refvalues[j],MINCOUNTS);
61 
62  test_fail( __FILE__, __LINE__, buff, 1 );
63  }
64  }
65  if (!TESTS_QUIET) printf( "\n\n" );
66 #if 0
67  if ( !TESTS_QUIET ) {
68  for ( j = 0; j < nevents; j++ ) {
69  PAPI_get_event_info( events[j], &info );
70  printf( "Event %.2d: ref=", j );
71  printf( LLDFMT10, refvalues[j] );
72  printf( ", diff/ref=%7.2g -- %s\n", spread[j], info.short_descr );
73  printf( "\n" );
74  }
75  printf( "\n" );
76  }
77 #else
78  ( void ) eventset;
79  ( void ) events;
80 #endif
81 
82 
83 }
84 
85 void
86 ref_measurements( int iters, int *eventset, int *events, int nevents,
87  long long *refvalues )
88 {
89  PAPI_event_info_t info;
90  int i, retval;
91  double x = 1.1, y;
92  long long t1, t2;
93 
94  if (!TESTS_QUIET) printf( "PAPI reference measurements:\n" );
95 
96  if ( ( retval = PAPI_create_eventset( eventset ) ) )
97  test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
98 
99  for ( i = 0; i < nevents; i++ ) {
100  if ( ( retval = PAPI_add_event( *eventset, events[i] ) ) )
101  test_fail( __FILE__, __LINE__, "PAPI_add_event", retval );
102 
103  x = 1.0;
104 
105  t1 = PAPI_get_real_usec( );
106  if ( ( retval = PAPI_start( *eventset ) ) )
107  test_fail( __FILE__, __LINE__, "PAPI_start", retval );
108  y = do_flops3( x, iters, 1 );
109  if ( ( retval = PAPI_stop( *eventset, &refvalues[i] ) ) )
110  test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
111  t2 = PAPI_get_real_usec( );
112 
113  if (!TESTS_QUIET) {
114  printf( "\tOperations= %.1f Mflop", y * 1e-6 );
115  printf( "\t(%g Mflop/s)\n\n", ( ( float ) y / ( t2 - t1 ) ) );
116  }
117 
118  PAPI_get_event_info( events[i], &info );
119  if (!TESTS_QUIET) {
120  printf( "%20s = ", info.short_descr );
121  printf( LLDFMT, refvalues[i] );
122  printf( "\n" );
123  }
124 
125  if ( ( retval = PAPI_cleanup_eventset( *eventset ) ) )
126  test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval );
127  }
128  if ( ( retval = PAPI_destroy_eventset( eventset ) ) )
129  test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval );
130  *eventset = PAPI_NULL;
131 }
132 
133 
134 
135 int
136 main( int argc, char **argv )
137 {
138  PAPI_event_info_t info;
139  int i, j, retval;
140  int iters = NUM_FLOPS;
141  double x = 1.1, y;
142  long long t1, t2;
143  long long values[MAXEVENTS], refvalues[MAXEVENTS];
144  int sleep_time = SLEEPTIME;
145  int nevents = MAXEVENTS;
146  int eventset = PAPI_NULL;
147  int events[MAXEVENTS];
148  int quiet;
149 
150  quiet = tests_quiet( argc, argv );
151 
152  if ( argc > 1 ) {
153  if ( !strcmp( argv[1], "TESTS_QUIET" ) ) {
154  }
155  else {
156  sleep_time = atoi( argv[1] );
157  if ( sleep_time <= 0 )
158  sleep_time = SLEEPTIME;
159  }
160  }
161 
162  events[0] = PAPI_FP_INS;
163  events[1] = PAPI_TOT_INS;
164  events[2] = PAPI_INT_INS;
165  events[3] = PAPI_TOT_CYC;
166  events[4] = PAPI_STL_CCY;
167  events[5] = PAPI_BR_INS;
168  events[6] = PAPI_SR_INS;
169  events[7] = PAPI_LD_INS;
170  events[8] = PAPI_TOT_IIS;
171  events[9] = PAPI_FAD_INS;
172  events[10] = PAPI_BR_TKN;
173  events[11] = PAPI_BR_MSP;
174  events[12] = PAPI_L1_ICA;
175  events[13] = PAPI_L1_DCA;
176 
177  for ( i = 0; i < MAXEVENTS; i++ ) {
178  values[i] = 0;
179  }
180 
181 
182  if ( !quiet ) {
183  printf( "\nAccuracy check of multiplexing routines.\n" );
184  printf( "Comparing a multiplex measurement with separate measurements.\n\n" );
185  }
186 
187  /* Initialize PAPI */
189  if (retval != PAPI_VER_CURRENT ) {
190  test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
191  }
192 
193  /* Iterate through event list and remove those that aren't suitable */
194  nevents = MAXEVENTS;
195  for ( i = 0; i < nevents; i++ ) {
196  if (( PAPI_get_event_info( events[i], &info ) == PAPI_OK ) &&
197  (info.count && (strcmp( info.derived, "NOT_DERIVED")==0))) {
198  if (!quiet) printf( "Added %s\n", info.symbol );
199  }
200  else {
201  for ( j = i; j < MAXEVENTS-1; j++ ) {
202  events[j] = events[j + 1];
203  }
204  nevents--;
205  i--;
206  }
207  }
208 
209  /* Skip test if not enough events available */
210  if ( nevents < 2 ) {
211  test_skip( __FILE__, __LINE__, "Not enough events to multiplex...", 0 );
212  }
213 
214  if (!quiet) printf( "Using %d events\n\n", nevents );
215 
217  if ( retval != PAPI_OK ) {
218  test_fail( __FILE__, __LINE__,
219  "PAPI multiplex init fail\n", retval );
220  }
221 
222  /* Find a reasonable number of iterations (each
223  * event active 20 times) during the measurement
224  */
225  /* Target: 10000 usec/multiplex, 20 repeats */
226  t2 = 10000 * 20 * nevents;
227  if ( t2 > 30e6 ) {
228  test_skip( __FILE__, __LINE__, "This test takes too much time",
229  retval );
230  }
231 
232  /* Warmup? */
233  y = do_flops3( x, iters, 1 );
234 
235  /* Measure time of one run */
236  t1 = PAPI_get_real_usec( );
237  y = do_flops3( x, iters, 1 );
238  t1 = PAPI_get_real_usec( ) - t1;
239 
240  if (t1==0) {
241  test_fail(__FILE__, __LINE__,
242  "do_flops3 takes no time to run!\n", retval);
243  }
244 
245  /* Scale up execution time to match t2 */
246  if ( t2 > t1 ) {
247  iters = iters * ( int ) ( t2 / t1 );
248  if (!quiet) {
249  printf( "Modified iteration count to %d\n\n", iters );
250  }
251  }
252 
253  if (!quiet) fprintf(stdout,"y=%lf\n",y);
254 
255  /* Now loop through the items one at a time */
256 
257  ref_measurements( iters, &eventset, events, nevents, refvalues );
258 
259  /* Now check multiplexed */
260 
261  if ( ( retval = PAPI_create_eventset( &eventset ) ) )
262  test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
263 
264 
265  /* In Component PAPI, EventSets must be assigned a component index
266  before you can fiddle with their internals.
267  0 is always the cpu component */
268  retval = PAPI_assign_eventset_component( eventset, 0 );
269  if ( retval != PAPI_OK )
270  test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component",
271  retval );
272 
273  if ( ( retval = PAPI_set_multiplex( eventset ) ) ) {
274  if ( retval == PAPI_ENOSUPP) {
275  test_skip(__FILE__, __LINE__, "Multiplex not supported", 1);
276  }
277 
278  test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval );
279  }
280 
281  if ( ( retval = PAPI_add_events( eventset, events, nevents ) ) )
282  test_fail( __FILE__, __LINE__, "PAPI_add_events", retval );
283 
284  if (!quiet) printf( "\nPAPI multiplexed measurements:\n" );
285  x = 1.0;
286  t1 = PAPI_get_real_usec( );
287  if ( ( retval = PAPI_start( eventset ) ) )
288  test_fail( __FILE__, __LINE__, "PAPI_start", retval );
289  y = do_flops3( x, iters, 1 );
290  if ( ( retval = PAPI_stop( eventset, values ) ) )
291  test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
292  t2 = PAPI_get_real_usec( );
293 
294  for ( j = 0; j < nevents; j++ ) {
295  PAPI_get_event_info( events[j], &info );
296  if ( !quiet ) {
297  printf( "%20s = ", info.short_descr );
298  printf( LLDFMT, values[j] );
299  printf( "\n" );
300  }
301  }
302 
303  check_values( eventset, events, nevents, values, refvalues );
304 
305  if ( ( retval = PAPI_remove_events( eventset, events, nevents ) ) )
306  test_fail( __FILE__, __LINE__, "PAPI_remove_events", retval );
307  if ( ( retval = PAPI_cleanup_eventset( eventset ) ) )
308  test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval );
309  if ( ( retval = PAPI_destroy_eventset( &eventset ) ) )
310  test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval );
311  eventset = PAPI_NULL;
312 
313  /* Now loop through the items one at a time */
314 
315  ref_measurements( iters, &eventset, events, nevents, refvalues );
316 
317  check_values( eventset, events, nevents, values, refvalues );
318 
319  test_pass( __FILE__ );
320 
321  return 0;
322 }
323 
324 
#define PAPI_OK
Definition: fpapi.h:105
int atoi()
unsigned int count
Definition: papi.h:988
int PAPI_stop(int EventSet, long long *values)
Definition: papi.c:2314
#define PAPI_INT_INS
Definition: fpapi.h:187
void test_pass(const char *filename)
Definition: test_utils.c:432
#define MINCOUNTS
Definition: sdsc-mpx.c:22
int PAPI_add_event(int EventSet, int EventCode)
Definition: papi.c:1663
#define PAPI_ENOSUPP
Definition: fpapi.h:123
double do_flops3(double x, int iters, int quiet)
#define PAPI_L1_ICA
Definition: fpapi.h:212
#define PAPI_L1_DCA
Definition: fpapi.h:200
#define MAXEVENTS
Definition: sdsc-mpx.c:20
#define PAPI_VER_CURRENT
Definition: fpapi.h:14
volatile double t2
int retval
Definition: zero_fork.c:53
#define PAPI_STL_CCY
Definition: fpapi.h:175
int PAPI_remove_events(int EventSet, int *Events, int number)
Definition: papi.c:5931
char derived[PAPI_MIN_STR_LEN]
Definition: papi.h:996
volatile double t1
#define SLEEPTIME
Definition: sdsc-mpx.c:21
#define NUM_FLOPS
Definition: sdsc-mpx.c:24
int PAPI_add_events(int EventSet, int *Events, int number)
Definition: papi.c:5843
Return codes and api definitions.
#define MPX_TOLERANCE
Definition: sdsc-mpx.c:23
int PAPI_get_event_info(int EventCode, PAPI_event_info_t *info)
Definition: papi.c:835
void test_skip(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:561
#define LLDFMT10
Definition: papi_test.h:95
char events[MAX_EVENTS][BUFSIZ]
void ref_measurements(int iters, int *eventset, int *events, int nevents, long long *refvalues)
Definition: sdsc-mpx.c:86
int PAPI_library_init(int version)
Definition: papi.c:500
#define PAPI_TOT_INS
Definition: fpapi.h:186
void check_values(int eventset, int *events, int nevents, long long *values, long long *refvalues)
Definition: sdsc-mpx.c:27
int quiet
Definition: rapl_overflow.c:18
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:967
#define PAPI_TOT_IIS
Definition: fpapi.h:185
int main(int argc, char **argv)
Definition: sdsc-mpx.c:136
#define PAPI_NULL
Definition: fpapi.h:13
#define PAPI_FAD_INS
Definition: fpapi.h:234
#define PAPI_BR_INS
Definition: fpapi.h:191
char short_descr[PAPI_MIN_STR_LEN]
Definition: papi.h:968
int PAPI_cleanup_eventset(int EventSet)
Definition: papi.c:2890
int PAPI_assign_eventset_component(int EventSet, int cidx)
Definition: papi.c:1526
int PAPI_create_eventset(int *EventSet)
Definition: papi.c:1464
#define LLDFMT
Definition: papi_test.h:94
int PAPI_multiplex_init(void)
Definition: papi.c:2982
long long PAPI_get_real_usec(void)
Definition: papi.c:6264
#define PAPI_BR_MSP
Definition: fpapi.h:182
int TESTS_QUIET
Definition: test_utils.c:18
int tests_quiet(int argc, char **argv)
Definition: test_utils.c:376
void test_fail(const char *file, int line, const char *call, int retval)
Definition: test_utils.c:468
int x
Definition: fileop.c:78
int PAPI_set_multiplex(int EventSet)
Definition: papi.c:3333
int PAPI_destroy_eventset(int *EventSet)
Definition: papi.c:2014
#define PAPI_BR_TKN
Definition: fpapi.h:180
int PAPI_start(int EventSet)
Definition: papi.c:2096
#define PAPI_TOT_CYC
Definition: fpapi.h:195
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
#define PAPI_LD_INS
Definition: fpapi.h:189
#define PAPI_SR_INS
Definition: fpapi.h:190
#define PAPI_FP_INS
Definition: fpapi.h:188
int i
Definition: fileop.c:140
long long y
Definition: iozone.c:1335