PAPI 7.1.0.0
Loading...
Searching...
No Matches
papi_preset.c File Reference
Include dependency graph for papi_preset.c:

Go to the source code of this file.

Macros

#define PAPI_EVENT_FILE   "papi_events.csv"
 

Functions

static int papi_load_derived_events (char *pmu_str, int pmu_type, int cidx, int preset_flag)
 
int _papi_hwi_setup_all_presets (hwi_search_t *findem, int cidx)
 
int _papi_hwi_cleanup_all_presets (void)
 
static char * trim_string (char *in)
 
static char * trim_note (char *in)
 
static int find_event_index (hwi_presets_t *array, int size, char *tmp)
 
static FILE * open_event_table (char *name)
 
static int get_event_line (char *line, FILE *table, char **tmp_perfmon_events_table)
 
static void update_ops_string (char **formula, int old_index, int new_index)
 
static void ops_string_append (hwi_presets_t *results, hwi_presets_t *depends_on, int addition)
 
static void ops_string_merge (char **original, char *insertion, int replaces, int start_index)
 
static int check_derived_events (char *target, int derived_type, hwi_presets_t *results, hwi_presets_t *search, int search_size, int token_index)
 
static int check_native_events (char *target, hwi_presets_t *results)
 
static int is_event (char *event_name, int derived_type, hwi_presets_t *results, int token_index)
 
int _papi_load_preset_table (char *pmu_str, int pmu_type, int cidx)
 
static int priority (char symbol)
 
static int push (char symbol)
 
static char pop ()
 
static char * infix_to_postfix (char *infix)
 

Variables

hwi_presets_t user_defined_events []
 
int user_defined_events_count
 
static char * papi_events_table = NULL
 
static char stack [2 *PAPI_HUGE_STR_LEN]
 
static int stacktop = -1
 

Macro Definition Documentation

◆ PAPI_EVENT_FILE

#define PAPI_EVENT_FILE   "papi_events.csv"

Definition at line 151 of file papi_preset.c.

Function Documentation

◆ _papi_hwi_cleanup_all_presets()

int _papi_hwi_cleanup_all_presets ( void  )

Definition at line 114 of file papi_preset.c.

115{
116 int preset_index,cidx;
117 unsigned int j;
118
119 for ( preset_index = 0; preset_index < PAPI_MAX_PRESET_EVENTS;
120 preset_index++ ) {
121 if ( _papi_hwi_presets[preset_index].postfix != NULL ) {
122 papi_free( _papi_hwi_presets[preset_index].postfix );
123 _papi_hwi_presets[preset_index].postfix = NULL;
124 }
125 if ( _papi_hwi_presets[preset_index].note != NULL ) {
126 papi_free( _papi_hwi_presets[preset_index].note );
127 _papi_hwi_presets[preset_index].note = NULL;
128 }
129 for(j=0; j<_papi_hwi_presets[preset_index].count;j++) {
130 papi_free(_papi_hwi_presets[preset_index].name[j]);
131 }
132 }
133
135 _papi_hwd[cidx]->cmp_info.num_preset_events = 0;
136 }
137
138#if defined(ITANIUM2) || defined(ITANIUM3)
139 /* NOTE: This memory may need to be freed for BG/P builds as well */
140 if ( preset_search_map != NULL ) {
142 preset_search_map = NULL;
143 }
144#endif
145
146 return PAPI_OK;
147}
struct papi_vectors * _papi_hwd[]
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_MAX_PRESET_EVENTS
hwi_presets_t _papi_hwi_presets[PAPI_MAX_PRESET_EVENTS]
int papi_num_components
#define papi_free(a)
Definition: papi_memory.h:35
static int cidx
hwi_search_t * preset_search_map
const char * name
Definition: rocs.c:225
unsigned int count
Definition: papi_preset.h:29
char * postfix
Definition: papi_preset.h:31
Here is the caller graph for this function:

◆ _papi_hwi_setup_all_presets()

int _papi_hwi_setup_all_presets ( hwi_search_t findem,
int  cidx 
)

Definition at line 44 of file papi_preset.c.

45{
46 int i, pnum, did_something = 0;
47 unsigned int preset_index, j, k;
48
49 /* dense array of events is terminated with a 0 preset.
50 don't do anything if NULL pointer. This allows just notes to be loaded.
51 It's also good defensive programming.
52 */
53 if ( findem != NULL ) {
54 for ( pnum = 0; ( pnum < PAPI_MAX_PRESET_EVENTS ) &&
55 ( findem[pnum].event_code != 0 ); pnum++ ) {
56 /* find the index for the event to be initialized */
57 preset_index = ( findem[pnum].event_code & PAPI_PRESET_AND_MASK );
58 /* count and set the number of native terms in this event,
59 these items are contiguous.
60
61 PAPI_EVENTS_IN_DERIVED_EVENT is arbitrarily defined in the high
62 level to be a reasonable number of terms to use in a derived
63 event linear expression, currently 8.
64
65 This wastes space for components with less than 8 counters,
66 but keeps the framework independent of the components.
67
68 The 'native' field below is an arbitrary opaque identifier
69 that points to information on an actual native event.
70 It is not an event code itself (whatever that might mean).
71 By definition, this value can never == PAPI_NULL.
72 - dkt */
73
74 INTDBG( "Counting number of terms for preset index %d, "
75 "search map index %d.\n", preset_index, pnum );
76 i = 0;
77 j = 0;
79 if ( findem[pnum].native[i] != PAPI_NULL ) {
80 j++;
81 }
82 else if ( j ) {
83 break;
84 }
85 i++;
86 }
87
88 INTDBG( "This preset has %d terms.\n", j );
89 _papi_hwi_presets[preset_index].count = j;
90
91 _papi_hwi_presets[preset_index].derived_int = findem[pnum].derived;
92 for(k=0;k<j;k++) {
93 _papi_hwi_presets[preset_index].code[k] =
94 findem[pnum].native[k];
95 }
96 /* preset code list must be PAPI_NULL terminated */
98 _papi_hwi_presets[preset_index].code[k] = PAPI_NULL;
99 }
100
101 _papi_hwi_presets[preset_index].postfix=
102 papi_strdup(findem[pnum].operation);
103
104 did_something++;
105 }
106 }
107
108 _papi_hwd[cidx]->cmp_info.num_preset_events += did_something;
109
110 return ( did_something ? PAPI_OK : PAPI_ENOEVNT );
111}
int i
#define PAPI_NULL
Definition: f90papi.h:78
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_PRESET_AND_MASK
#define INTDBG(format, args...)
Definition: papi_debug.h:66
#define PAPI_EVENTS_IN_DERIVED_EVENT
#define papi_strdup(a)
Definition: papi_memory.h:39
static int native
unsigned int code[PAPI_MAX_INFO_TERMS]
Definition: papi_preset.h:32
unsigned int event_code
Definition: papi_preset.h:14
int native[PAPI_EVENTS_IN_DERIVED_EVENT]
Definition: papi_preset.h:16
Here is the caller graph for this function:

◆ _papi_load_preset_table()

int _papi_load_preset_table ( char *  pmu_str,
int  pmu_type,
int  cidx 
)

Definition at line 771 of file papi_preset.c.

771 {
772 SUBDBG("ENTER: pmu_str: %s, pmu_type: %d, cidx: %d\n", pmu_str, pmu_type, cidx);
773
774 int retval;
775
776 // go load papi preset events (last argument tells function if we are loading presets or user events)
777 retval = papi_load_derived_events(pmu_str, pmu_type, cidx, 1);
778 if (retval != PAPI_OK) {
779 SUBDBG("EXIT: retval: %d\n", retval);
780 return retval;
781 }
782
783 // go load the user defined event definitions if any are defined
784 retval = papi_load_derived_events(pmu_str, pmu_type, cidx, 0);
785
786 SUBDBG("EXIT: retval: %d\n", retval);
787 return retval;
788}
#define SUBDBG(format, args...)
Definition: papi_debug.h:64
static int papi_load_derived_events(char *pmu_str, int pmu_type, int cidx, int preset_flag)
Definition: papi_preset.c:947
int retval
Definition: zero_fork.c:53
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_derived_events()

static int check_derived_events ( char *  target,
int  derived_type,
hwi_presets_t results,
hwi_presets_t search,
int  search_size,
int  token_index 
)
static

Definition at line 617 of file papi_preset.c.

618{
619 INTDBG("ENTER: target: %p (%s), results: %p, search: %p, search_size: %d, token_index: %d\n", target, target, results, search, search_size, token_index);
620 unsigned int i;
621 int j;
622 int k;
623 int found = 0;
624
625 for (j=0; j < search_size; j++) {
626 // INTDBG("search[%d].symbol: %s, looking for: %s\n", j, search[j].symbol, target);
627 if (search[j].symbol == NULL) {
628 INTDBG("EXIT: returned: 0\n");
629 return 0;
630 }
631
632 // if not the event we depend on, just look at next
633 if ( strcasecmp( target, search[j].symbol) != 0 ) {
634 continue;
635 }
636
637 INTDBG("Found a match\n");
638
639 // derived formulas need to be adjusted based on what kind of derived event we are processing
640 // the derived type passed to this function is the type of the new event being defined (not the events it is based on)
641 // when we get here the formula must be in reverse polish notation (RPN) format
642 switch (derived_type) {
643 case DERIVED_POSTFIX: {
644 // go create a formula to merge the second formula into a spot identified by one of the tokens in
645 // the first formula.
646 ops_string_merge(&(results->postfix), search[j].postfix, token_index, results->count);
647 break;
648 }
649 case DERIVED_ADD: {
650 // the new derived event adds two things together, go handle this target events role in the add
651 ops_string_append(results, &search[j], 1);
652 break;
653 }
654 case DERIVED_SUB: {
655 // go create a formula to subtract the value generated by the second formula from the value generated by the first formula.
656 ops_string_append(results, &search[j], 0);
657 break;
658 }
659 default: {
660 INTDBG("Derived type: %d, not currently handled\n", derived_type);
661 break;
662 }
663 }
664
665 // copy event name and code used by the derived event into the results table (place where new derived event is getting created)
666 for ( k = 0; k < (int)search[j].count; k++ ) {
667// INTDBG("search[%d]: %p, name[%d]: %s, code[%d]: %#x\n", j, &search[j], k, search[j].name[k], k, search[j].code[k]);
668 // if this event is already in the list, just update the formula so that references to this event point to the existing one
669 for (i=0 ; i < results->count ; i++) {
670 if (results->code[i] == search[j].code[k]) {
671 INTDBG("event: %s, code: %#x, already in results at index: %d\n", search[j].name[k], search[j].code[k], i);
672 // replace all tokens in the formula that refer to index "results->count + found" with a token that refers to index "i".
673 // the index "results->count + found" identifies the index used in the formula for the event we just determined is a duplicate
674 update_ops_string(&(results->postfix), results->count + found, i);
675 found++;
676 break;
677 }
678 }
679
680 // if we did not find a match, copy native event info into results array
681 if (found == 0) {
682 // not a duplicate, go ahead and copy into results and bump number of native events in results
683 if (search[j].name[k]) {
684 results->name[results->count] = papi_strdup(search[j].name[k]);
685 } else {
686 results->name[results->count] = papi_strdup(target);
687 }
688 results->code[results->count] = search[j].code[k];
689 INTDBG("results: %p, name[%d]: %s, code[%d]: %#x\n", results, results->count, results->name[results->count], results->count, results->code[results->count]);
690
691 results->count++;
692 }
693 }
694
695 INTDBG("EXIT: returned: 1\n");
696 return 1;
697 }
698
699 INTDBG("EXIT: returned: 0\n");
700 return 0;
701}
static long count
#define DERIVED_POSTFIX
Definition: papi_internal.h:74
#define DERIVED_SUB
Definition: papi_internal.h:73
#define DERIVED_ADD
Definition: papi_internal.h:69
static void ops_string_merge(char **original, char *insertion, int replaces, int start_index)
Definition: papi_preset.c:464
static void update_ops_string(char **formula, int old_index, int new_index)
Definition: papi_preset.c:304
static void ops_string_append(hwi_presets_t *results, hwi_presets_t *depends_on, int addition)
Definition: papi_preset.c:363
int
Definition: sde_internal.h:89
char * name[PAPI_MAX_INFO_TERMS]
Definition: papi_preset.h:33
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_native_events()

static int check_native_events ( char *  target,
hwi_presets_t results 
)
static

Definition at line 704 of file papi_preset.c.

705{
706 INTDBG("ENTER: target: %p (%s), results: %p\n", target, target, results);
707 int ret;
708
709 // find this native events code
710 if ( ( ret = _papi_hwi_native_name_to_code( target, (int *)(&results->code[results->count])) ) != PAPI_OK ) {
711 INTDBG("EXIT: returned: 0, call to convert name to event code failed with ret: %d\n", ret);
712 return 0;
713 }
714
715 // if the code returned was 0, return to show it is not a valid native event
716 if ( results->code[results->count] == 0 ) {
717 INTDBG( "EXIT: returned: 0, event code not found\n");
718 return 0;
719 }
720
721 // if this native event is not for component 0, return to show it can not be used in derived events
722 // it should be possible to create derived events for other components as long as all events in the derived event are associated with the same component
723 if ( _papi_hwi_component_index(results->code[results->count]) != 0 ) {
724 INTDBG( "EXIT: returned: 0, new event not associated with component 0 (current limitation with derived events)\n");
725 return 0;
726 }
727
728 // found = 1;
729 INTDBG("\tFound a native event %s\n", target);
730 results->name[results->count++] = papi_strdup(target);
731
732 INTDBG( "EXIT: returned: 1\n");
733 return 1;
734}
int _papi_hwi_native_name_to_code(const char *in, int *out)
int _papi_hwi_component_index(int event_code)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_event_index()

static int find_event_index ( hwi_presets_t array,
int  size,
char *  tmp 
)
inlinestatic

Definition at line 225 of file papi_preset.c.

225 {
226 SUBDBG("ENTER: array: %p, size: %d, tmp: %s\n", array, size, tmp);
227 int i;
228 for (i = 0; i < size; i++) {
229 if (array[i].symbol == NULL) {
230 array[i].symbol = papi_strdup(tmp);
231 SUBDBG("EXIT: i: %d\n", i);
232 return i;
233 }
234 if (strcasecmp(tmp, array[i].symbol) == 0) {
235 SUBDBG("EXIT: i: %d\n", i);
236 return i;
237 }
238 }
239 SUBDBG("EXIT: PAPI_EINVAL\n");
240 return PAPI_EINVAL;
241}
double tmp
#define PAPI_EINVAL
Definition: f90papi.h:115
static double array[ARRAYSIZE]
Definition: papi_l1_dca.c:23
Here is the caller graph for this function:

◆ get_event_line()

static int get_event_line ( char *  line,
FILE *  table,
char **  tmp_perfmon_events_table 
)
static

Definition at line 273 of file papi_preset.c.

274{
275 int i;
276
277 if ( table ) {
278 if ( fgets( line, LINE_MAX, table ) == NULL)
279 return 0;
280
281 i = ( int ) strlen( line );
282 if (i == 0)
283 return 0;
284 if ( line[i-1] == '\n' )
285 line[i-1] = '\0';
286 return 1;
287 } else {
288 for ( i = 0;
289 **tmp_perfmon_events_table && **tmp_perfmon_events_table != '\n';
290 i++, ( *tmp_perfmon_events_table )++ )
291 line[i] = **tmp_perfmon_events_table;
292 if (i == 0)
293 return 0;
294 if ( **tmp_perfmon_events_table && **tmp_perfmon_events_table == '\n' ) {
295 ( *tmp_perfmon_events_table )++;
296 }
297 line[i] = '\0';
298 return 1;
299 }
300}
Here is the caller graph for this function:

◆ infix_to_postfix()

static char * infix_to_postfix ( char *  infix)
static

Definition at line 839 of file papi_preset.c.

839 {
840 INTDBG("ENTER: in: %s, size: %zu\n", infix, strlen(infix));
841 static char postfix[2*PAPI_HUGE_STR_LEN]; // output
842 unsigned int index;
843 int postfixlen;
844 char token;
845 if ( strlen(infix) > PAPI_HUGE_STR_LEN )
846 PAPIERROR("A infix string (probably in user-defined presets) is too big (max allowed %d): %s", PAPI_HUGE_STR_LEN, infix );
847
848 // initialize stack
849 memset(stack, 0, 2*PAPI_HUGE_STR_LEN);
850 stacktop = -1;
851 push('#');
852 stacktop = 0; // after initialization of stack to #
853 /* initialize output string */
854 memset(postfix,0,2*PAPI_HUGE_STR_LEN);
855 postfixlen = 0;
856
857 for( index=0; index<strlen(infix); index++ ) {
858 token = infix[index];
859 INTDBG("INTDBG: in: %s, length: %zu, index: %d token %c\n", infix, strlen( infix ), index, token);
860 switch( token ) {
861 case '(':
862 push( token );
863 break;
864 case ')':
865 if (postfix[postfixlen-1]!='|') postfix[postfixlen++] = '|';
866 while ( stack[stacktop] != '(' ) {
867 postfix[postfixlen++] = pop();
868 postfix[postfixlen++] = '|';
869 }
870 token = pop(); /* pop the '(' character */
871 break;
872 case '+':
873 case '-':
874 case '*':
875 case '/':
876 case '%':
877 case '^': /* if an operator */
878 if (postfix[postfixlen-1]!='|') postfix[postfixlen++] = '|';
879 while ( priority(stack[stacktop]) > priority(token) ) {
880 postfix[postfixlen++] = pop();
881 postfix[postfixlen++] = '|';
882 }
883 push( token ); /* save current operator */
884 break;
885 default: // if alphanumeric character which is not parenthesis or an operator
886 postfix[postfixlen++] = token;
887 break;
888 } // end switch symbol
889 } // end while
890
891 /* Write any remaining operators */
892 if (postfix[postfixlen-1]!='|') postfix[postfixlen++] = '|';
893 while ( stacktop>0 ) {
894 postfix[postfixlen++] = pop();
895 postfix[postfixlen++] = '|';
896 }
897 postfix[postfixlen++] = '\0';
898 stacktop = -1;
899
900 INTDBG("EXIT: postfix: %s, size: %zu\n", postfix, strlen(postfix));
901 return (postfix);
902} // end infix_to_postfix
#define PAPI_HUGE_STR_LEN
Definition: f90papi.h:120
void PAPIERROR(char *format,...)
static int push(char symbol)
Definition: papi_preset.c:815
static char stack[2 *PAPI_HUGE_STR_LEN]
Definition: papi_preset.c:791
static int stacktop
Definition: papi_preset.c:792
static int priority(char symbol)
Definition: papi_preset.c:796
static char pop()
Definition: papi_preset.c:826
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_event()

static int is_event ( char *  event_name,
int  derived_type,
hwi_presets_t results,
int  token_index 
)
static

Definition at line 739 of file papi_preset.c.

739 {
740 INTDBG("ENTER: event_name: %p (%s), derived_type: %d, results: %p, token_index: %d\n", event_name, event_name, derived_type, results, token_index);
741
742 /* check if its a preset event */
743 if ( check_derived_events(event_name, derived_type, results, &_papi_hwi_presets[0], PAPI_MAX_PRESET_EVENTS, token_index) ) {
744 INTDBG("EXIT: found preset event\n");
745 return 1;
746 }
747
748 /* check if its a user defined event */
749 if ( check_derived_events(event_name, derived_type, results, user_defined_events, user_defined_events_count, token_index) ) {
750 INTDBG("EXIT: found user event\n");
751 return 1;
752 }
753
754 /* check if its a native event */
755 if ( check_native_events(event_name, results) ) {
756 INTDBG("EXIT: found native event\n");
757 return 1;
758 }
759
760 INTDBG("EXIT: event not found\n");
761 return 0;
762}
char event_name[2][PAPI_MAX_STR_LEN]
Definition: data_range.c:29
static int check_native_events(char *target, hwi_presets_t *results)
Definition: papi_preset.c:704
hwi_presets_t user_defined_events[]
Definition: papi_internal.c:59
static int check_derived_events(char *target, int derived_type, hwi_presets_t *results, hwi_presets_t *search, int search_size, int token_index)
Definition: papi_preset.c:617
int user_defined_events_count
Definition: papi_internal.c:60
Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_event_table()

static FILE * open_event_table ( char *  name)
static

Definition at line 246 of file papi_preset.c.

247{
248 FILE *table;
249
250 SUBDBG( "Opening %s\n", name );
251 table = fopen( name, "r" );
252 if ( table == NULL ) {
253 SUBDBG( "Open %s failed, trying ./%s.\n",
255 sprintf( name, "%s", PAPI_EVENT_FILE );
256 table = fopen( name, "r" );
257 }
258 if ( table == NULL ) {
259 SUBDBG( "Open ./%s failed, trying ../%s.\n",
261 sprintf( name, "../%s", PAPI_EVENT_FILE );
262 table = fopen( name, "r" );
263 }
264 if ( table ) {
265 SUBDBG( "Open %s succeeded.\n", name );
266 }
267 return table;
268}
#define PAPI_EVENT_FILE
Definition: papi_preset.c:151
Here is the caller graph for this function:

◆ ops_string_append()

static void ops_string_append ( hwi_presets_t results,
hwi_presets_t depends_on,
int  addition 
)
static

Definition at line 363 of file papi_preset.c.

363 {
364 INTDBG("ENTER: results: %p, depends_on: %p, addition %d\n", results, depends_on, addition);
365
366 int i;
367 int second_event = 0;
368 char newFormula[PAPI_MIN_STR_LEN] = "";
369 char work[20];
370
371 // if our results already have a formula, start with what was collected so far
372 // this should only happens when processing the second event of a new derived add
373 if (results->postfix != NULL) {
374 INTDBG("Event %s has existing formula %s\n", results->symbol, results->postfix);
375 // get the existing formula
376 strncat(newFormula, results->postfix, sizeof(newFormula)-1);
377 newFormula[sizeof(newFormula)-1] = '\0';
378 second_event = 1;
379 }
380
381 // process based on what kind of event the one we depend on is
382 switch (depends_on->derived_int) {
383 case DERIVED_POSTFIX: {
384 // the event we depend on has a formula, append it our new events formula
385
386 // if event we depend on does not have a formula, report error
387 if (depends_on->postfix == NULL) {
388 INTDBG("Event %s is of type DERIVED_POSTFIX but is missing operation string\n", depends_on->symbol);
389 return;
390 }
391
392 // may need to renumber the native event index values in the depends on event formula before putting it into new derived event
393 char *temp = papi_strdup(depends_on->postfix);
394
395 // If this is not the first event of the new derived add, need to adjust native event index values in formula.
396 // At this time we assume that all the native events in the second events formula are unique for the new event
397 // and just bump the indexes by the number of events already known to the new event. Later when we add the events
398 // to the native event list for this new derived event, we will check to see if the native events are already known
399 // to the new derived event and if so adjust the indexes again.
400 if (second_event) {
401 for ( i=depends_on->count-1 ; i>=0 ; i--) {
402 update_ops_string(&temp, i, results->count + i);
403 }
404 }
405
406 // append the existing formula from the event we depend on (but get rid of last '|' character)
407 strncat(newFormula, temp, sizeof(newFormula)-1);
408 newFormula[sizeof(newFormula)-1] = '\0';
409 papi_free (temp);
410 break;
411 }
412 case DERIVED_ADD: {
413 // the event we depend on has no formula, create a formula for our new event to add together the depends_on native event values
414
415 // build a formula for this add event
416 sprintf(work, "N%d|N%d|+|", results->count, results->count + 1);
417 strcat(newFormula, work);
418 break;
419 }
420 case DERIVED_SUB: {
421 // the event we depend on has no formula, create a formula for our new event to subtract the depends_on native event values
422
423 // build a formula for this subtract event
424 sprintf(work, "N%d|N%d|-|", results->count, results->count + 1);
425 strcat(newFormula, work);
426 break;
427 }
428 case NOT_DERIVED: {
429 // the event we depend on has no formula and is itself only based on one native event, create a formula for our new event to include this native event
430
431 // build a formula for this subtract event
432 sprintf(work, "N%d|", results->count);
433 strcat(newFormula, work);
434 break;
435 }
436 default: {
437 // the event we depend on has unsupported derived type, put out some debug and give up
438 INTDBG("Event %s depends on event %s which has an unsupported derived type of %d\n", results->symbol, depends_on->symbol, depends_on->derived_int);
439 return;
440 }
441 }
442
443 // if this was the second event, append to the formula an operation to add or subtract the results of the two events
444 if (second_event) {
445 if (addition != 0) {
446 strcat(newFormula, "+|");
447 } else {
448 strcat(newFormula, "-|");
449 }
450 // also change the new derived events type to show it has a formula now
451 results->derived_int = DERIVED_POSTFIX;
452 }
453
454 // we need to free the existing space (created by malloc and we need to create a new one)
455 papi_free (results->postfix);
456 results->postfix = papi_strdup(newFormula);
457 INTDBG("EXIT: newFormula: %s\n", newFormula);
458 return;
459}
#define PAPI_MIN_STR_LEN
Definition: f90papi.h:208
#define NOT_DERIVED
Definition: papi_internal.h:68
static void work(int EventSet, int sleep_test, int quiet)
Definition: papi_ref_cyc.c:56
char * symbol
Definition: papi_preset.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ops_string_merge()

static void ops_string_merge ( char **  original,
char *  insertion,
int  replaces,
int  start_index 
)
static

Definition at line 464 of file papi_preset.c.

464 {
465 INTDBG("ENTER: original: %p, *original: %s, insertion: %s, replaces: %d, start_index: %d\n", original, *original, insertion, replaces, start_index);
466
467 int orig_len=0;
468 int ins_len=0;
469 char *subtoken;
470 char *workBuf;
471 char *workPtr;
472 char *tok_save_ptr=NULL;
473 char *newOriginal;
474 char *newInsertion;
475 char *newFormula;
476 int insert_events;
477
478 if (*original != NULL) {
479 orig_len = strlen(*original);
480 }
481 if (insertion != NULL) {
482 ins_len = strlen(insertion);
483 }
484 newFormula = papi_calloc (orig_len + ins_len + 40, 1);
485
486 // if insertion formula is not provided, then the original formula remains basically unchanged.
487 if (insertion == NULL) {
488 // if the original formula has a leading '|' then get rid of it
489 workPtr = *original;
490 if (workPtr[0] == '|') {
491 strcpy(newFormula, &workPtr[1]);
492 } else {
493 strcpy(newFormula, workPtr);
494 }
495 // formula fields are always malloced space so free the previous one
496 papi_free (*original);
497 *original = newFormula;
498 INTDBG("EXIT: newFormula: %s\n", *original);
499 return;
500 }
501
502 // renumber the token numbers in the insertion formula
503 // also count how many native events are used in this formula
504 insert_events = 0;
505 newInsertion = papi_calloc(ins_len+20, 1);
506 workBuf = papi_calloc(ins_len+10, 1);
507 workPtr = papi_strdup(insertion);
508 subtoken = strtok_r(workPtr, "|", &tok_save_ptr);
509 while ( subtoken != NULL) {
510// INTDBG("subtoken: %s, newInsertion: %s\n", subtoken, newInsertion);
511 if ((subtoken[0] == 'N') && (isdigit(subtoken[1]))) {
512 insert_events++;
513 int val = atoi(&subtoken[1]);
514 val += start_index;
515 subtoken[1] = '\0';
516 sprintf (workBuf, "N%d", val);
517 } else {
518 strcpy(workBuf, subtoken);
519 }
520 strcat (newInsertion, workBuf);
521 strcat (newInsertion, "|");
522 subtoken = strtok_r(NULL, "|", &tok_save_ptr);
523 }
524 papi_free (workBuf);
525 papi_free (workPtr);
526 INTDBG("newInsertion: %s\n", newInsertion);
527
528 // if original formula is not provided, then the updated insertion formula becomes the new formula
529 // but we still had to renumber the native event tokens in case another native event was put into the list first
530 if (*original == NULL) {
531 *original = papi_strdup(newInsertion);
532 INTDBG("EXIT: newFormula: %s\n", newInsertion);
533 papi_free (newInsertion);
534 papi_free (newFormula);
535 return;
536 }
537
538 // if token to replace not valid, return null (do we also need to check an upper bound ???)
539 if ((replaces < 0)) {
540 papi_free (newInsertion);
541 papi_free (newFormula);
542 INTDBG("EXIT: Invalid value for token in original formula to be replaced\n");
543 return;
544 }
545
546 // renumber the token numbers in the original formula
547 // tokens with an index greater than the replaces token need to be incremented by number of events in insertion formula-1
548 newOriginal = papi_calloc (orig_len+20, 1);
549 workBuf = papi_calloc(orig_len+10, 1);
550 workPtr = papi_strdup(*original);
551
552 subtoken = strtok_r(workPtr, "|", &tok_save_ptr);
553 while ( subtoken != NULL) {
554// INTDBG("subtoken: %s, newOriginal: %s\n", subtoken, newOriginal);
555 // prime the work area with the next token, then see if we need to change it
556 strcpy(workBuf, subtoken);
557 if ((subtoken[0] == 'N') && (isdigit(subtoken[1]))) {
558 int val = atoi(&subtoken[1]);
559 if (val > replaces) {
560 val += insert_events-1;
561 subtoken[1] = '\0';
562 sprintf (workBuf, "N%d", val);
563 }
564 }
565 // put the work buffer into the new original formula
566 strcat (newOriginal, workBuf);
567 strcat (newOriginal, "|");
568 subtoken = strtok_r(NULL, "|", &tok_save_ptr);
569 }
570 papi_free (workBuf);
571 papi_free (workPtr);
572 INTDBG("newOriginal: %s\n", newOriginal);
573
574 // replace the specified "replace" tokens in the new original formula with the new insertion formula
575 newFormula[0] = '\0';
576 workPtr = newOriginal;
577 subtoken = strtok_r(workPtr, "|", &tok_save_ptr);
578 while ( subtoken != NULL) {
579// INTDBG("subtoken: %s, newFormula: %s\n", subtoken, newFormula);
580 // if this is the token we want to replace with the insertion string, do it now
581 if ((subtoken[0] == 'N') && (isdigit(subtoken[1])) && (replaces == atoi(&subtoken[1]))) {
582 // copy updated insertion string into the original string (replacing this token)
583 strcat(newFormula, newInsertion);
584 } else {
585 // copy this part of the original formula into the new formula
586 strcat(newFormula, subtoken);
587 strcat(newFormula, "|");
588 }
589 subtoken = strtok_r(NULL, "|", &tok_save_ptr);
590 }
591 papi_free (newInsertion);
592 papi_free (workPtr);
593
594 // formula fields are always malloced space so free the previous one
595 papi_free (*original);
596 *original = newFormula;
597 INTDBG("EXIT: newFormula: %s\n", newFormula);
598 return;
599}
#define papi_calloc(a, b)
Definition: papi_memory.h:37
Here is the caller graph for this function:

◆ papi_load_derived_events()

static int papi_load_derived_events ( char *  pmu_str,
int  pmu_type,
int  cidx,
int  preset_flag 
)
static

Definition at line 947 of file papi_preset.c.

947 {
948 SUBDBG( "ENTER: pmu_str: %s, pmu_type: %d, cidx: %d, preset_flag: %d\n", pmu_str, pmu_type, cidx, preset_flag);
949
950 char pmu_name[PAPI_MIN_STR_LEN];
951 char line[LINE_MAX];
952 char name[PATH_MAX] = "builtin papi_events_table";
953 char *event_file_path=NULL;
954 char *event_table_ptr=NULL;
955 int event_type_bits = 0;
956 char *tmpn;
957 char *tok_save_ptr=NULL;
958 FILE *event_file = NULL;
959 hwi_presets_t *results=NULL;
960 int result_size = 0;
961 int *event_count = NULL;
962 int invalid_event;
963 int line_no = 0; /* count of lines read from event definition input */
964 int derived = 0;
965 int res_idx = 0; /* index into results array for where to store next event */
966 int preset = 0;
967 int get_events = 0; /* only process derived events after CPU type they apply to is identified */
968 int found_events = 0; /* flag to track if event definitions (PRESETS) are found since last CPU declaration */
969#ifdef PAPI_DATADIR
970 char path[PATH_MAX];
971#endif
972
973
974 if (preset_flag) {
975 /* try the environment variable first */
976 if ((tmpn = getenv("PAPI_CSV_EVENT_FILE")) && (strlen(tmpn) > 0)) {
977 event_file_path = tmpn;
978 }
979 /* if no valid environment variable, look for built-in table */
980 else if (papi_events_table) {
981 event_table_ptr = papi_events_table;
982 }
983 /* if no env var and no built-in, search for default file */
984 else {
985#ifdef PAPI_DATADIR
986 sprintf( path, "%s/%s", PAPI_DATADIR, PAPI_EVENT_FILE );
987 event_file_path = path;
988#else
989 event_file_path = PAPI_EVENT_FILE;
990#endif
991 }
992 event_type_bits = PAPI_PRESET_MASK;
993 results = &_papi_hwi_presets[0];
994 result_size = PAPI_MAX_PRESET_EVENTS;
995 event_count = &_papi_hwd[cidx]->cmp_info.num_preset_events;
996 } else {
997 if ((event_file_path = getenv( "PAPI_USER_EVENTS_FILE" )) == NULL ) {
998 SUBDBG("EXIT: User event definition file not provided.\n");
999 return PAPI_OK;
1000 }
1001
1002 event_type_bits = PAPI_UE_MASK;
1003 results = &user_defined_events[0];
1004 result_size = PAPI_MAX_USER_EVENTS;
1006 }
1007
1008 // if we have an event file pathname, open it and read event definitions from the file
1009 if (event_file_path != NULL) {
1010 if ((event_file = open_event_table(event_file_path)) == NULL) {
1011 // if file open fails, return an error
1012 SUBDBG("EXIT: Event file open failed.\n");
1013 return PAPI_ESYS;
1014 }
1015 strncpy(name, event_file_path, sizeof(name)-1);
1016 name[sizeof(name)-1] = '\0';
1017 } else if (event_table_ptr == NULL) {
1018 // if we do not have a path name or table pointer, return an error
1019 SUBDBG("EXIT: Both event_file_path and event_table_ptr are NULL.\n");
1020 return PAPI_ESYS;
1021 }
1022
1023 /* copy the pmu identifier, stripping commas if found */
1024 tmpn = pmu_name;
1025 while (*pmu_str) {
1026 if (*pmu_str != ',')
1027 *tmpn++ = *pmu_str;
1028 pmu_str++;
1029 }
1030 *tmpn = '\0';
1031
1032 /* at this point we have either a valid file pointer or built-in table pointer */
1033 while (get_event_line(line, event_file, &event_table_ptr)) {
1034 char *t;
1035 int i;
1036
1037 // increment number of lines we have read
1038 line_no++;
1039
1040 t = trim_string(strtok_r(line, ",", &tok_save_ptr));
1041
1042 /* Skip blank lines */
1043 if ((t == NULL) || (strlen(t) == 0))
1044 continue;
1045
1046 /* Skip comments */
1047 if (t[0] == '#') {
1048 continue;
1049 }
1050
1051 if (strcasecmp(t, "CPU") == 0) {
1052 if (get_events != 0 && found_events != 0) {
1053 SUBDBG( "Ending event scanning at line %d of %s.\n", line_no, name);
1054 get_events = 0;
1055 found_events = 0;
1056 }
1057
1058 t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
1059 if ((t == NULL) || (strlen(t) == 0)) {
1060 PAPIERROR("Expected name after CPU token at line %d of %s -- ignoring", line_no, name);
1061 continue;
1062 }
1063
1064 if (strcasecmp(t, pmu_name) == 0) {
1065 int type;
1066
1067 SUBDBG( "Process events for PMU %s found at line %d of %s.\n", t, line_no, name);
1068
1069 t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
1070 if ((t == NULL) || (strlen(t) == 0)) {
1071 SUBDBG("No additional qualifier found, matching on string.\n");
1072 get_events = 1;
1073 } else if ((sscanf(t, "%d", &type) == 1) && (type == pmu_type)) {
1074 SUBDBG( "Found CPU %s type %d at line %d of %s.\n", pmu_name, type, line_no, name);
1075 get_events = 1;
1076 } else {
1077 SUBDBG( "Additional qualifier match failed %d vs %d.\n", pmu_type, type);
1078 }
1079 }
1080 continue;
1081 }
1082
1083 if ((strcasecmp(t, "PRESET") == 0) || (strcasecmp(t, "EVENT") == 0)) {
1084
1085 if (get_events == 0)
1086 continue;
1087
1088 found_events = 1;
1089 t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
1090
1091 if ((t == NULL) || (strlen(t) == 0)) {
1092 PAPIERROR("Expected name after PRESET token at line %d of %s -- ignoring", line_no, name);
1093 continue;
1094 }
1095
1096 SUBDBG( "Examining event %s\n", t);
1097
1098 // see if this event already exists in the results array, if not already known it sets up event in unused entry
1099 if ((res_idx = find_event_index (results, result_size, t)) < 0) {
1100 PAPIERROR("No room left for event %s -- ignoring", t);
1101 continue;
1102 }
1103
1104 // add the proper event bits (preset or user defined bits)
1105 preset = res_idx | event_type_bits;
1106 (void) preset;
1107
1108 SUBDBG( "Use event code: %#x for %s\n", preset, t);
1109
1110 t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
1111 if ((t == NULL) || (strlen(t) == 0)) {
1112 // got an error, make this entry unused
1113 if (results[res_idx].symbol != NULL){
1114 papi_free (results[res_idx].symbol);
1115 results[res_idx].symbol = NULL;
1116 }
1117 PAPIERROR("Expected derived type after PRESET token at line %d of %s -- ignoring", line_no, name);
1118 continue;
1119 }
1120
1121 if (_papi_hwi_derived_type(t, &derived) != PAPI_OK) {
1122 // got an error, make this entry unused
1123 if (results[res_idx].symbol != NULL){
1124 papi_free (results[res_idx].symbol);
1125 results[res_idx].symbol = NULL;
1126 }
1127 PAPIERROR("Invalid derived name %s after PRESET token at line %d of %s -- ignoring", t, line_no, name);
1128 continue;
1129 }
1130
1131 /****************************************/
1132 /* Have an event, let's start assigning */
1133 /****************************************/
1134
1135 SUBDBG( "Adding event: %s, code: %#x, derived: %d results[%d]: %p.\n", t, preset, derived, res_idx, &results[res_idx]);
1136
1137 /* results[res_idx].event_code = preset; */
1138 results[res_idx].derived_int = derived;
1139
1140 /* Derived support starts here */
1141 /* Special handling for postfix and infix */
1142 if ((derived == DERIVED_POSTFIX) || (derived == DERIVED_INFIX)) {
1143 t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
1144 if ((t == NULL) || (strlen(t) == 0)) {
1145 // got an error, make this entry unused
1146 if (results[res_idx].symbol != NULL){
1147 papi_free (results[res_idx].symbol);
1148 results[res_idx].symbol = NULL;
1149 }
1150 PAPIERROR("Expected Operation string after derived type DERIVED_POSTFIX or DERIVED_INFIX at line %d of %s -- ignoring", line_no, name);
1151 continue;
1152 }
1153
1154 // if it is an algebraic formula, we need to convert it to postfix
1155 if (derived == DERIVED_INFIX) {
1156 SUBDBG( "Converting InFix operations %s\n", t);
1157 t = infix_to_postfix( t );
1158 results[res_idx].derived_int = DERIVED_POSTFIX;
1159 }
1160
1161 SUBDBG( "Saving PostFix operations %s\n", t);
1162 results[res_idx].postfix = papi_strdup(t);
1163 }
1164
1165 /* All derived terms collected here */
1166 i = 0;
1167 invalid_event = 0;
1168 results[res_idx].count = 0;
1169 do {
1170 t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
1171 if ((t == NULL) || (strlen(t) == 0))
1172 break;
1173 if (strcasecmp(t, "NOTE") == 0)
1174 break;
1175 if (strcasecmp(t, "LDESC") == 0)
1176 break;
1177 if (strcasecmp(t, "SDESC") == 0)
1178 break;
1179
1180 SUBDBG( "Adding term (%d) %s to derived event %#x, current native event count: %d.\n", i, t, preset, results[res_idx].count);
1181
1182 // show that we do not have an event code yet (the component may create one and update this info)
1183 // this also clears any values left over from a previous call
1185
1186 // make sure that this term in the derived event is a valid event name
1187 // this call replaces preset and user event names with the equivalent native events in our results table
1188 // it also updates formulas for derived events so that they refer to the correct native event index
1189 if (is_event(t, results[res_idx].derived_int, &results[res_idx], i) == 0) {
1190 invalid_event = 1;
1191 PAPIERROR("Missing event %s, used in derived event %s", t, results[res_idx].symbol);
1192 break;
1193 }
1194
1195 i++;
1196 } while (results[res_idx].count < PAPI_EVENTS_IN_DERIVED_EVENT);
1197
1198 /* preset code list must be PAPI_NULL terminated */
1200 results[res_idx].code[results[res_idx].count] = PAPI_NULL;
1201 }
1202
1203 if (invalid_event) {
1204 // got an error, make this entry unused
1205 // preset table is statically allocated, user defined is dynamic
1206 unsigned int j;
1207 for (j = 0; j < results[res_idx].count; j++){
1208 if (results[res_idx].name[j] != NULL){
1209 papi_free( results[res_idx].name[j] );
1210 results[res_idx].name[j] = NULL;
1211 }
1212 }
1213
1214 if (!preset_flag){
1215 if(results[res_idx].symbol != NULL){
1216 papi_free (results[res_idx].symbol);
1217 results[res_idx].symbol = NULL;
1218 }
1219 }
1220
1221 continue;
1222 }
1223
1224 /* End of derived support */
1225
1226 // if we did not find any terms to base this derived event on, report error
1227 if (i == 0) {
1228 // got an error, make this entry unused
1229 if (!preset_flag){
1230 if(results[res_idx].symbol != NULL){
1231 papi_free (results[res_idx].symbol);
1232 results[res_idx].symbol = NULL;
1233 }
1234 }
1235 PAPIERROR("Expected PFM event after DERIVED token at line %d of %s -- ignoring", line_no, name);
1236 continue;
1237 }
1238
1240 t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
1241 }
1242
1243 // if something was provided following the list of events to be used by the operation, process it
1244 if ( t!= NULL && strlen(t) > 0 ) {
1245 do {
1246 // save the field name
1247 char *fptr = papi_strdup(t);
1248
1249 // get the value to be used with this field
1250 t = trim_note(strtok_r(NULL, ",", &tok_save_ptr));
1251 if ( t== NULL || strlen(t) == 0 ) {
1252 papi_free(fptr);
1253 break;
1254 }
1255
1256 // Handle optional short descriptions, long descriptions and notes
1257 if (strcasecmp(fptr, "SDESC") == 0) {
1258 results[res_idx].short_descr = papi_strdup(t);
1259 }
1260 if (strcasecmp(fptr, "LDESC") == 0) {
1261 results[res_idx].long_descr = papi_strdup(t);
1262 }
1263 if (strcasecmp(fptr, "NOTE") == 0) {
1264 results[res_idx].note = papi_strdup(t);
1265 }
1266
1267 SUBDBG( "Found %s (%s) on line %d\n", fptr, t, line_no);
1268 papi_free (fptr);
1269
1270 // look for another field name
1271 t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
1272 if ( t== NULL || strlen(t) == 0 ) {
1273 break;
1274 }
1275 } while (t != NULL);
1276 }
1277 (*event_count)++;
1278 continue;
1279 }
1280
1281 PAPIERROR("Unrecognized token %s at line %d of %s -- ignoring", t, line_no, name);
1282 }
1283
1284 if (event_file) {
1285 fclose(event_file);
1286 }
1287
1288 SUBDBG("EXIT: Done processing derived event file.\n");
1289 return PAPI_OK;
1290}
#define PAPI_ESYS
Definition: f90papi.h:136
uint16_t type
#define PAPI_UE_MASK
#define PAPI_MAX_USER_EVENTS
#define PAPI_PRESET_MASK
int fclose(FILE *__stream)
int _papi_hwi_derived_type(char *tmp, int *code)
void _papi_hwi_set_papi_event_code(unsigned int event_code, int update_flag)
#define DERIVED_INFIX
Definition: papi_internal.h:75
static int is_event(char *event_name, int derived_type, hwi_presets_t *results, int token_index)
Definition: papi_preset.c:739
static char * papi_events_table
Definition: papi_preset.c:768
static char * infix_to_postfix(char *infix)
Definition: papi_preset.c:839
static int get_event_line(char *line, FILE *table, char **tmp_perfmon_events_table)
Definition: papi_preset.c:273
static char * trim_string(char *in)
Definition: papi_preset.c:157
static char * trim_note(char *in)
Definition: papi_preset.c:197
static int find_event_index(hwi_presets_t *array, int size, char *tmp)
Definition: papi_preset.c:225
static FILE * open_event_table(char *name)
Definition: papi_preset.c:246
static int preset
static const int event_count[]
char * short_descr
Definition: papi_preset.h:25
char * long_descr
Definition: papi_preset.h:26
static int get_events(ntv_event_t *events, int num_events)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pop()

static char pop ( )
static

Definition at line 826 of file papi_preset.c.

826 {
827 if( stacktop < 0 ) {
828 INTDBG("stack underflow converting algebraic expression\n" );
829 return '\0'; //***TODO: Figure out how to exit gracefully
830 } // end if empty
831 return( stack[stacktop--] );
832} // end pop
Here is the caller graph for this function:

◆ priority()

static int priority ( char  symbol)
static

Definition at line 796 of file papi_preset.c.

796 {
797 switch( symbol ) {
798 case '@':
799 return -1;
800 case '(':
801 return 0;
802 case '+':
803 case '-':
804 return 1;
805 case '*':
806 case '/':
807 case '%':
808 return 2;
809 default :
810 return 0;
811 } // end switch symbol
812} // end priority
Here is the caller graph for this function:

◆ push()

static int push ( char  symbol)
static

Definition at line 815 of file papi_preset.c.

815 {
816 if (stacktop >= 2*PAPI_HUGE_STR_LEN - 1) {
817 INTDBG("stack overflow converting algebraic expression (%d,%c)\n", stacktop,symbol );
818 return -1; //***TODO: Figure out how to exit gracefully
819 } // end if stacktop>MAX
820 stack[++stacktop] = symbol;
821 return 0;
822} // end push
Here is the caller graph for this function:

◆ trim_note()

static char * trim_note ( char *  in)
inlinestatic

Definition at line 197 of file papi_preset.c.

198{
199 int len;
200 char *note, start, end;
201
202 note = trim_string( in );
203 if ( note != NULL ) {
204 len = ( int ) strlen( note );
205 if ( len > 0 ) {
206 if ( ispunct( *note ) ) {
207 start = *note;
208 end = note[len - 1];
209 if ( ( start == end )
210 || ( ( start == '(' ) && ( end == ')' ) )
211 || ( ( start == '<' ) && ( end == '>' ) )
212 || ( ( start == '{' ) && ( end == '}' ) )
213 || ( ( start == '[' ) && ( end == ']' ) ) ) {
214 note[len - 1] = '\0';
215 *note = '\0';
216 note++;
217 }
218 }
219 }
220 }
221 return note;
222}
static struct timeval start
Here is the call graph for this function:
Here is the caller graph for this function:

◆ trim_string()

static char * trim_string ( char *  in)
inlinestatic

Definition at line 157 of file papi_preset.c.

158{
159 int len, i = 0;
160 char *start = in;
161
162 if ( in == NULL )
163 return ( in );
164 len = ( int ) strlen( in );
165 if ( len == 0 )
166 return ( in );
167
168 /* Trim left */
169 while ( i < len ) {
170 if ( isblank( in[i] ) ) {
171 in[i] = '\0';
172 start++;
173 } else
174 break;
175 i++;
176 }
177
178 /* Trim right */
179 i = ( int ) strlen( start ) - 1;
180 while ( i >= 0 ) {
181 if ( isblank( start[i] ) )
182 start[i] = '\0';
183 else
184 break;
185 i--;
186 }
187 return ( start );
188}
Here is the caller graph for this function:

◆ update_ops_string()

static void update_ops_string ( char **  formula,
int  old_index,
int  new_index 
)
static

Definition at line 304 of file papi_preset.c.

304 {
305 INTDBG("ENTER: *formula: %s, old_index: %d, new_index: %d\n", *formula?*formula:"NULL", old_index, new_index);
306
307 int cur_index;
308 char *newFormula;
309 char *subtoken;
310 char *tok_save_ptr=NULL;
311
312 // if formula is null just return
313 if (*formula == NULL) {
314 INTDBG("EXIT: Null pointer to formula passed in\n");
315 return;
316 }
317
318 // get some space for the new formula we are going to create
319 newFormula = papi_calloc(strlen(*formula) + 20, 1);
320
321 // replace the specified "replace" tokens in the new original formula with the new insertion formula
322 newFormula[0] = '\0';
323 subtoken = strtok_r(*formula, "|", &tok_save_ptr);
324 while ( subtoken != NULL) {
325// INTDBG("subtoken: %s, newFormula: %s\n", subtoken, newFormula);
326 char work[16];
327 // if this is the token we want to replace with the new token index, do it now
328 if ((subtoken[0] == 'N') && (isdigit(subtoken[1]))) {
329 cur_index = atoi(&subtoken[1]);
330 // if matches old index, use the new one
331 if (cur_index == old_index) {
332 sprintf (work, "N%d", new_index);
333 strcat (newFormula, work);
334 } else if (cur_index > old_index) {
335 // current token greater than old index, make it one less than what it was
336 sprintf (work, "N%d", cur_index-1);
337 strcat (newFormula, work);
338 } else {
339 // current token less than old index, copy this part of the original formula into the new formula
340 strcat(newFormula, subtoken);
341 }
342 } else {
343 // copy this part of the original formula into the new formula
344 strcat(newFormula, subtoken);
345 }
346 strcat (newFormula, "|");
347 subtoken = strtok_r(NULL, "|", &tok_save_ptr);
348 }
349 papi_free (*formula);
350 *formula = newFormula;
351
352 INTDBG("EXIT: newFormula: %s\n", newFormula);
353 return;
354}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ papi_events_table

char* papi_events_table = NULL
static

Definition at line 768 of file papi_preset.c.

◆ stack

char stack[2 *PAPI_HUGE_STR_LEN]
static

Definition at line 791 of file papi_preset.c.

◆ stacktop

int stacktop = -1
static

Definition at line 792 of file papi_preset.c.

◆ user_defined_events

hwi_presets_t user_defined_events[]
extern

Definition at line 59 of file papi_internal.c.

◆ user_defined_events_count

int user_defined_events_count
extern

Definition at line 60 of file papi_internal.c.