/** file event_chooser.c * @brief papi_event_chooser utility. * @page papi_event_chooser * @section NAME * papi_event_chooser - given a list of named events, * lists other events that can be counted with them. * * @section Synopsis * papi_event_chooser NATIVE | PRESET < event > < event > ... * * @section Description * papi_event_chooser is a PAPI utility program that reports information * about the current PAPI installation and supported preset events. * * @section Options * This utility has no command line options. * * @section Bugs * There are no known bugs in this utility. * If you find a bug, it should be reported to the * PAPI Mailing List at . */ #include #include #include #include "papi.h" #include "print_header.h" int EventSet = PAPI_NULL; int retval; static char * is_derived( PAPI_event_info_t * info ) { if ( strlen( info->derived ) == 0 ) return ( "No" ); else if ( strcmp( info->derived, "NOT_DERIVED" ) == 0 ) return ( "No" ); else if ( strcmp( info->derived, "DERIVED_CMPD" ) == 0 ) return ( "No" ); else return ( "Yes" ); } static int add_remove_event( int EventSet, int evt ) { int retval; if ( ( retval = PAPI_add_event( EventSet, evt ) ) != PAPI_OK ) { //printf( "Error adding event.\n" ); } else { if ( ( retval = PAPI_remove_event( EventSet, evt ) ) != PAPI_OK ) { printf( "Error removing event.\n" ); } } return retval; } static int show_event_info( int evt ) { int k; int retval; PAPI_event_info_t info; if ( ( retval = PAPI_get_event_info( evt, &info ) ) == PAPI_OK ) { printf( "%s\t%#x\n |%s|\n", info.symbol, info.event_code, info.long_descr ); for( k = 0; k < ( int ) info.count; k++ ) { if ( strlen( info.name[k] ) ) { printf( " |Register Value[%d]: %#-10x %s|\n", k, info.code[k], info.name[k] ); } } } return retval; } static int native( int cidx ) { int i, j, k; int retval, added; PAPI_event_info_t info; j = 0; /* For platform independence, always ASK FOR the first event */ /* Don't just assume it'll be the first numeric value */ i = 0 | PAPI_NATIVE_MASK; retval=PAPI_enum_cmp_event( &i, PAPI_ENUM_FIRST, cidx ); if (retval==PAPI_ENOEVNT) { printf("Cannot find first event in component %d\n",cidx); } do { k = i; if ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cidx) == PAPI_OK ) { if ( ( added = add_remove_event( EventSet, k ) ) == PAPI_OK ) { show_event_info( i ); do { retval = PAPI_get_event_info( k, &info ); if ( retval == PAPI_OK ) { printf( " %#-10x%s |%s|\n", info.event_code, strchr( info.symbol, ':' ), strchr( info.long_descr, ':' ) + 1 ); } } while ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cidx ) == PAPI_OK ); j++; } } else { if ( ( added = add_remove_event( EventSet, i ) ) == PAPI_OK ) { show_event_info( i ); j++; } } if ( added == PAPI_OK ) { /* modifier = PAPI_NTV_ENUM_GROUPS returns event codes with a groups id for each group in which this native event lives, in bits 16 - 23 of event code terminating with PAPI_ENOEVNT at the end of the list. */ k = i; if ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_GROUPS, cidx ) == PAPI_OK ) { printf( "Groups: " ); do { printf( "%4d", ( ( k & PAPI_NTV_GROUP_AND_MASK ) >> PAPI_NTV_GROUP_SHIFT ) - 1 ); } while ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_GROUPS, cidx ) == PAPI_OK ); printf( "\n" ); } printf( "---------------------------------------------" "----------------------------\n" ); } } while ( PAPI_enum_cmp_event( &i, PAPI_ENUM_EVENTS, cidx ) == PAPI_OK ); printf( "------------------------------------------" "-------------------------------\n" ); printf( "Total events reported: %d\n", j ); exit( 0 ); } static int preset( void ) { int i, j = 0; int retval; PAPI_event_info_t info; printf( " Name Code " ); printf( "Deriv Description (Note)\n" ); /* For consistency, always ASK FOR the first event */ i = 0 | PAPI_PRESET_MASK; PAPI_enum_event( &i, PAPI_ENUM_FIRST ); do { retval = PAPI_add_event( EventSet, i ); if ( retval == PAPI_OK ) { if ( PAPI_get_event_info( i, &info ) == PAPI_OK ) { printf( "%-13s%#x %-5s%s", info.symbol, info.event_code, is_derived( &info ), info.long_descr ); if ( info.note[0] ) printf( " (%s)", info.note ); printf( "\n" ); } if ( ( retval = PAPI_remove_event( EventSet, i ) ) != PAPI_OK ) printf( "Error in PAPI_remove_event\n" ); j++; } } while ( PAPI_enum_event( &i, PAPI_PRESET_ENUM_AVAIL ) == PAPI_OK ); printf ( "-------------------------------------------------------------------------\n" ); printf( "Total events reported: %d\n", j ); exit( 0 ); } int main( int argc, char **argv ) { int i; int pevent,cevent; int cidx; const PAPI_hw_info_t *hwinfo = NULL; if ( argc < 3 ) { goto use_exit; } /* Init PAPI library */ retval = PAPI_library_init( PAPI_VER_CURRENT ); if ( retval != PAPI_VER_CURRENT ) { fprintf(stderr,"Error! PAPI_library_init\n"); return retval; } retval = PAPI_set_debug( PAPI_VERB_ECONT ); if ( retval != PAPI_OK ) { fprintf(stderr,"Error! PAPI_set_debug\n"); return retval; } retval = papi_print_header( "Event Chooser: Available events " "which can be added with given events.\n", &hwinfo ); if ( retval != PAPI_OK ) { fprintf(stderr, "Error! PAPI_get_hardware_info\n"); return 2; } retval = PAPI_create_eventset( &EventSet ); if ( retval != PAPI_OK ) { fprintf( stderr, "PAPI_create_eventset error\n" ); return 1; } retval = PAPI_event_name_to_code( argv[2], &cevent ); if ( retval != PAPI_OK ) { fprintf( stderr, "Event %s can't be found\n", argv[2] ); return 1; } cidx = PAPI_get_event_component(cevent); for( i = 2; i < argc; i++ ) { retval = PAPI_event_name_to_code( argv[i], &pevent ); if ( retval != PAPI_OK ) { fprintf( stderr, "Event %s can't be found\n", argv[i] ); return 1; } retval = PAPI_add_event( EventSet, pevent ); if ( retval != PAPI_OK ) { fprintf( stderr, "Event %s can't be counted with others %d\n", argv[i], retval ); return 1; } } if ( !strcmp( "NATIVE", argv[1] ) ) { native( cidx ); } else if ( !strcmp( "PRESET", argv[1] ) ) { preset( ); } else { goto use_exit; } return 0; use_exit: fprintf( stderr, "Usage: papi_event_chooser NATIVE|PRESET evt1 evt2 ... \n" ); return 1; }