|
PAPI
5.0.1.0
|
00001 #include "papi_test.h" 00002 00003 #include <unistd.h> 00004 00005 /* Variable to hold reporting status 00006 if TRUE, output is suppressed 00007 if FALSE output is sent to stdout 00008 initialized to FALSE 00009 declared here so it can be available globally 00010 */ 00011 int TESTS_QUIET = 0; 00012 static int TESTS_COLOR = 0; 00013 static int TEST_WARN = 0; 00014 00015 /* Support routine to display header information to the screen 00016 from the hardware info data structure. The same code was duplicated 00017 in a number of tests and utilities. Seems to make sense to refactor. 00018 This may not be the best place for it to live, but it works for now. 00019 */ 00020 int 00021 papi_print_header( char *prompt, const PAPI_hw_info_t ** hwinfo ) 00022 { 00023 int cnt, mpx; 00024 00025 if ( ( *hwinfo = PAPI_get_hardware_info( ) ) == NULL ) { 00026 return PAPI_ESYS; 00027 } 00028 00029 printf( "%s", prompt ); 00030 printf 00031 ( "--------------------------------------------------------------------------------\n" ); 00032 printf( "PAPI Version : %d.%d.%d.%d\n", 00033 PAPI_VERSION_MAJOR( PAPI_VERSION ), 00034 PAPI_VERSION_MINOR( PAPI_VERSION ), 00035 PAPI_VERSION_REVISION( PAPI_VERSION ), 00036 PAPI_VERSION_INCREMENT( PAPI_VERSION ) ); 00037 printf( "Vendor string and code : %s (%d)\n", ( *hwinfo )->vendor_string, 00038 ( *hwinfo )->vendor ); 00039 printf( "Model string and code : %s (%d)\n", ( *hwinfo )->model_string, 00040 ( *hwinfo )->model ); 00041 printf( "CPU Revision : %f\n", ( *hwinfo )->revision ); 00042 if ( ( *hwinfo )->cpuid_family > 0 ) 00043 printf 00044 ( "CPUID Info : Family: %d Model: %d Stepping: %d\n", 00045 ( *hwinfo )->cpuid_family, ( *hwinfo )->cpuid_model, 00046 ( *hwinfo )->cpuid_stepping ); 00047 printf( "CPU Max Megahertz : %d\n", ( *hwinfo )->cpu_max_mhz ); 00048 printf( "CPU Min Megahertz : %d\n", ( *hwinfo )->cpu_min_mhz ); 00049 if ( ( *hwinfo )->threads > 0 ) 00050 printf( "Hdw Threads per core : %d\n", ( *hwinfo )->threads ); 00051 if ( ( *hwinfo )->cores > 0 ) 00052 printf( "Cores per Socket : %d\n", ( *hwinfo )->cores ); 00053 if ( ( *hwinfo )->sockets > 0 ) 00054 printf( "Sockets : %d\n", ( *hwinfo )->sockets ); 00055 if ( ( *hwinfo )->nnodes > 0 ) 00056 printf( "NUMA Nodes : %d\n", ( *hwinfo )->nnodes ); 00057 printf( "CPUs per Node : %d\n", ( *hwinfo )->ncpu ); 00058 printf( "Total CPUs : %d\n", ( *hwinfo )->totalcpus ); 00059 printf( "Running in a VM : %s\n", ( *hwinfo )->virtualized? 00060 "yes":"no"); 00061 if ( (*hwinfo)->virtualized) { 00062 printf( "VM Vendor: : %s\n", (*hwinfo)->virtual_vendor_string); 00063 } 00064 cnt = PAPI_get_opt( PAPI_MAX_HWCTRS, NULL ); 00065 mpx = PAPI_get_opt( PAPI_MAX_MPX_CTRS, NULL ); 00066 if ( cnt >= 0 ) { 00067 printf( "Number Hardware Counters : %d\n",cnt ); 00068 } else { 00069 printf( "Number Hardware Counters : PAPI error %d: %s\n", cnt, PAPI_strerror(cnt)); 00070 } 00071 if ( mpx >= 0 ) { 00072 printf( "Max Multiplex Counters : %d\n", mpx ); 00073 } else { 00074 printf( "Max Multiplex Counters : PAPI error %d: %s\n", mpx, PAPI_strerror(mpx)); 00075 } 00076 printf 00077 ( "--------------------------------------------------------------------------------\n" ); 00078 printf( "\n" ); 00079 return PAPI_OK; 00080 } 00081 00082 00083 void 00084 validate_string( char *name, char *s ) 00085 { 00086 if ( ( s == NULL ) || ( strlen( s ) == 0 ) ) { 00087 char s2[1024] = ""; 00088 sprintf( s2, "%s was NULL or length 0", name ); 00089 test_fail( __FILE__, __LINE__, s2, 0 ); 00090 } 00091 } 00092 00093 int 00094 approx_equals( double a, double b ) 00095 { 00096 if ( ( a >= b * ( 1.0 - TOLERANCE ) ) && ( a <= b * ( 1.0 + TOLERANCE ) ) ) 00097 return 1; 00098 else { 00099 printf( "Out of tolerance range %2.2f: %.0f vs %.0f [%.0f,%.0f]\n", 00100 TOLERANCE, a, b, b * ( 1.0 - TOLERANCE ), 00101 b * ( 1.0 + TOLERANCE ) ); 00102 return 0; 00103 } 00104 } 00105 00106 long long ** 00107 allocate_test_space( int num_tests, int num_events ) 00108 { 00109 long long **values; 00110 int i; 00111 00112 values = 00113 ( long long ** ) malloc( ( size_t ) num_tests * 00114 sizeof ( long long * ) ); 00115 if ( values == NULL ) 00116 exit( 1 ); 00117 memset( values, 0x0, ( size_t ) num_tests * sizeof ( long long * ) ); 00118 00119 for ( i = 0; i < num_tests; i++ ) { 00120 values[i] = 00121 ( long long * ) malloc( ( size_t ) num_events * 00122 sizeof ( long long ) ); 00123 if ( values[i] == NULL ) 00124 exit( 1 ); 00125 memset( values[i], 0x00, ( size_t ) num_events * sizeof ( long long ) ); 00126 } 00127 return ( values ); 00128 } 00129 00130 void 00131 free_test_space( long long **values, int num_tests ) 00132 { 00133 int i; 00134 00135 for ( i = 0; i < num_tests; i++ ) 00136 free( values[i] ); 00137 free( values ); 00138 } 00139 00140 00141 00142 int is_event_derived(unsigned int event) { 00143 00144 PAPI_event_info_t info; 00145 00146 if (event & PAPI_PRESET_MASK) { 00147 00148 PAPI_get_event_info(event,&info); 00149 00150 if (strcmp(info.derived,"NOT_DERIVED")) { 00151 // printf("%x is derived\n",event); 00152 return 1; 00153 } 00154 } 00155 return 0; 00156 } 00157 00158 00159 int find_nonderived_event( void ) 00160 { 00161 /* query and set up the right event to monitor */ 00162 PAPI_event_info_t info; 00163 int potential_evt_to_add[3] = { PAPI_FP_OPS, PAPI_FP_INS, PAPI_TOT_INS }; 00164 int i; 00165 00166 for ( i = 0; i < 3; i++ ) { 00167 if ( PAPI_query_event( potential_evt_to_add[i] ) == PAPI_OK ) { 00168 if ( PAPI_get_event_info( potential_evt_to_add[i], &info ) == 00169 PAPI_OK ) { 00170 if ( ( info.count > 0 ) && 00171 !strcmp( info.derived, "NOT_DERIVED" ) ) 00172 return ( potential_evt_to_add[i] ); 00173 } 00174 } 00175 } 00176 return ( 0 ); 00177 } 00178 00179 00180 /* Add events to an EventSet, as specified by a mask. 00181 00182 Returns: number = number of events added 00183 00184 */ 00185 00186 //struct test_events_t { 00187 // unsigned int mask; 00188 // unsigned int event; 00189 //}; 00190 00191 struct test_events_t test_events[MAX_TEST_EVENTS] = { 00192 { MASK_TOT_CYC, PAPI_TOT_CYC }, 00193 { MASK_TOT_INS, PAPI_TOT_INS }, 00194 { MASK_FP_INS, PAPI_FP_INS }, 00195 { MASK_L1_TCM, PAPI_L1_TCM }, 00196 { MASK_L1_ICM, PAPI_L1_ICM }, 00197 { MASK_L1_DCM, PAPI_L1_DCM }, 00198 { MASK_L2_TCM, PAPI_L2_TCM }, 00199 { MASK_L2_TCA, PAPI_L2_TCA }, 00200 { MASK_L2_TCH, PAPI_L2_TCH }, 00201 { MASK_BR_CN, PAPI_BR_CN }, 00202 { MASK_BR_MSP, PAPI_BR_MSP }, 00203 { MASK_BR_PRC, PAPI_BR_PRC }, 00204 { MASK_TOT_IIS, PAPI_TOT_IIS}, 00205 { MASK_L1_DCR, PAPI_L1_DCR}, 00206 { MASK_L1_DCW, PAPI_L1_DCW}, 00207 { MASK_L1_DCA, PAPI_L1_DCA}, 00208 { MASK_FP_OPS, PAPI_FP_OPS}, 00209 }; 00210 00211 00212 int 00213 add_test_events( int *number, int *mask, int allow_derived ) 00214 { 00215 int retval,i; 00216 int EventSet = PAPI_NULL; 00217 int num_counters = 0; 00218 char name_string[BUFSIZ]; 00219 00220 *number = 0; 00221 00222 /* get the number of available HW counters */ 00223 num_counters = PAPI_get_opt( PAPI_MAX_HWCTRS, NULL ); 00224 if ( num_counters < 1 ) { 00225 test_fail( __FILE__, __LINE__, "Zero HW Counters available", 00226 num_counters ); 00227 } 00228 00229 /* create the eventset */ 00230 retval = PAPI_create_eventset( &EventSet ); 00231 if ( retval != PAPI_OK ) { 00232 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", 00233 retval ); 00234 } 00235 00236 /* check all the masks */ 00237 for(i=0;i<MAX_TEST_EVENTS;i++) { 00238 00239 if ( *mask & test_events[i].mask ) { 00240 00241 /* remove any derived events if told to */ 00242 if ((is_event_derived(test_events[i].event)) && (!allow_derived)) { 00243 *mask = *mask ^ test_events[i].mask; 00244 continue; 00245 } 00246 00247 retval = PAPI_add_event( EventSet, test_events[i].event ); 00248 00249 if ( retval == PAPI_OK ) { 00250 00251 ( *number )++; 00252 #if 0 00253 if ((*number)==num_counters) { 00254 if ( !TESTS_QUIET) { 00255 fprintf(stdout, "Stopping with %d events due to HW limit\n", 00256 num_counters); 00257 } 00258 break; 00259 } 00260 #endif 00261 } 00262 else { 00263 if ( !TESTS_QUIET ) { 00264 PAPI_event_code_to_name(test_events[i].event,name_string); 00265 fprintf( stdout, "%x %s is not available.\n", 00266 test_events[i].event,name_string); 00267 } 00268 *mask = *mask ^ test_events[i].mask; 00269 } 00270 } 00271 } 00272 00273 return EventSet; 00274 } 00275 00276 int 00277 remove_test_events( int *EventSet, int mask ) 00278 { 00279 int retval = PAPI_OK; 00280 00281 if ( mask & MASK_L1_DCA ) { 00282 retval = PAPI_remove_event( *EventSet, PAPI_L1_DCA ); 00283 if ( retval < PAPI_OK ) 00284 return ( retval ); 00285 } 00286 00287 if ( mask & MASK_L1_DCW ) { 00288 retval = PAPI_remove_event( *EventSet, PAPI_L1_DCW ); 00289 if ( retval < PAPI_OK ) 00290 return ( retval ); 00291 } 00292 00293 if ( mask & MASK_L1_DCR ) { 00294 retval = PAPI_remove_event( *EventSet, PAPI_L1_DCR ); 00295 if ( retval < PAPI_OK ) 00296 return ( retval ); 00297 } 00298 00299 if ( mask & MASK_L2_TCH ) { 00300 retval = PAPI_remove_event( *EventSet, PAPI_L2_TCH ); 00301 if ( retval < PAPI_OK ) 00302 return ( retval ); 00303 } 00304 00305 if ( mask & MASK_L2_TCA ) { 00306 retval = PAPI_remove_event( *EventSet, PAPI_L2_TCA ); 00307 if ( retval < PAPI_OK ) 00308 return ( retval ); 00309 } 00310 00311 if ( mask & MASK_L2_TCM ) { 00312 retval = PAPI_remove_event( *EventSet, PAPI_L2_TCM ); 00313 if ( retval < PAPI_OK ) 00314 return ( retval ); 00315 } 00316 00317 if ( mask & MASK_L1_DCM ) { 00318 retval = PAPI_remove_event( *EventSet, PAPI_L1_DCM ); 00319 if ( retval < PAPI_OK ) 00320 return ( retval ); 00321 } 00322 00323 if ( mask & MASK_L1_ICM ) { 00324 retval = PAPI_remove_event( *EventSet, PAPI_L1_ICM ); 00325 if ( retval < PAPI_OK ) 00326 return ( retval ); 00327 } 00328 00329 if ( mask & MASK_L1_TCM ) { 00330 retval = PAPI_remove_event( *EventSet, PAPI_L1_TCM ); 00331 if ( retval < PAPI_OK ) 00332 return ( retval ); 00333 } 00334 00335 if ( mask & MASK_FP_OPS ) { 00336 retval = PAPI_remove_event( *EventSet, PAPI_FP_OPS ); 00337 if ( retval < PAPI_OK ) 00338 return ( retval ); 00339 } 00340 00341 if ( mask & MASK_FP_INS ) { 00342 retval = PAPI_remove_event( *EventSet, PAPI_FP_INS ); 00343 if ( retval < PAPI_OK ) 00344 return ( retval ); 00345 } 00346 00347 if ( mask & MASK_TOT_INS ) { 00348 retval = PAPI_remove_event( *EventSet, PAPI_TOT_INS ); 00349 if ( retval < PAPI_OK ) 00350 return ( retval ); 00351 } 00352 00353 if ( mask & MASK_TOT_IIS ) { 00354 retval = PAPI_remove_event( *EventSet, PAPI_TOT_IIS ); 00355 if ( retval < PAPI_OK ) 00356 return ( retval ); 00357 } 00358 00359 if ( mask & MASK_TOT_CYC ) { 00360 retval = PAPI_remove_event( *EventSet, PAPI_TOT_CYC ); 00361 if ( retval < PAPI_OK ) 00362 return ( retval ); 00363 } 00364 00365 return ( PAPI_destroy_eventset( EventSet ) ); 00366 } 00367 00368 char * 00369 stringify_all_domains( int domains ) 00370 { 00371 static char buf[PAPI_HUGE_STR_LEN]; 00372 int i, did = 0; 00373 buf[0] = '\0'; 00374 00375 for ( i = PAPI_DOM_MIN; i <= PAPI_DOM_MAX; i = i << 1 ) 00376 if ( domains & i ) { 00377 if ( did ) 00378 strcpy( buf + strlen( buf ), "|" ); 00379 strcpy( buf + strlen( buf ), stringify_domain( domains & i ) ); 00380 did++; 00381 } 00382 if ( did == 0 ) 00383 test_fail( __FILE__, __LINE__, "Unrecognized domains!", 0 ); 00384 return ( buf ); 00385 } 00386 00387 char * 00388 stringify_domain( int domain ) 00389 { 00390 switch ( domain ) { 00391 case PAPI_DOM_SUPERVISOR: 00392 return ( "PAPI_DOM_SUPERVISOR" ); 00393 case PAPI_DOM_USER: 00394 return ( "PAPI_DOM_USER" ); 00395 case PAPI_DOM_KERNEL: 00396 return ( "PAPI_DOM_KERNEL" ); 00397 case PAPI_DOM_OTHER: 00398 return ( "PAPI_DOM_OTHER" ); 00399 case PAPI_DOM_ALL: 00400 return ( "PAPI_DOM_ALL" ); 00401 default: 00402 test_fail( __FILE__, __LINE__, "Unrecognized domains!", 0 ); 00403 } 00404 return ( NULL ); 00405 } 00406 00407 char * 00408 stringify_all_granularities( int granularities ) 00409 { 00410 static char buf[PAPI_HUGE_STR_LEN]; 00411 int i, did = 0; 00412 00413 buf[0] = '\0'; 00414 for ( i = PAPI_GRN_MIN; i <= PAPI_GRN_MAX; i = i << 1 ) 00415 if ( granularities & i ) { 00416 if ( did ) 00417 strcpy( buf + strlen( buf ), "|" ); 00418 strcpy( buf + strlen( buf ), 00419 stringify_granularity( granularities & i ) ); 00420 did++; 00421 } 00422 if ( did == 0 ) 00423 test_fail( __FILE__, __LINE__, "Unrecognized granularity!", 0 ); 00424 00425 return ( buf ); 00426 } 00427 00428 char * 00429 stringify_granularity( int granularity ) 00430 { 00431 switch ( granularity ) { 00432 case PAPI_GRN_THR: 00433 return ( "PAPI_GRN_THR" ); 00434 case PAPI_GRN_PROC: 00435 return ( "PAPI_GRN_PROC" ); 00436 case PAPI_GRN_PROCG: 00437 return ( "PAPI_GRN_PROCG" ); 00438 case PAPI_GRN_SYS_CPU: 00439 return ( "PAPI_GRN_SYS_CPU" ); 00440 case PAPI_GRN_SYS: 00441 return ( "PAPI_GRN_SYS" ); 00442 default: 00443 test_fail( __FILE__, __LINE__, "Unrecognized granularity!", 0 ); 00444 } 00445 return ( NULL ); 00446 } 00447 00448 void 00449 tests_quiet( int argc, char **argv ) 00450 { 00451 if ( ( argc > 1 ) 00452 && ( ( strcasecmp( argv[1], "TESTS_QUIET" ) == 0 ) 00453 || ( strcasecmp( argv[1], "-q" ) == 0 ) ) ) { 00454 TESTS_QUIET = 1; 00455 } else { 00456 int retval; 00457 00458 retval = PAPI_set_debug( PAPI_VERB_ECONT ); 00459 if ( retval != PAPI_OK ) 00460 test_fail( __FILE__, __LINE__, "PAPI_set_debug", retval ); 00461 } 00462 if (getenv("TESTS_COLOR")!=NULL) { 00463 TESTS_COLOR=1; 00464 } 00465 00466 } 00467 00468 #define RED "\033[1;31m" 00469 #define YELLOW "\033[1;33m" 00470 #define GREEN "\033[1;32m" 00471 #define NORMAL "\033[0m" 00472 00473 void 00474 test_pass( char *file, long long **values, int num_tests ) 00475 { 00476 int line_pad; 00477 00478 line_pad=(int)(50-strlen(file)); 00479 if (line_pad<0) line_pad=0; 00480 00481 if ( TEST_WARN ) { 00482 if (TESTS_COLOR) { 00483 fprintf( stdout, "%-*s %sPASSED with WARNING%s\n", 00484 line_pad, file, YELLOW, NORMAL); 00485 } 00486 else { 00487 fprintf( stdout, "%-*s PASSED with WARNING\n", 00488 line_pad, file ); 00489 } 00490 } 00491 else { 00492 if (TESTS_COLOR) { 00493 fprintf( stdout, "%-*s %sPASSED%s\n", line_pad, file, 00494 GREEN, NORMAL ); 00495 } 00496 else { 00497 fprintf( stdout, "%-*s PASSED\n", line_pad, file ); 00498 } 00499 } 00500 00501 if ( values ) 00502 free_test_space( values, num_tests ); 00503 00504 if ( PAPI_is_initialized( ) ) 00505 PAPI_shutdown( ); 00506 00507 exit( 0 ); 00508 00509 } 00510 00511 /* Use a positive value of retval to simply print an error message */ 00512 void 00513 test_fail( char *file, int line, char *call, int retval ) 00514 { 00515 00516 int line_pad; 00517 char buf[128]; 00518 00519 line_pad=(int)(50-strlen(file)); 00520 if (line_pad<0) line_pad=0; 00521 00522 memset( buf, '\0', sizeof ( buf ) ); 00523 00524 if (TESTS_COLOR) { 00525 fprintf( stdout, "%-*s %sFAILED%s\nLine # %d\n", line_pad, file, 00526 RED,NORMAL,line ); 00527 } 00528 else { 00529 fprintf( stdout, "%-*s FAILED\nLine # %d\n", line_pad, file, line ); 00530 } 00531 00532 if ( retval == PAPI_ESYS ) { 00533 sprintf( buf, "System error in %s", call ); 00534 perror( buf ); 00535 } else if ( retval > 0 ) { 00536 fprintf( stdout, "Error: %s\n", call ); 00537 } else if ( retval == 0 ) { 00538 #if defined(sgi) 00539 fprintf( stdout, "SGI requires root permissions for this test\n" ); 00540 #else 00541 fprintf( stdout, "Error: %s\n", call ); 00542 #endif 00543 } else { 00544 fprintf( stdout, "Error in %s: %s\n", call, PAPI_strerror( retval ) ); 00545 } 00546 00547 fprintf( stdout, "\n" ); 00548 00549 /* NOTE: Because test_fail is called from thread functions, 00550 calling PAPI_shutdown here could prevent some threads 00551 from being able to free memory they have allocated. 00552 */ 00553 00554 /* This is stupid. Threads are the rare case */ 00555 /* and in any case an exit() should clear everything out */ 00556 /* adding back the exit() call */ 00557 00558 exit(1); 00559 } 00560 00561 /* This routine mimics the previous implementation of test_fail() 00562 by exiting on completion. It caused problems for threaded apps. 00563 If you are not threaded and want to exit, replace calls to 00564 test_fail() with calls to test_fail_exit(). 00565 */ 00566 void 00567 test_fail_exit( char *file, int line, char *call, int retval ) 00568 { 00569 test_fail( file, line, call, retval ); 00570 if ( PAPI_is_initialized( ) ) 00571 PAPI_shutdown( ); 00572 exit( 1 ); 00573 } 00574 00575 00576 /* Use a positive value of retval to simply print an error message */ 00577 void 00578 test_warn( char *file, int line, char *call, int retval ) 00579 { 00580 00581 int line_pad; 00582 00583 line_pad=(int)(50-strlen(file)); 00584 if (line_pad<0) line_pad=0; 00585 00586 char buf[128]; 00587 memset( buf, '\0', sizeof ( buf ) ); 00588 00589 if (TESTS_COLOR) { 00590 fprintf( stdout, "%-*s %sWARNING%s\nLine # %d\n", line_pad, file, 00591 YELLOW, NORMAL, line ); 00592 } 00593 else { 00594 fprintf( stdout, "%-*s WARNING\nLine # %d\n", line_pad, file, line ); 00595 } 00596 00597 if ( retval == PAPI_ESYS ) { 00598 sprintf( buf, "System warning in %s", call ); 00599 perror( buf ); 00600 } else if ( retval > 0 ) { 00601 fprintf( stdout, "Warning: %s\n", call ); 00602 } else if ( retval == 0 ) { 00603 fprintf( stdout, "Warning: %s\n", call ); 00604 } else { 00605 fprintf( stdout, "Warning in %s: %s\n", call, PAPI_strerror( retval )); 00606 } 00607 00608 fprintf( stdout, "\n" ); 00609 TEST_WARN++; 00610 00611 } 00612 00613 void 00614 test_skip( char *file, int line, char *call, int retval ) 00615 { 00616 char buf[128]; 00617 00618 memset( buf, '\0', sizeof ( buf ) ); 00619 fprintf( stdout, "%-40s SKIPPED\n", file ); 00620 if ( !TESTS_QUIET ) { 00621 if ( retval == PAPI_ESYS ) { 00622 fprintf( stdout, "Line # %d\n", line ); 00623 sprintf( buf, "System error in %s:", call ); 00624 perror( buf ); 00625 } else if ( retval == PAPI_EPERM ) { 00626 fprintf( stdout, "Line # %d\n", line ); 00627 fprintf( stdout, "Invalid permissions for %s.", call ); 00628 } else if ( retval == PAPI_ECMP ) { 00629 fprintf( stdout, "Line # %d\n", line ); 00630 fprintf( stdout, "%s.", call ); 00631 } else if ( retval >= 0 ) { 00632 fprintf( stdout, "Line # %d\n", line ); 00633 fprintf( stdout, "Error calculating: %s\n", call ); 00634 } else if ( retval < 0 ) { 00635 fprintf( stdout, "Line # %d\n", line ); 00636 fprintf( stdout, "Error in %s: %s\n", call, PAPI_strerror(retval) ); 00637 } 00638 fprintf( stdout, "\n" ); 00639 } 00640 exit( 0 ); 00641 } 00642 00643 00644 void 00645 test_print_event_header( char *call, int evset ) 00646 { 00647 int *ev_ids; 00648 int i, nev; 00649 int retval; 00650 char evname[PAPI_MAX_STR_LEN]; 00651 00652 if ( *call ) 00653 fprintf( stdout, "%s", call ); 00654 00655 if ((nev = PAPI_get_cmp_opt(PAPI_MAX_MPX_CTRS,NULL,0)) <= 0) { 00656 fprintf( stdout, "Can not list event names.\n" ); 00657 return; 00658 } 00659 00660 if ((ev_ids = calloc(nev,sizeof(int))) == NULL) { 00661 fprintf( stdout, "Can not list event names.\n" ); 00662 return; 00663 } 00664 00665 retval = PAPI_list_events( evset, ev_ids, &nev ); 00666 00667 if ( retval == PAPI_OK ) { 00668 for ( i = 0; i < nev; i++ ) { 00669 PAPI_event_code_to_name( ev_ids[i], evname ); 00670 printf( ONEHDR, evname ); 00671 } 00672 } else { 00673 fprintf( stdout, "Can not list event names." ); 00674 } 00675 fprintf( stdout, "\n" ); 00676 free(ev_ids); 00677 } 00678 00679 int 00680 add_two_events( int *num_events, int *papi_event, int *mask ) { 00681 00682 /* query and set up the right event to monitor */ 00683 int EventSet = PAPI_NULL; 00684 PAPI_event_info_t info; 00685 unsigned int potential_evt_to_add[3][2] = 00686 { {( unsigned int ) PAPI_FP_INS, MASK_FP_INS}, 00687 {( unsigned int ) PAPI_FP_OPS, MASK_FP_OPS}, 00688 {( unsigned int ) PAPI_TOT_INS, MASK_TOT_INS} 00689 }; 00690 int i = 0; 00691 int counters = 0; 00692 00693 *mask = 0; 00694 counters = PAPI_num_hwctrs( ); 00695 00696 if (counters<=0) { 00697 test_fail(__FILE__,__LINE__,"Zero Counters Available! PAPI Won't like this!\n",0); 00698 } 00699 00700 /* This code tries to ensure that the event generated will fit in the */ 00701 /* number of available counters. It has the potential to leak up to */ 00702 /* two event sets if events fail to add successfully. */ 00703 00704 for(i=0;i<3;i++) { 00705 if ( PAPI_query_event( (int) potential_evt_to_add[i][0] ) == PAPI_OK ) { 00706 if ( PAPI_get_event_info( (int) potential_evt_to_add[i][0], &info ) == PAPI_OK ) { 00707 if ( ( info.count > 0 ) && ( (unsigned) counters > info.count ) ) { 00708 *papi_event = ( int ) potential_evt_to_add[i][0]; 00709 *mask = ( int ) potential_evt_to_add[i][1] | MASK_TOT_CYC; 00710 EventSet = add_test_events( num_events, mask, 1 ); 00711 if ( *num_events == 2 ) break; 00712 } 00713 } 00714 } 00715 } 00716 if ( i == 3 ) { 00717 test_fail( __FILE__, __LINE__, "Not enough room to add an event!", 0 ); 00718 } 00719 return EventSet; 00720 } 00721 00722 int 00723 add_two_nonderived_events( int *num_events, int *papi_event, int *mask ) { 00724 00725 /* query and set up the right event to monitor */ 00726 int EventSet = PAPI_NULL; 00727 00728 #define POTENTIAL_EVENTS 3 00729 00730 unsigned int potential_evt_to_add[POTENTIAL_EVENTS][2] = 00731 { {( unsigned int ) PAPI_FP_INS, MASK_FP_INS}, 00732 {( unsigned int ) PAPI_FP_OPS, MASK_FP_OPS}, 00733 {( unsigned int ) PAPI_TOT_INS, MASK_TOT_INS} 00734 }; 00735 00736 int i; 00737 00738 *mask = 0; 00739 00740 /* could leak up to two event sets. */ 00741 for(i=0;i<POTENTIAL_EVENTS;i++) { 00742 00743 if ( PAPI_query_event( ( int ) potential_evt_to_add[i][0] ) == PAPI_OK ) { 00744 if ( !is_event_derived(potential_evt_to_add[i][0])) { 00745 *papi_event = ( int ) potential_evt_to_add[i][0]; 00746 *mask = ( int ) potential_evt_to_add[i][1] | MASK_TOT_CYC; 00747 EventSet = add_test_events( num_events, mask, 0 ); 00748 if ( *num_events == 2 ) break; 00749 } 00750 } 00751 } 00752 00753 if ( i == POTENTIAL_EVENTS ) { 00754 test_fail( __FILE__, __LINE__, "Can't find a non-derived event!", 0 ); 00755 } 00756 return EventSet; 00757 } 00758 00759 /* add native events to use all counters */ 00760 int 00761 enum_add_native_events( int *num_events, int **evtcodes, 00762 int need_interrupt, int no_software_events, 00763 int cidx) 00764 { 00765 /* query and set up the right event to monitor */ 00766 int EventSet = PAPI_NULL; 00767 int i = 0, k, event_code, retval; 00768 int counters, event_found = 0; 00769 PAPI_event_info_t info; 00770 const PAPI_component_info_t *s = NULL; 00771 const PAPI_hw_info_t *hw_info = NULL; 00772 00773 s = PAPI_get_component_info( cidx ); 00774 if ( s == NULL ) { 00775 test_fail( __FILE__, __LINE__, 00776 "PAPI_get_component_info", PAPI_ECMP ); 00777 } 00778 00779 hw_info = PAPI_get_hardware_info( ); 00780 if ( hw_info == NULL ) { 00781 test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 ); 00782 } 00783 00784 counters = PAPI_num_hwctrs( ); 00785 if (counters<1) { 00786 test_fail(__FILE__,__LINE__, "No counters available!\n",1); 00787 } 00788 00789 if (!TESTS_QUIET) printf("Trying to fill %d hardware counters...\n", 00790 counters); 00791 00792 if (need_interrupt) { 00793 if ( (!strcmp(hw_info->model_string,"POWER6")) || 00794 (!strcmp(hw_info->model_string,"POWER5")) ) { 00795 00796 test_warn(__FILE__, __LINE__, 00797 "Limiting num_counters because of LIMITED_PMC on Power5 and Power6",1); 00798 counters=4; 00799 } 00800 } 00801 00802 ( *evtcodes ) = ( int * ) calloc( counters, sizeof ( int ) ); 00803 00804 retval = PAPI_create_eventset( &EventSet ); 00805 if ( retval != PAPI_OK ) { 00806 test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval ); 00807 } 00808 00809 /* For platform independence, always ASK FOR the first event */ 00810 /* Don't just assume it'll be the first numeric value */ 00811 i = 0 | PAPI_NATIVE_MASK; 00812 PAPI_enum_cmp_event( &i, PAPI_ENUM_FIRST, cidx ); 00813 00814 do { 00815 retval = PAPI_get_event_info( i, &info ); 00816 00817 /* HACK! FIXME */ 00818 if (no_software_events && ( strstr(info.symbol,"PERF_COUNT_SW") || strstr(info.long_descr, "PERF_COUNT_SW") ) ) { 00819 if (!TESTS_QUIET) { 00820 printf("Blocking event %s as a SW event\n", info.symbol); 00821 } 00822 continue; 00823 } 00824 00825 if ( s->cntr_umasks ) { 00826 k = i; 00827 00828 if ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cidx ) == PAPI_OK ) { 00829 do { 00830 retval = PAPI_get_event_info( k, &info ); 00831 event_code = ( int ) info.event_code; 00832 00833 retval = PAPI_add_event( EventSet, event_code ); 00834 if ( retval == PAPI_OK ) { 00835 ( *evtcodes )[event_found] = event_code; 00836 if ( !TESTS_QUIET ) { 00837 printf( "event_code[%d] = 0x%x (%s)\n", 00838 event_found, event_code, info.symbol ); 00839 } 00840 event_found++; 00841 } else { 00842 if ( !TESTS_QUIET ) { 00843 printf( "0x%x (%s) can't be added to the EventSet.\n", 00844 event_code, info.symbol ); 00845 } 00846 } 00847 } while ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cidx ) == PAPI_OK 00848 && event_found < counters ); 00849 } else { 00850 event_code = ( int ) info.event_code; 00851 retval = PAPI_add_event( EventSet, event_code ); 00852 if ( retval == PAPI_OK ) { 00853 ( *evtcodes )[event_found] = event_code; 00854 if ( !TESTS_QUIET ) { 00855 printf( "event_code[%d] = 0x%x (%s)\n", 00856 event_found, event_code, info.symbol ); 00857 } 00858 event_found++; 00859 } 00860 } 00861 if ( !TESTS_QUIET && retval == PAPI_OK ) { 00862 /* */ 00863 } 00864 } else { 00865 event_code = ( int ) info.event_code; 00866 retval = PAPI_add_event( EventSet, event_code ); 00867 if ( retval == PAPI_OK ) { 00868 ( *evtcodes )[event_found] = event_code; 00869 event_found++; 00870 } else { 00871 if ( !TESTS_QUIET ) 00872 fprintf( stdout, "0x%x is not available.\n", event_code ); 00873 } 00874 } 00875 } 00876 while ( PAPI_enum_cmp_event( &i, PAPI_ENUM_EVENTS, cidx ) == PAPI_OK && 00877 event_found < counters ); 00878 00879 *num_events = ( int ) event_found; 00880 00881 if (!TESTS_QUIET) printf("Tried to fill %d counters with events, " 00882 "found %d\n",counters,event_found); 00883 00884 return EventSet; 00885 } 00886 00887 void 00888 init_multiplex( void ) 00889 { 00890 int retval; 00891 const PAPI_hw_info_t *hw_info; 00892 const PAPI_component_info_t *cmpinfo; 00893 00894 /* Initialize the library */ 00895 00896 /* for now, assume multiplexing on CPU compnent only */ 00897 cmpinfo = PAPI_get_component_info( 0 ); 00898 if ( cmpinfo == NULL ) 00899 test_fail( __FILE__, __LINE__, "PAPI_get_component_info", 2 ); 00900 00901 hw_info = PAPI_get_hardware_info( ); 00902 if ( hw_info == NULL ) 00903 test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 ); 00904 00905 if ( ( strstr( cmpinfo->name, "perfctr.c" ) ) && (hw_info !=NULL) && 00906 strcmp( hw_info->model_string, "POWER6" ) == 0 ) { 00907 retval = PAPI_set_domain( PAPI_DOM_ALL ); 00908 if ( retval != PAPI_OK ) 00909 test_fail( __FILE__, __LINE__, "PAPI_set_domain", retval ); 00910 } 00911 retval = PAPI_multiplex_init( ); 00912 if ( retval != PAPI_OK ) 00913 test_fail( __FILE__, __LINE__, "PAPI multiplex init fail\n", retval ); 00914 } 00915