File: papi_avail.c

package info (click to toggle)
papi 5.7.0+dfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 9,856 kB
  • sloc: ansic: 93,265; fortran: 3,338; xml: 2,460; makefile: 815; sh: 290
file content (604 lines) | stat: -rw-r--r-- 24,184 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
// Define the papi_avail man page contents.
/**
  * file papi_avail.c
  *	@brief papi_avail utility.
  * @page papi_avail
  *	@section Name
  *	papi_avail - provides availability and detailed information for PAPI preset and user defined events.
  *
  *	@section Synopsis
  *	papi_avail [-adht] [-e event]
  *
  *	@section Description
  *	papi_avail is a PAPI utility program that reports information about the 
  *	current PAPI installation and supported preset and user defined events.
  *
  *	@section Options
  * <ul>
  *		<li>-h	Display help information about this utility.
  *		<li>-a	Display only the available PAPI events.
  *     <li>-c  Display only the available PAPI events after a check.
  *		<li>-d	Display PAPI event information in a more detailed format.
  *		<li>-e < event >	Display detailed event information for the named event. 
  *			This event can be a preset event, a user defined event, or a native event.
  *			If the event is a preset or a user defined event the output shows a list of native
  *			events the event is based on and the formula that is used to compute the events final value.\n
  *	</ul>
  *
  * Event filtering options 
  * <ul>
  *     <li>--br        Display branch related PAPI preset events
  *     <li>--cache     Display cache related PAPI preset events
  *     <li>--cnd       Display conditional PAPI preset events
  *     <li>--fp        Display Floating Point related PAPI preset events
  *     <li>--ins       Display instruction related PAPI preset events
  *     <li>--idl       Display Stalled or Idle PAPI preset events
  *     <li>--l1        Display level 1 cache related PAPI preset events
  *     <li>--l2        Display level 2 cache related PAPI preset events
  *     <li>--l3        Display level 3 cache related PAPI preset events
  *     <li>--mem       Display memory related PAPI preset events
  *     <li>--msc       Display miscellaneous PAPI preset events
  *     <li>--tlb       Display Translation Lookaside Buffer PAPI preset events
  * </ul>
  *	@section Bugs
  *	There are no known bugs in this utility.
  *	If you find a bug, it should be reported to the PAPI Mailing List at <ptools-perfapi@icl.utk.edu>.
  * <br>
  *	@see PAPI_derived_event_files
  *
  */

// Define the PAPI_derived_event_files man page contents.
/**
 *	@page PAPI_derived_event_files
 *	@brief Describes derived event definition file syntax.
 *
 *	@section main Derived Events
 *		PAPI provides the ability to define events whose value will be derived from multiple native events.  The list of native
 *		events to be used in a derived event and a formula which describes how to use them is provided in an event definition file.
 *		The PAPI team provides an event definition file which describes all of the supported PAPI preset events.  PAPI also allows
 *		a user to provide an event definition file that describes a set of user defined events which can extend the events PAPI
 *		normally supports.
 *
 *		This page documents the syntax of the commands which can appear in an event definition file.
 *
 * <br>
 *	@subsection rules General Rules:
 *	<ul>
 *		<li>Blank lines are ignored.</li>
 *		<li>Lines that begin with '#' are comments (they are also ignored).</li>
 *		<li>Names shown inside < > below represent values that must be provided by the user.</li>
 *		<li>If a user provided value contains white space, it must be protected with quotes.</li>
 *	</ul>
 *
 * <br>
 *	@subsection commands Commands:
 *		@par CPU,\<pmuName\>
 *		Specifies a PMU name which controls if the PRESET and EVENT commands that follow this line should
 *		be processed.  Multiple CPU commands can be entered without PRESET or EVENT commands between them to provide
 *		a list of PMU names to which the derived events that follow will apply.  When a PMU name provided in the list
 *		matches a PMU name known to the running system, the events which follow will be created.  If none of the PMU
 *		names provided in the list match a PMU name on the running system, the events which follow will be ignored.
 *		When a new CPU command follows either a PRESET or EVENT command, the PMU list is rebuilt.<br><br>
 *
 *		@par PRESET,\<eventName\>,\<derivedType\>,\<eventAttr\>,LDESC,\"\<longDesc\>\",SDESC,\"\<shortDesc\>\",NOTE,\"\<note\>\"
 *		Declare a PAPI preset derived event.<br><br>
 *
 *		@par EVENT,\<eventName\>,\<derivedType\>,\<eventAttr\>,LDESC,\"\<longDesc\>\",SDESC,\"\<shortDesc\>\",NOTE,\"\<note\>\"
 *		Declare a user defined derived event.<br><br>
 *
 *		@par Where:
 *		@par pmuName:
 *			The PMU which the following events should apply to.  A list of PMU names supported by your
 *			system can be obtained by running papi_component_avail on your system.<br>
 *		@par eventName:
 *			Specifies the name used to identify this derived event.  This name should be unique within the events on your system.<br>
 *		@par derivedType:
 *			Specifies the kind of derived event being defined (see 'Derived Types' below).<br>
 *		@par eventAttr:
 *			Specifies a formula and a list of base events that are used to compute the derived events value.  The syntax
 *			of this field depends on the 'derivedType' specified above (see 'Derived Types' below).<br>
 *		@par longDesc:
 *			Provides the long description of the event.<br>
 *		@par shortDesc:
 *			Provides the short description of the event.<br>
 *		@par note:
 *			Provides an event note.<br>
 *		@par baseEvent (used below):
 *			Identifies an event on which this derived event is based.  This may be a native event (possibly with event masks),
 *			an already known preset event, or an already known user event.<br>
 *
 * <br>
 *	@subsection notes Notes:
 *		The PRESET command has traditionally been used in the PAPI provided preset definition file.
 *		The EVENT command is intended to be used in user defined event definition files.  The code treats them
 *		the same so they are interchangeable and they can both be used in either event definition file.<br>
 *
 * <br>
 *	@subsection types Derived Types:
 *		This describes values allowed in the 'derivedType' field of the PRESET and EVENT commands.  It also
 *		shows the syntax of the 'eventAttr' field for each derived type supported by these commands.
 *		All of the derived events provide a list of one or more events which the derived event is based
 *		on (baseEvent).  Some derived events provide a formula that specifies how to compute the derived
 *		events value using the baseEvents in the list.  The following derived types are supported, the syntax
 *		of the 'eventAttr' parameter for each derived event type is shown in parentheses.<br><br>
 *
 *		@par NOT_DERIVED (\<baseEvent\>):
 *			This derived type defines an alias for the existing event 'baseEvent'.<br>
 *		@par DERIVED_ADD (\<baseEvent1\>,\<baseEvent2\>):
 *			This derived type defines a new event that will be the sum of two other
 *			events.  It has a value of 'baseEvent1' plus 'baseEvent2'.<br>
 *		@par DERIVED_PS (PAPI_TOT_CYC,\<baseEvent1\>):
 *			This derived type defines a new event that will report the number of 'baseEvent1' events which occurred
 *			per second.  It has a value of ((('baseEvent1' * cpu_max_mhz) * 1000000 ) / PAPI_TOT_CYC).  The user must
 *			provide PAPI_TOT_CYC as the first event of two events in the event list for this to work correctly.<br>
 *		@par DERIVED_ADD_PS (PAPI_TOT_CYC,\<baseEvent1\>,\<baseEvent2\>):
 *			This derived type defines a new event that will add together two event counters and then report the number
 *			which occurred per second.  It has a value of (((('baseEvent1' + baseEvent2) * cpu_max_mhz) * 1000000 ) / PAPI_TOT_CYC).
 *			The user must provide PAPI_TOT_CYC as the first event of three events in the event list for this to work correctly.<br>
 *		@par DERIVED_CMPD (\<baseEvent1\>,\<baseEvent2\):
 *			This derived type works much like the NOT_DERIVED type.  It is rarely used and it looks like the code just returns
 *			a single value returned from the kernel.  There is no calculation done to compute this events value.  Not sure why
 *			multiple input events seem to be needed to use this event type.<br>
 *		@par DERIVED_SUB (\<baseEvent1\>,\<baseEvent2\>):
 *			This derived type defines a new event that will be the difference between two other
 *			events.  It has a value of 'baseEvent1' minus 'baseEvent2'.<br>
 *		@par DERIVED_POSTFIX (\<pfFormula\>,\<baseEvent1\>,\<baseEvent2\>, ... ,\<baseEventn\>):
 *			This derived type defines a new event whose value is computed from several native events using
 *			a postfix (reverse polish notation) formula.  Its value is the result of processing the postfix
 *			formula.  The 'pfFormula' is of the form 'N0|N1|N2|5|*|+|-|' where the '|' acts as a token
 *			separator and the tokens N0, N1, and N2 are place holders that represent baseEvent0, baseEvent1,
 *			and baseEvent2 respectively.<br>
 *		@par DERIVED_INFIX (\<ifFormula\>,\<baseEvent1\>,\<baseEvent2\>, ... ,\<baseEventn\>):
 *			This derived type defines a new event whose value is computed from several native events using
 *			an infix (algebraic notation) formula.  Its value is the result of processing the infix
 *			formula.  The 'ifFormula' is of the form 'N0-(N1+(N2*5))' where the tokens N0, N1, and N2
 *			are place holders that represent baseEvent0, baseEvent1, and baseEvent2 respectively.<br>
 *
 * <br>
 *	@subsection example Example:
 *		In the following example, the events PAPI_SP_OPS, USER_SP_OPS, and ALIAS_SP_OPS will all measure the same events and return
 *		the same value.  They just demonstrate different ways to use the PRESET and EVENT event definition commands.<br><br>
 *
 *		<ul>
 *			<li># The following lines define pmu names that all share the following events</li>
 *			<li>CPU nhm</li>
 *			<li>CPU nhm-ex</li>
 *			<li>\# Events which should be defined for either of the above pmu types</li>
 *			<li>PRESET,PAPI_TOT_CYC,NOT_DERIVED,UNHALTED_CORE_CYCLES</li>
 *			<li>PRESET,PAPI_REF_CYC,NOT_DERIVED,UNHALTED_REFERENCE_CYCLES</li>
 *			<li>PRESET,PAPI_SP_OPS,DERIVED_POSTFIX,N0|N1|3|*|+|,FP_COMP_OPS_EXE:SSE_SINGLE_PRECISION,FP_COMP_OPS_EXE:SSE_FP_PACKED,NOTE,"Using a postfix formula"</li>
 *			<li>EVENT,USER_SP_OPS,DERIVED_INFIX,N0+(N1*3),FP_COMP_OPS_EXE:SSE_SINGLE_PRECISION,FP_COMP_OPS_EXE:SSE_FP_PACKED,NOTE,"Using the same formula in infix format"</li>
 *			<li>EVENT,ALIAS_SP_OPS,NOT_DERIVED,PAPI_SP_OPS,LDESC,"Alias for preset event PAPI_SP_OPS"</li>
 *			<li># End of event definitions for above pmu names and start of a section for a new pmu name.</li>
 *			<li>CPU snb</li>
 *		</ul>
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "papi.h"
#include "print_header.h"

static char *
is_derived( PAPI_event_info_t * info )
{
	if ( strlen( info->derived ) == 0 )
		return ( "No" );
	else if ( strcmp( info->derived, "NOT_DERIVED" ) == 0 )
		return ( "No" );
	else if ( strcmp( info->derived, "DERIVED_CMPD" ) == 0 )
		return ( "No" );
	else
		return ( "Yes" );
}

static void
print_help( char **argv )
{
        printf( "This is the PAPI avail program.\n" );
        printf( "It provides availability and details about PAPI Presets and User-defined Events.\n" );
	printf( "PAPI Preset Event filters can be combined in a logical OR.\n" );
	printf( "Usage: %s [options]\n", argv[0] );
	printf( "Options:\n\n" );
	printf( "General command options:\n" );
	printf( "\t-h, --help       Print this help message\n" );
	printf( "\t-a, --avail      Display only available PAPI preset and user defined events\n" );
	printf( "\t-c, --check      Display only available PAPI preset and user defined events after an availability check\n" );
	printf( "\t-d, --detail     Display detailed information about events\n" );
	printf( "\t-e EVENTNAME     Display detail information about specified event\n" );
	printf( "\nEvent filtering options:\n" );
	printf( "\t--br             Display branch related PAPI preset events\n" );
	printf( "\t--cache          Display cache related PAPI preset events\n" );
	printf( "\t--cnd            Display conditional PAPI preset events\n" );
	printf( "\t--fp             Display Floating Point related PAPI preset events\n" );
	printf( "\t--ins            Display instruction related PAPI preset events\n" );
	printf( "\t--idl            Display Stalled or Idle PAPI preset events\n" );
	printf( "\t--l1             Display level 1 cache related PAPI preset events\n" );
	printf( "\t--l2             Display level 2 cache related PAPI preset events\n" );
	printf( "\t--l3             Display level 3 cache related PAPI preset events\n" );
	printf( "\t--mem            Display memory related PAPI preset events\n" );
	printf( "\t--msc            Display miscellaneous PAPI preset events\n" );
	printf( "\t--tlb            Display Translation Lookaside Buffer PAPI preset events\n" );
	printf( "\n" );
}

static int
parse_unit_masks( PAPI_event_info_t * info )
{
	char *pmask;

	if ( ( pmask = strchr( info->symbol, ':' ) ) == NULL ) {
		return ( 0 );
	}
	memmove( info->symbol, pmask, ( strlen( pmask ) + 1 ) * sizeof ( char ) );
	pmask = strchr( info->long_descr, ':' );
	if ( pmask == NULL )
		info->long_descr[0] = 0;
	else
		memmove( info->long_descr, pmask + sizeof ( char ),
				 ( strlen( pmask ) + 1 ) * sizeof ( char ) );
	return 1;
}

static int
checkCounter (int eventcode)
{
	int EventSet = PAPI_NULL;
	if (PAPI_create_eventset(&EventSet) != PAPI_OK)
		return 0;
	if (PAPI_add_event (EventSet, eventcode) != PAPI_OK)
		return 0;
	if (PAPI_cleanup_eventset (EventSet) != PAPI_OK)
		return 0;
	if (PAPI_destroy_eventset (&EventSet) != PAPI_OK)
		return 0;
	return 1;
}


/*
  Checks whether a preset event is available. If it is available,
  the function returns 1, or 0 otherwise. */

int is_preset_event_available(char *name) {

  int  event_code = 0 | PAPI_PRESET_MASK;
  PAPI_event_info_t info;
  int check_counter = 1;


  if (PAPI_enum_event( &event_code, PAPI_ENUM_FIRST ) != PAPI_OK) {
    printf("error!");
    exit(1);
  }

  /* Iterate over all the available preset events and compare them by names. */
  do {
    if ( PAPI_get_event_info( event_code, &info ) == PAPI_OK ) {
      
      if ( info.count ) {
	if ( (check_counter && checkCounter (event_code)) || !check_counter) {
	  if (strcmp(info.symbol, name) == 0)
	    return 1;
	}
      }
    }
  } while (PAPI_enum_event( &event_code, PAPI_PRESET_ENUM_AVAIL ) == PAPI_OK);

  return 0;
}



int
main( int argc, char **argv )
{
   int args, i, j, k;
   int retval;
   unsigned int filter = 0;
   int print_event_info = 0;
   char *name = NULL;
   int print_avail_only = PAPI_ENUM_EVENTS;
   int print_tabular = 1;
   PAPI_event_info_t info;
   const PAPI_hw_info_t *hwinfo = NULL;
   int tot_count = 0;
   int avail_count = 0;
   int deriv_count = 0;
   int check_counter = 0;
   int event_code;

   PAPI_event_info_t n_info;

   /* Parse command line arguments */

   for( args = 1; args < argc; args++ ) {
      if ( strstr( argv[args], "-e" ) ) {
	 print_event_info = 1;
	 name = argv[args + 1];
	 if ( ( name == NULL ) || ( strlen( name ) == 0 ) ) {
	    print_help( argv );
	    exit( 1 );
	 }
      }
      else if ( strstr( argv[args], "-c" ) || strstr (argv[args], "--check") )
      {
	 print_avail_only = PAPI_PRESET_ENUM_AVAIL;
         check_counter = 1;
      }
      else if ( strstr( argv[args], "-a" ))
	 print_avail_only = PAPI_PRESET_ENUM_AVAIL;
      else if ( strstr( argv[args], "-d" ) )
	 print_tabular = 0;
      else if ( strstr( argv[args], "-h" ) ) {
	 print_help( argv );
	 exit( 1 );
      } else if ( strstr( argv[args], "--br" ) )
	 filter |= PAPI_PRESET_BIT_BR;
      else if ( strstr( argv[args], "--cache" ) )
	 filter |= PAPI_PRESET_BIT_CACH;
      else if ( strstr( argv[args], "--cnd" ) )
	 filter |= PAPI_PRESET_BIT_CND;
      else if ( strstr( argv[args], "--fp" ) )
	 filter |= PAPI_PRESET_BIT_FP;
      else if ( strstr( argv[args], "--ins" ) )
	 filter |= PAPI_PRESET_BIT_INS;
      else if ( strstr( argv[args], "--idl" ) )
	 filter |= PAPI_PRESET_BIT_IDL;
      else if ( strstr( argv[args], "--l1" ) )
	 filter |= PAPI_PRESET_BIT_L1;
      else if ( strstr( argv[args], "--l2" ) )
	 filter |= PAPI_PRESET_BIT_L2;
      else if ( strstr( argv[args], "--l3" ) )
	 filter |= PAPI_PRESET_BIT_L3;
      else if ( strstr( argv[args], "--mem" ) )
	 filter |= PAPI_PRESET_BIT_BR;
      else if ( strstr( argv[args], "--msc" ) )
	 filter |= PAPI_PRESET_BIT_MSC;
      else if ( strstr( argv[args], "--tlb" ) )
	 filter |= PAPI_PRESET_BIT_TLB;
   }

   if ( filter == 0 ) {
      filter = ( unsigned int ) ( -1 );
   }

   /* Init PAPI */

   retval = PAPI_library_init( PAPI_VER_CURRENT );
   if ( retval != PAPI_VER_CURRENT ) {
	fprintf(stderr,"Error!  PAPI library mismatch!\n");
	return 1;
   }


	retval = PAPI_set_debug( PAPI_VERB_ECONT );
	if ( retval != PAPI_OK ) {
		fprintf(stderr,"Error with PAPI_set debug!\n");
		return 1;
	}

      retval=papi_print_header("Available PAPI preset and user defined events plus hardware information.\n",
			       &hwinfo );
	if ( retval != PAPI_OK ) {
		fprintf(stderr,"Error with PAPI_get_hardware_info!\n");
		return 1;
	}

      /* Code for info on just one event */

      if ( print_event_info ) {

	 if ( PAPI_event_name_to_code( name, &event_code ) == PAPI_OK ) {
	    if ( PAPI_get_event_info( event_code, &info ) == PAPI_OK ) {

	       if ( event_code & PAPI_PRESET_MASK ) {
		  printf( "%-30s%s\n%-30s%#-10x\n%-30s%d\n",
			  "Event name:", info.symbol, "Event Code:",
			  info.event_code, "Number of Native Events:",
			  info.count );
		  printf( "%-29s|%s|\n%-29s|%s|\n%-29s|%s|\n",
			  "Short Description:", info.short_descr,
			  "Long Description:", info.long_descr,
			  "Developer's Notes:", info.note );
		  printf( "%-29s|%s|\n%-29s|%s|\n", "Derived Type:",
			  info.derived, "Postfix Processing String:",
			  info.postfix );

		  for( j = 0; j < ( int ) info.count; j++ ) {
		     printf( " Native Code[%d]: %#x |%s|\n", j,
			     info.code[j], info.name[j] );
		     PAPI_get_event_info( (int) info.code[j], &n_info );
		     printf(" Number of Register Values: %d\n", n_info.count );
		     for( k = 0; k < ( int ) n_info.count; k++ ) {
			printf( " Register[%2d]: %#08x |%s|\n", k,
				n_info.code[k], n_info.name[k] );
		     }
		     printf( " Native Event Description: |%s|\n\n",
			     n_info.long_descr );
		  }

		  if (!is_preset_event_available(name)) {
		    printf("\nPRESET event %s is NOT available on this architecture!\n\n", name);
		  }

	       } else {	 /* must be a native event code */
		  printf( "%-30s%s\n%-30s%#-10x\n%-30s%d\n",
			  "Event name:", info.symbol, "Event Code:",
			  info.event_code, "Number of Register Values:",
			  info.count );
		  printf( "%-29s|%s|\n", "Description:", info.long_descr );
		  for ( k = 0; k < ( int ) info.count; k++ ) {
		      printf( " Register[%2d]: %#08x |%s|\n", k,
			      info.code[k], info.name[k] );
		  }

		  /* if unit masks exist but none are specified, process all */
		  if ( !strchr( name, ':' ) ) {
		     if ( 1 ) {
			if ( PAPI_enum_event( &event_code, PAPI_NTV_ENUM_UMASKS ) == PAPI_OK ) {
			   printf( "\nUnit Masks:\n" );
			   do {
			      retval = PAPI_get_event_info(event_code, &info );
			      if ( retval == PAPI_OK ) {
				 if ( parse_unit_masks( &info ) ) {
				    printf( "%-29s|%s|%s|\n",
					    " Mask Info:", info.symbol,
					    info.long_descr );
				    for ( k = 0; k < ( int ) info.count;k++ ) {
					printf( "  Register[%2d]:  %#08x  |%s|\n",
						k, info.code[k], info.name[k] );
				    }
				 }
			      }
			   } while ( PAPI_enum_event( &event_code,
					  PAPI_NTV_ENUM_UMASKS ) == PAPI_OK );
			}
		     }
		  }
	       }
	    }
	 } else {
	    printf( "Sorry, an event by the name '%s' could not be found.\n"
                    " Is it typed correctly?\n\n", name );
	 }
      } else {

	 /* Print *ALL* Events */

  for (i=0 ; i<2 ; i++) {
	// set the event code to fetch preset events the first time through loop and user events the second time through the loop
	if (i== 0) {
		event_code = 0 | PAPI_PRESET_MASK;
	} else {
		event_code = 0 | PAPI_UE_MASK;
	}

	/* For consistency, always ASK FOR the first event, if there is not one then nothing to process */
	if (PAPI_enum_event( &event_code, PAPI_ENUM_FIRST ) != PAPI_OK) {
		 continue;
	}

	// print heading to show which kind of events follow
	if (i== 0) {
		printf( "================================================================================\n" );
		printf( "  PAPI Preset Events\n" );
		printf( "================================================================================\n" );
	} else {
		printf( "\n");       // put a blank line after the presets before strarting the user events
		printf( "================================================================================\n" );
		printf( "  User Defined Events\n" );
		printf( "================================================================================\n" );
	}

	 if ( print_tabular ) {
	    printf( "    Name        Code    " );
	    if ( !print_avail_only ) {
	       printf( "Avail " );
	    }
	    printf( "Deriv Description (Note)\n" );
	 } else {
	    printf( "%-13s%-11s%-8s%-16s\n |Long Description|\n"
                    " |Developer's Notes|\n |Derived|\n |PostFix|\n"
                    " Native Code[n]: <hex> |name|\n",
		    "Symbol", "Event Code", "Count", "|Short Description|" );
	 }
	 do {
	    if ( PAPI_get_event_info( event_code, &info ) == PAPI_OK ) {
	       if ( print_tabular ) {
	      // if this is a user defined event or its a preset and matches the preset event filters, display its information
		  if ( (i==1) || (filter & info.event_type)) {
		     if ( print_avail_only ) {
		        if ( info.count ) {
                   if ( (check_counter && checkCounter (event_code)) || !check_counter)
                   {
                      printf( "%-13s%#x  %-5s%s",
                         info.symbol,
                         info.event_code,
                         is_derived( &info ), info.long_descr );
                   }
			}
		        if ( info.note[0] ) {
			   printf( " (%s)", info.note );
			}
			printf( "\n" );
		     } else {
			printf( "%-13s%#x  %-6s%-4s %s",
				info.symbol,
				info.event_code,
				( info.count ? "Yes" : "No" ),
				is_derived( &info ), info.long_descr );
			if ( info.note[0] ) {
			   printf( " (%s)", info.note );
			}
			printf( "\n" );
		     }
		     tot_count++;
		     if ( info.count ) {
	            if ((check_counter && checkCounter (event_code)) || !check_counter )
	              avail_count++;
		     }
		     if ( !strcmp( is_derived( &info ), "Yes" ) ) {
			deriv_count++;
		     }
		  }
	       } else {
		  if ( ( print_avail_only && info.count ) ||
		       ( print_avail_only == 0 ) )
	      {
	         if ((check_counter && checkCounter (event_code)) || !check_counter)
	         {
	           printf( "%s\t%#x\t%d\t|%s|\n |%s|\n"
			     " |%s|\n |%s|\n |%s|\n",
			     info.symbol, info.event_code, info.count,
			     info.short_descr, info.long_descr, info.note,
			     info.derived, info.postfix );
	           for ( j = 0; j < ( int ) info.count; j++ ) {
	              printf( " Native Code[%d]: %#x |%s|\n", j,
	              info.code[j], info.name[j] );
	           }
             }
		  }
		  tot_count++;
		  if ( info.count ) {
	         if ((check_counter && checkCounter (event_code)) || !check_counter )
		        avail_count++;
		  }
		  if ( !strcmp( is_derived( &info ), "Yes" ) ) {
		     deriv_count++;
		  }
	       }
	    }
	 } while (PAPI_enum_event( &event_code, print_avail_only ) == PAPI_OK);
  }
      }

	printf( "--------------------------------------------------------------------------------\n" );

	if ( !print_event_info ) {
		if ( print_avail_only ) {
			printf( "Of %d available events, %d ", avail_count, deriv_count );
		} else {
			printf( "Of %d possible events, %d are available, of which %d ",
				tot_count, avail_count, deriv_count );
		}
		if ( deriv_count == 1 ) {
			printf( "is derived.\n\n" );
		} else {
			printf( "are derived.\n\n" );
		}

		if (avail_count==0) {
			printf("No events detected!  Check papi_component_avail to find out why.\n");
			printf("\n");
		}
	}

	return 0;

}