|
PAPI
5.3.0.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 = 1; i < argc; i++ ) { 00186 if ( !strcmp( argv[i], "-b" ) ) { 00187 i++; 00188 if ( i >= argc || (bins = atoi( argv[i] ) > 0 ) ) { 00189 printf( "-b requires a positive bin count!\n" ); 00190 exit( 1 ); 00191 } 00192 } 00193 else if ( !strcmp( argv[i], "-d" ) ) 00194 show_dist = 1; 00195 else if ( !strcmp( argv[i], "-h" ) ) { 00196 print_help( ); 00197 exit( 1 ); 00198 } 00199 else if ( !strcmp( argv[i], "-s" ) ) 00200 show_std_dev = 1; 00201 else if ( !strcmp( argv[i], "-t" ) ) { 00202 i++; 00203 if ( i >= argc || (num_iters = ( int ) atol( argv[i] ) > 0) ) { 00204 printf( "-t requires a positive threshold value!\n" ); 00205 exit( 1 ); 00206 } 00207 } 00208 else { 00209 /* If not a valid option, print out some help information */ 00210 print_help( ); 00211 exit( 1 ); 00212 } 00213 } 00214 00215 printf( "Cost of execution for PAPI start/stop, read and accum.\n" ); 00216 printf( "This test takes a while. Please be patient...\n" ); 00217 00218 if ( ( retval = 00219 PAPI_library_init( PAPI_VER_CURRENT ) ) != PAPI_VER_CURRENT ) 00220 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval ); 00221 if ( ( retval = PAPI_set_debug( PAPI_VERB_ECONT ) ) != PAPI_OK ) 00222 test_fail( __FILE__, __LINE__, "PAPI_set_debug", retval ); 00223 if ( ( retval = PAPI_query_event( PAPI_TOT_CYC ) ) != PAPI_OK ) 00224 test_fail( __FILE__, __LINE__, "PAPI_query_event", retval ); 00225 if ( ( retval = PAPI_query_event( PAPI_TOT_INS ) ) != PAPI_OK ) 00226 test_fail( __FILE__, __LINE__, "PAPI_query_event", retval ); 00227 if ( ( retval = PAPI_create_eventset( &EventSet ) ) != PAPI_OK ) 00228 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00229 00230 if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_CYC ) ) != PAPI_OK ) 00231 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval ); 00232 00233 if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_INS ) ) != PAPI_OK ) 00234 if ( ( retval = PAPI_add_event( EventSet, PAPI_TOT_IIS ) ) != PAPI_OK ) 00235 test_fail( __FILE__, __LINE__, "PAPI_add_event", retval ); 00236 00237 /* Make sure no errors and warm up */ 00238 00239 totcyc = PAPI_get_real_cyc( ); 00240 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00241 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00242 if ( ( retval = PAPI_stop( EventSet, NULL ) ) != PAPI_OK ) 00243 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00244 00245 array = 00246 ( long long * ) malloc( ( size_t ) num_iters * sizeof ( long long ) ); 00247 if ( array == NULL ) 00248 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00249 00250 /* Determine clock latency */ 00251 00252 printf( "\nPerforming loop latency test...\n" ); 00253 00254 for ( i = 0; i < num_iters; i++ ) { 00255 totcyc = PAPI_get_real_cyc( ); 00256 totcyc = PAPI_get_real_cyc( ) - totcyc; 00257 array[i] = totcyc; 00258 } 00259 00260 do_output( 0, array, bins, show_std_dev, show_dist ); 00261 00262 /* Start the start/stop eval */ 00263 00264 printf( "\nPerforming start/stop test...\n" ); 00265 00266 for ( i = 0; i < num_iters; i++ ) { 00267 totcyc = PAPI_get_real_cyc( ); 00268 retval_start=PAPI_start( EventSet ); 00269 retval_stop=PAPI_stop( EventSet, values ); 00270 totcyc = PAPI_get_real_cyc( ) - totcyc; 00271 array[i] = totcyc; 00272 if (retval_start || retval_stop) { 00273 test_fail( __FILE__, __LINE__, "PAPI start/stop", retval_start ); 00274 } 00275 } 00276 00277 do_output( 1, array, bins, show_std_dev, show_dist ); 00278 00279 /* Start the read eval */ 00280 printf( "\nPerforming read test...\n" ); 00281 00282 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00283 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00284 PAPI_read( EventSet, values ); 00285 00286 for ( i = 0; i < num_iters; i++ ) { 00287 totcyc = PAPI_get_real_cyc( ); 00288 PAPI_read( EventSet, values ); 00289 totcyc = PAPI_get_real_cyc( ) - totcyc; 00290 array[i] = totcyc; 00291 } 00292 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00293 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00294 00295 do_output( 2, array, bins, show_std_dev, show_dist ); 00296 00297 /* Start the read with timestamp eval */ 00298 printf( "\nPerforming read with timestamp test...\n" ); 00299 00300 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00301 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00302 PAPI_read_ts( EventSet, values, &totcyc ); 00303 00304 for ( i = 0; i < num_iters; i++ ) { 00305 PAPI_read_ts( EventSet, values, &array[i] ); 00306 } 00307 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00308 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00309 00310 /* post-process the timing array */ 00311 for ( i = num_iters - 1; i > 0; i-- ) { 00312 array[i] -= array[i - 1]; 00313 } 00314 array[0] -= totcyc; 00315 00316 do_output( 3, array, bins, show_std_dev, show_dist ); 00317 00318 /* Start the accum eval */ 00319 printf( "\nPerforming accum test...\n" ); 00320 00321 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00322 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00323 PAPI_accum( EventSet, values ); 00324 00325 for ( i = 0; i < num_iters; i++ ) { 00326 totcyc = PAPI_get_real_cyc( ); 00327 PAPI_accum( EventSet, values ); 00328 totcyc = PAPI_get_real_cyc( ) - totcyc; 00329 array[i] = totcyc; 00330 } 00331 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00332 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00333 00334 do_output( 4, array, bins, show_std_dev, show_dist ); 00335 00336 /* Start the reset eval */ 00337 printf( "\nPerforming reset test...\n" ); 00338 00339 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00340 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00341 00342 for ( i = 0; i < num_iters; i++ ) { 00343 totcyc = PAPI_get_real_cyc( ); 00344 PAPI_reset( EventSet ); 00345 totcyc = PAPI_get_real_cyc( ) - totcyc; 00346 array[i] = totcyc; 00347 } 00348 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00349 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00350 00351 do_output( 5, array, bins, show_std_dev, show_dist ); 00352 00353 /* Derived event test */ 00354 PAPI_cleanup_eventset( EventSet ); 00355 00356 event = 0 | PAPI_PRESET_MASK; 00357 00358 if ( ( event = find_derived_postfix( event ) ) != PAPI_NULL ) { 00359 if ( (retval = PAPI_add_event( EventSet, event) ) != PAPI_OK ) 00360 test_fail(__FILE__, __LINE__, "PAPI_add_event", retval); 00361 00362 PAPI_get_event_info(event, &info); 00363 printf( "\nPerforming DERIVED_POSTFIX PAPI_read(%d counters) test...", info.count ); 00364 00365 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00366 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00367 PAPI_read( EventSet, values ); 00368 00369 for ( i = 0; i < num_iters; i++ ) { 00370 totcyc = PAPI_get_real_cyc( ); 00371 PAPI_read( EventSet, values ); 00372 totcyc = PAPI_get_real_cyc( ) - totcyc; 00373 array[i] = totcyc; 00374 } 00375 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00376 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00377 00378 do_output( 6, array, bins, show_std_dev, show_dist ); 00379 00380 } else { 00381 printf("\tI was unable to find a DERIVED_POSTFIX preset event to " 00382 "test on this architecture, skipping.\n"); 00383 } 00384 00385 if ( ( event = find_derived_add( event ) ) != PAPI_NULL ) { 00386 if ( (retval = PAPI_add_event( EventSet, event) ) != PAPI_OK ) 00387 test_fail(__FILE__, __LINE__, "PAPI_add_event", retval); 00388 00389 PAPI_get_event_info(event, &info); 00390 printf( "\nPerforming DERIVED_[ADD|SUB] PAPI_read(%d counters) test...", info.count ); 00391 00392 if ( ( retval = PAPI_start( EventSet ) ) != PAPI_OK ) 00393 test_fail( __FILE__, __LINE__, "PAPI_start", retval ); 00394 PAPI_read( EventSet, values ); 00395 00396 for ( i = 0; i < num_iters; i++ ) { 00397 totcyc = PAPI_get_real_cyc( ); 00398 PAPI_read( EventSet, values ); 00399 totcyc = PAPI_get_real_cyc( ) - totcyc; 00400 array[i] = totcyc; 00401 } 00402 if ( ( retval = PAPI_stop( EventSet, values ) ) != PAPI_OK ) 00403 test_fail( __FILE__, __LINE__, "PAPI_stop", retval ); 00404 00405 do_output( 7, array, bins, show_std_dev, show_dist ); 00406 } else { 00407 printf("\tI was unable to find a suitable DERIVED_[ADD|SUB] event to test, skipping.\n"); 00408 } 00409 00410 free( array ); 00411 test_pass( __FILE__, NULL, 0 ); 00412 exit( 1 ); 00413 }