Add support for collecting PAPI native events
authordmp@rice.edu <unknown>
Tue, 22 Jun 2010 19:59:53 +0000 (19:59 +0000)
committerdmp@rice.edu <unknown>
Tue, 22 Jun 2010 19:59:53 +0000 (19:59 +0000)
This patch extends the PAPI support in the RTS to allow collection of native
events. PAPI can collect data for native events that are exposed by the
hardware beyond the PAPI present events. The native events supported on your
hardware can found by using the papi_native_avail tool.

The RTS already allows users to specify PAPI preset events from the command
line. This patch extends that support to allow users to specify native events.
The changes needed are:

1) New option (#) for the RTS PAPI flag for native events. For example, to
   collect the native event 0x40000000, use ./a.out +RTS -a#0x40000000 -sstderr

2) Update the PAPI_FLAGS struct to store whether the user specified event is a
   papi preset or a native event

3) Update init_countable_events function to add the native events after parsing
   the event code and decoding the name using PAPI_event_code_to_name

includes/rts/Flags.h
rts/Papi.c
rts/RtsFlags.c

index b861461..8bfadaa 100644 (file)
@@ -173,6 +173,8 @@ struct PAPI_FLAGS {
     nat     eventType;          /* The type of events to count */
     nat     numUserEvents;
     char *  userEvents[MAX_PAPI_USER_EVENTS];
+    /* Allow user to enter either PAPI preset or native events */
+    nat     userEventsKind[MAX_PAPI_USER_EVENTS];
 };
 
 #define PAPI_FLAG_CACHE_L1 1
@@ -181,6 +183,8 @@ struct PAPI_FLAGS {
 #define PAPI_FLAG_STALLS 4
 #define PAPI_FLAG_CB_EVENTS 5
 #define PAPI_USER_EVENTS 6
+#define PAPI_PRESET_EVENT_KIND 0
+#define PAPI_NATIVE_EVENT_KIND 1
 
 #endif
 
index 4d54c72..f726604 100644 (file)
@@ -74,6 +74,7 @@ int papi_error;
 
 /* Arbitrary, to avoid using malloc */
 #define MAX_PAPI_EVENTS 10
+static char papiNativeEventNames[MAX_PAPI_EVENTS][PAPI_MAX_STR_LEN];
 
 static nat n_papi_events = 0;
 
@@ -86,10 +87,10 @@ long_long GC0Counters[MAX_PAPI_EVENTS];
 long_long GC1Counters[MAX_PAPI_EVENTS];
 
 long_long start_mutator_cycles;
-long_long mutator_cycles;
+long_long mutator_cycles = 0;
 long_long start_gc_cycles;
-long_long gc0_cycles;
-long_long gc1_cycles;
+long_long gc0_cycles = 0;
+long_long gc1_cycles = 0;
 
 
 
@@ -145,11 +146,20 @@ init_countable_events(void)
     } else if (RtsFlags.PapiFlags.eventType==PAPI_USER_EVENTS) {
         nat i;
         char *name;
+        char *asciiEventCode;
         int code;
         for (i = 0; i < RtsFlags.PapiFlags.numUserEvents; i++) {
+          if(RtsFlags.PapiFlags.userEventsKind[i] == PAPI_PRESET_EVENT_KIND) {
             name = RtsFlags.PapiFlags.userEvents[i];
             PAPI_CHECK(PAPI_event_name_to_code(name, &code))
-            papi_add_event(name, code);
+          }
+          else { // PAPI_NATIVE_EVENT_KIND
+            asciiEventCode = RtsFlags.PapiFlags.userEvents[i];
+            name = papiNativeEventNames[i];
+            code = strtol(asciiEventCode, NULL, 16 /* hex number expected */);
+            PAPI_CHECK(PAPI_event_code_to_name(code, name))
+          }
+          papi_add_event(name, code);
         }
     } else {
        // PAPI_ADD_EVENT(PAPI_L1_DCA); // L1 data cache accesses
index 0bd1b04..5eb7800 100644 (file)
@@ -340,6 +340,8 @@ usage_text[] = {
 "            b - branch mispredictions",
 "            s - stalled cycles",
 "            e - cache miss and branch misprediction events",
+"            +PAPI_EVENT   - collect papi preset event PAPI_EVENT",
+"            #NATIVE_EVENT - collect native event NATIVE_EVENT (in hex)",
 #endif
 "",
 "RTS options may also be specified using the GHCRTS environment variable.",
@@ -577,12 +579,18 @@ error = rtsTrue;
                  RtsFlags.PapiFlags.eventType = PAPI_FLAG_CB_EVENTS;
                  break;
                 case '+':
+                case '#':
                   if (RtsFlags.PapiFlags.numUserEvents >= MAX_PAPI_USER_EVENTS) {
                       errorBelch("maximum number of PAPI events reached");
                       stg_exit(EXIT_FAILURE);
                   }
+                  nat eventNum  = RtsFlags.PapiFlags.numUserEvents++;
+                  char kind     = rts_argv[arg][2];
+                  nat eventKind = kind == '+' ? PAPI_PRESET_EVENT_KIND : PAPI_NATIVE_EVENT_KIND;
+
+                  RtsFlags.PapiFlags.userEvents[eventNum] = rts_argv[arg] + 3;
                   RtsFlags.PapiFlags.eventType = PAPI_USER_EVENTS;
-                  RtsFlags.PapiFlags.userEvents[RtsFlags.PapiFlags.numUserEvents++] = rts_argv[arg] + 3;
+                  RtsFlags.PapiFlags.userEventsKind[eventNum] = eventKind;
                   break;
                default:
                  bad_option( rts_argv[arg] );