PAPI  5.4.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
papi_preset.c
Go to the documentation of this file.
1 /*
2 * File: papi_preset.c
3 * Author: Haihang You
4 * you@cs.utk.edu
5 * Mods: Brian Sheely
6 * bsheely@eecs.utk.edu
7 * Author: Vince Weaver
8 * vweaver1 @ eecs.utk.edu
9 * Merge of the libpfm3/libpfm4/pmapi-ppc64_events preset code
10 */
11 
12 
13 #include <string.h>
14 #include <ctype.h>
15 #include <errno.h>
16 
17 #include "papi.h"
18 #include "papi_internal.h"
19 #include "papi_vector.h"
20 #include "papi_memory.h"
21 #include "papi_preset.h"
22 #include "extras.h"
23 
24 
25 /* This routine copies values from a dense 'findem' array of events
26  into the sparse global _papi_hwi_presets array, which is assumed
27  to be empty at initialization.
28 
29  Multiple dense arrays can be copied into the sparse array, allowing
30  event overloading at run-time, or allowing a baseline table to be
31  augmented by a model specific table at init time.
32 
33  This method supports adding new events; overriding existing events, or
34  deleting deprecated events.
35 */
36 int
38 {
39  int i, pnum, did_something = 0;
40  unsigned int preset_index, j, k;
41 
42  /* dense array of events is terminated with a 0 preset.
43  don't do anything if NULL pointer. This allows just notes to be loaded.
44  It's also good defensive programming.
45  */
46  if ( findem != NULL ) {
47  for ( pnum = 0; ( pnum < PAPI_MAX_PRESET_EVENTS ) &&
48  ( findem[pnum].event_code != 0 ); pnum++ ) {
49  /* find the index for the event to be initialized */
50  preset_index = ( findem[pnum].event_code & PAPI_PRESET_AND_MASK );
51  /* count and set the number of native terms in this event,
52  these items are contiguous.
53 
54  PAPI_EVENTS_IN_DERIVED_EVENT is arbitrarily defined in the high
55  level to be a reasonable number of terms to use in a derived
56  event linear expression, currently 8.
57 
58  This wastes space for components with less than 8 counters,
59  but keeps the framework independent of the components.
60 
61  The 'native' field below is an arbitrary opaque identifier
62  that points to information on an actual native event.
63  It is not an event code itself (whatever that might mean).
64  By definition, this value can never == PAPI_NULL.
65  - dkt */
66 
67  INTDBG( "Counting number of terms for preset index %d, "
68  "search map index %d.\n", preset_index, pnum );
69  i = 0;
70  j = 0;
71  while ( i < PAPI_EVENTS_IN_DERIVED_EVENT ) {
72  if ( findem[pnum].native[i] != PAPI_NULL ) {
73  j++;
74  }
75  else if ( j ) {
76  break;
77  }
78  i++;
79  }
80 
81  INTDBG( "This preset has %d terms.\n", j );
82  _papi_hwi_presets[preset_index].count = j;
83 
84  _papi_hwi_presets[preset_index].derived_int = findem[pnum].derived;
85  for(k=0;k<j;k++) {
86  _papi_hwi_presets[preset_index].code[k] =
87  findem[pnum].native[k];
88  }
89  /* preset code list must be PAPI_NULL terminated */
91  _papi_hwi_presets[preset_index].code[k] = PAPI_NULL;
92  }
93 
94  _papi_hwi_presets[preset_index].postfix=
95  strdup(findem[pnum].operation);
96 
97  did_something++;
98  }
99  }
100 
101  _papi_hwd[cidx]->cmp_info.num_preset_events += did_something;
102 
103  return ( did_something ? PAPI_OK : PAPI_ENOEVNT );
104 }
105 
106 int
108 {
109  int preset_index,cidx;
110  unsigned int j;
111 
112  for ( preset_index = 0; preset_index < PAPI_MAX_PRESET_EVENTS;
113  preset_index++ ) {
114  if ( _papi_hwi_presets[preset_index].postfix != NULL ) {
115  free( _papi_hwi_presets[preset_index].postfix );
116  _papi_hwi_presets[preset_index].postfix = NULL;
117  }
118  if ( _papi_hwi_presets[preset_index].note != NULL ) {
119  free( _papi_hwi_presets[preset_index].note );
120  _papi_hwi_presets[preset_index].note = NULL;
121  }
122  for(j=0; j<_papi_hwi_presets[preset_index].count;j++) {
123  free(_papi_hwi_presets[preset_index].name[j]);
124  }
125  }
126 
127  for(cidx=0;cidx<papi_num_components;cidx++) {
129  }
130 
131 #if defined(ITANIUM2) || defined(ITANIUM3)
132  /* NOTE: This memory may need to be freed for BG/P builds as well */
133  if ( preset_search_map != NULL ) {
135  preset_search_map = NULL;
136  }
137 #endif
138 
139  return PAPI_OK;
140 }
141 
142 
143 
144 #define PAPI_EVENT_FILE "papi_events.csv"
145 
146 
147 /* Trims blank space from both ends of a string (in place).
148  Returns pointer to new start address */
149 static inline char *
150 trim_string( char *in )
151 {
152  int len, i = 0;
153  char *start = in;
154 
155  if ( in == NULL )
156  return ( in );
157  len = ( int ) strlen( in );
158  if ( len == 0 )
159  return ( in );
160 
161  /* Trim left */
162  while ( i < len ) {
163  if ( isblank( in[i] ) ) {
164  in[i] = '\0';
165  start++;
166  } else
167  break;
168  i++;
169  }
170 
171  /* Trim right */
172  i = ( int ) strlen( start ) - 1;
173  while ( i >= 0 ) {
174  if ( isblank( start[i] ) )
175  start[i] = '\0';
176  else
177  break;
178  i--;
179  }
180  return ( start );
181 }
182 
183 
184 /* Calls trim_string to remove blank space;
185  Removes paired punctuation delimiters from
186  beginning and end of string. If the same punctuation
187  appears first and last (quotes, slashes) they are trimmed;
188  Also checks for the following pairs: () <> {} [] */
189 static inline char *
190 trim_note( char *in )
191 {
192  int len;
193  char *note, start, end;
194 
195  note = trim_string( in );
196  if ( note != NULL ) {
197  len = ( int ) strlen( note );
198  if ( len > 0 ) {
199  if ( ispunct( *note ) ) {
200  start = *note;
201  end = note[len - 1];
202  if ( ( start == end )
203  || ( ( start == '(' ) && ( end == ')' ) )
204  || ( ( start == '<' ) && ( end == '>' ) )
205  || ( ( start == '{' ) && ( end == '}' ) )
206  || ( ( start == '[' ) && ( end == ']' ) ) ) {
207  note[len - 1] = '\0';
208  *note = '\0';
209  note++;
210  }
211  }
212  }
213  }
214  return note;
215 }
216 
217 static inline int
218 find_preset_code( char *tmp, int *code )
219 {
220  int i = 0;
221 
222  while ( _papi_hwi_presets[i].symbol != NULL ) {
223  if ( strcasecmp( tmp, _papi_hwi_presets[i].symbol ) == 0 ) {
224  *code = ( int ) ( i | PAPI_PRESET_MASK );
225  return PAPI_OK;
226  }
227  i++;
228  }
229  return PAPI_EINVAL;
230 }
231 
232 /* Look for an event file 'name' in a couple common locations.
233  Return a valid file handle if found */
234 static FILE *
236 {
237  FILE *table;
238 
239  SUBDBG( "Opening %s\n", name );
240  table = fopen( name, "r" );
241  if ( table == NULL ) {
242  SUBDBG( "Open %s failed, trying ./%s.\n",
243  name, PAPI_EVENT_FILE );
244  sprintf( name, "%s", PAPI_EVENT_FILE );
245  table = fopen( name, "r" );
246  }
247  if ( table == NULL ) {
248  SUBDBG( "Open ./%s failed, trying ../%s.\n",
249  name, PAPI_EVENT_FILE );
250  sprintf( name, "../%s", PAPI_EVENT_FILE );
251  table = fopen( name, "r" );
252  }
253  if ( table ) {
254  SUBDBG( "Open %s succeeded.\n", name );
255  }
256  return table;
257 }
258 
259 /* parse a single line from either a file or character table
260  Strip trailing <cr>; return 0 if empty */
261 static int
262 get_event_line( char *line, FILE * table, char **tmp_perfmon_events_table )
263 {
264  int i;
265 
266  if ( table ) {
267  if ( fgets( line, LINE_MAX, table ) == NULL)
268  return 0;
269 
270  i = ( int ) strlen( line );
271  if (i == 0)
272  return 0;
273  if ( line[i-1] == '\n' )
274  line[i-1] = '\0';
275  return 1;
276  } else {
277  for ( i = 0;
278  **tmp_perfmon_events_table && **tmp_perfmon_events_table != '\n';
279  i++, ( *tmp_perfmon_events_table )++ )
280  line[i] = **tmp_perfmon_events_table;
281  if (i == 0)
282  return 0;
283  if ( **tmp_perfmon_events_table && **tmp_perfmon_events_table == '\n' ) {
284  ( *tmp_perfmon_events_table )++;
285  }
286  line[i] = '\0';
287  return 1;
288  }
289 }
290 
291 /* Static version of the events file. */
292 #if defined(STATIC_PAPI_EVENTS_TABLE)
293 #include "papi_events_table.h"
294 #else
295 static char *papi_events_table = NULL;
296 #endif
297 
298 int
299 _papi_load_preset_table( char *pmu_str, int pmu_type, int cidx)
300 {
301 
302  (void) cidx; /* We'll use this later */
303 
304  char pmu_name[PAPI_MIN_STR_LEN];
305  char line[LINE_MAX];
306  char name[PATH_MAX] = "builtin papi_events_table";
307  char *tmp_papi_events_table = NULL;
308  char *tmpn;
309  FILE *table;
310  int ret;
311  unsigned int event_idx;
312  int invalid_event;
313  int line_no = 1, derived = 0, insert = 0, preset = 0;
314  int get_presets = 0; /* only get PRESETS after CPU is identified */
315  int found_presets = 0; /* only terminate search after PRESETS are found */
316  /* this allows support for synonyms for CPU names*/
317 
318  SUBDBG("ENTER\n");
319 
320  /* copy the pmu identifier, stripping commas if found */
321  tmpn = pmu_name;
322  while ( *pmu_str ) {
323  if ( *pmu_str != ',' ) *tmpn++ = *pmu_str;
324  pmu_str++;
325  }
326  *tmpn = '\0';
327 
328  /* try the environment variable first */
329  if ( ( tmpn = getenv( "PAPI_CSV_EVENT_FILE" ) ) &&
330  ( strlen( tmpn ) != 0 ) ) {
331  sprintf( name, "%s", tmpn );
332  table = fopen( name, "r" );
333  }
334  /* if no valid environment variable, look for built-in table */
335  else if ( papi_events_table ) {
336  tmp_papi_events_table = papi_events_table;
337  table = NULL;
338  }
339  /* if no env var and no built-in, search for default file */
340  else {
341 #ifdef PAPI_DATADIR
342  sprintf( name, "%s/%s", PAPI_DATADIR, PAPI_EVENT_FILE );
343 #else
344  sprintf( name, "%s", PAPI_EVENT_FILE );
345 #endif
346  table = open_event_table( name );
347  }
348 
349  /* if no valid file or built-in table, bail */
350  if ( table == NULL && tmp_papi_events_table == NULL ) {
351  PAPIERROR( "fopen(%s): %s, please set the PAPI_CSV_EVENT_FILE "
352  "env. variable", name, strerror( errno ) );
353  return PAPI_ESYS;
354  }
355 
356  /* at this point either a valid file pointer or built-in table pointer */
357  while ( get_event_line( line, table, &tmp_papi_events_table ) ) {
358  char *t;
359  int i;
360 
361  t = trim_string( strtok( line, "," ) );
362 
363  /* Skip blank lines */
364  if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) continue;
365 
366  /* Skip comments */
367  if ( t[0] == '#' ) {
368  goto nextline;
369  }
370 
371  if ( strcasecmp( t, "CPU" ) == 0 ) {
372 
373  if ( get_presets != 0 && found_presets != 0 ) {
374  SUBDBG( "Ending preset scanning at line %d of %s.\n",
375  line_no, name );
376 
377  get_presets=0; found_presets=0;
378 
379  }
380 
381  t = trim_string( strtok( NULL, "," ) );
382  if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
383  PAPIERROR( "Expected name after CPU token at line %d of %s "
384  "-- ignoring", line_no, name );
385  goto nextline;
386  }
387 
388  SUBDBG( "Examining CPU (%s) vs. (%s)\n", t, pmu_name );
389 
390  if ( strcasecmp( t, pmu_name ) == 0 ) {
391  int type;
392 
393  SUBDBG( "Found CPU %s at line %d of %s.\n", t, line_no, name );
394 
395  t = trim_string( strtok( NULL, "," ) );
396  if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
397  SUBDBG("No additional qualifier found, matching on string.\n");
398 
399  get_presets = 1;
400  } else if ( ( sscanf( t,"%d",&type )==1) && (type==pmu_type) ) {
401  SUBDBG( "Found CPU %s type %d at line %d of %s.\n",
402  pmu_name, type, line_no, name );
403  get_presets = 1;
404  } else {
405  SUBDBG( "Additional qualifier match failed %d vs %d.\n",
406  pmu_type, type );
407 
408  }
409  }
410  } else if ( strcasecmp( t, "PRESET" ) == 0 ) {
411 
412  if ( get_presets == 0 ) goto nextline;
413 
414  found_presets = 1;
415  t = trim_string( strtok( NULL, "," ) );
416 
417  if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
418 
419  PAPIERROR( "Expected name after PRESET token at line %d of %s "
420  "-- ignoring", line_no, name );
421  goto nextline;
422  }
423 
424  SUBDBG( "Examining preset %s\n", t );
425 
426  if ( find_preset_code( t, &preset ) != PAPI_OK ) {
427  PAPIERROR ( "Invalid preset name %s after PRESET token "
428  "at line %d of %s -- ignoring",
429  t, line_no, name );
430  goto nextline;
431  }
432 
433  SUBDBG( "Found %#08x for %s\n", preset, t );
434 
435  t = trim_string( strtok( NULL, "," ) );
436  if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
437  PAPIERROR( "Expected derived type after PRESET token at "
438  "line %d of %s -- ignoring", line_no, name );
439  goto nextline;
440  }
441 
442  if ( _papi_hwi_derived_type( t, &derived ) != PAPI_OK ) {
443  PAPIERROR( "Invalid derived name %s after PRESET token at "
444  "line %d of %s -- ignoring",
445  t, line_no, name );
446  goto nextline;
447  }
448 
449  /****************************************/
450  /* Have a preset, let's start assigning */
451  /****************************************/
452 
453  SUBDBG( "Found %d for %s\n", derived, t );
454  SUBDBG( "Adding %#x,%d to preset search table.\n",
455  preset, derived );
456 
458 
459  /* _papi_hwi_presets[insert].event_code = preset; */
460  _papi_hwi_presets[insert].derived_int = derived;
461 
462  /* Derived support starts here */
463  /* Special handling for postfix */
464  if ( derived == DERIVED_POSTFIX ) {
465  t = trim_string( strtok( NULL, "," ) );
466  if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
467  PAPIERROR( "Expected Operation string after derived type "
468  "DERIVED_POSTFIX at line %d of %s -- ignoring",
469  line_no, name );
470  goto nextline;
471  }
472 
473  SUBDBG( "Saving PostFix operations %s\n", t );
474 
475  _papi_hwi_presets[insert].postfix=strdup(t);
476  }
477 
478  /* All derived terms collected here */
479  i = 0;
480  invalid_event=0;
481  do {
482  t = trim_string( strtok( NULL, "," ) );
483  if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) break;
484  if ( strcasecmp( t, "NOTE" ) == 0 ) break;
485  _papi_hwi_presets[insert].name[i]=strdup(t);
486 
487  SUBDBG( "Adding term (%d) %s to preset event %#x.\n",
488  i, t, preset );
489 
490  SUBDBG("Looking up: %s\n",t);
491 
492  // show that we do not have an event code yet (the component may create one and update this info)
493  // this also clears any values left over from a previous call
495 
496  ret=_papi_hwd[cidx]->ntv_name_to_code(t, &event_idx);
497 
498  if (ret==PAPI_OK) {
499  _papi_hwi_presets[insert].code[i]=
500  _papi_hwi_native_to_eventcode(cidx, event_idx, -1, t);
501  SUBDBG("Found: %s %#x c%d e%d\n",t,
502  _papi_hwi_presets[insert].code[i],
503  cidx,event_idx);
504  }
505  else {
506  PAPIERROR("papi_preset: Error finding event %s",t);
507  invalid_event=1;
508  }
509 
510  } while ( ++i < PAPI_EVENTS_IN_DERIVED_EVENT );
511 
512  /* preset code list must be PAPI_NULL terminated */
514  _papi_hwi_presets[insert].code[i] = PAPI_NULL;
515  }
516 
517  if (invalid_event) {
518  /* We signify a valid preset if count > 0 */
519  _papi_hwi_presets[insert].count=0;
520  } else {
521  _papi_hwi_presets[insert].count=i;
522  }
523 
524  /* End of derived support */
525 
526  if ( i == 0 ) {
527  PAPIERROR( "Expected PFM event after DERIVED token at "
528  "line %d of %s -- ignoring", line_no, name );
529  goto nextline;
530  }
531  if ( i == PAPI_EVENTS_IN_DERIVED_EVENT ) {
532  t = trim_string( strtok( NULL, "," ) );
533  }
534 
535  /* Handle optional NOTEs */
536  if ( t && ( strcasecmp( t, "NOTE" ) == 0 ) ) {
537  SUBDBG( "%s found on line %d\n", t, line_no );
538 
539  /* read the rest of the line */
540  t = trim_note( strtok( NULL, "" ) );
541 
542  if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
543  PAPIERROR( "Expected Note string at line %d of %s",
544  line_no, name );
545  }
546  else {
547  _papi_hwi_presets[insert].note = strdup( t );
548  SUBDBG( "NOTE: --%s-- found on line %d\n", t, line_no );
549  }
550  }
552 
553  } else {
554  PAPIERROR( "Unrecognized token %s at line %d of %s -- ignoring",
555  t, line_no, name );
556  goto nextline;
557  }
558 nextline:
559  line_no++;
560  }
561 
562  if ( table ) {
563  fclose( table );
564  }
565 
566  SUBDBG("Done parsing preset table\n");
567 
568  return PAPI_OK;
569 }
570 
571 
572 
573 
574 /* The following code is proof of principle for reading preset events from an
575  xml file. It has been tested and works for pentium3. It relys on the expat
576  library and is invoked by adding
577  XMLFLAG = -DXML
578  to the Makefile. It is presently hardcoded to look for "./papi_events.xml"
579 */
580 #ifdef XML
581 
582 #define BUFFSIZE 8192
583 #define SPARSE_BEGIN 0
584 #define SPARSE_EVENT_SEARCH 1
585 #define SPARSE_EVENT 2
586 #define SPARSE_DESC 3
587 #define ARCH_SEARCH 4
588 #define DENSE_EVENT_SEARCH 5
589 #define DENSE_NATIVE_SEARCH 6
590 #define DENSE_NATIVE_DESC 7
591 #define FINISHED 8
592 
593 char buffer[BUFFSIZE], *xml_arch;
594 int location = SPARSE_BEGIN, sparse_index = 0, native_index, error = 0;
595 
596 /* The function below, _xml_start(), is a hook into expat's XML
597  * parser. _xml_start() defines how the parser handles the
598  * opening tags in PAPI's XML file. This function can be understood
599  * more easily if you follow along with its logic while looking at
600  * papi_events.xml. The location variable is a global telling us
601  * where we are in the XML file. Have we found our architecture's
602  * events yet? Are we looking at an event definition?...etc.
603  */
604 static void
605 _xml_start( void *data, const char *el, const char **attr )
606 {
607  int native_encoding;
608 
609  if ( location == SPARSE_BEGIN && !strcmp( "papistdevents", el ) ) {
610  location = SPARSE_EVENT_SEARCH;
611  } else if ( location == SPARSE_EVENT_SEARCH && !strcmp( "papievent", el ) ) {
612  _papi_hwi_presets[sparse_index].info.symbol = papi_strdup( attr[1] );
613 // strcpy(_papi_hwi_presets.info[sparse_index].symbol, attr[1]);
614  location = SPARSE_EVENT;
615  } else if ( location == SPARSE_EVENT && !strcmp( "desc", el ) ) {
616  location = SPARSE_DESC;
617  } else if ( location == ARCH_SEARCH && !strcmp( "availevents", el ) &&
618  !strcmp( xml_arch, attr[1] ) ) {
619  location = DENSE_EVENT_SEARCH;
620  } else if ( location == DENSE_EVENT_SEARCH && !strcmp( "papievent", el ) ) {
621  if ( !strcmp( "PAPI_NULL", attr[1] ) ) {
622  location = FINISHED;
623  return;
624  } else if ( PAPI_event_name_to_code( ( char * ) attr[1], &sparse_index )
625  != PAPI_OK ) {
626  PAPIERROR( "Improper Preset name given in XML file for %s.",
627  attr[1] );
628  error = 1;
629  }
630  sparse_index &= PAPI_PRESET_AND_MASK;
631 
632  /* allocate and initialize data space for this event */
633  papi_valid_free( _papi_hwi_presets[sparse_index].data );
634  _papi_hwi_presets[sparse_index].data =
635  papi_malloc( sizeof ( hwi_preset_data_t ) );
636  native_index = 0;
637  _papi_hwi_presets[sparse_index].data->native[native_index] = PAPI_NULL;
638  _papi_hwi_presets[sparse_index].data->operation[0] = '\0';
639 
640 
641  if ( attr[2] ) { /* derived event */
642  _papi_hwi_presets[sparse_index].data->derived =
643  _papi_hwi_derived_type( ( char * ) attr[3] );
644  /* where does DERIVED POSTSCRIPT get encoded?? */
645  if ( _papi_hwi_presets[sparse_index].data->derived == -1 ) {
646  PAPIERROR( "No derived type match for %s in Preset XML file.",
647  attr[3] );
648  error = 1;
649  }
650 
651  if ( attr[5] ) {
652  _papi_hwi_presets[sparse_index].count = atoi( attr[5] );
653  } else {
654  PAPIERROR( "No count given for %s in Preset XML file.",
655  attr[1] );
656  error = 1;
657  }
658  } else {
659  _papi_hwi_presets[sparse_index].data->derived = NOT_DERIVED;
660  _papi_hwi_presets[sparse_index].count = 1;
661  }
662  location = DENSE_NATIVE_SEARCH;
663  } else if ( location == DENSE_NATIVE_SEARCH && !strcmp( "native", el ) ) {
664  location = DENSE_NATIVE_DESC;
665  } else if ( location == DENSE_NATIVE_DESC && !strcmp( "event", el ) ) {
666  if ( _papi_hwi_native_name_to_code( attr[1], &native_encoding ) !=
667  PAPI_OK ) {
668  printf( "Improper Native name given in XML file for %s\n",
669  attr[1] );
670  PAPIERROR( "Improper Native name given in XML file for %s",
671  attr[1] );
672  error = 1;
673  }
674  _papi_hwi_presets[sparse_index].data->native[native_index] =
675  native_encoding;
676  native_index++;
677  _papi_hwi_presets[sparse_index].data->native[native_index] = PAPI_NULL;
678  } else if ( location && location != ARCH_SEARCH && location != FINISHED ) {
679  PAPIERROR( "Poorly-formed Preset XML document." );
680  error = 1;
681  }
682 }
683 
684 /* The function below, _xml_end(), is a hook into expat's XML
685  * parser. _xml_end() defines how the parser handles the
686  * end tags in PAPI's XML file.
687  */
688 static void
689 _xml_end( void *data, const char *el )
690 {
691  int i;
692 
693  if ( location == SPARSE_EVENT_SEARCH && !strcmp( "papistdevents", el ) ) {
694  for ( i = sparse_index; i < PAPI_MAX_PRESET_EVENTS; i++ ) {
695  _papi_hwi_presets[i].info.symbol = NULL;
696  _papi_hwi_presets[i].info.long_descr = NULL;
697  _papi_hwi_presets[i].info.short_descr = NULL;
698  }
699  location = ARCH_SEARCH;
700  } else if ( location == DENSE_NATIVE_DESC && !strcmp( "native", el ) ) {
701  location = DENSE_EVENT_SEARCH;
702  } else if ( location == DENSE_EVENT_SEARCH && !strcmp( "availevents", el ) ) {
703  location = FINISHED;
704  }
705 }
706 
707 /* The function below, _xml_content(), is a hook into expat's XML
708  * parser. _xml_content() defines how the parser handles the
709  * text between tags in PAPI's XML file. The information between
710  * tags is usally text for event descriptions.
711  */
712 static void
713 _xml_content( void *data, const char *el, const int len )
714 {
715  int i;
716  if ( location == SPARSE_DESC ) {
717  _papi_hwi_presets[sparse_index].info.long_descr =
718  papi_malloc( len + 1 );
719  for ( i = 0; i < len; i++ )
720  _papi_hwi_presets[sparse_index].info.long_descr[i] = el[i];
721  _papi_hwi_presets[sparse_index].info.long_descr[len] = '\0';
722  /* the XML data currently doesn't contain a short description */
723  _papi_hwi_presets[sparse_index].info.short_descr = NULL;
724  sparse_index++;
725  _papi_hwi_presets[sparse_index].data = NULL;
726  location = SPARSE_EVENT_SEARCH;
727  }
728 }
729 
730 int
731 _xml_papi_hwi_setup_all_presets( char *arch, hwi_dev_notes_t * notes )
732 {
733  int done = 0;
734  FILE *fp = fopen( "./papi_events.xml", "r" );
735  XML_Parser p = XML_ParserCreate( NULL );
736 
737  if ( !p ) {
738  PAPIERROR( "Couldn't allocate memory for XML parser." );
739  fclose(fp);
740  return ( PAPI_ESYS );
741  }
742  XML_SetElementHandler( p, _xml_start, _xml_end );
743  XML_SetCharacterDataHandler( p, _xml_content );
744  if ( fp == NULL ) {
745  PAPIERROR( "Error opening Preset XML file." );
746  fclose(fp);
747  return ( PAPI_ESYS );
748  }
749 
750  xml_arch = arch;
751 
752  do {
753  int len;
754  void *buffer = XML_GetBuffer( p, BUFFSIZE );
755 
756  if ( buffer == NULL ) {
757  PAPIERROR( "Couldn't allocate memory for XML buffer." );
758  fclose(fp);
759  return ( PAPI_ESYS );
760  }
761  len = fread( buffer, 1, BUFFSIZE, fp );
762  if ( ferror( fp ) ) {
763  PAPIERROR( "XML read error." );
764  fclose(fp);
765  return ( PAPI_ESYS );
766  }
767  done = feof( fp );
768  if ( !XML_ParseBuffer( p, len, len == 0 ) ) {
769  PAPIERROR( "Parse error at line %d:\n%s",
770  XML_GetCurrentLineNumber( p ),
771  XML_ErrorString( XML_GetErrorCode( p ) ) );
772  fclose(fp);
773  return ( PAPI_ESYS );
774  }
775  if ( error ) {
776  fclose(fp);
777  return ( PAPI_ESYS );
778  }
779  } while ( !done );
780  XML_ParserFree( p );
781  fclose( fp );
782  return ( PAPI_OK );
783 }
784 #endif
#define PAPI_ENOEVNT
Definition: papi.h:258
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
int atoi()
int errno
char * getenv()
#define PAPI_EVENTS_IN_DERIVED_EVENT
Definition: genpapifdef.c:39
#define papi_free(a)
Definition: papi_memory.h:35
unsigned int event_code
Definition: papi_preset.h:14
start
Definition: iozone.c:22736
#define papi_malloc(a)
Definition: papi_memory.h:34
#define PAPI_NULL
Definition: papi.h:290
static char * trim_note(char *in)
Definition: papi_preset.c:190
#define PAPI_MAX_PRESET_EVENTS
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
Definition: appio.c:275
int _papi_hwi_derived_type(char *tmp, int *code)
return PAPI_OK
Definition: linux-nvml.c:458
#define papi_strdup(a)
Definition: papi_memory.h:39
static int preset
Definition: event_info.c:38
#define PAPI_PRESET_MASK
fclose(thread_wqfd)
void
Definition: iozone.c:18627
return PAPI_EINVAL
Definition: linux-nvml.c:408
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
#define printf
Definition: papi_test.h:125
int _papi_hwi_native_name_to_code(char *in, int *out)
papi_vector_t * _papi_hwd[]
Return codes and api definitions.
static char * papi_events_table
Definition: papi_preset.c:295
#define INTDBG(format, args...)
Definition: papi_debug.h:65
#define papi_valid_free(a)
Definition: papi_memory.h:38
long long ret
Definition: iozone.c:1346
t
Definition: iozone.c:23562
static int find_preset_code(char *tmp, int *code)
Definition: papi_preset.c:218
int _papi_hwi_setup_all_presets(hwi_search_t *findem, int cidx)
Definition: papi_preset.c:37
int i
Definition: fileop.c:140
int _papi_hwi_native_to_eventcode(int cidx, int event_code, int ntv_idx, const char *event_name)
#define NOT_DERIVED
Definition: papi_internal.h:69
free(dummyfile[xx])
int k
Definition: iozone.c:19136
static int cidx
Definition: event_info.c:40
#define PAPI_EVENT_FILE
Definition: papi_preset.c:144
hwi_presets_t _papi_hwi_presets[PAPI_MAX_PRESET_EVENTS]
#define PAPI_ESYS
Definition: papi.h:253
static int native
Definition: event_info.c:39
int native[PAPI_EVENTS_IN_DERIVED_EVENT]
Definition: papi_preset.h:16
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
static FILE * fp
void PAPIERROR(char *format,...)
int _papi_load_preset_table(char *pmu_str, int pmu_type, int cidx)
Definition: papi_preset.c:299
char * short_descr
Definition: papi_preset.h:25
hwi_search_t * preset_search_map
static int get_event_line(char *line, FILE *table, char **tmp_perfmon_events_table)
Definition: papi_preset.c:262
static FILE * open_event_table(char *name)
Definition: papi_preset.c:235
int PAPI_event_name_to_code(char *in, int *out)
Definition: papi.c:1010
char * buffer
Definition: iozone.c:1366
void _papi_hwi_set_papi_event_code(unsigned int event_code, int update_flag)
int papi_num_components
sscanf(mnc->m_child_port,"%d",&mc.m_child_port)
#define PATH_MAX
Definition: fileop.c:68
char * name
Definition: iozone.c:23648
char * long_descr
Definition: papi_preset.h:26
int
Definition: iozone.c:18528
#define PAPI_MIN_STR_LEN
Definition: papi.h:462
unsigned int code[PAPI_MAX_INFO_TERMS]
Definition: papi_preset.h:32
char * name[PAPI_MAX_INFO_TERMS]
Definition: papi_preset.h:33
static char * trim_string(char *in)
Definition: papi_preset.c:150
int(* ntv_name_to_code)(char *, unsigned int *)
Definition: papi_vector.h:44
#define PAPI_PRESET_AND_MASK
int _xml_papi_hwi_setup_all_presets(char *arch)
long j
Definition: iozone.c:19135
char * symbol
Definition: papi_preset.h:24
long long tmp
Definition: iozone.c:12031
int _papi_hwi_cleanup_all_presets(void)
Definition: papi_preset.c:107
#define DERIVED_POSTFIX
Definition: papi_internal.h:75
unsigned int count
Definition: papi_preset.h:29
pthread_attr_t attr
Definition: iozone.c:18466
char * postfix
Definition: papi_preset.h:31