PAPI  5.0.1.0
native_avail.c
Go to the documentation of this file.
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 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines