PAPI  5.3.2.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hybrid_native_avail.c
Go to the documentation of this file.
1 /* This file utility reports hardware info and native event availability on either the host
2  * CPU or on one of the attached MIC devices. It is based on the papi_native_avail utility,
3  * but uses offloading to run either on the host CPU or on a target device. */
50 #pragma offload_attribute (push,target(mic))
51 #include "papi_test.h"
52 #pragma offload_attribute (pop)
53 
54 #include <stdlib.h>
55 #include <offload.h>
56 
57 #define EVT_LINE 80
58 
59 typedef struct command_flags
60 {
61  int help;
62  int details;
63  int named;
64  int include;
65  int xclude;
66  char *name, *istr, *xstr;
67  int darr;
68  int dear;
69  int iarr;
70  int iear;
71  int opcm;
72  int umask;
73  int groups;
74  int mic;
75  int devidx;
77 
78 static void
79 print_help( char **argv )
80 {
81  printf( "This is the PAPI native avail program.\n" );
82  printf( "It provides availability and detail information for PAPI native events.\n" );
83  printf( "Usage: %s [options]\n", argv[0] );
84  printf( "\nOptions:\n" );
85  printf( " --help, -h print this help message\n" );
86  printf( " -d display detailed information about native events\n" );
87  printf( " -e EVENTNAME display detailed information about named native event\n" );
88  printf( " -i EVENTSTR include only event names that contain EVENTSTR\n" );
89  printf( " -x EVENTSTR exclude any event names that contain EVENTSTR\n" );
90  printf( " --noumasks suppress display of Unit Mask information\n" );
91  printf( "\nProcessor-specific options\n");
92  printf( " --darr display events supporting Data Address Range Restriction\n" );
93  printf( " --dear display Data Event Address Register events only\n" );
94  printf( " --iarr display events supporting Instruction Address Range Restriction\n" );
95  printf( " --iear display Instruction Event Address Register events only\n" );
96  printf( " --opcm display events supporting OpCode Matching\n" );
97  printf( " --nogroups suppress display of Event grouping information\n" );
98  printf( " --mic <index> display events on the specified Xeon Phi device\n" );
99  printf( "\n" );
100 }
101 
102 static int
103 no_str_arg( char *arg )
104 {
105  return ( ( arg == NULL ) || ( strlen( arg ) == 0 ) || ( arg[0] == '-' ) );
106 }
107 
108 static void
110 {
111 
112  int i;
113 
114  /* Look for all currently defined commands */
115  memset( f, 0, sizeof ( command_flags_t ) );
116  f->umask = 1;
117  f->groups = 1;
118 
119  for ( i = 1; i < argc; i++ ) {
120  if ( !strcmp( argv[i], "--darr" ) )
121  f->darr = 1;
122  else if ( !strcmp( argv[i], "--dear" ) )
123  f->dear = 1;
124  else if ( !strcmp( argv[i], "--iarr" ) )
125  f->iarr = 1;
126  else if ( !strcmp( argv[i], "--iear" ) )
127  f->iear = 1;
128  else if ( !strcmp( argv[i], "--opcm" ) )
129  f->opcm = 1;
130  else if ( !strcmp( argv[i], "--noumasks" ) )
131  f->umask = 0;
132  else if ( !strcmp( argv[i], "--nogroups" ) )
133  f->groups = 0;
134  else if ( !strcmp( argv[i], "-d" ) )
135  f->details = 1;
136  else if ( !strcmp( argv[i], "--mic" ) )
137  {
138  f->mic = 1;
139  i++;
140  if ( i >= argc || no_str_arg( argv[i] ) ) {
141  printf( "Specify a device index for --mic\n");
142  exit(1);
143  }
144  f->devidx = strtol(argv[i], 0, 10);
145  } else if ( !strcmp( argv[i], "-e" ) ) {
146  f->named = 1;
147  i++;
148  f->name = argv[i];
149  if ( i >= argc || no_str_arg( f->name ) ) {
150  printf( "Invalid argument for -e\n");
151  exit(1);
152  }
153  } else if ( !strcmp( argv[i], "-i" ) ) {
154  f->include = 1;
155  i++;
156  f->istr = argv[i];
157  if ( i >= argc || no_str_arg( f->istr ) ) {
158  printf( "Invalid argument for -i\n");
159  exit(1);
160  }
161  } else if ( !strcmp( argv[i], "-x" ) ) {
162  f->xclude = 1;
163  i++;
164  f->xstr = argv[i];
165  if ( i >= argc || no_str_arg( f->xstr ) ) {
166  printf( "Invalid argument for -x\n");
167  exit(1);
168  }
169  } else if ( !strcmp( argv[i], "-h" ) || !strcmp( argv[i], "--help" ) )
170  f->help = 1;
171  else {
172  printf( "%s is not supported\n", argv[i] );
173  exit(1);
174  }
175  }
176 
177  /* if help requested, print and bail */
178  if ( f->help ) {
179  print_help( argv);
180  exit( 1 );
181  }
182 }
183 
184 static void
185 space_pad( char *str, int spaces )
186 {
187  while ( spaces-- > 0 )
188  strcat( str, " " );
189 }
190 
191 static void
193 {
194  unsigned int i, j = 0;
195  char str[EVT_LINE + EVT_LINE];
196 
197  /* indent by offset */
198  if ( offset ) {
199  printf( "| %-73s|\n", info->symbol );
200  }
201  else {
202  printf( "| %-77s|\n", info->symbol );
203  }
204 
205  while ( j <= strlen( info->long_descr ) ) {
206  i = EVT_LINE - 12 - 2;
207  if ( i > 0 ) {
208  str[0] = 0;
209  strcat(str,"| " );
210  space_pad( str, 11 );
211  strncat( str, &info->long_descr[j], i );
212  j += i;
213  i = ( unsigned int ) strlen( str );
214  space_pad( str, EVT_LINE - ( int ) i - 1 );
215  strcat( str, "|" );
216  }
217  printf( "%s\n", str );
218  }
219 }
220 
221 static int
223 {
224  char *pmask,*ptr;
225 
226  /* handle the PAPI component-style events which have a component:::event type */
227  if ((ptr=strstr(info->symbol, ":::"))) {
228  ptr+=3;
229  /* handle libpfm4-style events which have a pmu::event type event name */
230  } else if ((ptr=strstr(info->symbol, "::"))) {
231  ptr+=2;
232  }
233  else {
234  ptr=info->symbol;
235  }
236 
237  if ( ( pmask = strchr( ptr, ':' ) ) == NULL ) {
238  return ( 0 );
239  }
240  memmove( info->symbol, pmask, ( strlen( pmask ) + 1 ) * sizeof ( char ) );
241  pmask = strchr( info->long_descr, ':' );
242  if ( pmask == NULL )
243  info->long_descr[0] = 0;
244  else
245  memmove( info->long_descr, pmask + sizeof ( char ),
246  ( strlen( pmask ) + 1 ) * sizeof ( char ) );
247  return ( 1 );
248 }
249 
250 
251 int
252 main( int argc, char **argv )
253 {
254  int i, j = 0, k;
255  int retval;
256  PAPI_event_info_t info;
257  const PAPI_hw_info_t *hwinfo = NULL;
259  int enum_modifier;
260  int numcmp, cid;
261 
262  int num_devices = 0;
263  int target_idx = 0;
264  int offload_mode = 0;
265  int target_ok = 0;
266 
267  /* Parse the command-line arguments */
268  parse_args( argc, argv, &flags );
269 
270  if (flags.mic)
271  {
272  printf("Checking for Intel(R) Xeon Phi(TM) (Target CPU) devices...\n\n");
273 
274 #ifdef __INTEL_OFFLOAD
275  num_devices = _Offload_number_of_devices();
276 #endif
277  printf("Number of Target devices installed: %d\n\n",num_devices);
278 
279  if (flags.devidx >= num_devices) {
280  // Run in fallback-mode
281  printf("Requested device index %d is not available. Specify a device between 0 and %d\n\n",
282  flags.devidx, num_devices-1);
283  exit(1);
284  }
285  else {
286  offload_mode = 1;
287  target_idx = flags.devidx;
288  printf("PAPI will list the native events available on device mic%d\n\n", target_idx);
289  }
290  }
291 
292  /* Set enum modifier mask */
293  if ( flags.dear )
294  enum_modifier = PAPI_NTV_ENUM_DEAR;
295  else if ( flags.darr )
296  enum_modifier = PAPI_NTV_ENUM_DARR;
297  else if ( flags.iear )
298  enum_modifier = PAPI_NTV_ENUM_IEAR;
299  else if ( flags.iarr )
300  enum_modifier = PAPI_NTV_ENUM_IARR;
301  else if ( flags.opcm )
302  enum_modifier = PAPI_NTV_ENUM_OPCM;
303  else
304  enum_modifier = PAPI_ENUM_EVENTS;
305 
306  /* Set TESTS_QUIET variable */
308  tests_quiet( argc, argv );
309 
310  /* Initialize before parsing the input arguments */
311 #ifdef __INTEL_OFFLOAD
312  __Offload_report(1);
313 #endif
314  #pragma offload target(mic: target_idx) if(offload_mode)
316  if ( retval != PAPI_VER_CURRENT ) {
317  test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
318  }
319 
320 
321  if ( !TESTS_QUIET ) {
322 #ifdef __INTEL_OFFLOAD
323  __Offload_report(1);
324 #endif
325  #pragma offload target(mic: target_idx) if(offload_mode)
326  retval = PAPI_set_debug( PAPI_VERB_ECONT );
327  if ( retval != PAPI_OK ) {
328  test_fail( __FILE__, __LINE__, "PAPI_set_debug", retval );
329  }
330  }
331 
332 #ifdef __INTEL_OFFLOAD
333  __Offload_report(1);
334 #endif
335  #pragma offload target(mic: target_idx) if(offload_mode) nocopy(hwinfo)
336  {
337  retval = papi_print_header( "Available native events and hardware information.\n", &hwinfo );
338  fflush(stdout);
339  }
340  if ( retval != PAPI_OK ) {
341  test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 2 );
342  }
343 
344 
345  /* Do this code if the event name option was specified on the commandline */
346  if ( flags.named )
347  {
348  int papi_ok = 0;
349  char *ename = flags.name;
350  int elen = 0;
351  if (ename)
352  elen = strlen(ename) + 1;
353 #ifdef __INTEL_OFFLOAD
354  __Offload_report(1);
355 #endif
356  #pragma offload target(mic: target_idx) if(offload_mode) in(ename:length(elen)) out(i)
357  papi_ok = PAPI_event_name_to_code(ename, &i);
358 
359  if (papi_ok == PAPI_OK)
360  {
361 #ifdef __INTEL_OFFLOAD
362  __Offload_report(1);
363 #endif
364  #pragma offload target(mic: target_idx) if(offload_mode) out(info)
365  papi_ok = PAPI_get_event_info(i, &info);
366  }
367 
368  if (papi_ok == PAPI_OK)
369  {
370  printf( "%-30s%s\n",
371  "Event name:", info.symbol);
372  printf( "%-29s|%s|\n", "Description:", info.long_descr );
373 
374  /* if unit masks exist but none specified, process all */
375  if ( !strchr( flags.name, ':' ) )
376  {
377 #ifdef __INTEL_OFFLOAD
378  __Offload_report(1);
379 #endif
380  #pragma offload target(mic: target_idx) if(offload_mode) inout(i)
381  papi_ok = PAPI_enum_event( &i, PAPI_NTV_ENUM_UMASKS);
382  if (papi_ok == PAPI_OK )
383  {
384  printf( "\nUnit Masks:\n" );
385  do
386  {
387 #ifdef __INTEL_OFFLOAD
388  __Offload_report(1);
389 #endif
390  #pragma offload target(mic: target_idx) if(offload_mode) inout(i, info)
391  retval = PAPI_get_event_info( i, &info );
392  if ( retval == PAPI_OK ) {
393  if ( parse_unit_masks( &info ) ) {
394  printf( "%-29s|%s|%s|\n", " Mask Info:",
395  info.symbol, info.long_descr );
396  }
397  }
398 #ifdef __INTEL_OFFLOAD
399  __Offload_report(1);
400 #endif
401  #pragma offload target(mic: target_idx) if(offload_mode) inout(i, info)
402  papi_ok = PAPI_enum_event(&i, PAPI_NTV_ENUM_UMASKS);
403  } while (papi_ok == PAPI_OK);
404  }
405  }
406  } else {
407  printf("Sorry, an event by the name '%s' could not be found.\n",
408  flags.name);
409  printf("Is it typed correctly?\n\n");
410  exit( 1 );
411  }
412  }
413  else {
414 
415  /* Print *ALL* available events */
416 
417 #ifdef __INTEL_OFFLOAD
418  __Offload_report(1);
419 #endif
420  #pragma offload target(mic: target_idx) if(offload_mode)
421  numcmp = PAPI_num_components( );
422 
423  j = 0;
424 
425  for ( cid = 0; cid < numcmp; cid++ ) {
426 
427  PAPI_component_info_t component;
428 // if (offload_mode) // I must allocate local memory to receive the result
429 // component = (PAPI_component_info_t*)malloc(sizeof(PAPI_component_info_t));
430 // #pragma offload target(mic: target_idx) if(offload_mode) out(*component:length(sizeof(PAPI_component_info_t)) alloc_if(0) free_if(0))
431 #ifdef __INTEL_OFFLOAD
432  __Offload_report(1);
433 #endif
434  #pragma offload target(mic: target_idx) if(offload_mode) out(component)
435  {
436  memcpy(&component, PAPI_get_component_info(cid), sizeof(PAPI_component_info_t));
437  }
438 
439  /* Skip disabled components */
440  if (component.disabled) continue;
441 
442  printf( "===============================================================================\n" );
443  printf( " Native Events in Component: %s\n",component.name);
444  printf( "===============================================================================\n" );
445 
446  /* Always ASK FOR the first event */
447  /* Don't just assume it'll be the first numeric value */
448  i = 0 | PAPI_NATIVE_MASK;
449 
450 #ifdef __INTEL_OFFLOAD
451  __Offload_report(1);
452 #endif
453  #pragma offload target(mic: target_idx) if(offload_mode) inout(i)
454  retval=PAPI_enum_cmp_event( &i, PAPI_ENUM_FIRST, cid );
455 
456  do
457  {
458  memset( &info, 0, sizeof ( info ) );
459 #ifdef __INTEL_OFFLOAD
460  __Offload_report(1);
461 #endif
462  #pragma offload target(mic: target_idx) if(offload_mode) inout(info)
463  retval = PAPI_get_event_info( i, &info );
464 
465  /* This event may not exist */
466  if ( retval != PAPI_OK )
467  goto endloop;
468 
469  /* Bail if event name doesn't contain include string */
470  if ( flags.include ) {
471  if ( !strstr( info.symbol, flags.istr ) ) {
472  goto endloop;
473  }
474  }
475 
476  /* Bail if event name does contain exclude string */
477  if ( flags.xclude ) {
478  if ( strstr( info.symbol, flags.xstr ) )
479  goto endloop;
480  }
481 
482  /* count only events that are actually processed */
483  j++;
484 
485  print_event( &info, 0 );
486 
487  if (flags.details) {
488  if (info.units[0]) printf( "| Units: %-67s|\n",
489  info.units );
490  }
491 
492 /* modifier = PAPI_NTV_ENUM_GROUPS returns event codes with a
493  groups id for each group in which this
494  native event lives, in bits 16 - 23 of event code
495  terminating with PAPI_ENOEVNT at the end of the list.
496 */
497 
498  /* This is an IBM Power issue */
499  if ( flags.groups ) {
500  int papi_ok = 0;
501  k = i;
502 #ifdef __INTEL_OFFLOAD
503  __Offload_report(1);
504 #endif
505  #pragma offload target(mic: target_idx) if(offload_mode) inout(k)
506  papi_ok = PAPI_enum_cmp_event(&k, PAPI_NTV_ENUM_GROUPS, cid);
507  if (papi_ok == PAPI_OK )
508  {
509  printf("Groups: ");
510  do {
511  printf( "%4d", ( ( k & PAPI_NTV_GROUP_AND_MASK ) >>
512  PAPI_NTV_GROUP_SHIFT ) - 1 );
513 #ifdef __INTEL_OFFLOAD
514  __Offload_report(1);
515 #endif
516  #pragma offload target(mic: target_idx) if(offload_mode) inout(k)
517  papi_ok = PAPI_enum_cmp_event(&k, PAPI_NTV_ENUM_GROUPS, cid);
518  } while (papi_ok==PAPI_OK );
519  printf( "\n" );
520  }
521  }
522 
523  /* Print umasks */
524  /* components that don't have them can just ignore */
525 
526  if ( flags.umask )
527  {
528  int papi_ok = 0;
529  k = i;
530 #ifdef __INTEL_OFFLOAD
531  __Offload_report(1);
532 #endif
533  #pragma offload target(mic: target_idx) if(offload_mode) inout(k)
534  papi_ok = PAPI_enum_cmp_event(&k, PAPI_NTV_ENUM_UMASKS, cid);
535  if (papi_ok == PAPI_OK )
536  {
537  do {
538 #ifdef __INTEL_OFFLOAD
539  __Offload_report(1);
540 #endif
541  #pragma offload target(mic: target_idx) if(offload_mode) inout(info)
542  retval = PAPI_get_event_info(k, &info);
543  if ( retval == PAPI_OK ) {
544  if (parse_unit_masks( &info ))
545  print_event(&info, 2);
546  }
547 #ifdef __INTEL_OFFLOAD
548  __Offload_report(1);
549 #endif
550  #pragma offload target(mic: target_idx) if(offload_mode) inout(k)
551  papi_ok = PAPI_enum_cmp_event(&k, PAPI_NTV_ENUM_UMASKS, cid);
552  } while (papi_ok == PAPI_OK);
553  }
554  }
555  printf( "--------------------------------------------------------------------------------\n" );
556 
557 endloop:
558 #ifdef __INTEL_OFFLOAD
559  __Offload_report(1);
560 #endif
561  #pragma offload target(mic: target_idx) if(offload_mode) inout(i)
562  retval=PAPI_enum_cmp_event(&i, enum_modifier, cid);
563  } while (retval == PAPI_OK );
564  }
565 
566 
567  printf("\n");
568  printf( "Total events reported: %d\n", j );
569  }
570 
571  test_pass( __FILE__, NULL, 0 );
572  exit( 0 );
573 }
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:625
memset(eventId, 0, size)
#define PAPI_NATIVE_MASK
double f(double a)
Definition: cpi.c:23
const PAPI_component_info_t * PAPI_get_component_info(int cidx)
Definition: papi.c:805
Hardware info structure.
Definition: papi.h:775
long long flags
Definition: iozone.c:12330
int papi_print_header(char *prompt, const PAPI_hw_info_t **hwinfo)
Definition: test_utils.c:21
off64_t offset
Definition: iozone.c:1279
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:964
int PAPI_num_components(void)
Definition: papi.c:4285
int PAPI_enum_event(int *EventCode, int modifier)
Definition: papi.c:1148
#define PAPI_VERB_ECONT
Definition: fpapi.h:39
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:961
return PAPI_OK
Definition: linux-nvml.c:458
tests_quiet(argc, argv)
fflush(stdout)
static void print_event(PAPI_event_info_t *info, int offset)
#define printf
Definition: papi_test.h:125
test_pass(__FILE__, NULL, 0)
int int argc
Definition: iozone.c:1609
int PAPI_get_event_info(int EventCode, PAPI_event_info_t *info)
Definition: papi.c:844
static void space_pad(char *str, int spaces)
int TESTS_QUIET
Definition: test_utils.c:11
char ** argv
Definition: iozone.c:1610
test_fail(__FILE__, __LINE__,"PAPI_library_init", retval)
int PAPI_library_init(int version)
Definition: papi.c:495
int i
Definition: fileop.c:140
#define PAPI_NTV_GROUP_SHIFT
Definition: papi.h:523
int k
Definition: iozone.c:19136
#define PAPI_VER_CURRENT
Definition: fpapi.h:14
strcat(command, mountname)
int PAPI_enum_cmp_event(int *EventCode, int modifier, int cidx)
Definition: papi.c:1311
again struct sockaddr sizeof(struct sockaddr_in))
int PAPI_event_name_to_code(char *in, int *out)
Definition: papi.c:1008
char * help[]
Definition: iozone.c:129
#define PAPI_NTV_GROUP_AND_MASK
Definition: papi.h:522
static int no_str_arg(char *arg)
#define EVT_LINE
char * name
Definition: iozone.c:23648
int
Definition: iozone.c:18528
static void parse_args(int argc, char **argv, command_flags_t *f)
static void print_help(char **argv)
long j
Definition: iozone.c:19135
ssize_t retval
Definition: libasync.c:338
int main(int argc, char **argv)
List all appio events codes and names.
void exit()
char units[PAPI_MIN_STR_LEN]
Definition: papi.h:970
int PAPI_set_debug(int level)
Definition: papi.c:3037
static int parse_unit_masks(PAPI_event_info_t *info)
char * ptr
Definition: iozone.c:23586