Blame src/utils/papi_xml_event_info.c

Packit 577717
/** file papi_xml_event_info.c
Packit 577717
 *     @page papi_xml_event_info
Packit 577717
 * @brief papi_xml_event_info utility.
Packit 577717
 *     @section  NAME
Packit 577717
 *             papi_xml_event_info - provides detailed information for PAPI events in XML format
Packit 577717
 *
Packit 577717
 *     @section Synopsis
Packit 577717
 *
Packit 577717
 *     @section Description
Packit 577717
 *             papi_native_avail is a PAPI utility program that reports information 
Packit 577717
 *             about the events available on the current platform in an XML format.
Packit 577717
 *
Packit 577717
 *             It will attempt to create an EventSet with each event in it, which
Packit 577717
 *             can be slow.
Packit 577717
 *
Packit 577717
 *     @section Options
Packit 577717
 *      
    Packit 577717
     *          
  • -h print help message
  • Packit 577717
     *          
  • -p print only preset events
  • Packit 577717
     *          
  • -n print only native events
  • Packit 577717
     *          
  • -c COMPONENT print only events from component number COMPONENT
  • Packit 577717
     * event1, event2, ...  Print only events that can be created in the same
    Packit 577717
     *      event set with the events event1, event2, etc.
    Packit 577717
     *       
    Packit 577717
     *
    Packit 577717
     *     @section Bugs
    Packit 577717
     *             There are no known bugs in this utility.
    Packit 577717
     *             If you find a bug, it should be reported to the
    Packit 577717
     *             PAPI Mailing List at <ptools-perfapi@icl.utk.edu>.
    Packit 577717
     */
    Packit 577717
    Packit 577717
    #include <stdio.h>
    Packit 577717
    #include <stdlib.h>
    Packit 577717
    Packit 577717
    #include "papi.h"
    Packit 577717
    Packit 577717
    static int EventSet;
    Packit 577717
    static int preset = 1;
    Packit 577717
    static int native = 1;
    Packit 577717
    static int cidx = -1;
    Packit 577717
    Packit 577717
    /**********************************************************************/
    Packit 577717
    /* Take a string and print a version with properly escaped XML        */
    Packit 577717
    /**********************************************************************/
    Packit 577717
    static int
    Packit 577717
    xmlize( const char *msg, FILE *f )
    Packit 577717
    {
    Packit 577717
    	const char *op;
    Packit 577717
    Packit 577717
    	if ( !msg )
    Packit 577717
    		return PAPI_OK;
    Packit 577717
    Packit 577717
    	for ( op = msg; *op != '\0'; op++ ) {
    Packit 577717
    		switch ( *op ) {
    Packit 577717
    		case '"':
    Packit 577717
    			fprintf( f, """ );
    Packit 577717
    			break;
    Packit 577717
    		case '&':
    Packit 577717
    			fprintf( f, "&" );
    Packit 577717
    			break;
    Packit 577717
    		case '\'':
    Packit 577717
    			fprintf( f, "'" );
    Packit 577717
    			break;
    Packit 577717
    		case '<':
    Packit 577717
    			fprintf( f, "<" );
    Packit 577717
    			break;
    Packit 577717
    		case '>':
    Packit 577717
    			fprintf( f, ">" );
    Packit 577717
    			break;
    Packit 577717
    		default:
    Packit 577717
    		        fprintf( f, "%c", *op);
    Packit 577717
    		}
    Packit 577717
    	}
    Packit 577717
    Packit 577717
    	return PAPI_OK;
    Packit 577717
    }
    Packit 577717
    Packit 577717
    /*************************************/
    Packit 577717
    /* print hardware info in XML format */
    Packit 577717
    /*************************************/
    Packit 577717
    static int
    Packit 577717
    papi_xml_hwinfo( FILE * f )
    Packit 577717
    {
    Packit 577717
    	const PAPI_hw_info_t *hwinfo;
    Packit 577717
    Packit 577717
    	if ( ( hwinfo = PAPI_get_hardware_info(  ) ) == NULL )
    Packit 577717
    		return PAPI_ESYS;
    Packit 577717
    Packit 577717
    	fprintf( f, "<hardware>\n" );
    Packit 577717
    Packit 577717
    	fprintf( f, "  
    Packit 577717
    	   xmlize( hwinfo->vendor_string, f );
    Packit 577717
    	   fprintf( f,"\"/>\n");
    Packit 577717
    	fprintf( f, "  <vendorCode value=\"%d\"/>\n", hwinfo->vendor );
    Packit 577717
    	fprintf( f, "  
    Packit 577717
    	xmlize( hwinfo->model_string, f );
    Packit 577717
    	   fprintf( f, "\"/>\n");
    Packit 577717
    	fprintf( f, "  <modelCode value=\"%d\"/>\n", hwinfo->model );
    Packit 577717
    	fprintf( f, "  <cpuRevision value=\"%f\"/>\n", hwinfo->revision );
    Packit 577717
    	fprintf( f, "  <cpuID>\n" );
    Packit 577717
    	fprintf( f, "    <family value=\"%d\"/>\n", hwinfo->cpuid_family );
    Packit 577717
    	fprintf( f, "    <model value=\"%d\"/>\n", hwinfo->cpuid_model );
    Packit 577717
    	fprintf( f, "    <stepping value=\"%d\"/>\n", hwinfo->cpuid_stepping );
    Packit 577717
    	fprintf( f, "  </cpuID>\n" );
    Packit 577717
    	fprintf( f, "  <cpuMaxMegahertz value=\"%d\"/>\n", hwinfo->cpu_max_mhz );
    Packit 577717
    	fprintf( f, "  <cpuMinMegahertz value=\"%d\"/>\n", hwinfo->cpu_min_mhz );
    Packit 577717
    	fprintf( f, "  <threads value=\"%d\"/>\n", hwinfo->threads );
    Packit 577717
    	fprintf( f, "  <cores value=\"%d\"/>\n", hwinfo->cores );
    Packit 577717
    	fprintf( f, "  <sockets value=\"%d\"/>\n", hwinfo->sockets );
    Packit 577717
    	fprintf( f, "  <nodes value=\"%d\"/>\n", hwinfo->nnodes );
    Packit 577717
    	fprintf( f, "  <cpuPerNode value=\"%d\"/>\n", hwinfo->ncpu );
    Packit 577717
    	fprintf( f, "  <totalCPUs value=\"%d\"/>\n", hwinfo->totalcpus );
    Packit 577717
    	fprintf( f, "</hardware>\n" );
    Packit 577717
    Packit 577717
    	return PAPI_OK;
    Packit 577717
    }
    Packit 577717
    Packit 577717
    Packit 577717
    Packit 577717
    /****************************************************************/
    Packit 577717
    /* Test if event can be added to an eventset                    */
    Packit 577717
    /* (there might be existing events if specified on command line */
    Packit 577717
    /****************************************************************/
    Packit 577717
    Packit 577717
    static int
    Packit 577717
    test_event( int evt )
    Packit 577717
    {
    Packit 577717
    	int retval;
    Packit 577717
    Packit 577717
    	retval = PAPI_add_event( EventSet, evt );
    Packit 577717
    	if ( retval != PAPI_OK ) {
    Packit 577717
    		return retval;
    Packit 577717
    	}
    Packit 577717
    Packit 577717
    	if ( ( retval = PAPI_remove_event( EventSet, evt ) ) != PAPI_OK ) {
    Packit 577717
    	   fprintf( stderr, "Error removing event from eventset\n" );
    Packit 577717
    	   exit( 1 );
    Packit 577717
    	}
    Packit 577717
    	return PAPI_OK;
    Packit 577717
    }
    Packit 577717
    Packit 577717
    /***************************************/
    Packit 577717
    /* Convert an event to XML             */
    Packit 577717
    /***************************************/
    Packit 577717
    Packit 577717
    static void
    Packit 577717
    xmlize_event( FILE * f, PAPI_event_info_t * info, int num )
    Packit 577717
    {
    Packit 577717
    Packit 577717
    	if ( num >= 0 ) {
    Packit 577717
    	   fprintf( f, "    
    Packit 577717
    	   xmlize( info->symbol, f );
    Packit 577717
    	   fprintf( f, "\" desc=\"");
    Packit 577717
    	   xmlize( info->long_descr, f );
    Packit 577717
    	   fprintf( f, "\">\n");
    Packit 577717
    	}
    Packit 577717
    	else {
    Packit 577717
    	   fprintf( f,"        
    Packit 577717
    	   xmlize( info->symbol, f );
    Packit 577717
    	   fprintf( f,"\" desc=\"");
    Packit 577717
    	   xmlize( info->long_descr, f );
    Packit 577717
    	   fprintf( f,"\"> </modifier>\n");
    Packit 577717
    	}
    Packit 577717
    Packit 577717
    }
    Packit 577717
    Packit 577717
    Packit 577717
    /****************************************/
    Packit 577717
    /* Print all preset events              */
    Packit 577717
    /****************************************/
    Packit 577717
    Packit 577717
    static void
    Packit 577717
    enum_preset_events( FILE * f, int cidx)
    Packit 577717
    {
    Packit 577717
    	int i, num;
    Packit 577717
    	int retval;
    Packit 577717
    	PAPI_event_info_t info;
    Packit 577717
    Packit 577717
    	i = PAPI_PRESET_MASK;
    Packit 577717
    	fprintf( f, "  <eventset type=\"PRESET\">\n" );
    Packit 577717
    	num = -1;
    Packit 577717
    	retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_FIRST, cidx );
    Packit 577717
    Packit 577717
    	while ( retval == PAPI_OK ) {
    Packit 577717
    	   num++;
    Packit 577717
    	   retval = PAPI_get_event_info( i, &info );
    Packit 577717
    	   if ( retval != PAPI_OK ) {
    Packit 577717
    	     retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_EVENTS, cidx );
    Packit 577717
    	      continue;
    Packit 577717
    	   }
    Packit 577717
    	   if ( test_event( i ) == PAPI_OK ) {
    Packit 577717
    	      xmlize_event( f, &info, num );
    Packit 577717
    	      fprintf( f, "    </event>\n" );
    Packit 577717
    	   }
    Packit 577717
    	   retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_EVENTS, cidx );
    Packit 577717
    	}
    Packit 577717
    	fprintf( f, "  </eventset>\n" );
    Packit 577717
    }
    Packit 577717
    Packit 577717
    /****************************************/
    Packit 577717
    /* Print all native events              */
    Packit 577717
    /****************************************/
    Packit 577717
    Packit 577717
    static void
    Packit 577717
    enum_native_events( FILE * f, int cidx)
    Packit 577717
    {
    Packit 577717
    	int i, k, num;
    Packit 577717
    	int retval;
    Packit 577717
    	PAPI_event_info_t info;
    Packit 577717
    Packit 577717
    	i = PAPI_NATIVE_MASK;
    Packit 577717
    	fprintf( f, "  <eventset type=\"NATIVE\">\n" );
    Packit 577717
    	num = -1;
    Packit 577717
    	retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_FIRST, cidx );
    Packit 577717
    Packit 577717
    	while ( retval == PAPI_OK ) {
    Packit 577717
    Packit 577717
    	   num++;
    Packit 577717
    	   retval = PAPI_get_event_info( i, &info );
    Packit 577717
    	   if ( retval != PAPI_OK ) {
    Packit 577717
    	      retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_EVENTS, cidx );
    Packit 577717
    	      continue;
    Packit 577717
    	   }
    Packit 577717
    Packit 577717
    	   /* enumerate any umasks */
    Packit 577717
    	   k = i;
    Packit 577717
    	   if ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cidx ) == PAPI_OK ) {
    Packit 577717
    Packit 577717
    	      /* Test if event can be added */
    Packit 577717
    	      if ( test_event( k ) == PAPI_OK ) {
    Packit 577717
    Packit 577717
    		 /* add the event */
    Packit 577717
    		 xmlize_event( f, &info, num );
    Packit 577717
    Packit 577717
    		 /* add the event's unit masks */
    Packit 577717
    		 do {
    Packit 577717
    		    retval = PAPI_get_event_info( k, &info );
    Packit 577717
    		    if ( retval == PAPI_OK ) {
    Packit 577717
    		       if ( test_event( k )!=PAPI_OK ) {
    Packit 577717
    			   break;
    Packit 577717
    		       }
    Packit 577717
    		       xmlize_event( f, &info, -1 );
    Packit 577717
    		    }
    Packit 577717
    		 } while ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cidx ) == PAPI_OK);
    Packit 577717
    		 fprintf( f, "    </event>\n" );
    Packit 577717
    	      }
    Packit 577717
    	   } else {
    Packit 577717
                  /* this event has no unit masks; test & write the event */
    Packit 577717
    	      if ( test_event( i ) == PAPI_OK ) {
    Packit 577717
    		 xmlize_event( f, &info, num );
    Packit 577717
    		 fprintf( f, "    </event>\n" );
    Packit 577717
    	      }
    Packit 577717
    	   }
    Packit 577717
    	   retval = PAPI_enum_cmp_event( &i, PAPI_ENUM_EVENTS, cidx );
    Packit 577717
    	}
    Packit 577717
    	fprintf( f, "  </eventset>\n" );
    Packit 577717
    }
    Packit 577717
    Packit 577717
    /****************************************/
    Packit 577717
    /* Print usage information              */
    Packit 577717
    /****************************************/
    Packit 577717
    Packit 577717
    static void
    Packit 577717
    usage( char *argv[] )
    Packit 577717
    {
    Packit 577717
    	fprintf( stderr, "Usage: %s [options] [[event1] event2 ...]\n", argv[0] );
    Packit 577717
    	fprintf( stderr, "     options: -h     print help message\n" );
    Packit 577717
    	fprintf( stderr, "              -p     print only preset events\n" );
    Packit 577717
    	fprintf( stderr, "              -n     print only native events\n" );
    Packit 577717
    	fprintf( stderr,"              -c n   print only events for component index n\n" );
    Packit 577717
    	fprintf( stderr, "If event1, event2, etc., are specified, then only events\n");
    Packit 577717
    	fprintf( stderr, "that can be run in addition to these events will be printed\n\n");
    Packit 577717
    }
    Packit 577717
    Packit 577717
    static void
    Packit 577717
    parse_command_line (int argc, char **argv, int numc) {
    Packit 577717
    Packit 577717
      int i,retval;
    Packit 577717
    Packit 577717
         for( i = 1; i < argc; i++ ) {
    Packit 577717
    	if ( argv[i][0] == '-' ) {
    Packit 577717
    	   switch ( argv[i][1] ) {
    Packit 577717
    	      case 'c':
    Packit 577717
          	                 /* only events for specified component */
    Packit 577717
    Packit 577717
                             /* UGH, what is this, the IOCCC? */
    Packit 577717
                             cidx = (i+1) < argc ? atoi( argv[(i++)+1] ) : -1;
    Packit 577717
    			 if ( cidx < 0 || cidx >= numc ) {
    Packit 577717
    			    fprintf( stderr,"Error: component index %d out of bounds (0..%d)\n",
    Packit 577717
    				     cidx, numc - 1 );
    Packit 577717
    			    usage( argv );
    Packit 577717
    			    exit(1);
    Packit 577717
    			 }
    Packit 577717
    			 break;
    Packit 577717
    Packit 577717
    	      case 'p':
    Packit 577717
    		         /* only preset events */
    Packit 577717
    			 preset = 1;
    Packit 577717
    			 native = 0;
    Packit 577717
    			 break;
    Packit 577717
    Packit 577717
    	      case 'n':
    Packit 577717
    		         /* only native events */
    Packit 577717
    			 native = 1;
    Packit 577717
    			 preset = 0;
    Packit 577717
    			 break;
    Packit 577717
    Packit 577717
    	      case 'h':
    Packit 577717
    		         /* print help */
    Packit 577717
    			 usage( argv );
    Packit 577717
    			 exit(0);
    Packit 577717
    			 break;
    Packit 577717
    Packit 577717
    	      default:
    Packit 577717
    			 fprintf( stderr, 
    Packit 577717
    				     "Error: unknown option: %s\n", argv[i] );
    Packit 577717
    			 usage( argv );
    Packit 577717
    			 exit(1);
    Packit 577717
    	   }
    Packit 577717
    	} else {
    Packit 577717
    Packit 577717
    	   /* If event names are specified, add them to the */
    Packit 577717
    	   /* EventSet and test if other events can be run with them */
    Packit 577717
    Packit 577717
    	   int code = -1;
    Packit 577717
    Packit 577717
    	   retval = PAPI_event_name_to_code( argv[i], &code );
    Packit 577717
    	   retval = PAPI_query_event( code );
    Packit 577717
    	   if ( retval != PAPI_OK ) {
    Packit 577717
    	      fprintf( stderr, "Error: unknown event: %s\n", argv[i] );
    Packit 577717
    	      usage( argv );
    Packit 577717
    	      exit(1);
    Packit 577717
    	   }
    Packit 577717
    Packit 577717
    	   retval = PAPI_add_event( EventSet, code );
    Packit 577717
    	   if ( retval != PAPI_OK ) {
    Packit 577717
    	      fprintf( stderr, 
    Packit 577717
                           "Error: event %s cannot be counted with others\n",
    Packit 577717
    		       argv[i] );
    Packit 577717
    	      usage( argv );
    Packit 577717
    	      exit(1);
    Packit 577717
    	   }
    Packit 577717
    	}
    Packit 577717
         }
    Packit 577717
    Packit 577717
    }
    Packit 577717
    Packit 577717
    Packit 577717
    int
    Packit 577717
    main( int argc, char **argv)
    Packit 577717
    {
    Packit 577717
    	int retval;
    Packit 577717
    	const PAPI_component_info_t *comp;
    Packit 577717
    Packit 577717
    	int numc = 0;
    Packit 577717
    Packit 577717
    	retval = PAPI_library_init( PAPI_VER_CURRENT );
    Packit 577717
    	if ( retval != PAPI_VER_CURRENT ) {
    Packit 577717
    		fprintf(stderr,"Error!  PAPI_library_init\n");
    Packit 577717
    		return retval;
    Packit 577717
    	}
    Packit 577717
    Packit 577717
    	/* report any return codes less than 0? */
    Packit 577717
    	/* Why? */
    Packit 577717
    #if 0
    Packit 577717
    	retval = PAPI_set_debug( PAPI_VERB_ECONT );
    Packit 577717
    	if ( retval != PAPI_OK ) {
    Packit 577717
    	   test_fail( __FILE__, __LINE__, "PAPI_set_debug", retval );
    Packit 577717
    	}
    Packit 577717
    #endif
    Packit 577717
    Packit 577717
    	/* Create EventSet to use */
    Packit 577717
    	EventSet = PAPI_NULL;
    Packit 577717
    Packit 577717
    	retval = PAPI_create_eventset( &EventSet  );
    Packit 577717
    	if ( retval != PAPI_OK ) {
    Packit 577717
    		fprintf(stderr,"Error!  PAPI_create_eventset\n");
    Packit 577717
    		return retval;
    Packit 577717
    	}
    Packit 577717
    Packit 577717
    	/* Get number of components */
    Packit 577717
    	numc = PAPI_num_components(  );
    Packit 577717
    Packit 577717
    	/* parse command line arguments */
    Packit 577717
            parse_command_line(argc,argv,numc);
    Packit 577717
    Packit 577717
    	/* print XML header */
    Packit 577717
    	fprintf( stdout, "\n" );
    Packit 577717
    	fprintf( stdout, "<eventinfo>\n" );
    Packit 577717
    Packit 577717
    Packit 577717
    	/* print hardware info */
    Packit 577717
    	papi_xml_hwinfo( stdout );
    Packit 577717
    Packit 577717
    	/* If a specific component specified, only print events from there */
    Packit 577717
    	if ( cidx >= 0 ) {
    Packit 577717
    	   comp = PAPI_get_component_info( cidx );
    Packit 577717
    Packit 577717
    	   fprintf( stdout, "<component index=\"%d\" type=\"%s\" id=\"%s\">\n",
    Packit 577717
    			    cidx, cidx ? "Unknown" : "CPU", comp->name );
    Packit 577717
    Packit 577717
    	   if ( native )
    Packit 577717
    	      enum_native_events( stdout, cidx);
    Packit 577717
    	   if ( preset )
    Packit 577717
    	      enum_preset_events( stdout, cidx);
    Packit 577717
    Packit 577717
    	   fprintf( stdout, "</component>\n" );
    Packit 577717
    	}
    Packit 577717
    	else {
    Packit 577717
    	   /* Otherwise, print info for all components */
    Packit 577717
    	   for ( cidx = 0; cidx < numc; cidx++ ) {
    Packit 577717
    	       comp = PAPI_get_component_info( cidx );
    Packit 577717
    Packit 577717
    	       fprintf( stdout, "<component index=\"%d\" type=\"%s\" id=\"%s\">\n",
    Packit 577717
    				cidx, cidx ? "Unknown" : "CPU", comp->name );
    Packit 577717
    Packit 577717
    	       if ( native )
    Packit 577717
    		  enum_native_events( stdout, cidx );
    Packit 577717
    	       if ( preset )
    Packit 577717
    		  enum_preset_events( stdout, cidx );
    Packit 577717
    Packit 577717
    	       fprintf( stdout, "</component>\n" );
    Packit 577717
    Packit 577717
    	       /* clean out eventset */
    Packit 577717
    	       retval = PAPI_cleanup_eventset( EventSet );
    Packit 577717
    	       if ( retval != PAPI_OK ) {
    Packit 577717
    			fprintf(stderr,"Error!  PAPI_cleanup_eventset\n");
    Packit 577717
    			return retval;
    Packit 577717
    		}
    Packit 577717
    	       retval = PAPI_destroy_eventset( &EventSet );
    Packit 577717
    	       if ( retval != PAPI_OK ) {
    Packit 577717
    			fprintf(stderr,"Error!  PAPI_destroy_eventset\n");
    Packit 577717
    			return retval;
    Packit 577717
    		}
    Packit 577717
    	       EventSet = PAPI_NULL;
    Packit 577717
    Packit 577717
    		retval = PAPI_create_eventset( &EventSet  );
    Packit 577717
    		if ( retval != PAPI_OK ) {
    Packit 577717
    			fprintf(stderr,"Error!  PAPI_create_eventset\n");
    Packit 577717
    			return retval;
    Packit 577717
    		}
    Packit 577717
    Packit 577717
    	       /* re-parse command line to set up any events specified */
    Packit 577717
    	       parse_command_line (argc, argv, numc);
    Packit 577717
    	   }
    Packit 577717
    	}
    Packit 577717
    	fprintf( stdout, "</eventinfo>\n" );
    Packit 577717
    Packit 577717
    	return 0;
    Packit 577717
    }