|
PAPI
5.0.1.0
|
00001 00033 #include "papi_test.h" 00034 #include "cost_utils.h" 00035 00036 int 00037 find_derived( int i , char *type) 00038 { 00039 PAPI_event_info_t info; 00040 00041 PAPI_enum_event( &i, PAPI_ENUM_FIRST ); 00042 00043 do { 00044 if ( PAPI_get_event_info( i, &info ) == PAPI_OK ) { 00045 if ( strcmp( info.derived, type) == 0 ) 00046 return i; 00047 } 00048 } while ( PAPI_enum_event( &i, PAPI_PRESET_ENUM_AVAIL ) == PAPI_OK ); 00049 00050 return PAPI_NULL; 00051 } 00052 00053 /* Slight misnomer, find derived event != DERIVED_POSTFIX */ 00054 int 00055 find_derived_add( int i ) 00056 { 00057 int ret; 00058 00059 if ( (ret = find_derived( i, "DERIVED_ADD")) != PAPI_NULL) 00060 return ret; 00061 00062 00063 return find_derived( i, "DERIVED_SUB"); 00064 } 00065 00066 int 00067 find_derived_postfix( int i ) 00068 { 00069 return ( find_derived ( i, "DERIVED_POSTFIX" ) ); 00070 } 00071 00072 static void 00073 print_help( void ) 00074 { 00075 printf( "This is the PAPI cost program.\n" ); 00076 printf 00077 ( "It computes min / max / mean / std. deviation for PAPI start/stop pairs; for PAPI reads, and for PAPI_accums. Usage:\n\n" ); 00078 printf( " cost [options] [parameters]\n" ); 00079 printf( " cost TESTS_QUIET\n\n" ); 00080 printf( "Options:\n\n" ); 00081 printf 00082 ( " -b BINS set the number of bins for the graphical distribution of costs. Default: 100\n" ); 00083 printf( " -d show a graphical distribution of costs\n" ); 00084 printf( " -h print this help message\n" ); 00085 printf 00086 ( " -s show number of iterations above the first 10 std deviations\n" ); 00087 printf 00088 ( " -t THRESHOLD set the threshold for the number of iterations. Default: 100,000\n" ); 00089 printf( "\n" ); 00090 } 00091 00092 00093 static void 00094 print_stats( int i, long long min, long long max, double average, double std ) 00095 { 00096 char *test[] = { "loop latency", "PAPI_start/stop (2 counters)", 00097 "PAPI_read (2 counters)", "PAPI_read_ts (2 counters)", 00098 "PAPI_accum (2 counters)", "PAPI_reset (2 counters)", 00099 "PAPI_read (1 derived_postfix counter)"," PAPI_read (1 derived_[add|sub] counter)" 00100 }; 00101 printf( "\nTotal cost for %s over %d iterations\n", test[i], num_iters ); 00102 printf 00103 ( "min cycles : %lld\nmax cycles : %lld\nmean cycles : %lf\nstd deviation: %lf\n ", 00104 min, max, average, std ); 00105 } 00106 00107 static void 00108 print_std_dev( int *s ) 00109 { 00110 int i; 00111 00112 printf( "\n" ); 00113 printf 00114 ( " --------# Standard Deviations Above the Mean--------\n" ); 00115 printf 00116 ( "0-------1-------2-------3-------4-------5-------6-------7-------8-------9-----10\n" ); 00117 for ( i = 0; i < 10; i++ ) 00118 printf( " %d\t", s[i] ); 00119 printf( "\n\n" ); 00120 } 00121 00122 static void 00123 print_dist( long long min, long long max, int bins, int *d ) 00124 { 00125 int i, j; 00126 int step = ( int ) ( max - min ) / bins; 00127 00128 printf( "\nCost distribution profile\n\n" ); 00129 for ( i = 0; i < bins; i++ ) { 00130 printf( "%8d:", ( int ) min + ( step * i ) ); 00131 if ( d[i] > 100 ) { 00132 printf 00133 ( "**************************** %d counts ****************************", 00134 d[i] ); 00135 } else { 00136 for ( j = 0; j < d[i]; j++ ) 00137 printf( "*" ); 00138 } 00139 printf( "\n" ); 00140 } 00141 } 00142 00143 static void 00144 do_output( int test_type, long long *array, int bins, int show_std_dev, 00145 int show_dist ) 00146 { 00147 int s[10]; 00148 long long min, max; 00149 double average, std; 00150 00151 std = do_stats( array, &min, &max, &average ); 00152 00153 print_stats( test_type, min, max, average, std ); 00154 00155 if ( show_std_dev ) { 00156 do_std_dev( array, s, std, average ); 00157 print_std_dev( s ); 00158 } 00159 00160 if ( show_dist ) { 00161 int *d; 00162 d = calloc( bins , sizeof ( int ) ); 00163 do_dist( array, min, max, bins, d ); 00164 print_dist( min, max, bins, d ); 00165 free( d ); 00166 } 00167 } 00168 00169 00170 int 00171 main( int argc, char **argv ) 00172 { 00173 int i, retval, EventSet = PAPI_NULL; 00174 int retval_start,retval_stop; 00175 int bins = 100; 00176 int show_dist = 0, show_std_dev = 0; 00177 long long totcyc, values[2]; 00178 long long *array; 00179 int event; 00180 PAPI_event_info_t info; 00181 00182 00183 tests_quiet( argc, argv ); /* Set TESTS_QUIET variable */ 00184 00185 for ( i = 0; i < argc; i++ ) { 00186 if ( argv[i] ) { 00187 if ( strstr( argv[i], "-b" ) ) { 00188 bins = atoi( argv[i + 1] ); 00189 if ( bins ) 00190 i++; 00191 else { 00192 printf( "-b requires a bin count!\n" ); 00193 exit( 1 ); 00194 } 00195 } 00196 if ( strstr( argv[i], "-d" ) ) 00197 show_dist = 1; 00198 if ( strstr( argv[i], "-h" ) ) { 00199 print_help( ); 00200 exit( 1 ); 00201 } 00202 if ( strstr( argv[i], "-s" ) ) 00203 show_std_dev = 1; 00204 if ( strstr( argv[i], "-t" ) ) { 00205 num_iters = ( int ) atol( argv[i + 1] ); 00206 if ( num_iters ) 00207 i++; 00208 else { 00209 printf( "-t requires a threshold value!\n" ); 00210 exit( 1 ); 00211 } 00212 } 00213 } 00214 } 00215 00216 printf( "Cost of execution for PAPI start/stop, read and accum.\n" ); 00217 printf( "This test takes a while. Please be patient...\n" ); 00218 00219 if ( ( retval = 00220 PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT ) 00221 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval ); 00222 if ( ( retval = PAPI_set_debug( PAPI_VERB_ECONT ) ) != PAPI_OK ) 00223 test_fail( __FILE__, __LINE__, "PAPI_set_debug", retval ); 00224 if ( ( retval = PAPI_query_event( PAPI_TOT_CYC ) ) != PAPI_OK ) 00225 test_fail( __FILE__, __LINE__, "PAPI_query_event", retval ); 00226 if ( ( retval = PAPI_query_event( PAPI_TOT_INS ) ) != PAPI_OK ) 00227 test_fail( __FILE__, __LINE__, "PAPI_query_event", retval ); 00228 if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK ) 00229 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00230 00231 if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_CYC ) ) != PAPI_OK ) 00232 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval ); 00233 00234 if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_INS ) ) != PAPI_OK ) 00235 if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_IIS ) ) != PAPI_OK ) 00236 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval ); 00237 00238 /* Make sure no errors and warm up */ 00239 00240 totcyc = PAPI_get_real_cyc( ); 00241 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00242 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00243 if ( ( retval = PAPI_stop( EventSet, NULL ) ) != PAPI_OK ) 00244 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00245 00246 array = 00247 ( long long * ) malloc( ( size_t ) num_iters * sizeof ( long long ) ); 00248 if ( array == NULL ) 00249 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00250 00251 /* Determine clock latency */ 00252 00253 printf( "\nPerforming loop latency test...\n" ); 00254 00255 for ( i = 0; i < num_iters; i++ ) { 00256 totcyc = PAPI_get_real_cyc( ); 00257 totcyc = PAPI_get_real_cyc( ) - totcyc; 00258 array[i] = totcyc; 00259 } 00260 00261 do_output( 0, array, bins, show_std_dev, show_dist ); 00262 00263 /* Start the start/stop eval */ 00264 00265 printf( "\nPerforming start/stop test...\n" ); 00266 00267 for ( i = 0; i < num_iters; i++ ) { 00268 totcyc = PAPI_get_real_cyc( ); 00269 retval_start=PAPI_start( EventSet ); 00270 retval_stop=PAPI_stop( EventSet, values ); 00271 totcyc = PAPI_get_real_cyc( ) - totcyc; 00272 array[i] = totcyc; 00273 if (retval_start || retval_stop) { 00274 test_fail( __FILE__, __LINE__, "PAPI start/stop", retval_start ); 00275 } 00276 } 00277 00278 do_output( 1, array, bins, show_std_dev, show_dist ); 00279 00280 /* Start the read eval */ 00281 printf( "\nPerforming read test...\n" ); 00282 00283 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00284 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00285 PAPI_read( EventSet, values ); 00286 00287 for ( i = 0; i < num_iters; i++ ) { 00288 totcyc = PAPI_get_real_cyc( ); 00289 PAPI_read( EventSet, values ); 00290 totcyc = PAPI_get_real_cyc( ) - totcyc; 00291 array[i] = totcyc; 00292 } 00293 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00294 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00295 00296 do_output( 2, array, bins, show_std_dev, show_dist ); 00297 00298 /* Start the read with timestamp eval */ 00299 printf( "\nPerforming read with timestamp test...\n" ); 00300 00301 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00302 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00303 PAPI_read_ts( EventSet, values, &totcyc ); 00304 00305 for ( i = 0; i < num_iters; i++ ) { 00306 PAPI_read_ts( EventSet, values, &array[i] ); 00307 } 00308 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00309 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00310 00311 /* post-process the timing array */ 00312 for ( i = num_iters - 1; i > 0; i-- ) { 00313 array[i] -= array[i - 1]; 00314 } 00315 array[0] -= totcyc; 00316 00317 do_output( 3, array, bins, show_std_dev, show_dist ); 00318 00319 /* Start the accum eval */ 00320 printf( "\nPerforming accum test...\n" ); 00321 00322 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00323 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00324 PAPI_accum( EventSet, values ); 00325 00326 for ( i = 0; i < num_iters; i++ ) { 00327 totcyc = PAPI_get_real_cyc( ); 00328 PAPI_accum( EventSet, values ); 00329 totcyc = PAPI_get_real_cyc( ) - totcyc; 00330 array[i] = totcyc; 00331 } 00332 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00333 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00334 00335 do_output( 4, array, bins, show_std_dev, show_dist ); 00336 00337 /* Start the reset eval */ 00338 printf( "\nPerforming reset test...\n" ); 00339 00340 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00341 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00342 00343 for ( i = 0; i < num_iters; i++ ) { 00344 totcyc = PAPI_get_real_cyc( ); 00345 PAPI_reset( EventSet ); 00346 totcyc = PAPI_get_real_cyc( ) - totcyc; 00347 array[i] = totcyc; 00348 } 00349 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00350 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00351 00352 do_output( 5, array, bins, show_std_dev, show_dist ); 00353 00354 /* Derived event test */ 00355 PAPI_cleanup_eventset( EventSet ); 00356 00357 event = 0 | PAPI_PRESET_MASK; 00358 00359 if ( ( event = find_derived_postfix( event ) ) != PAPI_NULL ) { 00360 if ( (retval = PAPI_add_event( EventSet, event) ) != PAPI_OK ) 00361 test_fail(__FILE__, __LINE__, "PAPI_add_event", retval); 00362 00363 PAPI_get_event_info(event, &info); 00364 printf( "\nPerforming DERIVED_POSTFIX PAPI_read(%d counters) test...", info.count ); 00365 00366 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00367 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00368 PAPI_read( EventSet, values ); 00369 00370 for ( i = 0; i < num_iters; i++ ) { 00371 totcyc = PAPI_get_real_cyc( ); 00372 PAPI_read( EventSet, values ); 00373 totcyc = PAPI_get_real_cyc( ) - totcyc; 00374 array[i] = totcyc; 00375 } 00376 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00377 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00378 00379 do_output( 6, array, bins, show_std_dev, show_dist ); 00380 00381 } else { 00382 printf("\tI was unable to find a DERIVED_POSTFIX preset event to " 00383 "test on this architecture, skipping.\n"); 00384 } 00385 00386 if ( ( event = find_derived_add( event ) ) != PAPI_NULL ) { 00387 if ( (retval = PAPI_add_event( EventSet, event) ) != PAPI_OK ) 00388 test_fail(__FILE__, __LINE__, "PAPI_add_event", retval); 00389 00390 PAPI_get_event_info(event, &info); 00391 printf( "\nPerforming DERIVED_[ADD|SUB] PAPI_read(%d counters) test...", info.count ); 00392 00393 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00394 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00395 PAPI_read( EventSet, values ); 00396 00397 for ( i = 0; i < num_iters; i++ ) { 00398 totcyc = PAPI_get_real_cyc( ); 00399 PAPI_read( EventSet, values ); 00400 totcyc = PAPI_get_real_cyc( ) - totcyc; 00401 array[i] = totcyc; 00402 } 00403 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00404 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00405 00406 do_output( 7, array, bins, show_std_dev, show_dist ); 00407 } else { 00408 printf("\tI was unable to find a suitable DERIVED_[ADD|SUB] event to test, skipping.\n"); 00409 } 00410 00411 free( array ); 00412 test_pass( __FILE__, NULL, 0 ); 00413 exit( 1 ); 00414 }