|
PAPI
5.3.0.0
|
00001 /* This file utility reports hardware info and native event availability */ 00045 #include "papi_test.h" 00046 00047 #define EVT_LINE 80 00048 00049 typedef struct command_flags 00050 { 00051 int help; 00052 int details; 00053 int named; 00054 int include; 00055 int xclude; 00056 char *name, *istr, *xstr; 00057 int darr; 00058 int dear; 00059 int iarr; 00060 int iear; 00061 int opcm; 00062 int umask; 00063 int groups; 00064 } command_flags_t; 00065 00066 static void 00067 print_help( char **argv ) 00068 { 00069 printf( "This is the PAPI native avail program.\n" ); 00070 printf( "It provides availability and detail information for PAPI native events.\n" ); 00071 printf( "Usage: %s [options]\n", argv[0] ); 00072 printf( "\nOptions:\n" ); 00073 printf( " --help, -h print this help message\n" ); 00074 printf( " -d display detailed information about native events\n" ); 00075 printf( " -e EVENTNAME display detailed information about named native event\n" ); 00076 printf( " -i EVENTSTR include only event names that contain EVENTSTR\n" ); 00077 printf( " -x EVENTSTR exclude any event names that contain EVENTSTR\n" ); 00078 printf( " --noumasks suppress display of Unit Mask information\n" ); 00079 printf( "\nProcessor-specific options\n"); 00080 printf( " --darr display events supporting Data Address Range Restriction\n" ); 00081 printf( " --dear display Data Event Address Register events only\n" ); 00082 printf( " --iarr display events supporting Instruction Address Range Restriction\n" ); 00083 printf( " --iear display Instruction Event Address Register events only\n" ); 00084 printf( " --opcm display events supporting OpCode Matching\n" ); 00085 printf( " --nogroups suppress display of Event grouping information\n" ); 00086 printf( "\n" ); 00087 } 00088 00089 static int 00090 no_str_arg( char *arg ) 00091 { 00092 return ( ( arg == NULL ) || ( strlen( arg ) == 0 ) || ( arg[0] == '-' ) ); 00093 } 00094 00095 static void 00096 parse_args( int argc, char **argv, command_flags_t * f ) 00097 { 00098 00099 int i; 00100 00101 /* Look for all currently defined commands */ 00102 memset( f, 0, sizeof ( command_flags_t ) ); 00103 f->umask = 1; 00104 f->groups = 1; 00105 00106 for ( i = 1; i < argc; i++ ) { 00107 if ( !strcmp( argv[i], "--darr" ) ) 00108 f->darr = 1; 00109 else if ( !strcmp( argv[i], "--dear" ) ) 00110 f->dear = 1; 00111 else if ( !strcmp( argv[i], "--iarr" ) ) 00112 f->iarr = 1; 00113 else if ( !strcmp( argv[i], "--iear" ) ) 00114 f->iear = 1; 00115 else if ( !strcmp( argv[i], "--opcm" ) ) 00116 f->opcm = 1; 00117 else if ( !strcmp( argv[i], "--noumasks" ) ) 00118 f->umask = 0; 00119 else if ( !strcmp( argv[i], "--nogroups" ) ) 00120 f->groups = 0; 00121 else if ( !strcmp( argv[i], "-d" ) ) 00122 f->details = 1; 00123 else if ( !strcmp( argv[i], "-e" ) ) { 00124 f->named = 1; 00125 i++; 00126 f->name = argv[i]; 00127 if ( i >= argc || no_str_arg( f->name ) ) { 00128 printf( "Invalid argument for -e\n"); 00129 exit(1); 00130 } 00131 } else if ( !strcmp( argv[i], "-i" ) ) { 00132 f->include = 1; 00133 i++; 00134 f->istr = argv[i]; 00135 if ( i >= argc || no_str_arg( f->istr ) ) { 00136 printf( "Invalid argument for -i\n"); 00137 exit(1); 00138 } 00139 } else if ( !strcmp( argv[i], "-x" ) ) { 00140 f->xclude = 1; 00141 i++; 00142 f->xstr = argv[i]; 00143 if ( i >= argc || no_str_arg( f->xstr ) ) { 00144 printf( "Invalid argument for -x\n"); 00145 exit(1); 00146 } 00147 } else if ( !strcmp( argv[i], "-h" ) || !strcmp( argv[i], "--help" ) ) 00148 f->help = 1; 00149 else { 00150 printf( "%s is not supported\n", argv[i] ); 00151 exit(1); 00152 } 00153 } 00154 00155 /* if help requested, print and bail */ 00156 if ( f->help ) { 00157 print_help( argv); 00158 exit( 1 ); 00159 } 00160 } 00161 00162 static void 00163 space_pad( char *str, int spaces ) 00164 { 00165 while ( spaces-- > 0 ) 00166 strcat( str, " " ); 00167 } 00168 00169 static void 00170 print_event( PAPI_event_info_t * info, int offset ) 00171 { 00172 unsigned int i, j = 0; 00173 char str[EVT_LINE + EVT_LINE]; 00174 00175 /* indent by offset */ 00176 if ( offset ) { 00177 printf( "| %-73s|\n", info->symbol ); 00178 } 00179 else { 00180 printf( "| %-77s|\n", info->symbol ); 00181 } 00182 00183 while ( j <= strlen( info->long_descr ) ) { 00184 i = EVT_LINE - 12 - 2; 00185 if ( i > 0 ) { 00186 str[0] = 0; 00187 strcat(str,"| " ); 00188 space_pad( str, 11 ); 00189 strncat( str, &info->long_descr[j], i ); 00190 j += i; 00191 i = ( unsigned int ) strlen( str ); 00192 space_pad( str, EVT_LINE - ( int ) i - 1 ); 00193 strcat( str, "|" ); 00194 } 00195 printf( "%s\n", str ); 00196 } 00197 } 00198 00199 static int 00200 parse_unit_masks( PAPI_event_info_t * info ) 00201 { 00202 char *pmask,*ptr; 00203 00204 /* handle the PAPI component-style events which have a component:::event type */ 00205 if ((ptr=strstr(info->symbol, ":::"))) { 00206 ptr+=3; 00207 /* handle libpfm4-style events which have a pmu::event type event name */ 00208 } else if ((ptr=strstr(info->symbol, "::"))) { 00209 ptr+=2; 00210 } 00211 else { 00212 ptr=info->symbol; 00213 } 00214 00215 if ( ( pmask = strchr( ptr, ':' ) ) == NULL ) { 00216 return ( 0 ); 00217 } 00218 memmove( info->symbol, pmask, ( strlen( pmask ) + 1 ) * sizeof ( char ) ); 00219 pmask = strchr( info->long_descr, ':' ); 00220 if ( pmask == NULL ) 00221 info->long_descr[0] = 0; 00222 else 00223 memmove( info->long_descr, pmask + sizeof ( char ), 00224 ( strlen( pmask ) + 1 ) * sizeof ( char ) ); 00225 return ( 1 ); 00226 } 00227 00228 int 00229 main( int argc, char **argv ) 00230 { 00231 int i, j = 0, k; 00232 int retval; 00233 PAPI_event_info_t info; 00234 const PAPI_hw_info_t *hwinfo = NULL; 00235 command_flags_t flags; 00236 int enum_modifier; 00237 int numcmp, cid; 00238 00239 /* Set TESTS_QUIET variable */ 00240 tests_quiet( argc, argv ); 00241 00242 /* Initialize before parsing the input arguments */ 00243 retval = PAPI_library_init( PAPI_VER_CURRENT ); 00244 if ( retval != PAPI_VER_CURRENT ) { 00245 test_fail( __FILE__, __LINE__, "PAPI_library_init", retval ); 00246 } 00247 00248 /* Parse the command-line arguments */ 00249 parse_args( argc, argv, &flags ); 00250 00251 /* Set enum modifier mask */ 00252 if ( flags.dear ) 00253 enum_modifier = PAPI_NTV_ENUM_DEAR; 00254 else if ( flags.darr ) 00255 enum_modifier = PAPI_NTV_ENUM_DARR; 00256 else if ( flags.iear ) 00257 enum_modifier = PAPI_NTV_ENUM_IEAR; 00258 else if ( flags.iarr ) 00259 enum_modifier = PAPI_NTV_ENUM_IARR; 00260 else if ( flags.opcm ) 00261 enum_modifier = PAPI_NTV_ENUM_OPCM; 00262 else 00263 enum_modifier = PAPI_ENUM_EVENTS; 00264 00265 00266 if ( !TESTS_QUIET ) { 00267 retval = PAPI_set_debug( PAPI_VERB_ECONT ); 00268 if ( retval != PAPI_OK ) { 00269 test_fail( __FILE__, __LINE__, "PAPI_set_debug", retval ); 00270 } 00271 } 00272 00273 retval = papi_print_header( "Available native events and hardware information.\n", &hwinfo ); 00274 if ( retval != PAPI_OK ) { 00275 test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 ); 00276 } 00277 00278 00279 /* Do this code if the event name option was specified on the commandline */ 00280 if ( flags.named ) { 00281 if ( PAPI_event_name_to_code( flags.name, &i ) == PAPI_OK ) { 00282 if ( PAPI_get_event_info( i, &info ) == PAPI_OK ) { 00283 printf( "%-30s%s\n", 00284 "Event name:", info.symbol); 00285 printf( "%-29s|%s|\n", "Description:", info.long_descr ); 00286 00287 /* if unit masks exist but none specified, process all */ 00288 if ( !strchr( flags.name, ':' ) ) { 00289 if ( PAPI_enum_event( &i, PAPI_NTV_ENUM_UMASKS ) == PAPI_OK ) { 00290 printf( "\nUnit Masks:\n" ); 00291 do { 00292 retval = PAPI_get_event_info( i, &info ); 00293 if ( retval == PAPI_OK ) { 00294 if ( parse_unit_masks( &info ) ) { 00295 printf( "%-29s|%s|%s|\n", " Mask Info:", 00296 info.symbol, info.long_descr ); 00297 } 00298 } 00299 } while ( PAPI_enum_event( &i, PAPI_NTV_ENUM_UMASKS ) == PAPI_OK ); 00300 } 00301 } 00302 } 00303 } else { 00304 printf("Sorry, an event by the name '%s' could not be found.\n", 00305 flags.name); 00306 printf("Is it typed correctly?\n\n"); 00307 exit( 1 ); 00308 } 00309 } 00310 else { 00311 00312 /* Print *ALL* available events */ 00313 00314 numcmp = PAPI_num_components( ); 00315 00316 j = 0; 00317 00318 for ( cid = 0; cid < numcmp; cid++ ) { 00319 00320 const PAPI_component_info_t *component; 00321 component=PAPI_get_component_info(cid); 00322 00323 /* Skip disabled components */ 00324 if (component->disabled) continue; 00325 00326 printf( "===============================================================================\n" ); 00327 printf( " Native Events in Component: %s\n",component->name); 00328 printf( "===============================================================================\n" ); 00329 00330 /* Always ASK FOR the first event */ 00331 /* Don't just assume it'll be the first numeric value */ 00332 i = 0 | PAPI_NATIVE_MASK; 00333 00334 retval=PAPI_enum_cmp_event( &i, PAPI_ENUM_FIRST, cid ); 00335 00336 if (retval==PAPI_OK) 00337 00338 do { 00339 memset( &info, 0, sizeof ( info ) ); 00340 retval = PAPI_get_event_info( i, &info ); 00341 00342 /* This event may not exist */ 00343 if ( retval != PAPI_OK ) 00344 continue; 00345 00346 /* Bail if event name doesn't contain include string */ 00347 if ( flags.include ) { 00348 if ( !strstr( info.symbol, flags.istr ) ) { 00349 continue; 00350 } 00351 } 00352 00353 /* Bail if event name does contain exclude string */ 00354 if ( flags.xclude ) { 00355 if ( strstr( info.symbol, flags.xstr ) ) 00356 continue; 00357 } 00358 00359 /* count only events that are actually processed */ 00360 j++; 00361 00362 print_event( &info, 0 ); 00363 00364 if (flags.details) { 00365 if (info.units[0]) printf( "| Units: %-67s|\n", 00366 info.units ); 00367 } 00368 00369 /* modifier = PAPI_NTV_ENUM_GROUPS returns event codes with a 00370 groups id for each group in which this 00371 native event lives, in bits 16 - 23 of event code 00372 terminating with PAPI_ENOEVNT at the end of the list. 00373 */ 00374 00375 /* This is an IBM Power issue */ 00376 if ( flags.groups ) { 00377 k = i; 00378 if ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_GROUPS, cid ) == PAPI_OK ) { 00379 printf( "Groups: " ); 00380 do { 00381 printf( "%4d", ( ( k & PAPI_NTV_GROUP_AND_MASK ) >> 00382 PAPI_NTV_GROUP_SHIFT ) - 1 ); 00383 } while ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_GROUPS, cid ) ==PAPI_OK ); 00384 printf( "\n" ); 00385 } 00386 } 00387 00388 /* Print umasks */ 00389 /* components that don't have them can just ignore */ 00390 00391 if ( flags.umask ) { 00392 k = i; 00393 if ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cid ) == PAPI_OK ) { 00394 do { 00395 retval = PAPI_get_event_info( k, &info ); 00396 if ( retval == PAPI_OK ) { 00397 if ( parse_unit_masks( &info ) ) 00398 print_event( &info, 2 ); 00399 } 00400 } while ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cid ) == PAPI_OK ); 00401 } 00402 00403 } 00404 printf( "--------------------------------------------------------------------------------\n" ); 00405 00406 } while (PAPI_enum_cmp_event( &i, enum_modifier, cid ) == PAPI_OK ); 00407 } 00408 00409 00410 printf("\n"); 00411 printf( "Total events reported: %d\n", j ); 00412 } 00413 00414 test_pass( __FILE__, NULL, 0 ); 00415 exit( 0 ); 00416 }