From 62dceb9bf350941f05bd4ee0a570c6adc17cbff0 Mon Sep 17 00:00:00 2001
From: Heike Jagode <jagode@eecs.utk.edu>
Date: Thu, 28 Aug 2014 19:19:03 -0400
Subject: [PATCH 22/44] Extend 'papi_native_event --validate' to check for
 umasks.

---
 src/utils/native_avail.c | 428 ++++++++++++++++++++++++-----------------------
 1 file changed, 223 insertions(+), 205 deletions(-)

diff --git a/src/utils/native_avail.c b/src/utils/native_avail.c
index 59fc1b4..07a9745 100644
--- a/src/utils/native_avail.c
+++ b/src/utils/native_avail.c
@@ -1,45 +1,45 @@
 /* This file utility reports hardware info and native event availability */
 /** file native_avail.c
-  *	@page papi_native_avail
-  * @brief papi_native_avail utility. 
-  *	@section  NAME
-  *		papi_native_avail - provides detailed information for PAPI native events. 
-  *
-  *	@section Synopsis
-  *
-  *	@section Description
-  *		papi_native_avail is a PAPI utility program that reports information 
-  *		about the native events available on the current platform. 
-  *		A native event is an event specific to a specific hardware platform. 
-  *		On many platforms, a specific native event may have a number of optional settings. 
-  *		In such cases, the native event and the valid settings are presented, 
-  *		rather than every possible combination of those settings. 
-  *		For each native event, a name, a description, and specific bit patterns are provided.
-  *
-  *	@section Options
-  * <ul>
-  * <li>--help, -h    print this help message
-  * <li>-d            display detailed information about native events
-  * <li>-e EVENTNAME  display detailed information about named native event
-  * <li>-i EVENTSTR   include only event names that contain EVENTSTR
-  * <li>-x EVENTSTR   exclude any event names that contain EVENTSTR
-  * <li>--noumasks    suppress display of Unit Mask information
-  * </ul>
-  *
-  * Processor-specific options
-  * <ul>
-  * <li>--darr        display events supporting Data Address Range Restriction
-  * <li>--dear        display Data Event Address Register events only
-  * <li>--iarr        display events supporting Instruction Address Range Restriction
-  * <li>--iear        display Instruction Event Address Register events only
-  * <li>--opcm        display events supporting OpCode Matching
-  * <li>--nogroups    suppress display of Event grouping information
-  * </ul> 
-  *
-  *	@section Bugs
-  *		There are no known bugs in this utility. 
-  *		If you find a bug, it should be reported to the 
-  *		PAPI Mailing List at <ptools-perfapi@ptools.org>. 
+ *	@page papi_native_avail
+ * @brief papi_native_avail utility. 
+ *	@section  NAME
+ *		papi_native_avail - provides detailed information for PAPI native events. 
+ *
+ *	@section Synopsis
+ *
+ *	@section Description
+ *		papi_native_avail is a PAPI utility program that reports information 
+ *		about the native events available on the current platform. 
+ *		A native event is an event specific to a specific hardware platform. 
+ *		On many platforms, a specific native event may have a number of optional settings. 
+ *		In such cases, the native event and the valid settings are presented, 
+ *		rather than every possible combination of those settings. 
+ *		For each native event, a name, a description, and specific bit patterns are provided.
+ *
+ *	@section Options
+ * <ul>
+ * <li>--help, -h    print this help message
+ * <li>-d            display detailed information about native events
+ * <li>-e EVENTNAME  display detailed information about named native event
+ * <li>-i EVENTSTR   include only event names that contain EVENTSTR
+ * <li>-x EVENTSTR   exclude any event names that contain EVENTSTR
+ * <li>--noumasks    suppress display of Unit Mask information
+ * </ul>
+ *
+ * Processor-specific options
+ * <ul>
+ * <li>--darr        display events supporting Data Address Range Restriction
+ * <li>--dear        display Data Event Address Register events only
+ * <li>--iarr        display events supporting Instruction Address Range Restriction
+ * <li>--iear        display Instruction Event Address Register events only
+ * <li>--opcm        display events supporting OpCode Matching
+ * <li>--nogroups    suppress display of Event grouping information
+ * </ul> 
+ *
+ *	@section Bugs
+ *		There are no known bugs in this utility. 
+ *		If you find a bug, it should be reported to the 
+ *		PAPI Mailing List at <ptools-perfapi@ptools.org>. 
  */
 
 #include "papi_test.h"
@@ -83,7 +83,7 @@ print_help( char **argv )
 	printf( "  --dear        display Data Event Address Register events only\n" );
 	printf( "  --iarr        display events supporting Instruction Address Range Restriction\n" );
 	printf( "  --iear        display Instruction Event Address Register events only\n" );
-    printf( "  --opcm        display events supporting OpCode Matching\n" );
+	printf( "  --opcm        display events supporting OpCode Matching\n" );
 	printf( "  --nogroups    suppress display of Event grouping information\n" );
 	printf( "\n" );
 }
@@ -97,7 +97,6 @@ no_str_arg( char *arg )
 static void
 parse_args( int argc, char **argv, command_flags_t * f )
 {
-
 	int i;
 
 	/* Look for all currently defined commands */
@@ -170,14 +169,13 @@ space_pad( char *str, int spaces )
 		strcat( str, " " );
 }
 
-static void
-print_event( PAPI_event_info_t * info, int offset, int validate )
+static int
+validate_event( PAPI_event_info_t * info )
 {
-	unsigned int i, j = 0, na = 0;
-	char str[EVT_LINE + EVT_LINE];
+	unsigned int na = 0;
 	int EventSet = PAPI_NULL;
 
-	if (validate && PAPI_create_eventset (&EventSet) == PAPI_OK) {
+	if (PAPI_create_eventset (&EventSet) == PAPI_OK) {
 		if (PAPI_add_named_event (EventSet, info->symbol) == PAPI_OK) {
 			PAPI_remove_named_event (EventSet, info->symbol);
 		} else {
@@ -189,45 +187,54 @@ print_event( PAPI_event_info_t * info, int offset, int validate )
 		}
 	}
 
+	return na;
+}
+
+static void
+print_event( PAPI_event_info_t * info, int offset, int validate, int na )
+{
+	unsigned int i, j = 0;
+	char str[EVT_LINE + EVT_LINE];
+
 	/* indent by offset */
 	if ( offset ) {
-	   printf( "|     %-69s%4s|\n", info->symbol, (na ? "<NA>" : "") );
+		printf( "|     %-69s%4s|\n", info->symbol, ((validate && na) ? "<NA>" : "") );
 	}
 	else {
-	   printf( "| %-73s%4s|\n", info->symbol, (na ? "<NA>" : "") );
+		printf( "| %-73s%4s|\n", info->symbol, ((validate && na) ? "<NA>" : "") );
 	}
 
 	while ( j <= strlen( info->long_descr ) ) {
-	   i = EVT_LINE - 12 - 2;
-	   if ( i > 0 ) {
-	      str[0] = 0;
-	      strcat(str,"| " );
-	      space_pad( str, 11 );
-	      strncat( str, &info->long_descr[j], i );
-	      j += i;
-	      i = ( unsigned int ) strlen( str );
-	      space_pad( str, EVT_LINE - ( int ) i - 1 );
-	      strcat( str, "|" );
-	   }
-	   printf( "%s\n", str );
+		i = EVT_LINE - 12 - 2;
+		if ( i > 0 ) {
+			str[0] = 0;
+			strcat(str,"| " );
+			space_pad( str, 11 );
+			strncat( str, &info->long_descr[j], i );
+			j += i;
+			i = ( unsigned int ) strlen( str );
+			space_pad( str, EVT_LINE - ( int ) i - 1 );
+			strcat( str, "|" );
+		}
+		printf( "%s\n", str );
 	}
 }
 
 static int
 parse_unit_masks( PAPI_event_info_t * info )
 {
-  char *pmask,*ptr;
-
-  /* handle the PAPI component-style events which have a component:::event type */
-  if ((ptr=strstr(info->symbol, ":::"))) {
-    ptr+=3;
-  /* handle libpfm4-style events which have a pmu::event type event name */
-  } else if ((ptr=strstr(info->symbol, "::"))) {
-    ptr+=2;
-  }
-  else {
-    ptr=info->symbol;
-  }
+	char *pmask,*ptr;
+
+	/* handle the PAPI component-style events which have a component:::event type */
+	if ((ptr=strstr(info->symbol, ":::"))) {
+		ptr+=3;
+		/* handle libpfm4-style events which have a pmu::event type event name */
+	} else if ((ptr=strstr(info->symbol, "::"))) {
+		ptr+=2;
+	}
+	else {
+		ptr=info->symbol;
+	}
 
 	if ( ( pmask = strchr( ptr, ':' ) ) == NULL ) {
 		return ( 0 );
@@ -287,10 +294,10 @@ main( int argc, char **argv )
 
 
 	if ( !TESTS_QUIET ) {
-	   retval = PAPI_set_debug( PAPI_VERB_ECONT );
-	   if ( retval != PAPI_OK ) {
-	      test_fail( __FILE__, __LINE__, "PAPI_set_debug", retval );
-	   }
+		retval = PAPI_set_debug( PAPI_VERB_ECONT );
+		if ( retval != PAPI_OK ) {
+			test_fail( __FILE__, __LINE__, "PAPI_set_debug", retval );
+		}
 	}
 
 	retval = papi_print_header( "Available native events and hardware information.\n", &hwinfo );
@@ -300,149 +307,160 @@ main( int argc, char **argv )
 
 	/* Do this code if the event name option was specified on the commandline */
 	if ( flags.named ) {
-	   if ( PAPI_event_name_to_code( flags.name, &i ) == PAPI_OK ) {
-	      if ( PAPI_get_event_info( i, &info ) == PAPI_OK ) {
-		 printf( "%-30s%s\n",
-			 "Event name:", info.symbol);
-		 printf( "%-29s|%s|\n", "Description:", info.long_descr );
-
-		  /* handle the PAPI component-style events which have a component:::event type */
-		  char *ptr;
-		  if ((ptr=strstr(flags.name, ":::"))) {
-		    ptr+=3;
-		  /* handle libpfm4-style events which have a pmu::event type event name */
-		  } else if ((ptr=strstr(flags.name, "::"))) {
-		    ptr+=2;
-		  }
-		  else {
-		    ptr=flags.name;
-		  }
-
-		     /* if unit masks exist but none specified, process all */
-		     if ( !strchr( ptr, ':' ) ) {
-			if ( PAPI_enum_event( &i, PAPI_NTV_ENUM_UMASKS ) == PAPI_OK ) {
-			   printf( "\nUnit Masks:\n" );
-			   do {
-			      retval = PAPI_get_event_info( i, &info );
-			      if ( retval == PAPI_OK ) {
-				 if ( parse_unit_masks( &info ) ) {
-				    printf( "%-29s|%s|%s|\n", " Mask Info:",
-					    info.symbol, info.long_descr );
-				 }
-			      }
-			   } while ( PAPI_enum_event( &i, PAPI_NTV_ENUM_UMASKS ) == PAPI_OK );
+		if ( PAPI_event_name_to_code( flags.name, &i ) == PAPI_OK ) {
+			if ( PAPI_get_event_info( i, &info ) == PAPI_OK ) {
+				printf( "%-30s%s\n",
+						"Event name:", info.symbol);
+				printf( "%-29s|%s|\n", "Description:", info.long_descr );
+
+				/* handle the PAPI component-style events which have a component:::event type */
+				char *ptr;
+				if ((ptr=strstr(flags.name, ":::"))) {
+					ptr+=3;
+					/* handle libpfm4-style events which have a pmu::event type event name */
+				} else if ((ptr=strstr(flags.name, "::"))) {
+					ptr+=2;
+				}
+				else {
+					ptr=flags.name;
+				}
+
+				/* if unit masks exist but none specified, process all */
+				if ( !strchr( ptr, ':' ) ) {
+					if ( PAPI_enum_event( &i, PAPI_NTV_ENUM_UMASKS ) == PAPI_OK ) {
+						printf( "\nUnit Masks:\n" );
+						do {
+							retval = PAPI_get_event_info( i, &info );
+							if ( retval == PAPI_OK ) {
+								if ( parse_unit_masks( &info ) ) {
+									printf( "%-29s|%s|%s|\n", " Mask Info:",
+											info.symbol, info.long_descr );
+								}
+							}
+						} while ( PAPI_enum_event( &i, PAPI_NTV_ENUM_UMASKS ) == PAPI_OK );
+					}
+				}
 			}
-		     }
-	      }
-	   } else {
-	     printf("Sorry, an event by the name '%s' could not be found.\n",
-		    flags.name);
-	     printf("Is it typed correctly?\n\n");
-	     exit( 1 );
-	   }
+		} else {
+			printf("Sorry, an event by the name '%s' could not be found.\n",
+					flags.name);
+			printf("Is it typed correctly?\n\n");
+			exit( 1 );
+		}
 	}
-    else {
-
-	   /* Print *ALL* available events */
-
-	   numcmp = PAPI_num_components(  );
-
-	   j = 0;
-
-	   for ( cid = 0; cid < numcmp; cid++ ) {
+	else {
 
-	       const PAPI_component_info_t *component;
-	       component=PAPI_get_component_info(cid);
+		/* Print *ALL* available events */
 
-	       /* Skip disabled components */
-	       if (component->disabled) continue;
+		numcmp = PAPI_num_components(  );
 
-	       printf( "===============================================================================\n" );
-	       printf( " Native Events in Component: %s\n",component->name);
-	       printf( "===============================================================================\n" );
-	     
-	       /* Always ASK FOR the first event */
-	       /* Don't just assume it'll be the first numeric value */
-	       i = 0 | PAPI_NATIVE_MASK;
+		j = 0;
 
-	       retval=PAPI_enum_cmp_event( &i, PAPI_ENUM_FIRST, cid );
+		for ( cid = 0; cid < numcmp; cid++ ) {
 
-	       if (retval==PAPI_OK) 
+			const PAPI_component_info_t *component;
+			component=PAPI_get_component_info(cid);
 
-	       do {
-			  memset( &info, 0, sizeof ( info ) );
-			  retval = PAPI_get_event_info( i, &info );
+			/* Skip disabled components */
+			if (component->disabled) continue;
 
-			  /* This event may not exist */
-			  if ( retval != PAPI_OK )
-				 continue;
+			printf( "===============================================================================\n" );
+			printf( " Native Events in Component: %s\n",component->name);
+			printf( "===============================================================================\n" );
 
-			  /* Bail if event name doesn't contain include string */
-			  if ( flags.include ) {
-			  	 if ( !strstr( info.symbol, flags.istr ) ) {
-				 	continue;
-				 }
-			  }
+			/* Always ASK FOR the first event */
+			/* Don't just assume it'll be the first numeric value */
+			i = 0 | PAPI_NATIVE_MASK;
 
-			  /* Bail if event name does contain exclude string */
-			  if ( flags.xclude ) {
-			  	 if ( strstr( info.symbol, flags.xstr ) )
-				 	continue;
-			  }
-			  
-			  /* count only events that are actually processed */
-			  j++;
+			retval=PAPI_enum_cmp_event( &i, PAPI_ENUM_FIRST, cid );
 
-			  print_event( &info, 0, flags.validate );
+			if (retval==PAPI_OK) 
 
-			  if (flags.details) {
-				if (info.units[0]) printf( "|     Units: %-67s|\n", 
-							   info.units );
-			  }
+				do {
+					memset( &info, 0, sizeof ( info ) );
+					retval = PAPI_get_event_info( i, &info );
+
+					/* This event may not exist */
+					if ( retval != PAPI_OK )
+						continue;
+
+					/* Bail if event name doesn't contain include string */
+					if ( flags.include ) {
+						if ( !strstr( info.symbol, flags.istr ) ) {
+							continue;
+						}
+					}
+
+					/* Bail if event name does contain exclude string */
+					if ( flags.xclude ) {
+						if ( strstr( info.symbol, flags.xstr ) )
+							continue;
+					}
+
+					/* count only events that are actually processed */
+					j++;
+
+					if (flags.validate){
+						retval = validate_event(&info);
+					} else {
+						retval = 0;
+					}
+
+					print_event( &info, 0, flags.validate, retval );
+
+					if (flags.details) {
+						if (info.units[0]) printf( "|     Units: %-67s|\n", 
+								info.units );
+					}
+
+					/*		modifier = PAPI_NTV_ENUM_GROUPS returns event codes with a
+							groups id for each group in which this
+							native event lives, in bits 16 - 23 of event code
+							terminating with PAPI_ENOEVNT at the end of the list.
+							*/
+
+					/* This is an IBM Power issue */
+					if ( flags.groups ) {
+						k = i;
+						if ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_GROUPS, cid ) == PAPI_OK ) {
+							printf( "Groups: " );
+							do {
+								printf( "%4d", ( ( k & PAPI_NTV_GROUP_AND_MASK ) >>
+											PAPI_NTV_GROUP_SHIFT ) - 1 );
+							} while ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_GROUPS, cid ) ==PAPI_OK );
+							printf( "\n" );
+						}
+					}
+
+					/* Print umasks */
+					/* components that don't have them can just ignore */
+
+					if ( flags.umask ) { 
+						k = i;
+						if ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cid ) == PAPI_OK ) {
+							do {
+								retval = PAPI_get_event_info( k, &info );
+								if ( retval == PAPI_OK ) {
+									if (flags.validate){
+										retval = validate_event(&info);
+									} else {
+										retval = 0; 
+									}
+									if ( parse_unit_masks( &info ) )
+										print_event( &info, 2, flags.validate, retval );
+								}
+							} while ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cid ) == PAPI_OK );
+						}
+
+					}
+					printf( "--------------------------------------------------------------------------------\n" );
+
+				} while (PAPI_enum_cmp_event( &i, enum_modifier, cid ) == PAPI_OK );
+		}
 
-/*		modifier = PAPI_NTV_ENUM_GROUPS returns event codes with a
-			groups id for each group in which this
-			native event lives, in bits 16 - 23 of event code
-			terminating with PAPI_ENOEVNT at the end of the list.
-*/
 
-			  /* This is an IBM Power issue */
-			  if ( flags.groups ) {
-				 k = i;
-				 if ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_GROUPS, cid ) == PAPI_OK ) {
-				printf( "Groups: " );
-				do {
-				  printf( "%4d", ( ( k & PAPI_NTV_GROUP_AND_MASK ) >>
-							 PAPI_NTV_GROUP_SHIFT ) - 1 );
-				} while ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_GROUPS, cid ) ==PAPI_OK );
-				printf( "\n" );
-				 }
-			  }
-
-			  /* Print umasks */
-			  /* components that don't have them can just ignore */
-
-				  if ( flags.umask ) { 
-				 k = i;
-				 if ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cid ) == PAPI_OK ) {
-					do {
-				   retval = PAPI_get_event_info( k, &info );
-				   if ( retval == PAPI_OK ) {
-					  if ( parse_unit_masks( &info ) )
-						 print_event( &info, 2, 0 );
-				   }
-					} while ( PAPI_enum_cmp_event( &k, PAPI_NTV_ENUM_UMASKS, cid ) == PAPI_OK );
-				 }
-
-			  }
-			  printf( "--------------------------------------------------------------------------------\n" );
-
-	       } while (PAPI_enum_cmp_event( &i, enum_modifier, cid ) == PAPI_OK );
-	   }
-	   	   	
-	
-	   printf("\n");
-	   printf( "Total events reported: %d\n", j );
+		printf("\n");
+		printf( "Total events reported: %d\n", j );
 	}
 
 	test_pass( __FILE__, NULL, 0 );
-- 
2.1.1

