static int load_preset_table(char *pmu_name, int pmu_type, pfm_preset_search_entry_t *here) { char line[LINE_MAX]; char name[PATH_MAX] = "builtin papi_events_table"; char *tmp_papi_events_table = NULL; char *tmpn; FILE *table; int line_no = 1, derived = 0, insert = 0, preset = 0; int get_presets = 0; /* only get PRESETS after CPU is identified */ int found_presets = 0; /* only terminate search after PRESETS are found */ /* this allows support for synonyms for CPU names */ #ifdef SHOW_LOADS SUBDBG("%p\n",here); #endif /* here[0].preset = PAPI_TOT_CYC; here[0].derived = NOT_DERIVED; here[1].preset = PAPI_TOT_INS; here[1].derived = NOT_DERIVED; */ /* try the environment variable first */ if ((tmpn = getenv("PAPI_PERFMON_EVENT_FILE")) && (strlen(tmpn) != 0)) { sprintf(name,"%s",tmpn); table = fopen(name,"r"); } /* if no valid environment variable, look for built-in table */ else if (papi_events_table) { tmp_papi_events_table = papi_events_table; table = NULL; } /* if no env var and no built-in, search for default file */ else { #ifdef PAPI_DATADIR sprintf(name,"%s/%s",PAPI_DATADIR,PAPI_EVENT_FILE); #else sprintf(name,"%s",PAPI_EVENT_FILE); #endif table = open_event_table(name); } /* if no valid file or built-in table, bail */ if (table == NULL && tmp_papi_events_table == NULL) { PAPIERROR("fopen(%s): %s, please set the PAPI_PERFMON_EVENT_FILE env. variable",name,strerror(errno)); return(PAPI_ESYS); } /* at this point either a valid file pointer or built-in table pointer */ while (get_event_line(line, table, &tmp_papi_events_table)) { char *t; int i; t = trim_string(strtok(line,",")); if ((t == NULL) || (strlen(t) == 0)) continue; if (t[0] == '#') { /* SUBDBG("Comment found on line %d\n",line_no); */ goto nextline; } else if (strcasecmp(t,"CPU") == 0) { #ifdef SHOW_LOADS SUBDBG("CPU token found on line %d\n",line_no); #endif if (get_presets != 0 && found_presets != 0) { #ifdef SHOW_LOADS SUBDBG("Ending preset scanning at line %d of %s.\n",line_no,name); #endif goto done; } t = trim_string(strtok(NULL,",")); if ((t == NULL) || (strlen(t) == 0)) { PAPIERROR("Expected name after CPU token at line %d of %s -- ignoring",line_no,name); goto nextline; } #ifdef SHOW_LOADS SUBDBG("Examining CPU (%s) vs. (%s)\n",t,pmu_name); #endif if (strcasecmp(t, pmu_name) == 0) { int type; #ifdef SHOW_LOADS SUBDBG("Found CPU %s at line %d of %s.\n",t,line_no,name); #endif t = trim_string(strtok(NULL,",")); if ((t == NULL) || (strlen(t) == 0)) { #ifdef SHOW_LOADS SUBDBG("No additional qualifier found, matching on string.\n"); #endif get_presets = 1; } else if ((sscanf(t,"%d",&type) == 1) && (type == pmu_type)) { #ifdef SHOW_LOADS SUBDBG("Found CPU %s type %d at line %d of %s.\n",pmu_name,type,line_no,name); #endif get_presets = 1; } else #ifdef SHOW_LOADS SUBDBG("Additional qualifier match failed %d vs %d.\n",pmu_type,type) #endif ; } } else if (strcasecmp(t,"PRESET") == 0) { #ifdef SHOW_LOADS SUBDBG("PRESET token found on line %d\n",line_no); #endif if (get_presets == 0) goto nextline; found_presets = 1; t = trim_string(strtok(NULL,",")); if ((t == NULL) || (strlen(t) == 0)) { printf("Expected name after PRESET token at line %d of %s -- ignoring",line_no,name); goto nextline; } #ifdef SHOW_LOADS SUBDBG("Examining preset %s\n",t); #endif if (find_preset_code(t,&preset) != PAPI_OK) { PAPIERROR("Invalid preset name %s after PRESET token at line %d of %s -- ignoring",t,line_no,name); goto nextline; } #ifdef SHOW_LOADS SUBDBG("Found 0x%08x for %s\n",preset,t); #endif t = trim_string(strtok(NULL,",")); if ((t == NULL) || (strlen(t) == 0)) { PAPIERROR("Expected derived type after PRESET token at line %d of %s -- ignoring",line_no,name); goto nextline; } #ifdef SHOW_LOADS SUBDBG("Examining derived %s\n",t); #endif if (_papi_hwi_derived_type(t,&derived) != PAPI_OK) { PAPIERROR("Invalid derived name %s after PRESET token at line %d of %s -- ignoring",t,line_no,name); goto nextline; } #ifdef SHOW_LOADS SUBDBG("Found %d for %s\n",derived,t); SUBDBG("Adding 0x%x,%d to preset search table.\n",preset,derived); #endif here[insert].preset = preset; here[insert].derived = derived; #ifdef SHOW_LOADS SUBDBG("%d Adding 0x%x,%d to preset search table.\n",insert, here[insert].preset,here[insert].derived); #endif /* Derived support starts here */ /* Special handling for postfix */ if (derived == DERIVED_POSTFIX) { t = trim_string(strtok(NULL,",")); if ((t == NULL) || (strlen(t) == 0)) { PAPIERROR("Expected Operation string after derived type DERIVED_POSTFIX at line %d of %s -- ignoring",line_no,name); goto nextline; } #ifdef SHOW_LOADS SUBDBG("Saving PostFix operations %s\n",t); #endif here[insert].operation = strdup(t); } /* All derived terms collected here */ i = 0; do { t = trim_string(strtok(NULL,",")); if ((t == NULL) || (strlen(t) == 0)) break; if (strcasecmp(t,"NOTE") == 0) break; here[insert].findme[i] = strdup(t); #ifdef SHOW_LOADS SUBDBG("Adding term (%d) %s to preset event 0x%x.\n",i,t,preset); #endif } while (++i < MAX_COUNTER_TERMS); /* End of derived support */ if (i == 0) { PAPIERROR("Expected PFM event after DERIVED token at line %d of %s -- ignoring",line_no,name); goto nextline; } if (i == MAX_COUNTER_TERMS) t = trim_string(strtok(NULL,",")); /* Handle optional NOTEs */ if (t && (strcasecmp(t,"NOTE") == 0)) { #ifdef SHOW_LOADS SUBDBG("%s found on line %d\n",t,line_no); #endif t = trim_note(strtok(NULL,"")); /* read the rest of the line */ if ((t == NULL) || (strlen(t) == 0)) PAPIERROR("Expected Note string at line %d of %s\n",line_no,name); else { here[insert].note = strdup(t); #ifdef SHOW_LOADS SUBDBG("NOTE: --%s-- found on line %d\n",t,line_no); #endif } } insert++; } else { PAPIERROR("Unrecognized token %s at line %d of %s -- ignoring",t,line_no,name); goto nextline; } nextline: line_no++; } done: if (table) fclose(table); return(insert); }
int _papi_load_preset_table( char *pmu_str, int pmu_type, int cidx) { (void) cidx; /* We'll use this later */ char pmu_name[PAPI_MIN_STR_LEN]; char line[LINE_MAX]; char name[PATH_MAX] = "builtin papi_events_table"; char *tmp_papi_events_table = NULL; char *tmpn; FILE *table; int ret; unsigned int event_idx; int invalid_event; int line_no = 1, derived = 0, insert = 0, preset = 0; int get_presets = 0; /* only get PRESETS after CPU is identified */ int found_presets = 0; /* only terminate search after PRESETS are found */ /* this allows support for synonyms for CPU names*/ SUBDBG("ENTER\n"); /* copy the pmu identifier, stripping commas if found */ tmpn = pmu_name; while ( *pmu_str ) { if ( *pmu_str != ',' ) *tmpn++ = *pmu_str; pmu_str++; } *tmpn = '\0'; /* try the environment variable first */ if ( ( tmpn = getenv( "PAPI_CSV_EVENT_FILE" ) ) && ( strlen( tmpn ) != 0 ) ) { sprintf( name, "%s", tmpn ); table = fopen( name, "r" ); } /* if no valid environment variable, look for built-in table */ else if ( papi_events_table ) { tmp_papi_events_table = papi_events_table; table = NULL; } /* if no env var and no built-in, search for default file */ else { #ifdef PAPI_DATADIR sprintf( name, "%s/%s", PAPI_DATADIR, PAPI_EVENT_FILE ); #else sprintf( name, "%s", PAPI_EVENT_FILE ); #endif table = open_event_table( name ); } /* if no valid file or built-in table, bail */ if ( table == NULL && tmp_papi_events_table == NULL ) { PAPIERROR( "fopen(%s): %s, please set the PAPI_CSV_EVENT_FILE " "env. variable", name, strerror( errno ) ); return PAPI_ESYS; } /* at this point either a valid file pointer or built-in table pointer */ while ( get_event_line( line, table, &tmp_papi_events_table ) ) { char *t; int i; t = trim_string( strtok( line, "," ) ); /* Skip blank lines */ if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) continue; /* Skip comments */ if ( t[0] == '#' ) { goto nextline; } if ( strcasecmp( t, "CPU" ) == 0 ) { SUBDBG( "CPU token found on line %d\n", line_no ); if ( get_presets != 0 && found_presets != 0 ) { SUBDBG( "Ending preset scanning at line %d of %s.\n", line_no, name ); get_presets=0; found_presets=0; } t = trim_string( strtok( NULL, "," ) ); if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) { PAPIERROR( "Expected name after CPU token at line %d of %s " "-- ignoring", line_no, name ); goto nextline; } SUBDBG( "Examining CPU (%s) vs. (%s)\n", t, pmu_name ); if ( strcasecmp( t, pmu_name ) == 0 ) { int type; SUBDBG( "Found CPU %s at line %d of %s.\n", t, line_no, name ); t = trim_string( strtok( NULL, "," ) ); if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) { SUBDBG("No additional qualifier found, matching on string.\n"); get_presets = 1; } else if ( ( sscanf( t,"%d",&type )==1) && (type==pmu_type) ) { SUBDBG( "Found CPU %s type %d at line %d of %s.\n", pmu_name, type, line_no, name ); get_presets = 1; } else { SUBDBG( "Additional qualifier match failed %d vs %d.\n", pmu_type, type ); } } } else if ( strcasecmp( t, "PRESET" ) == 0 ) { if ( get_presets == 0 ) goto nextline; found_presets = 1; t = trim_string( strtok( NULL, "," ) ); if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) { PAPIERROR( "Expected name after PRESET token at line %d of %s " "-- ignoring", line_no, name ); goto nextline; } SUBDBG( "Examining preset %s\n", t ); if ( find_preset_code( t, &preset ) != PAPI_OK ) { PAPIERROR ( "Invalid preset name %s after PRESET token " "at line %d of %s -- ignoring", t, line_no, name ); goto nextline; } SUBDBG( "Found 0x%08x for %s\n", preset, t ); t = trim_string( strtok( NULL, "," ) ); if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) { PAPIERROR( "Expected derived type after PRESET token at " "line %d of %s -- ignoring", line_no, name ); goto nextline; } if ( _papi_hwi_derived_type( t, &derived ) != PAPI_OK ) { PAPIERROR( "Invalid derived name %s after PRESET token at " "line %d of %s -- ignoring", t, line_no, name ); goto nextline; } /****************************************/ /* Have a preset, let's start assigning */ /****************************************/ SUBDBG( "Found %d for %s\n", derived, t ); SUBDBG( "Adding 0x%x,%d to preset search table.\n", preset, derived ); insert=preset&PAPI_PRESET_AND_MASK; /* _papi_hwi_presets[insert].event_code = preset; */ _papi_hwi_presets[insert].derived_int = derived; /* Derived support starts here */ /* Special handling for postfix */ if ( derived == DERIVED_POSTFIX ) { t = trim_string( strtok( NULL, "," ) ); if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) { PAPIERROR( "Expected Operation string after derived type " "DERIVED_POSTFIX at line %d of %s -- ignoring", line_no, name ); goto nextline; } SUBDBG( "Saving PostFix operations %s\n", t ); _papi_hwi_presets[insert].postfix=strdup(t); } /* All derived terms collected here */ i = 0; invalid_event=0; do { t = trim_string( strtok( NULL, "," ) ); if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) break; if ( strcasecmp( t, "NOTE" ) == 0 ) break; _papi_hwi_presets[insert].name[i]=strdup(t); SUBDBG( "Adding term (%d) %s to preset event 0x%x.\n", i, t, preset ); SUBDBG("Looking up: %s\n",t); ret=_papi_hwd[cidx]->ntv_name_to_code(t, &event_idx); if (ret==PAPI_OK) { SUBDBG("Found %x\n",event_idx); _papi_hwi_presets[insert].code[i]=event_idx; } else { PAPIERROR("papi_preset: Error finding event %s",t); invalid_event=1; } } while ( ++i < PAPI_MAX_COUNTER_TERMS ); if (invalid_event) { /* We signify a valid preset if count > 0 */ _papi_hwi_presets[insert].count=0; } else { _papi_hwi_presets[insert].count=i; } /* End of derived support */ if ( i == 0 ) { PAPIERROR( "Expected PFM event after DERIVED token at " "line %d of %s -- ignoring", line_no, name ); goto nextline; } if ( i == PAPI_MAX_COUNTER_TERMS ) { t = trim_string( strtok( NULL, "," ) ); } /* Handle optional NOTEs */ if ( t && ( strcasecmp( t, "NOTE" ) == 0 ) ) { SUBDBG( "%s found on line %d\n", t, line_no ); /* read the rest of the line */ t = trim_note( strtok( NULL, "" ) ); if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) { PAPIERROR( "Expected Note string at line %d of %s\n", line_no, name ); } else { _papi_hwi_presets[insert].note = strdup( t ); SUBDBG( "NOTE: --%s-- found on line %d\n", t, line_no ); } } } else { PAPIERROR( "Unrecognized token %s at line %d of %s -- ignoring", t, line_no, name ); goto nextline; } nextline: line_no++; } if ( table ) { fclose( table ); } return PAPI_OK; }
static int papi_load_derived_events (char *pmu_str, int pmu_type, int cidx, int preset_flag) { SUBDBG( "ENTER: pmu_str: %s, pmu_type: %d, cidx: %d, preset_flag: %d\n", pmu_str, pmu_type, cidx, preset_flag); char pmu_name[PAPI_MIN_STR_LEN]; char line[LINE_MAX]; char name[PATH_MAX] = "builtin papi_events_table"; char *event_file_path=NULL; char *event_table_ptr=NULL; int event_type_bits = 0; char *tmpn; char *tok_save_ptr=NULL; FILE *event_file = NULL; hwi_presets_t *results=NULL; int result_size = 0; int *event_count = NULL; int invalid_event; int line_no = 0; /* count of lines read from event definition input */ int derived = 0; int res_idx = 0; /* index into results array for where to store next event */ int preset = 0; int get_events = 0; /* only process derived events after CPU type they apply to is identified */ int found_events = 0; /* flag to track if event definitions (PRESETS) are found since last CPU declaration */ #ifdef PAPI_DATADIR char path[PATH_MAX]; #endif if (preset_flag) { /* try the environment variable first */ if ((tmpn = getenv("PAPI_CSV_EVENT_FILE")) && (strlen(tmpn) > 0)) { event_file_path = tmpn; } /* if no valid environment variable, look for built-in table */ else if (papi_events_table) { event_table_ptr = papi_events_table; } /* if no env var and no built-in, search for default file */ else { #ifdef PAPI_DATADIR sprintf( path, "%s/%s", PAPI_DATADIR, PAPI_EVENT_FILE ); event_file_path = path; #else event_file_path = PAPI_EVENT_FILE; #endif } event_type_bits = PAPI_PRESET_MASK; results = &_papi_hwi_presets[0]; result_size = PAPI_MAX_PRESET_EVENTS; event_count = &_papi_hwd[cidx]->cmp_info.num_preset_events; } else { if ((event_file_path = getenv( "PAPI_USER_EVENTS_FILE" )) == NULL ) { SUBDBG("EXIT: User event definition file not provided.\n"); return PAPI_OK; } event_type_bits = PAPI_UE_MASK; results = &user_defined_events[0]; result_size = PAPI_MAX_USER_EVENTS; event_count = &user_defined_events_count; } // if we have an event file pathname, open it and read event definitions from the file if (event_file_path != NULL) { if ((event_file = open_event_table(event_file_path)) == NULL) { // if file open fails, return an error SUBDBG("EXIT: Event file open failed.\n"); return PAPI_ESYS; } strncpy(name, event_file_path, sizeof(name)-1); name[sizeof(name)-1] = '\0'; } else if (event_table_ptr == NULL) { // if we do not have a path name or table pointer, return an error SUBDBG("EXIT: Both event_file_path and event_table_ptr are NULL.\n"); return PAPI_ESYS; } /* copy the pmu identifier, stripping commas if found */ tmpn = pmu_name; while (*pmu_str) { if (*pmu_str != ',') *tmpn++ = *pmu_str; pmu_str++; } *tmpn = '\0'; /* at this point we have either a valid file pointer or built-in table pointer */ while (get_event_line(line, event_file, &event_table_ptr)) { char *t; int i; // increment number of lines we have read line_no++; t = trim_string(strtok_r(line, ",", &tok_save_ptr)); /* Skip blank lines */ if ((t == NULL) || (strlen(t) == 0)) continue; /* Skip comments */ if (t[0] == '#') { continue; } if (strcasecmp(t, "CPU") == 0) { if (get_events != 0 && found_events != 0) { SUBDBG( "Ending event scanning at line %d of %s.\n", line_no, name); get_events = 0; found_events = 0; } t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); if ((t == NULL) || (strlen(t) == 0)) { PAPIERROR("Expected name after CPU token at line %d of %s -- ignoring", line_no, name); continue; } if (strcasecmp(t, pmu_name) == 0) { int type; SUBDBG( "Process events for PMU %s found at line %d of %s.\n", t, line_no, name); t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); if ((t == NULL) || (strlen(t) == 0)) { SUBDBG("No additional qualifier found, matching on string.\n"); get_events = 1; } else if ((sscanf(t, "%d", &type) == 1) && (type == pmu_type)) { SUBDBG( "Found CPU %s type %d at line %d of %s.\n", pmu_name, type, line_no, name); get_events = 1; } else { SUBDBG( "Additional qualifier match failed %d vs %d.\n", pmu_type, type); } } continue; } if ((strcasecmp(t, "PRESET") == 0) || (strcasecmp(t, "EVENT") == 0)) { if (get_events == 0) continue; found_events = 1; t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); if ((t == NULL) || (strlen(t) == 0)) { PAPIERROR("Expected name after PRESET token at line %d of %s -- ignoring", line_no, name); continue; } SUBDBG( "Examining event %s\n", t); // see if this event already exists in the results array, if not already known it sets up event in unused entry if ((res_idx = find_event_index (results, result_size, t)) < 0) { PAPIERROR("No room left for event %s -- ignoring", t); continue; } // add the proper event bits (preset or user defined bits) preset = res_idx | event_type_bits; SUBDBG( "Use event code: %#x for %s\n", preset, t); t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); if ((t == NULL) || (strlen(t) == 0)) { // got an error, make this entry unused papi_free (results[res_idx].symbol); results[res_idx].symbol = NULL; PAPIERROR("Expected derived type after PRESET token at line %d of %s -- ignoring", line_no, name); continue; } if (_papi_hwi_derived_type(t, &derived) != PAPI_OK) { // got an error, make this entry unused papi_free (results[res_idx].symbol); results[res_idx].symbol = NULL; PAPIERROR("Invalid derived name %s after PRESET token at line %d of %s -- ignoring", t, line_no, name); continue; } /****************************************/ /* Have an event, let's start assigning */ /****************************************/ SUBDBG( "Adding event: %s, code: %#x, derived: %d results[%d]: %p.\n", t, preset, derived, res_idx, &results[res_idx]); /* results[res_idx].event_code = preset; */ results[res_idx].derived_int = derived; /* Derived support starts here */ /* Special handling for postfix and infix */ if ((derived == DERIVED_POSTFIX) || (derived == DERIVED_INFIX)) { t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); if ((t == NULL) || (strlen(t) == 0)) { // got an error, make this entry unused papi_free (results[res_idx].symbol); results[res_idx].symbol = NULL; PAPIERROR("Expected Operation string after derived type DERIVED_POSTFIX or DERIVED_INFIX at line %d of %s -- ignoring", line_no, name); continue; } // if it is an algebraic formula, we need to convert it to postfix if (derived == DERIVED_INFIX) { SUBDBG( "Converting InFix operations %s\n", t); t = infix_to_postfix( t ); results[res_idx].derived_int = DERIVED_POSTFIX; } SUBDBG( "Saving PostFix operations %s\n", t); results[res_idx].postfix = papi_strdup(t); } /* All derived terms collected here */ i = 0; invalid_event = 0; results[res_idx].count = 0; do { t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); if ((t == NULL) || (strlen(t) == 0)) break; if (strcasecmp(t, "NOTE") == 0) break; if (strcasecmp(t, "LDESC") == 0) break; if (strcasecmp(t, "SDESC") == 0) break; SUBDBG( "Adding term (%d) %s to derived event %#x, current native event count: %d.\n", i, t, preset, results[res_idx].count); // show that we do not have an event code yet (the component may create one and update this info) // this also clears any values left over from a previous call _papi_hwi_set_papi_event_code(-1, -1); // make sure that this term in the derived event is a valid event name // this call replaces preset and user event names with the equivalent native events in our results table // it also updates formulas for derived events so that they refer to the correct native event index if (is_event(t, results[res_idx].derived_int, &results[res_idx], i) == 0) { invalid_event = 1; PAPIERROR("Error finding event %s, it is used in derived event %s", t, results[res_idx].symbol); break; } i++; } while (results[res_idx].count < PAPI_EVENTS_IN_DERIVED_EVENT); /* preset code list must be PAPI_NULL terminated */ if (i < PAPI_EVENTS_IN_DERIVED_EVENT) { results[res_idx].code[results[res_idx].count] = PAPI_NULL; } if (invalid_event) { // got an error, make this entry unused papi_free (results[res_idx].symbol); results[res_idx].symbol = NULL; continue; } /* End of derived support */ // if we did not find any terms to base this derived event on, report error if (i == 0) { // got an error, make this entry unused papi_free (results[res_idx].symbol); results[res_idx].symbol = NULL; PAPIERROR("Expected PFM event after DERIVED token at line %d of %s -- ignoring", line_no, name); continue; } if (i == PAPI_EVENTS_IN_DERIVED_EVENT) { t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); } // if something was provided following the list of events to be used by the operation, process it if ( t!= NULL && strlen(t) > 0 ) { do { // save the field name char *fptr = papi_strdup(t); // get the value to be used with this field t = trim_note(strtok_r(NULL, ",", &tok_save_ptr)); if ( t== NULL || strlen(t) == 0 ) { papi_free(fptr); break; } // Handle optional short descriptions, long descriptions and notes if (strcasecmp(fptr, "SDESC") == 0) { results[res_idx].short_descr = papi_strdup(t); } if (strcasecmp(fptr, "LDESC") == 0) { results[res_idx].long_descr = papi_strdup(t); } if (strcasecmp(fptr, "NOTE") == 0) { results[res_idx].note = papi_strdup(t); } SUBDBG( "Found %s (%s) on line %d\n", fptr, t, line_no); papi_free (fptr); // look for another field name t = trim_string(strtok_r(NULL, ",", &tok_save_ptr)); if ( t== NULL || strlen(t) == 0 ) { break; } } while (t != NULL); } (*event_count)++; continue; } PAPIERROR("Unrecognized token %s at line %d of %s -- ignoring", t, line_no, name); } if (event_file) { fclose(event_file); } SUBDBG("EXIT: Done processing derived event file.\n"); return PAPI_OK; }