PAPI  5.7.0.0
linux-emon.c
Go to the documentation of this file.
1 /****************************/
2 /* THIS IS OPEN SOURCE CODE */
3 /****************************/
4 
16 #include <stdint.h>
17 #include <string.h>
18 #include "papi.h"
19 #include "papi_internal.h"
20 #include "papi_vector.h"
21 #include "papi_memory.h"
22 #include "extras.h"
23 
24 #define EMON_DEFINE_GLOBALS
25 #include <hwi/include/bqc/A2_inlines.h>
26 #include <spi/include/emon/emon.h> // the emon library header file (no linking required)
27 
28 #define EMON_MAX_COUNTERS 8
29 #define EMON_TOTAL_EVENTS 8
30 
31 #ifndef DEBUG
32 #define EMONDBG( fmt, args...) do {} while(0)
33 #else
34 #define EMONDBG( fmt, args... ) do { printf("%s:%d\t"fmt, __func__, __LINE__, ##args); } while(0)
35 #endif
36 
37 /* Stores private information for each event */
38 typedef struct EMON_register
39 {
40  unsigned int selector;
41  /* Signifies which counter slot is being used */
42  /* Indexed from 1 as 0 has a special meaning */
44 
46 /* The contents of this structure will vary based on */
47 /* your component, however having name and description */
48 /* fields are probably useful. */
49 typedef struct EMON_native_event_entry
50 {
52  char *name;
53  char *description;
56 
57 
58 /* Used when doing register allocation */
59 typedef struct EMON_reg_alloc
60 {
63 
64 typedef struct EMON_overflow
65 {
66  int threshold;
69 
70 /* Holds control flags */
71 typedef struct EMON_control_state
72 {
73  int count;
74  long long counters[EMON_MAX_COUNTERS];
75  int being_measured[EMON_MAX_COUNTERS];
76  long long last_update;
78 
79 /* Holds per-thread information */
80 typedef struct EMON_context
81 {
84 
85 /* Declare our vector in advance */
87 
88 static void _check_EMON_error( char* emon2func, int err )
89 {
90  ( void ) emon2func;
91  if ( err < 0 ) {
92  printf( "Error: EMON API function '%s' returned %d.\n",
93  emon2func, err );
94  }
95 }
96 
97 
102 {
103  {
104  .name = "DOMAIN1",
105  .description = "Chip core",
106  .resources.selector = 1,
107  .return_type = PAPI_DATATYPE_FP64,
108  },
109  {
110  .name = "DOMAIN2",
111  .description = "Chip Memory Interface and Dramm",
112  .resources.selector = 2,
113  .return_type = PAPI_DATATYPE_FP64,
114  },
115  {
116  .name = "DOMAIN3",
117  .description = "Optics",
118  .resources.selector = 3,
119  .return_type = PAPI_DATATYPE_FP64,
120  },
121  {
122  .name = "DOMAIN4",
123  .description = "Optics + PCIExpress",
124  .resources.selector = 4,
125  .return_type = PAPI_DATATYPE_FP64,
126  },
127  {
128  .name = "DOMAIN6",
129  .description = "HSS Network and Link Chip",
130  .resources.selector = 5,
131  .return_type = PAPI_DATATYPE_FP64,
132  },
133  {
134  .name = "DOMAIN8",
135  .description = "Link Chip Core",
136  .resources.selector = 6,
137  .return_type = PAPI_DATATYPE_FP64,
138  },
139  {
140  .name = "DOMAIN7",
141  .description = "Chip SRAM",
142  .resources.selector = 7,
143  .return_type = PAPI_DATATYPE_FP64,
144  },
145  { .name="EMON_DOMAIN_ALL",
146  .description = "Measures power on all domains.",
147  .resources.selector = 8,
148  .return_type = PAPI_DATATYPE_FP64,
149  },
150 };
151 
152 
153 
154 
155 /*****************************************************************************
156  ******************* BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS *************
157  *****************************************************************************/
158 
159 /*
160  * This is called whenever a thread is initialized
161  */
162 int
164 {
165  EMONDBG( "EMON_init_thread\n" );
166 
167  ( void ) ctx;
168  return PAPI_OK;
169 }
170 
171 
172 /* Initialize hardware counters, setup the function vector table
173  * and get hardware information, this routine is called when the
174  * PAPI process is initialized (IE PAPI_library_init)
175  */
176 int
178 {
179  int ret = 0;
181  EMONDBG( "EMON_init_component cidx = %d\n", cidx );
182  /* Setup connection with the fpga:
183  * NOTE: any other threads attempting to call into the EMON API
184  * will be turned away. */
185  ret = EMON_SetupPowerMeasurement();
186  _check_EMON_error("EMON_SetupPowerMeasurement", ret );
187 
189 
192 
193 
194  return ( PAPI_OK );
195 }
196 
197 
198 /*
199  * Control of counters (Reading/Writing/Starting/Stopping/Setup)
200  * functions
201  */
202 int
204 {
205  EMONDBG( "EMON_init_control_state\n" );
206 
207  EMON_control_state_t * this_state = ( EMON_control_state_t * ) ptr;
208  memset( this_state, 0, sizeof ( EMON_control_state_t ) );
209 
210  return PAPI_OK;
211 }
212 
213 static int
215 {
216  union {
217  long long ll;
218  double fp;
219  } return_value;
220  return_value.fp = -1;
221 
222  double volts[14],amps[14];
223  double cpu = 0;
224  double dram = 0;
225  double link_chip = 0;
226  double network = 0;
227  double optics = 0;
228  double pci = 0;
229  double sram = 0;
230  unsigned k_const;
231 
232  EMONDBG( "_emon_accessor, enter this_state = %x\n", this_state);
233  return_value.fp = EMON_GetPower_impl( volts, amps );
234  EMONDBG("_emon_accessor, after EMON_GetPower %lf \n", return_value.fp);
235  if ( -1 == return_value.fp ) {
236  PAPIERROR("EMON_GetPower() failed!\n");
237  return ( PAPI_ESYS );
238  }
239 
240  this_state->counters[7] = return_value.ll;
241 
242 /* We just stuff everything in counters, there is no extra overhead here */
243  k_const = domain_info[0].k_const; /* Chip Core Voltage */
244  cpu += volts[0] * amps[0] * k_const;
245  cpu += volts[1] * amps[1] * k_const;
246 
247  k_const = domain_info[1].k_const; /* Chip Core Voltage */
248  dram += volts[2] * amps[2] * k_const;
249  dram += volts[3] * amps[3] * k_const;
250 
251  k_const = domain_info[2].k_const; /* Chip Core Voltage */
252  optics += volts[4] * amps[4] * k_const;
253  optics += volts[5] * amps[5] * k_const;
254 
255  k_const = domain_info[3].k_const; /* Chip Core Voltage */
256  pci += volts[6] * amps[6] * k_const;
257  pci += volts[7] * amps[7] * k_const;
258 
259  k_const = domain_info[4].k_const; /* Chip Core Voltage */
260  network += volts[8] * amps[8] * k_const;
261  network += volts[9] * amps[9] * k_const;
262 
263  k_const = domain_info[5].k_const; /* Chip Core Voltage */
264  link_chip += volts[10] * amps[10] * k_const;
265  link_chip += volts[11] * amps[11] * k_const;
266 
267  k_const = domain_info[6].k_const; /* Chip Core Voltage */
268  sram += volts[12] * amps[12] * k_const;
269  sram += volts[13] * amps[13] * k_const;
270 
271  this_state->counters[0] = *(long long*)&cpu;
272  this_state->counters[1] = *(long long*)&dram;
273  this_state->counters[2] = *(long long*)&optics;
274  this_state->counters[3] = *(long long*)&pci;
275  this_state->counters[4] = *(long long*)&link_chip;
276  this_state->counters[5] = *(long long*)&network;
277  this_state->counters[6] = *(long long*)&sram;
278 
279  EMONDBG("CPU = %lf\n", *(double*)&this_state->counters[0]);
280  EMONDBG("DRAM = %lf\n", *(double*)&this_state->counters[1]);
281  EMONDBG("Optics = %lf\n", *(double*)&this_state->counters[2]);
282  EMONDBG("PCI = %lf\n", *(double*)&this_state->counters[3]);
283  EMONDBG("Link Chip = %lf\n", *(double*)&this_state->counters[4]);
284  EMONDBG("Network = %lf\n", *(double*)&this_state->counters[5]);
285  EMONDBG("SRAM = %lf\n", *(double*)&this_state->counters[6]);
286  EMONDBG("TOTAL = %lf\n", *(double*)&this_state->counters[7] );
287 
288  return ( PAPI_OK );
289 }
290 
291 /*
292  *
293  */
294 int
296 {
297  EMONDBG( "EMON_start\n" );
298  ( void ) ctx;
299  ( void ) ptr;
300  /*EMON_control_state_t * this_state = ( EMON_control_state_t * ) ptr;*/
301 
302  return ( PAPI_OK );
303 }
304 
305 
306 /*
307  *
308  */
309 int
311 {
312  EMONDBG( "EMON_stop\n" );
313  ( void ) ctx;
314  EMON_control_state_t * this_state = ( EMON_control_state_t * ) ptr;
315 
316  return _emon_accessor( this_state );
317 }
318 
319 
320 /*
321  *
322  */
323 int
325  long long ** events, int flags )
326 {
327  EMONDBG( "EMON_read\n" );
328  ( void ) ctx;
329  ( void ) flags;
330  int ret;
331  EMON_control_state_t * this_state = ( EMON_control_state_t * ) ptr;
332 
333  ret = _emon_accessor( this_state );
334  *events = this_state->counters;
335  return ret;
336 }
337 
338 
339 /*
340  *
341  */
342 int
344 {
345  EMONDBG( "EMON_shutdown_thread\n" );
346 
347  ( void ) ctx;
348  return ( PAPI_OK );
349 }
350 
351 int
353 {
354  EMONDBG( "EMON_shutdown_component\n" );
355 
356  return ( PAPI_OK );
357 }
358 
359 /* This function sets various options in the component
360  * The valid codes being passed in are PAPI_SET_DEFDOM,
361  * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
362  */
363 int
364 EMON_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
365 {
366  EMONDBG( "EMON_ctl\n" );
367 
368  ( void ) ctx;
369  ( void ) code;
370  ( void ) option;
371  return ( PAPI_OK );
372 }
373 
374 
375 /*
376  * PAPI Cleanup Eventset
377  */
378 int
380 {
381  EMONDBG( "EMON_cleanup_eventset\n" );
382 
383  EMON_control_state_t * this_state = ( EMON_control_state_t * ) ctrl;
384  ( void ) this_state;
385 
386  return ( PAPI_OK );
387 }
388 
389 
390 /*
391  *
392  */
393 int
395  NativeInfo_t * native, int count,
396  hwd_context_t * ctx )
397 {
398  EMONDBG( "EMON_update_control_state: count = %d\n", count );
399 
400  ( void ) ctx;
401  int index, i;
402  EMON_control_state_t * this_state = ( EMON_control_state_t * ) ptr;
403  ( void ) ptr;
404 
405 
406 
407  // otherwise, add the events to the eventset
408  for ( i = 0; i < count; i++ ) {
409  index = ( native[i].ni_event ) ;
410 
411  native[i].ni_position = i;
412 
413  EMONDBG("EMON_update_control_state: ADD event: i = %d, index = %d\n", i, index );
414  }
415 
416  // store how many events we added to an EventSet
417  this_state->count = count;
418 
419  return ( PAPI_OK );
420 }
421 
422 
423 /*
424  * As a system wide count, PAPI_DOM_ALL is all we support
425  */
426 int
427 EMON_set_domain( hwd_control_state_t * cntrl, int domain )
428 {
429  EMONDBG( "EMON_set_domain\n" );
430  ( void ) cntrl;
431 
432  if ( PAPI_DOM_ALL != domain )
433  return ( PAPI_EINVAL );
434 
435  return ( PAPI_OK );
436 }
437 
438 
439 /*
440  *
441  */
442 int
444 {
445  EMONDBG( "EMON_reset\n" );
446  ( void ) ctx;
447  int retval;
448  EMON_control_state_t * this_state = ( EMON_control_state_t * ) ptr;
449  ( void ) this_state;
450  ( void ) retval;
451 
452  memset( this_state->counters, 0x0, sizeof(long long) * EMON_MAX_COUNTERS);
453 
454  return ( PAPI_OK );
455 }
456 
457 
458 /*
459  * Native Event functions
460  */
461 int
462 EMON_ntv_enum_events( unsigned int *EventCode, int modifier )
463 {
464  EMONDBG( "EMON_ntv_enum_events, EventCode = %#x\n", *EventCode );
465 
466  switch ( modifier ) {
467  case PAPI_ENUM_FIRST:
468  *EventCode = 0;
469 
470  return ( PAPI_OK );
471  break;
472 
473  case PAPI_ENUM_EVENTS:
474  {
475  int index = ( *EventCode );
476 
477  if ( index < EMON_TOTAL_EVENTS ) {
478  *EventCode = *EventCode + 1;
479  return ( PAPI_OK );
480  } else {
481  return ( PAPI_ENOEVNT );
482  }
483 
484  break;
485  }
486  default:
487  return ( PAPI_EINVAL );
488  }
489  return ( PAPI_EINVAL );
490 }
491 
492 /*
493  *
494  */
495 int
496 EMON_ntv_code_to_name( unsigned int EventCode, char *name, int len )
497 {
498  EMONDBG( "EMON_ntv_code_to_name\n" );
499  int index;
500  ( void ) name;
501  ( void ) len;
502 
503  index = ( EventCode );
504 
505  if ( index >= EMON_TOTAL_EVENTS || index < 0 ) {
506  return PAPI_ENOEVNT;
507  }
508 
509  strncpy( name, EMON_native_table[index].name, len );
510  return ( PAPI_OK );
511 }
512 
513 /*
514  *
515  */
516 int
517 EMON_ntv_name_to_code( const char *name, unsigned int *code )
518 {
519  int index;
520 
521  for ( index = 0; index < EMON_TOTAL_EVENTS; index++ ) {
522  if ( 0 == strcmp( name, EMON_native_table[index].name ) ) {
523  *code = index;
524  }
525  }
526  return ( PAPI_OK );
527 }
528 
529 int
530 EMON_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
531 {
532  EMONDBG( "EMON_ntv_code_to_descr\n" );
533  int index;
534  ( void ) name;
535  ( void ) len;
536 
537  index = ( EventCode ) ;
538 
539  if ( index >= EMON_TOTAL_EVENTS || index < 0 ) {
540  return PAPI_ENOEVNT;
541  }
542  strncpy( name, EMON_native_table[index].description, len );
543 
544  return ( PAPI_OK );
545 }
546 
547 
548 /*
549  *
550  */
551 int
552 EMON_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
553 {
554  EMONDBG( "EMON_ntv_code_to_bits\n" );
555  ( void ) EventCode;
556  ( void ) bits;
557  return ( PAPI_OK );
558 }
559 
560 int
561 EMON_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
562 {
563 
564  int index = EventCode;
565 
566  if ( ( index < 0) || (index >= EMON_TOTAL_EVENTS )) return PAPI_ENOEVNT;
567 
568  strncpy( info->symbol, EMON_native_table[index].name,
569  sizeof(info->symbol));
570 
571  strncpy( info->long_descr, EMON_native_table[index].description,
572  sizeof(info->symbol));
573 
574  //strncpy( info->units, rapl_native_events[index].units,
575  //sizeof(info->units));
576 
577  info->data_type = EMON_native_table[index].return_type;
578 
579  return PAPI_OK;
580 }
581 
582 /*
583  *
584  */
586  .cmp_info = {
587  /* default component information (unspecified values are initialized to 0) */
588  .name = "EMON",
589  .short_name = "EMON",
590  .description = "Blue Gene/Q EMON component",
591  .num_native_events = EMON_MAX_COUNTERS,
592  .num_cntrs = EMON_MAX_COUNTERS,
593  .num_mpx_cntrs = EMON_MAX_COUNTERS,
594  .default_domain = PAPI_DOM_ALL,
595  .available_domains = PAPI_DOM_ALL,
596  .default_granularity = PAPI_GRN_SYS,
597  .available_granularities = PAPI_GRN_SYS,
598 
599  .hardware_intr_sig = PAPI_INT_SIGNAL,
600  .hardware_intr = 1,
601 
602  .kernel_multiplex = 0,
603 
604  /* component specific cmp_info initializations */
605  .fast_real_timer = 0,
606  .fast_virtual_timer = 0,
607  .attach = 0,
608  .attach_must_ptrace = 0,
609  }
610  ,
611 
612  /* sizes of framework-opaque component-private structures */
613  .size = {
614  .context = sizeof ( EMON_context_t ),
615  .control_state = sizeof ( EMON_control_state_t ),
616  .reg_value = sizeof ( EMON_register_t ),
617  .reg_alloc = sizeof ( EMON_reg_alloc_t ),
618  }
619  ,
620  /* function pointers in this component */
621  .init_thread = EMON_init_thread,
622  .init_component = EMON_init_component,
623  .init_control_state = EMON_init_control_state,
624  .start = EMON_start,
625  .stop = EMON_stop,
626  .read = EMON_read,
627  .shutdown_thread = EMON_shutdown_thread,
628  .shutdown_component = EMON_shutdown_component,
629  .cleanup_eventset = EMON_cleanup_eventset,
630  .ctl = EMON_ctl,
631 
632  .update_control_state = EMON_update_control_state,
633  .set_domain = EMON_set_domain,
634  .reset = EMON_reset,
635 
636  .ntv_enum_events = EMON_ntv_enum_events,
637  .ntv_code_to_name = EMON_ntv_code_to_name,
638  .ntv_code_to_descr = EMON_ntv_code_to_descr,
639  .ntv_code_to_bits = EMON_ntv_code_to_bits,
640  .ntv_code_to_info = EMON_ntv_code_to_info,
641 };
#define PAPI_OK
Definition: fpapi.h:105
papi_vector_t _emon_vector
Definition: linux-emon.c:585
int EMON_read(hwd_context_t *ctx, hwd_control_state_t *ptr, long long **events, int flags)
Definition: linux-emon.c:324
static const char * name
Definition: fork_overflow.c:31
static int _emon_accessor(EMON_control_state_t *this_state)
Definition: linux-emon.c:214
#define PAPI_EINVAL
Definition: fpapi.h:106
int EMON_update_control_state(hwd_control_state_t *ptr, NativeInfo_t *native, int count, hwd_context_t *ctx)
Definition: linux-emon.c:394
#define EMONDBG(fmt, args...)
Definition: linux-emon.c:34
EMON_register_t ra_bits
Definition: linux-emon.c:61
int EMON_reset(hwd_context_t *ctx, hwd_control_state_t *ptr)
Definition: linux-emon.c:443
int EMON_ntv_code_to_name(unsigned int EventCode, char *name, int len)
Definition: linux-emon.c:496
int EMON_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
Definition: linux-emon.c:561
#define PAPI_GRN_SYS
Definition: fpapi.h:71
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:970
Definition: linux-emon.c:49
int EMON_init_control_state(hwd_control_state_t *ptr)
Definition: linux-emon.c:203
int retval
Definition: zero_fork.c:53
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
#define EMON_MAX_COUNTERS
Definition: linux-emon.c:28
papi_vector_t _emon2_vector
Definition: linux-emon.c:86
static FILE * fp
Return codes and api definitions.
char events[MAX_EVENTS][BUFSIZ]
static void _check_EMON_error(char *emon2func, int err)
Definition: linux-emon.c:88
#define PAPI_ESYS
Definition: fpapi.h:108
int EMON_ntv_name_to_code(const char *name, unsigned int *code)
Definition: linux-emon.c:517
static int cidx
int return_type
Definition: linux-emon.c:54
int EMON_init_thread(hwd_context_t *ctx)
Definition: linux-emon.c:163
int EMON_shutdown_thread(hwd_context_t *ctx)
Definition: linux-emon.c:343
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:967
unsigned int selector
Definition: linux-emon.c:40
static int native
int EMON_ntv_code_to_descr(unsigned int EventCode, char *name, int len)
Definition: linux-emon.c:530
int EMON_shutdown_component(void)
Definition: linux-emon.c:352
void PAPIERROR(char *format,...)
int EMON_cleanup_eventset(hwd_control_state_t *ctrl)
Definition: linux-emon.c:379
long long ret
Definition: iozone.c:1346
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:630
long long last_update
Definition: linux-emon.c:76
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:53
EMON_control_state_t state
Definition: linux-emon.c:82
EMON_register_t resources
Definition: linux-emon.c:51
static EMON_native_event_entry_t EMON_native_table[]
Definition: linux-emon.c:101
int EMON_ntv_enum_events(unsigned int *EventCode, int modifier)
Definition: linux-emon.c:462
#define EMON_TOTAL_EVENTS
Definition: linux-emon.c:29
int EMON_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
Definition: linux-emon.c:364
#define PAPI_ENOEVNT
Definition: fpapi.h:112
char * name
Definition: linux-emon.c:52
int EMON_stop(hwd_context_t *ctx, hwd_control_state_t *ptr)
Definition: linux-emon.c:310
int EMON_start(hwd_context_t *ctx, hwd_control_state_t *ptr)
Definition: linux-emon.c:295
char * description
Definition: linux-emon.c:53
long long counters[EMON_MAX_COUNTERS]
Definition: linux-emon.c:74
int EMON_set_domain(hwd_control_state_t *cntrl, int domain)
Definition: linux-emon.c:427
#define PAPI_DOM_ALL
Definition: fpapi.h:25
static long count
int EMON_init_component(int cidx)
Definition: linux-emon.c:177
int i
Definition: fileop.c:140
int EMON_ntv_code_to_bits(unsigned int EventCode, hwd_register_t *bits)
Definition: linux-emon.c:552