PAPI  5.3.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++) {
128  _papi_hwd[cidx]->cmp_info.num_preset_events = 0;
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 0x%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  ret=_papi_hwd[cidx]->ntv_name_to_code(t, &event_idx);
493 
494  if (ret==PAPI_OK) {
495  _papi_hwi_presets[insert].code[i]=
496  _papi_hwi_native_to_eventcode(cidx,event_idx);
497  SUBDBG("Found: %s %#x c%d e%d\n",t,
498  _papi_hwi_presets[insert].code[i],
499  cidx,event_idx);
500  }
501  else {
502  PAPIERROR("papi_preset: Error finding event %s",t);
503  invalid_event=1;
504  }
505 
506  } while ( ++i < PAPI_EVENTS_IN_DERIVED_EVENT );
507 
508  /* preset code list must be PAPI_NULL terminated */
510  _papi_hwi_presets[insert].code[i] = PAPI_NULL;
511  }
512 
513  if (invalid_event) {
514  /* We signify a valid preset if count > 0 */
515  _papi_hwi_presets[insert].count=0;
516  } else {
517  _papi_hwi_presets[insert].count=i;
518  }
519 
520  /* End of derived support */
521 
522  if ( i == 0 ) {
523  PAPIERROR( "Expected PFM event after DERIVED token at "
524  "line %d of %s -- ignoring", line_no, name );
525  goto nextline;
526  }
527  if ( i == PAPI_EVENTS_IN_DERIVED_EVENT ) {
528  t = trim_string( strtok( NULL, "," ) );
529  }
530 
531  /* Handle optional NOTEs */
532  if ( t && ( strcasecmp( t, "NOTE" ) == 0 ) ) {
533  SUBDBG( "%s found on line %d\n", t, line_no );
534 
535  /* read the rest of the line */
536  t = trim_note( strtok( NULL, "" ) );
537 
538  if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
539  PAPIERROR( "Expected Note string at line %d of %s\n",
540  line_no, name );
541  }
542  else {
543  _papi_hwi_presets[insert].note = strdup( t );
544  SUBDBG( "NOTE: --%s-- found on line %d\n", t, line_no );
545  }
546  }
547  _papi_hwd[cidx]->cmp_info.num_preset_events++;
548 
549  } else {
550  PAPIERROR( "Unrecognized token %s at line %d of %s -- ignoring",
551  t, line_no, name );
552  goto nextline;
553  }
554 nextline:
555  line_no++;
556  }
557 
558  if ( table ) {
559  fclose( table );
560  }
561 
562  SUBDBG("Done parsing preset table\n");
563 
564  return PAPI_OK;
565 }
566 
567 
568 
569 
570 /* The following code is proof of principle for reading preset events from an
571  xml file. It has been tested and works for pentium3. It relys on the expat
572  library and is invoked by adding
573  XMLFLAG = -DXML
574  to the Makefile. It is presently hardcoded to look for "./papi_events.xml"
575 */
576 #ifdef XML
577 
578 #define BUFFSIZE 8192
579 #define SPARSE_BEGIN 0
580 #define SPARSE_EVENT_SEARCH 1
581 #define SPARSE_EVENT 2
582 #define SPARSE_DESC 3
583 #define ARCH_SEARCH 4
584 #define DENSE_EVENT_SEARCH 5
585 #define DENSE_NATIVE_SEARCH 6
586 #define DENSE_NATIVE_DESC 7
587 #define FINISHED 8
588 
589 char buffer[BUFFSIZE], *xml_arch;
590 int location = SPARSE_BEGIN, sparse_index = 0, native_index, error = 0;
591 
592 /* The function below, _xml_start(), is a hook into expat's XML
593  * parser. _xml_start() defines how the parser handles the
594  * opening tags in PAPI's XML file. This function can be understood
595  * more easily if you follow along with its logic while looking at
596  * papi_events.xml. The location variable is a global telling us
597  * where we are in the XML file. Have we found our architecture's
598  * events yet? Are we looking at an event definition?...etc.
599  */
600 static void
601 _xml_start( void *data, const char *el, const char **attr )
602 {
603  int native_encoding;
604 
605  if ( location == SPARSE_BEGIN && !strcmp( "papistdevents", el ) ) {
606  location = SPARSE_EVENT_SEARCH;
607  } else if ( location == SPARSE_EVENT_SEARCH && !strcmp( "papievent", el ) ) {
608  _papi_hwi_presets[sparse_index].info.symbol = papi_strdup( attr[1] );
609 // strcpy(_papi_hwi_presets.info[sparse_index].symbol, attr[1]);
610  location = SPARSE_EVENT;
611  } else if ( location == SPARSE_EVENT && !strcmp( "desc", el ) ) {
612  location = SPARSE_DESC;
613  } else if ( location == ARCH_SEARCH && !strcmp( "availevents", el ) &&
614  !strcmp( xml_arch, attr[1] ) ) {
615  location = DENSE_EVENT_SEARCH;
616  } else if ( location == DENSE_EVENT_SEARCH && !strcmp( "papievent", el ) ) {
617  if ( !strcmp( "PAPI_NULL", attr[1] ) ) {
618  location = FINISHED;
619  return;
620  } else if ( PAPI_event_name_to_code( ( char * ) attr[1], &sparse_index )
621  != PAPI_OK ) {
622  PAPIERROR( "Improper Preset name given in XML file for %s.",
623  attr[1] );
624  error = 1;
625  }
626  sparse_index &= PAPI_PRESET_AND_MASK;
627 
628  /* allocate and initialize data space for this event */
629  papi_valid_free( _papi_hwi_presets[sparse_index].data );
630  _papi_hwi_presets[sparse_index].data =
631  papi_malloc( sizeof ( hwi_preset_data_t ) );
632  native_index = 0;
633  _papi_hwi_presets[sparse_index].data->native[native_index] = PAPI_NULL;
634  _papi_hwi_presets[sparse_index].data->operation[0] = '\0';
635 
636 
637  if ( attr[2] ) { /* derived event */
638  _papi_hwi_presets[sparse_index].data->derived =
639  _papi_hwi_derived_type( ( char * ) attr[3] );
640  /* where does DERIVED POSTSCRIPT get encoded?? */
641  if ( _papi_hwi_presets[sparse_index].data->derived == -1 ) {
642  PAPIERROR( "No derived type match for %s in Preset XML file.",
643  attr[3] );
644  error = 1;
645  }
646 
647  if ( attr[5] ) {
648  _papi_hwi_presets[sparse_index].count = atoi( attr[5] );
649  } else {
650  PAPIERROR( "No count given for %s in Preset XML file.",
651  attr[1] );
652  error = 1;
653  }
654  } else {
655  _papi_hwi_presets[sparse_index].data->derived = NOT_DERIVED;
656  _papi_hwi_presets[sparse_index].count = 1;
657  }
658  location = DENSE_NATIVE_SEARCH;
659  } else if ( location == DENSE_NATIVE_SEARCH && !strcmp( "native", el ) ) {
660  location = DENSE_NATIVE_DESC;
661  } else if ( location == DENSE_NATIVE_DESC && !strcmp( "event", el ) ) {
662  if ( _papi_hwi_native_name_to_code( attr[1], &native_encoding ) !=
663  PAPI_OK ) {
664  printf( "Improper Native name given in XML file for %s\n",
665  attr[1] );
666  PAPIERROR( "Improper Native name given in XML file for %s\n",
667  attr[1] );
668  error = 1;
669  }
670  _papi_hwi_presets[sparse_index].data->native[native_index] =
671  native_encoding;
672  native_index++;
673  _papi_hwi_presets[sparse_index].data->native[native_index] = PAPI_NULL;
674  } else if ( location && location != ARCH_SEARCH && location != FINISHED ) {
675  PAPIERROR( "Poorly-formed Preset XML document." );
676  error = 1;
677  }
678 }
679 
680 /* The function below, _xml_end(), is a hook into expat's XML
681  * parser. _xml_end() defines how the parser handles the
682  * end tags in PAPI's XML file.
683  */
684 static void
685 _xml_end( void *data, const char *el )
686 {
687  int i;
688 
689  if ( location == SPARSE_EVENT_SEARCH && !strcmp( "papistdevents", el ) ) {
690  for ( i = sparse_index; i < PAPI_MAX_PRESET_EVENTS; i++ ) {
691  _papi_hwi_presets[i].info.symbol = NULL;
692  _papi_hwi_presets[i].info.long_descr = NULL;
693  _papi_hwi_presets[i].info.short_descr = NULL;
694  }
695  location = ARCH_SEARCH;
696  } else if ( location == DENSE_NATIVE_DESC && !strcmp( "native", el ) ) {
697  location = DENSE_EVENT_SEARCH;
698  } else if ( location == DENSE_EVENT_SEARCH && !strcmp( "availevents", el ) ) {
699  location = FINISHED;
700  }
701 }
702 
703 /* The function below, _xml_content(), is a hook into expat's XML
704  * parser. _xml_content() defines how the parser handles the
705  * text between tags in PAPI's XML file. The information between
706  * tags is usally text for event descriptions.
707  */
708 static void
709 _xml_content( void *data, const char *el, const int len )
710 {
711  int i;
712  if ( location == SPARSE_DESC ) {
713  _papi_hwi_presets[sparse_index].info.long_descr =
714  papi_malloc( len + 1 );
715  for ( i = 0; i < len; i++ )
716  _papi_hwi_presets[sparse_index].info.long_descr[i] = el[i];
717  _papi_hwi_presets[sparse_index].info.long_descr[len] = '\0';
718  /* the XML data currently doesn't contain a short description */
719  _papi_hwi_presets[sparse_index].info.short_descr = NULL;
720  sparse_index++;
721  _papi_hwi_presets[sparse_index].data = NULL;
722  location = SPARSE_EVENT_SEARCH;
723  }
724 }
725 
726 int
727 _xml_papi_hwi_setup_all_presets( char *arch, hwi_dev_notes_t * notes )
728 {
729  int done = 0;
730  FILE *fp = fopen( "./papi_events.xml", "r" );
731  XML_Parser p = XML_ParserCreate( NULL );
732 
733  if ( !p ) {
734  PAPIERROR( "Couldn't allocate memory for XML parser." );
735  fclose(fp);
736  return ( PAPI_ESYS );
737  }
738  XML_SetElementHandler( p, _xml_start, _xml_end );
739  XML_SetCharacterDataHandler( p, _xml_content );
740  if ( fp == NULL ) {
741  PAPIERROR( "Error opening Preset XML file." );
742  fclose(fp);
743  return ( PAPI_ESYS );
744  }
745 
746  xml_arch = arch;
747 
748  do {
749  int len;
750  void *buffer = XML_GetBuffer( p, BUFFSIZE );
751 
752  if ( buffer == NULL ) {
753  PAPIERROR( "Couldn't allocate memory for XML buffer." );
754  fclose(fp);
755  return ( PAPI_ESYS );
756  }
757  len = fread( buffer, 1, BUFFSIZE, fp );
758  if ( ferror( fp ) ) {
759  PAPIERROR( "XML read error." );
760  fclose(fp);
761  return ( PAPI_ESYS );
762  }
763  done = feof( fp );
764  if ( !XML_ParseBuffer( p, len, len == 0 ) ) {
765  PAPIERROR( "Parse error at line %d:\n%s\n",
766  XML_GetCurrentLineNumber( p ),
767  XML_ErrorString( XML_GetErrorCode( p ) ) );
768  fclose(fp);
769  return ( PAPI_ESYS );
770  }
771  if ( error ) {
772  fclose(fp);
773  return ( PAPI_ESYS );
774  }
775  } while ( !done );
776  XML_ParserFree( p );
777  fclose( fp );
778  return ( PAPI_OK );
779 }
780 #endif
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_NULL
Definition: fpapi.h:13
#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_MIN_STR_LEN
Definition: fpapi.h:41
#define PAPI_ENOEVNT
Definition: fpapi.h:112
static char * trim_note(char *in)
Definition: papi_preset.c:190
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
#define printf
Definition: papi_test.h:125
int _papi_hwi_native_name_to_code(char *in, int *out)
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
#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]
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
#define PAPI_ESYS
Definition: fpapi.h:108
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_hwi_native_to_eventcode(int cidx, int event_code)
int PAPI_event_name_to_code(char *in, int *out)
Definition: papi.c:1003
char * buffer
Definition: iozone.c:1366
#define PAPI_MAX_PRESET_EVENTS
Definition: fpapi.h:16
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
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
#define PAPI_PRESET_AND_MASK
struct papi_vectors * _papi_hwd[]
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