PAPI  5.7.0.0
papi_hl.c
Go to the documentation of this file.
1 /****************************/
2 /* THIS IS OPEN SOURCE CODE */
3 /****************************/
4 
16 #include "papi.h"
17 #include "papi_internal.h"
18 #include "papi_memory.h"
19 #include <string.h>
20 
21 /* high level papi functions*/
22 
23 /*
24  * Which high-level interface are we using?
25  */
26 #define HL_STOP 0
27 #define HL_START 1
28 #define HL_FLIP 2
29 #define HL_FLOP 3
30 #define HL_IPC 4
31 #define HL_EPC 5
32 #define HL_READ 6
33 #define HL_ACCUM 7
34 
38 typedef struct _HighLevelInfo
39 {
40  int EventSet;
41  short int num_evts;
42  short int running;
43  long long initial_real_time;
44  long long initial_proc_time;
45  long long last_real_time;
46  long long last_proc_time;
47  long long total_ins;
49 
50 int _hl_rate_calls( float *real_time, float *proc_time, int *events,
51  long long *values, long long *ins, float *rate, int mode );
53 int _internal_check_state( HighLevelInfo ** state );
55 int _internal_hl_read_cnts( long long *values, int array_len, int flag );
56 
57 /* CHANGE LOG:
58  - ksl 10/17/03
59  Pretty much a complete rewrite of the high level interface. Now
60  the interface is thread safe and you don't have to worry as much
61  about mixing the various high level calls.
62 
63  - dkt 11/19/01:
64  After much discussion with users and developers, removed FMA and SLOPE
65  fudge factors. SLOPE was not being used, and we decided the place to
66  apply FMA was at a higher level where there could be a better understanding
67  of platform discrepancies and code implications.
68  ALL PAPI CALLS NOW RETURN EXACTLY WHAT THE HARDWARE REPORTS
69  - dkt 08/14/01:
70  Added reinitialization of values and proc_time to new reinit code.
71  Added SLOPE and FMA constants to correct for systemic errors on a
72  platform-by-platform basis.
73  SLOPE is a factor subtracted from flpins on each call to compensate
74  for platform overhead in the call.
75  FMA is a shifter that doubles floating point counts on platforms that
76  count FMA as one op instead of two.
77  NOTE: We are making the FLAWED assumption that ALL flpins are FMA!
78  This will result in counts that are TOO HIGH on the affected platforms
79  in instances where the code is NOT mostly FMA.
80  - dkt 08/01/01:
81  NOTE: Calling semantics have changed!
82  Now, if flpins < 0 (an invalid value) a PAPI_reset is issued to reset the
83  counter values. The internal start time is also reset. This should be a
84  benign change, exept in the rare case where a user passes an uninitialized
85  (and possibly negative) value for flpins to the routine *AFTER* it has been
86  called the first time. This is unlikely, since the first call clears and
87  returns th is value.
88  - dkt 08/01/01:
89  Internal sequencing changes:
90  -- initial PAPI_get_real_usec() call moved above PAPI_start to avoid unwanted flops.
91  -- PAPI_accum() replaced with PAPI_start() / PAPI_stop pair for same reason.
92 */
93 
99 int
101 {
102  int retval;
103  HighLevelInfo *state = NULL;
104 
105  /* Only allow one thread at a time in here */
106  if ( init_level == PAPI_NOT_INITED ) {
108  if ( retval != PAPI_VER_CURRENT ) {
109  return ( retval );
110  } else {
114  }
115  }
116 
117  /*
118  * Do we have the thread specific data setup yet?
119  */
120  if ( ( retval =
121  PAPI_get_thr_specific( PAPI_HIGH_LEVEL_TLS, ( void ** ) &state ) )
122  != PAPI_OK || state == NULL ) {
123  state = ( HighLevelInfo * ) papi_malloc( sizeof ( HighLevelInfo ) );
124  if ( state == NULL )
125  return ( PAPI_ENOMEM );
126 
127  memset( state, 0, sizeof ( HighLevelInfo ) );
128  state->EventSet = -1;
129 
130  if ( ( retval = PAPI_create_eventset( &state->EventSet ) ) != PAPI_OK )
131  return ( retval );
132 
133  if ( ( retval =
135  state ) ) != PAPI_OK )
136  return ( retval );
137  }
138  *outgoing = state;
139  return ( PAPI_OK );
140 }
141 
145 int
147 {
148  return ( PAPI_start( state->EventSet ) );
149 }
150 
151 void
153 {
154  state->num_evts = 0;
155  state->running = HL_STOP;
156  state->initial_real_time = -1;
157  state->initial_proc_time = -1;
158  state->total_ins = 0;
159  return;
160 }
161 
203 int
204 PAPI_flips( float *rtime, float *ptime, long long *flpins, float *mflips )
205 {
206  int retval;
207  int events[1] = {PAPI_FP_INS};
208  long long values = 0;
209 
210  if ( rtime == NULL || ptime == NULL ||
211  flpins == NULL || mflips == NULL ) {
212  return PAPI_EINVAL;
213  }
214 
215  retval = _hl_rate_calls( rtime, ptime, events,
216  &values, flpins, mflips, HL_FLIP );
217 
218  return ( retval );
219 }
220 
262 int
263 PAPI_flops( float *rtime, float *ptime, long long *flpops, float *mflops )
264 {
265  int retval;
266  int events[1] = {PAPI_FP_OPS};
267  long long values = 0;
268 
269  if ( rtime == NULL || ptime == NULL || flpops == NULL || mflops == NULL )
270  return PAPI_EINVAL;
271 
272  retval = _hl_rate_calls( rtime, ptime, events, &values, flpops, mflops, HL_FLOP );
273  return ( retval );
274 }
275 
319 int
320 PAPI_ipc( float *rtime, float *ptime, long long *ins, float *ipc )
321 {
322  long long values[2] = { 0, 0 };
323  int events[2] = {PAPI_TOT_INS, PAPI_TOT_CYC};
324  int retval = 0;
325 
326  if ( rtime == NULL || ptime == NULL || ins == NULL || ipc == NULL )
327  return PAPI_EINVAL;
328 
329  retval = _hl_rate_calls( rtime, ptime, events, values, ins, ipc, HL_IPC );
330  return ( retval );
331 }
332 
386 int
387 PAPI_epc( int event, float *rtime, float *ptime, long long *ref, long long *core, long long *evt, float *epc )
388 {
389  long long values[3] = { 0, 0, 0 };
391  int retval = 0;
392 
393  if ( rtime == NULL || ptime == NULL || ref == NULL ||core == NULL || evt == NULL || epc == NULL )
394  return PAPI_EINVAL;
395 
396  // if an event is provided, use it; otherwise use TOT_INS
397  if (event != 0 ) events[0] = event;
398 
399  if ( PAPI_query_event( ( int ) PAPI_REF_CYC ) != PAPI_OK )
400  events[2] = 0;
401 
402  retval = _hl_rate_calls( rtime, ptime, events, values, evt, epc, HL_EPC );
403  *core = values[1];
404  *ref = values[2];
405  return ( retval );
406 }
407 
408 int
409 _hl_rate_calls( float *real_time, float *proc_time, int *events,
410  long long *values, long long *ins, float *rate, int mode )
411 {
412  long long rt, pt; // current elapsed real and process times in usec
413  int num_events = 2;
414  int retval = 0;
415  HighLevelInfo *state = NULL;
416 
417  if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK ) {
418  return ( retval );
419  }
420 
421  if ( state->running != HL_STOP && state->running != mode ) {
422  return PAPI_EINVAL;
423  }
424 
425  if ( state->running == HL_STOP ) {
426 
427  switch (mode) {
428  case HL_FLOP:
429  case HL_FLIP:
430  num_events = 1;
431  break;
432  case HL_IPC:
433  break;
434  case HL_EPC:
435  if ( events[2] != 0 ) num_events = 3;
436  break;
437  default:
438  return PAPI_EINVAL;
439  }
440  if (( retval = PAPI_add_events( state->EventSet, events, num_events )) != PAPI_OK ) {
441  _internal_cleanup_hl_info( state );
443  return retval;
444  }
445 
446  state->total_ins = 0;
449 
450  if ( ( retval = PAPI_start( state->EventSet ) ) != PAPI_OK ) {
451  return retval;
452  }
453 
454  /* Initialize the interface */
455  state->running = mode;
456  *real_time = 0.0;
457  *proc_time = 0.0;
458  *rate = 0.0;
459 
460  } else {
461  if ( ( retval = PAPI_stop( state->EventSet, values ) ) != PAPI_OK ) {
462  state->running = HL_STOP;
463  return retval;
464  }
465 
466  /* Read elapsed real and process times */
467  rt = PAPI_get_real_usec();
468  pt = PAPI_get_virt_usec();
469 
470  /* Convert to seconds with multiplication because it is much faster */
471  *real_time = ((float)( rt - state->initial_real_time )) * .000001;
472  *proc_time = ((float)( pt - state->initial_proc_time )) * .000001;
473 
474  state->total_ins += values[0];
475 
476  switch (mode) {
477  case HL_FLOP:
478  case HL_FLIP:
479  /* Calculate MFLOP and MFLIP rates */
480  if ( pt > 0 ) {
481  *rate = (float)values[0] / (pt - state->last_proc_time);
482  } else *rate = 0;
483  break;
484  case HL_IPC:
485  case HL_EPC:
486  /* Calculate IPC */
487  if (values[1]!=0) {
488  *rate = (float) ((float)values[0] / (float) ( values[1]));
489  }
490  break;
491  default:
492  return PAPI_EINVAL;
493  }
494  state->last_real_time = rt;
495  state->last_proc_time = pt;
496 
497  if ( ( retval = PAPI_start( state->EventSet ) ) != PAPI_OK ) {
498  state->running = HL_STOP;
499  return retval;
500  }
501  }
502  *ins = state->total_ins;
503  return PAPI_OK;
504 }
505 
540 int
542 {
543  int retval;
544  HighLevelInfo *tmp = NULL;
545 
546  /* Make sure the Library is initialized, etc... */
547  if ( ( retval = _internal_check_state( &tmp ) ) != PAPI_OK )
548  return ( retval );
549 
550  return ( PAPI_get_opt( PAPI_MAX_HWCTRS, NULL ) );
551 }
552 
596 int
597 PAPI_start_counters( int *events, int array_len )
598 {
599  int i, retval;
600  HighLevelInfo *state = NULL;
601 
602  if ( events == NULL || array_len <= 0 )
603  return PAPI_EINVAL;
604 
605  if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK )
606  return ( retval );
607 
608  if ( state->running != 0 )
609  return ( PAPI_EINVAL );
610 
611  /* load events to the new EventSet */
612  for ( i = 0; i < array_len; i++ ) {
613  retval = PAPI_add_event( state->EventSet, events[i] );
614  if ( retval == PAPI_EISRUN )
615  return ( retval );
616 
617  if ( retval ) {
618  /* remove any prior events that may have been added
619  * and cleanup the high level information
620  */
621  _internal_cleanup_hl_info( state );
623  return ( retval );
624  }
625  }
626  /* start the EventSet */
627  if ( ( retval = _internal_start_hl_counters( state ) ) == PAPI_OK ) {
628  state->running = HL_START;
629  state->num_evts = ( short ) array_len;
630  }
631  return ( retval );
632 }
633 
634 /*========================================================================*/
635 /* int PAPI_read_counters(long long *values, int array_len) */
636 /* */
637 /* Read the running counters into the values array. This call */
638 /* implicitly initializes the internal counters to zero and allows */
639 /* them continue to run upon return. */
640 /*========================================================================*/
641 
642 int
643 _internal_hl_read_cnts( long long *values, int array_len, int flag )
644 {
645  int retval;
646  HighLevelInfo *state = NULL;
647 
648  if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK )
649  return ( retval );
650 
651  if ( state->running != HL_START || array_len < state->num_evts )
652  return ( PAPI_EINVAL );
653 
654  if ( flag == HL_ACCUM )
655  return ( PAPI_accum( state->EventSet, values ) );
656  else if ( flag == HL_READ ) {
657  if ( ( retval = PAPI_read( state->EventSet, values ) ) != PAPI_OK )
658  return ( retval );
659  return ( PAPI_reset( state->EventSet ) );
660  }
661 
662  /* Invalid flag passed in */
663  return ( PAPI_EINVAL );
664 }
665 
709 int
710 PAPI_read_counters( long long *values, int array_len )
711 {
712  return ( _internal_hl_read_cnts( values, array_len, HL_READ ) );
713 }
714 
715 
759 int
760 PAPI_accum_counters( long long *values, int array_len )
761 {
762  if ( values == NULL || array_len <= 0 )
763  return PAPI_EINVAL;
764 
765  return ( _internal_hl_read_cnts( values, array_len, HL_ACCUM ) );
766 }
767 
806 int
807 PAPI_stop_counters( long long *values, int array_len )
808 {
809  int retval;
810  HighLevelInfo *state = NULL;
811 
812  if ( ( retval = _internal_check_state( &state ) ) != PAPI_OK )
813  return ( retval );
814 
815  if ( state->running == 0 )
816  return ( PAPI_ENOTRUN );
817 
818  if ( state->running == HL_START ) {
819  if ( array_len < state->num_evts || values == NULL) {
820  return ( PAPI_EINVAL );
821  } else {
822  retval = PAPI_stop( state->EventSet, values );
823  }
824  }
825 
826  if ( state->running > HL_START ) {
827  long long tmp_values[3];
828  retval = PAPI_stop( state->EventSet, tmp_values );
829  }
830 
831  if ( retval == PAPI_OK ) {
832  _internal_cleanup_hl_info( state );
834  }
835  APIDBG( "PAPI_stop_counters returns %d\n", retval );
836  return retval;
837 }
838 
839 void
841 {
842  HighLevelInfo *state = NULL;
843 
844  if ( PAPI_get_thr_specific( PAPI_HIGH_LEVEL_TLS, ( void ** ) &state ) ==
845  PAPI_OK ) {
846  if ( state )
847  papi_free( state );
848  }
849 }
#define PAPI_OK
Definition: fpapi.h:105
int PAPI_stop(int EventSet, long long *values)
Definition: papi.c:2314
int _internal_hl_read_cnts(long long *values, int array_len, int flag)
Definition: papi_hl.c:643
long long initial_proc_time
Definition: papi_hl.c:44
#define PAPI_ENOMEM
Definition: fpapi.h:107
#define PAPI_EINVAL
Definition: fpapi.h:106
int PAPI_add_event(int EventSet, int EventCode)
Definition: papi.c:1663
long long PAPI_get_virt_usec(void)
Definition: papi.c:6372
int PAPI_reset(int EventSet)
Definition: papi.c:2459
long long initial_real_time
Definition: papi_hl.c:43
#define HL_FLOP
Definition: papi_hl.c:29
#define papi_free(a)
Definition: papi_memory.h:35
short int num_evts
Definition: papi_hl.c:41
int PAPI_ipc(float *rtime, float *ptime, long long *ins, float *ipc)
Definition: papi_hl.c:320
#define papi_malloc(a)
Definition: papi_memory.h:34
int PAPI_flops(float *rtime, float *ptime, long long *flpops, float *mflops)
Definition: papi_hl.c:263
static int num_events
int PAPI_accum_counters(long long *values, int array_len)
Definition: papi_hl.c:760
#define PAPI_FP_OPS
Definition: fpapi.h:238
int _internal_check_state(HighLevelInfo **state)
Definition: papi_hl.c:100
#define PAPI_VER_CURRENT
Definition: fpapi.h:14
int retval
Definition: zero_fork.c:53
#define PAPI_REF_CYC
Definition: fpapi.h:243
#define HL_EPC
Definition: papi_hl.c:31
int PAPI_add_events(int EventSet, int *Events, int number)
Definition: papi.c:5843
double tmp
#define PAPI_HIGH_LEVEL_INITED
Definition: fpapi.h:19
Return codes and api definitions.
#define APIDBG(format, args...)
Definition: papi_debug.h:64
char events[MAX_EVENTS][BUFSIZ]
#define HL_READ
Definition: papi_hl.c:32
#define HL_STOP
Definition: papi_hl.c:26
int PAPI_flips(float *rtime, float *ptime, long long *flpins, float *mflips)
Definition: papi_hl.c:204
#define HL_IPC
Definition: papi_hl.c:30
int PAPI_epc(int event, float *rtime, float *ptime, long long *ref, long long *core, long long *evt, float *epc)
Definition: papi_hl.c:387
int PAPI_get_thr_specific(int tag, void **ptr)
Definition: papi.c:362
int PAPI_accum(int EventSet, long long *values)
Definition: papi.c:2745
void _papi_hwi_shutdown_highlevel()
Definition: papi_hl.c:840
int PAPI_library_init(int version)
Definition: papi.c:500
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:64
int PAPI_stop_counters(long long *values, int array_len)
Definition: papi_hl.c:807
#define PAPI_TOT_INS
Definition: fpapi.h:186
int PAPI_get_opt(int option, PAPI_option_t *ptr)
Definition: papi.c:4143
#define HL_ACCUM
Definition: papi_hl.c:33
long long last_proc_time
Definition: papi_hl.c:46
int _internal_start_hl_counters(HighLevelInfo *state)
Definition: papi_hl.c:146
#define HL_START
Definition: papi_hl.c:27
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:78
#define PAPI_EISRUN
Definition: fpapi.h:115
int _hl_rate_calls(float *real_time, float *proc_time, int *events, long long *values, long long *ins, float *rate, int mode)
Definition: papi_hl.c:409
int PAPI_cleanup_eventset(int EventSet)
Definition: papi.c:2890
int PAPI_create_eventset(int *EventSet)
Definition: papi.c:1464
void _internal_cleanup_hl_info(HighLevelInfo *state)
Definition: papi_hl.c:152
short int running
Definition: papi_hl.c:42
int PAPI_query_event(int EventCode)
Definition: papi.c:684
#define PAPI_ENOTRUN
Definition: fpapi.h:114
#define HL_FLIP
Definition: papi_hl.c:28
long long PAPI_get_real_usec(void)
Definition: papi.c:6264
#define HIGHLEVEL_LOCK
Definition: papi_internal.h:89
int PAPI_set_thr_specific(int tag, void *ptr)
Definition: papi.c:438
int PAPI_read_counters(long long *values, int array_len)
Definition: papi_hl.c:710
int PAPI_num_counters(void)
Definition: papi_hl.c:541
int PAPI_start_counters(int *events, int array_len)
Definition: papi_hl.c:597
long long total_ins
Definition: papi_hl.c:47
long long last_real_time
Definition: papi_hl.c:45
#define PAPI_MAX_HWCTRS
Definition: fpapi.h:58
#define PAPI_NOT_INITED
Definition: fpapi.h:17
int EventSet
Definition: papi_hl.c:40
int PAPI_read(int EventSet, long long *values)
Definition: papi.c:2559
int PAPI_start(int EventSet)
Definition: papi.c:2096
#define PAPI_TOT_CYC
Definition: fpapi.h:195
int init_level
Definition: papi_internal.c:53
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
#define PAPI_FP_INS
Definition: fpapi.h:188
#define PAPI_HIGH_LEVEL_TLS
Definition: papi.h:322
int i
Definition: fileop.c:140