PAPI  5.0.1.0
event_info.c
Go to the documentation of this file.
00001 
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include "papi.h"
00035 #include "papi_test.h"
00036 
00037 static int EventSet;
00038 static int preset = 1;
00039 static int native = 1;
00040 static int cidx = -1;
00041 
00042 /**********************************************************************/
00043 /* Take a string and print a version with properly escaped XML        */
00044 /**********************************************************************/
00045 static int
00046 xmlize( const char *msg, FILE *f )
00047 {
00048     const char *op;
00049 
00050     if ( !msg )
00051         return PAPI_OK;
00052 
00053     for ( op = msg; *op != '\0'; op++ ) {
00054         switch ( *op ) {
00055         case '"':
00056             fprintf( f, "&quot;" );
00057             break;
00058         case '&':
00059             fprintf( f, "&amp;" );
00060             break;
00061         case '\'':
00062             fprintf( f, "&apos;" );
00063             break;
00064         case '<':
00065             fprintf( f, "&lt;" );
00066             break;
00067         case '>':
00068             fprintf( f, "&gt;" );
00069             break;
00070         default:
00071                 fprintf( f, "%c", *op);
00072         }
00073     }
00074 
00075     return PAPI_OK;
00076 }
00077 
00078 /*************************************/
00079 /* print hardware info in XML format */
00080 /*************************************/
00081 static int
00082 papi_xml_hwinfo( FILE * f )
00083 {
00084     const PAPI_hw_info_t *hwinfo;
00085 
00086     if ( ( hwinfo = PAPI_get_hardware_info(  ) ) == NULL )
00087         return PAPI_ESYS;
00088 
00089     fprintf( f, "<hardware>\n" );
00090 
00091     fprintf( f, "  <vendor string=\"");
00092        xmlize( hwinfo->vendor_string, f );
00093        fprintf( f,"\"/>\n");
00094     fprintf( f, "  <vendorCode value=\"%d\"/>\n", hwinfo->vendor );
00095     fprintf( f, "  <model string=\"");
00096     xmlize( hwinfo->model_string, f );
00097        fprintf( f, "\"/>\n");
00098     fprintf( f, "  <modelCode value=\"%d\"/>\n", hwinfo->model );
00099     fprintf( f, "  <cpuRevision value=\"%f\"/>\n", hwinfo->revision );
00100     fprintf( f, "  <cpuID>\n" );
00101     fprintf( f, "    <family value=\"%d\"/>\n", hwinfo->cpuid_family );
00102     fprintf( f, "    <model value=\"%d\"/>\n", hwinfo->cpuid_model );
00103     fprintf( f, "    <stepping value=\"%d\"/>\n", hwinfo->cpuid_stepping );
00104     fprintf( f, "  </cpuID>\n" );
00105     fprintf( f, "  <cpuMaxMegahertz value=\"%d\"/>\n", hwinfo->cpu_max_mhz );
00106     fprintf( f, "  <cpuMinMegahertz value=\"%d\"/>\n", hwinfo->cpu_min_mhz );
00107     fprintf( f, "  <threads value=\"%d\"/>\n", hwinfo->threads );
00108     fprintf( f, "  <cores value=\"%d\"/>\n", hwinfo->cores );
00109     fprintf( f, "  <sockets value=\"%d\"/>\n", hwinfo->sockets );
00110     fprintf( f, "  <nodes value=\"%d\"/>\n", hwinfo->nnodes );
00111     fprintf( f, "  <cpuPerNode value=\"%d\"/>\n", hwinfo->ncpu );
00112     fprintf( f, "  <totalCPUs value=\"%d\"/>\n", hwinfo->totalcpus );
00113     fprintf( f, "</hardware>\n" );
00114 
00115     return PAPI_OK;
00116 }
00117 
00118 
00119 
00120 /****************************************************************/
00121 /* Test if event can be added to an eventset                    */
00122 /* (there might be existing events if specified on command line */
00123 /****************************************************************/
00124 
00125 static int
00126 test_event( int evt )
00127 {
00128     int retval;
00129 
00130     retval = PAPI_add_event( EventSet, evt );
00131     if ( retval != PAPI_OK ) {
00132         return retval;
00133     }
00134 
00135     if ( ( retval = PAPI_remove_event( EventSet, evt ) ) != PAPI_OK ) {
00136        fprintf( stderr, "Error removing event from eventset\n" );
00137        exit( 1 );
00138     }
00139     return PAPI_OK;
00140 }
00141 
00142 /***************************************/
00143 /* Convert an event to XML             */
00144 /***************************************/
00145 
00146 static void
00147 xmlize_event( FILE * f, PAPI_event_info_t * info, int num )
00148 {
00149 
00150     if ( num >= 0 ) {
00151        fprintf( f, "    <event index=\"%d\" name=\"",num);
00152        xmlize( info->symbol, f );
00153        fprintf( f, "\" desc=\"");
00154        xmlize( info->long_descr, f );
00155        fprintf( f, "\">\n");
00156     }
00157     else {
00158        fprintf( f,"        <modifier name=\"");
00159        xmlize( info->symbol, f );
00160        fprintf( f,"\" desc=\"");
00161        xmlize( info->long_descr, f );
00162        fprintf( f,"\"> </modifier>\n");
00163     }
00164 
00165 }
00166 
00167 
00168 /****************************************/
00169 /* Print all preset events              */
00170 /****************************************/
00171 
00172 static void
00173 enum_preset_events( FILE * f, int cidx)
00174 {
00175     int i, num;
00176     int retval;
00177     PAPI_event_info_t info;
00178 
00179     i = PAPI_PRESET_MASK;
00180     fprintf( f, "  <eventset type=\"PRESET\">\n" );
00181     num = -1;
00182     retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_FIRST, cidx );
00183 
00184     while ( retval == PAPI_OK ) {
00185        num++;
00186        retval = PAPI_get_event_info( i, &info );
00187        if ( retval != PAPI_OK ) {
00188          retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_EVENTS, cidx );
00189           continue;
00190        }
00191        if ( test_event( i ) == PAPI_OK ) {
00192           xmlize_event( f, &info, num );
00193           fprintf( f, "    </event>\n" );
00194        }
00195        retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_EVENTS, cidx );
00196     }
00197     fprintf( f, "  </eventset>\n" );
00198 }
00199 
00200 /****************************************/
00201 /* Print all native events              */
00202 /****************************************/
00203 
00204 static void
00205 enum_native_events( FILE * f, int cidx)
00206 {
00207     int i, k, num;
00208     int retval;
00209     PAPI_event_info_t info;
00210 
00211     i = PAPI_NATIVE_MASK;
00212     fprintf( f, "  <eventset type=\"NATIVE\">\n" );
00213     num = -1;
00214     retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_FIRST, cidx );
00215 
00216     while ( retval == PAPI_OK ) {
00217 
00218        num++;
00219        retval = PAPI_get_event_info( i, &info );
00220        if ( retval != PAPI_OK ) {
00221           retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_EVENTS, cidx );
00222           continue;
00223        }
00224             
00225        /* enumerate any umasks */
00226        k = i;
00227        if ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cidx ) == PAPI_OK ) {
00228          
00229           /* Test if event can be added */
00230           if ( test_event( k ) == PAPI_OK ) {
00231 
00232          /* add the event */
00233          xmlize_event( f, &info, num );
00234             
00235          /* add the event's unit masks */
00236          do {
00237             retval = PAPI_get_event_info( k, &info );
00238             if ( retval == PAPI_OK ) {
00239                if ( test_event( k )!=PAPI_OK ) {
00240              retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_EVENTS, cidx );
00241               continue;
00242                }
00243                xmlize_event( f, &info, -1 );
00244             }
00245          } while ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cidx ) == PAPI_OK);
00246          fprintf( f, "    </event>\n" );
00247           }
00248        } else {      
00249               /* this event has no unit masks; test & write the event */
00250           if ( test_event( i ) == PAPI_OK ) {
00251          xmlize_event( f, &info, num );
00252          fprintf( f, "    </event>\n" );
00253           }
00254        }
00255        retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_EVENTS, cidx );
00256     }
00257     fprintf( f, "  </eventset>\n" );
00258 }
00259 
00260 /****************************************/
00261 /* Print usage information              */
00262 /****************************************/
00263 
00264 static void
00265 usage( char *argv[] )
00266 {
00267     fprintf( stderr, "Usage: %s [options] [[event1] event2 ...]\n", argv[0] );
00268     fprintf( stderr, "     options: -h     print help message\n" );
00269     fprintf( stderr, "              -p     print only preset events\n" );
00270     fprintf( stderr, "              -n     print only native events\n" );
00271     fprintf( stderr,"              -c n   print only events for component index n\n" );
00272     fprintf( stderr, "If event1, event2, etc., are specified, then only events\n");
00273     fprintf( stderr, "that can be run in addition to these events will be printed\n\n");
00274 }
00275 
00276 static void
00277 parse_command_line (int argc, char **argv, int numc) {
00278 
00279   int i,retval;
00280 
00281      for( i = 1; i < argc; i++ ) {
00282     if ( argv[i][0] == '-' ) {
00283        switch ( argv[i][1] ) {
00284           case 'c': 
00285                          /* only events for specified component */
00286 
00287                          /* UGH, what is this, the IOCCC? */
00288                          cidx = (i+1) < argc ? atoi( argv[(i++)+1] ) : -1;
00289              if ( cidx < 0 || cidx >= numc ) {
00290                 fprintf( stderr,"Error: component index %d out of bounds (0..%d)\n",
00291                      cidx, numc - 1 );
00292                 usage( argv );
00293                 exit(1);
00294              }
00295              break;
00296 
00297           case 'p':
00298                  /* only preset events */
00299              preset = 1;
00300              native = 0;
00301              break;
00302 
00303           case 'n':
00304                  /* only native events */
00305              native = 1;
00306              preset = 0;
00307              break;
00308 
00309           case 'h':
00310                  /* print help */
00311              usage( argv );
00312              exit(0);
00313              break;
00314 
00315           default:
00316              fprintf( stderr, 
00317                      "Error: unknown option: %s\n", argv[i] );
00318              usage( argv );
00319              exit(1);
00320        }
00321     } else {
00322 
00323        /* If event names are specified, add them to the */
00324        /* EventSet and test if other events can be run with them */
00325 
00326        int code = -1;
00327 
00328        retval = PAPI_event_name_to_code( argv[i], &code );
00329        retval = PAPI_query_event( code );
00330        if ( retval != PAPI_OK ) {
00331           fprintf( stderr, "Error: unknown event: %s\n", argv[i] );
00332           usage( argv );
00333           exit(1);
00334        }
00335 
00336        retval = PAPI_add_event( EventSet, code );
00337        if ( retval != PAPI_OK ) {
00338           fprintf( stderr, 
00339                        "Error: event %s cannot be counted with others\n",
00340                argv[i] );
00341           usage( argv );
00342           exit(1);
00343        }
00344     }
00345      }
00346 
00347 }
00348 
00349 
00350 int
00351 main( int argc, char **argv)
00352 {
00353     int retval;
00354     const PAPI_component_info_t *comp;
00355 
00356     int numc = 0;
00357 
00358     /* Set TESTS_QUIET variable */
00359     tests_quiet( argc, argv );  
00360 
00361     retval = PAPI_library_init( PAPI_VER_CURRENT );
00362     if ( retval != PAPI_VER_CURRENT ) {
00363        test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
00364     }
00365 
00366     /* report any return codes less than 0? */
00367     /* Why? */
00368 #if 0
00369     retval = PAPI_set_debug( PAPI_VERB_ECONT );
00370     if ( retval != PAPI_OK ) {
00371        test_fail( __FILE__, __LINE__, "PAPI_set_debug", retval );
00372     }
00373 #endif
00374 
00375     /* Create EventSet to use */
00376     EventSet = PAPI_NULL;
00377 
00378     retval = PAPI_create_eventset( &EventSet  );
00379     if ( retval != PAPI_OK ) {
00380        test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
00381        return 1;
00382     }
00383 
00384     /* Get number of components */
00385     numc = PAPI_num_components(  );
00386 
00387     /* parse command line arguments */
00388         parse_command_line(argc,argv,numc);
00389 
00390     /* print XML header */
00391     fprintf( stdout, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
00392     fprintf( stdout, "<eventinfo>\n" );
00393 
00394 
00395     /* print hardware info */
00396     papi_xml_hwinfo( stdout );
00397 
00398     /* If a specific component specified, only print events from there */
00399     if ( cidx >= 0 ) {
00400        comp = PAPI_get_component_info( cidx );
00401 
00402        fprintf( stdout, "<component index=\"%d\" type=\"%s\" id=\"%s\">\n",
00403                 cidx, cidx ? "Unknown" : "CPU", comp->name );
00404 
00405        if ( native )
00406           enum_native_events( stdout, cidx);
00407        if ( preset )
00408           enum_preset_events( stdout, cidx);
00409 
00410        fprintf( stdout, "</component>\n" );
00411     } 
00412     else {
00413        /* Otherwise, print info for all components */
00414        for ( cidx = 0; cidx < numc; cidx++ ) {
00415            comp = PAPI_get_component_info( cidx );
00416 
00417            fprintf( stdout, "<component index=\"%d\" type=\"%s\" id=\"%s\">\n",
00418                 cidx, cidx ? "Unknown" : "CPU", comp->name );
00419 
00420            if ( native )
00421           enum_native_events( stdout, cidx );
00422            if ( preset )
00423           enum_preset_events( stdout, cidx );
00424 
00425            fprintf( stdout, "</component>\n" );
00426 
00427            /* clean out eventset */
00428            retval = PAPI_cleanup_eventset( EventSet );
00429            if ( retval != PAPI_OK )
00430           test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval );
00431            retval = PAPI_destroy_eventset( &EventSet );
00432            if ( retval != PAPI_OK )
00433           test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval );
00434            EventSet = PAPI_NULL;
00435 
00436            retval = PAPI_create_eventset( &EventSet  );
00437            if ( retval != PAPI_OK ) {
00438           test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );          }
00439 
00440            /* re-parse command line to set up any events specified */
00441            parse_command_line (argc, argv, numc);
00442            
00443 
00444        }
00445     }
00446     fprintf( stdout, "</eventinfo>\n" );
00447 
00448     return 0;
00449 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines