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