|
PAPI
5.0.1.0
|
00001 /* 00002 * $Id$ 00003 * 00004 * Test example for multiplex functionality, originally 00005 * provided by Timothy Kaiser, SDSC. It was modified to fit the 00006 * PAPI test suite by Nils Smeds, <smeds@pdc.kth.se>. 00007 * 00008 * This example verifies the accuracy of multiplexed events 00009 */ 00010 00011 #include "papi_test.h" 00012 #include <stdio.h> 00013 #include <math.h> 00014 00015 #define REPEATS 5 00016 #define MAXEVENTS 14 00017 #define SLEEPTIME 100 00018 #define MINCOUNTS 100000 00019 00020 static double dummy3( double x, int iters ); 00021 00022 void 00023 check_values( int eventset, int *events, int nevents, long long *values, 00024 long long *refvalues ) 00025 { 00026 double spread[MAXEVENTS]; 00027 int i = nevents, j = 0; 00028 00029 if ( !TESTS_QUIET ) { 00030 printf( "\nRelative accuracy:\n" ); 00031 for ( j = 0; j < nevents; j++ ) 00032 printf( " Event %.2d", j + 1 ); 00033 printf( "\n" ); 00034 } 00035 00036 for ( j = 0; j < nevents; j++ ) { 00037 spread[j] = abs( (int) ( refvalues[j] - values[j] ) ); 00038 if ( values[j] ) 00039 spread[j] /= ( double ) values[j]; 00040 if ( !TESTS_QUIET ) 00041 printf( "%10.3g ", spread[j] ); 00042 /* Make sure that NaN get counted as errors */ 00043 if ( spread[j] < MPX_TOLERANCE ) { 00044 i--; 00045 } 00046 else if ( refvalues[j] < MINCOUNTS ) { /* Neglect inprecise results with low counts */ 00047 i--; 00048 } 00049 else { 00050 char buff[BUFSIZ]; 00051 00052 printf("reference = %lld, value = %lld, diff = %lld\n", 00053 refvalues[j],values[j],refvalues[j] - values[j] ); 00054 sprintf(buff,"Error on %d, spread %lf > threshold %lf AND count %lld > minimum size threshold %d\n",j,spread[j],MPX_TOLERANCE, 00055 refvalues[j],MINCOUNTS); 00056 00057 test_fail( __FILE__, __LINE__, buff, 1 ); 00058 } 00059 } 00060 printf( "\n\n" ); 00061 #if 0 00062 if ( !TESTS_QUIET ) { 00063 for ( j = 0; j < nevents; j++ ) { 00064 PAPI_get_event_info( events[j], &info ); 00065 printf( "Event %.2d: ref=", j ); 00066 printf( LLDFMT10, refvalues[j] ); 00067 printf( ", diff/ref=%7.2g -- %s\n", spread[j], info.short_descr ); 00068 printf( "\n" ); 00069 } 00070 printf( "\n" ); 00071 } 00072 #else 00073 ( void ) eventset; 00074 ( void ) events; 00075 #endif 00076 00077 00078 } 00079 00080 void 00081 ref_measurements( int iters, int *eventset, int *events, int nevents, 00082 long long *refvalues ) 00083 { 00084 PAPI_event_info_t info; 00085 int i, retval; 00086 double x = 1.1, y; 00087 long long t1, t2; 00088 00089 printf( "PAPI reference measurements:\n" ); 00090 00091 if ( ( retval = PAPI_create_eventset( eventset ) ) ) 00092 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00093 00094 for ( i = 0; i < nevents; i++ ) { 00095 if ( ( retval = PAPI_add_event( *eventset, events[i] ) ) ) 00096 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval ); 00097 00098 x = 1.0; 00099 00100 t1 = PAPI_get_real_usec( ); 00101 if ( ( retval = PAPI_start( *eventset ) ) ) 00102 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00103 y = dummy3( x, iters ); 00104 if ( ( retval = PAPI_stop( *eventset, &refvalues[i] ) ) ) 00105 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00106 t2 = PAPI_get_real_usec( ); 00107 00108 if (!TESTS_QUIET) { 00109 printf( "\tOperations= %.1f Mflop", y * 1e-6 ); 00110 printf( "\t(%g Mflop/s)\n\n", ( ( float ) y / ( t2 - t1 ) ) ); 00111 } 00112 00113 PAPI_get_event_info( events[i], &info ); 00114 printf( "%20s = ", info.short_descr ); 00115 printf( LLDFMT, refvalues[i] ); 00116 printf( "\n" ); 00117 00118 if ( ( retval = PAPI_cleanup_eventset( *eventset ) ) ) 00119 test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval ); 00120 } 00121 if ( ( retval = PAPI_destroy_eventset( eventset ) ) ) 00122 test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval ); 00123 *eventset = PAPI_NULL; 00124 } 00125 00126 void 00127 decide_which_events( int *events, int *nevents ) 00128 { 00129 int i, j = 0; 00130 PAPI_event_info_t info; 00131 int newevents[MAXEVENTS]; 00132 00133 for ( i = 0; i < MAXEVENTS; i++ ) { 00134 if ( PAPI_get_event_info( events[i], &info ) == PAPI_OK ) { 00135 if ( info.count && ( strcmp( info.derived, "NOT_DERIVED" ) == 0 ) ) { 00136 printf( "Added %s\n", info.symbol ); 00137 newevents[j++] = events[i]; 00138 } 00139 } 00140 } 00141 00142 if ( j < 2 ) 00143 test_skip( __FILE__, __LINE__, "Not enough events to multiplex...", 0 ); 00144 *nevents = j; 00145 memcpy( events, newevents, sizeof ( newevents ) ); 00146 00147 printf( "Using %d events\n\n", *nevents ); 00148 } 00149 00150 int 00151 main( int argc, char **argv ) 00152 { 00153 PAPI_event_info_t info; 00154 int i, j, retval; 00155 int iters = NUM_FLOPS; 00156 double x = 1.1, y; 00157 long long t1, t2; 00158 long long values[MAXEVENTS], refvalues[MAXEVENTS]; 00159 int sleep_time = SLEEPTIME; 00160 int nevents = MAXEVENTS; 00161 int eventset = PAPI_NULL; 00162 int events[MAXEVENTS]; 00163 00164 events[0] = PAPI_FP_INS; 00165 events[1] = PAPI_TOT_INS; 00166 events[2] = PAPI_INT_INS; 00167 events[3] = PAPI_TOT_CYC; 00168 events[4] = PAPI_STL_CCY; 00169 events[5] = PAPI_BR_INS; 00170 events[6] = PAPI_SR_INS; 00171 events[7] = PAPI_LD_INS; 00172 events[8] = PAPI_TOT_IIS; 00173 events[9] = PAPI_FAD_INS; 00174 events[10] = PAPI_BR_TKN; 00175 events[11] = PAPI_BR_MSP; 00176 events[12] = PAPI_L1_ICA; 00177 events[13] = PAPI_L1_DCA; 00178 00179 for ( i = 0; i < MAXEVENTS; i++ ) { 00180 values[i] = 0; 00181 } 00182 00183 if ( argc > 1 ) { 00184 if ( !strcmp( argv[1], "TESTS_QUIET" ) ) 00185 tests_quiet( argc, argv ); 00186 else { 00187 sleep_time = atoi( argv[1] ); 00188 if ( sleep_time <= 0 ) 00189 sleep_time = SLEEPTIME; 00190 } 00191 } 00192 00193 if ( !TESTS_QUIET ) { 00194 printf( "\nAccuracy check of multiplexing routines.\n" ); 00195 printf 00196 ( "Comparing a multiplex measurement with separate measurements.\n\n" ); 00197 } 00198 00199 if ( ( retval = 00200 PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT ) 00201 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval ); 00202 00203 decide_which_events( events, &nevents ); 00204 00205 init_multiplex( ); 00206 00207 /* Find a reasonable number of iterations (each 00208 * event active 20 times) during the measurement 00209 */ 00210 t2 = 10000 * 20 * nevents; /* Target: 10000 usec/multiplex, 20 repeats */ 00211 if ( t2 > 30e6 ) 00212 test_skip( __FILE__, __LINE__, "This test takes too much time", 00213 retval ); 00214 00215 y = dummy3( x, iters ); 00216 /* Measure one run */ 00217 t1 = PAPI_get_real_usec( ); 00218 y = dummy3( x, iters ); 00219 t1 = PAPI_get_real_usec( ) - t1; 00220 00221 if ( t1 < 1000000 ) { /* Scale up execution time to match t2 */ 00222 iters = iters * ( int ) ( 1000000 / t1 ); 00223 printf( "Modified iteration count to %d\n\n", iters ); 00224 } 00225 00226 if (!TESTS_QUIET) fprintf(stdout,"y=%lf\n",y); 00227 00228 /* Now loop through the items one at a time */ 00229 00230 ref_measurements( iters, &eventset, events, nevents, refvalues ); 00231 00232 /* Now check multiplexed */ 00233 00234 if ( ( retval = PAPI_create_eventset( &eventset ) ) ) 00235 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00236 00237 00238 /* In Component PAPI, EventSets must be assigned a component index 00239 before you can fiddle with their internals. 00240 0 is always the cpu component */ 00241 retval = PAPI_assign_eventset_component( eventset, 0 ); 00242 if ( retval != PAPI_OK ) 00243 test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component", 00244 retval ); 00245 00246 if ( ( retval = PAPI_set_multiplex( eventset ) ) ) { 00247 if ( retval == PAPI_ENOSUPP) { 00248 test_skip(__FILE__, __LINE__, "Multiplex not supported", 1); 00249 } 00250 00251 test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval ); 00252 } 00253 00254 if ( ( retval = PAPI_add_events( eventset, events, nevents ) ) ) 00255 test_fail( __FILE__, __LINE__, "PAPI_add_events", retval ); 00256 00257 printf( "\nPAPI multiplexed measurements:\n" ); 00258 x = 1.0; 00259 t1 = PAPI_get_real_usec( ); 00260 if ( ( retval = PAPI_start( eventset ) ) ) 00261 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00262 y = dummy3( x, iters ); 00263 if ( ( retval = PAPI_stop( eventset, values ) ) ) 00264 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00265 t2 = PAPI_get_real_usec( ); 00266 00267 for ( j = 0; j < nevents; j++ ) { 00268 PAPI_get_event_info( events[j], &info ); 00269 if ( !TESTS_QUIET ) { 00270 printf( "%20s = ", info.short_descr ); 00271 printf( LLDFMT, values[j] ); 00272 printf( "\n" ); 00273 } 00274 } 00275 00276 check_values( eventset, events, nevents, values, refvalues ); 00277 00278 if ( ( retval = PAPI_remove_events( eventset, events, nevents ) ) ) 00279 test_fail( __FILE__, __LINE__, "PAPI_remove_events", retval ); 00280 if ( ( retval = PAPI_cleanup_eventset( eventset ) ) ) 00281 test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval ); 00282 if ( ( retval = PAPI_destroy_eventset( &eventset ) ) ) 00283 test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval ); 00284 eventset = PAPI_NULL; 00285 00286 /* Now loop through the items one at a time */ 00287 00288 ref_measurements( iters, &eventset, events, nevents, refvalues ); 00289 00290 check_values( eventset, events, nevents, values, refvalues ); 00291 00292 test_pass( __FILE__, NULL, 0 ); 00293 00294 return 0; 00295 } 00296 00297 static double 00298 dummy3( double x, int iters ) 00299 { 00300 int i; 00301 double w, y, z, a, b, c, d, e, f, g, h; 00302 double one; 00303 one = 1.0; 00304 w = x; 00305 y = x; 00306 z = x; 00307 a = x; 00308 b = x; 00309 c = x; 00310 d = x; 00311 e = x; 00312 f = x; 00313 g = x; 00314 h = x; 00315 for ( i = 1; i <= iters; i++ ) { 00316 w = w * 1.000000000001 + one; 00317 y = y * 1.000000000002 + one; 00318 z = z * 1.000000000003 + one; 00319 a = a * 1.000000000004 + one; 00320 b = b * 1.000000000005 + one; 00321 c = c * 0.999999999999 + one; 00322 d = d * 0.999999999998 + one; 00323 e = e * 0.999999999997 + one; 00324 f = f * 0.999999999996 + one; 00325 g = h * 0.999999999995 + one; 00326 h = h * 1.000000000006 + one; 00327 } 00328 return 2.0 * ( a + b + c + d + e + f + w + x + y + z + g + h ); 00329 }