PAPI  5.7.0.0
linux-libmsr.c
Go to the documentation of this file.
1 
25 /* Based on the rapl component by Vince Weaver */
26 
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <dirent.h>
30 #include <fcntl.h>
31 #include <string.h>
32 #include <stdint.h>
33 #include <errno.h>
34 
35 /* Headers required by PAPI */
36 #include "papi.h"
37 #include "papi_internal.h"
38 #include "papi_vector.h"
39 #include "papi_memory.h"
40 
41 #include <msr/msr_core.h>
42 #include <msr/msr_rapl.h>
43 #include <msr/msr_counters.h>
44 
45 typedef enum {
56 
57 typedef struct _libmsr_register {
58  unsigned int selector;
60 
61 typedef struct _libmsr_native_event_entry {
64  char description[PAPI_MAX_STR_LEN];
65  int package_num; /* which package/socket for this event */
70 
71 typedef struct _libmsr_reg_alloc {
74 
75 /* actually 32? But setting this to be safe? */
76 #define LIBMSR_MAX_COUNTERS 64
77 #define LIBMSR_MAX_PACKAGES 64
78 
79 typedef struct _libmsr_control_state {
80  /* The following are one per event being measured */
82  /* int domain; */
83  /* int multiplexed; */
84  /* int overflow; */
85  /* int inherit; */
86  int being_measured[LIBMSR_MAX_COUNTERS];
87  int which_counter[LIBMSR_MAX_COUNTERS];
89  /* The following is boolean: Is package NN active in for event */
90  int package_being_measured[LIBMSR_MAX_PACKAGES];
92 
93 typedef struct _libmsr_context {
96 
98 
100 static int num_events_global = 0;
102 
103 /***************************************************************************/
104 
105 /* For dynamic linking to libmsr */
106 /* Using weak symbols allows PAPI to be built with the component, but
107  * installed in a system without the required library */
108 #include <dlfcn.h>
109 static void* dllib1 = NULL;
110 void (*_dl_non_dynamic_init)(void) __attribute__((weak));
111 
112 /* Functions pointers */
113 static int (*init_msr_ptr)();
114 static int (*finalize_msr_ptr)();
115 static int (*rapl_init_ptr)(struct rapl_data ** rapl, uint64_t ** rapl_flags);
116 static int (*poll_rapl_data_ptr) ( );
117 static void (*set_pkg_rapl_limit_ptr) ( const int socket, struct rapl_limit* limit1, struct rapl_limit* limit2 );
118 static void (*get_pkg_rapl_limit_ptr) ( const int socket, struct rapl_limit* limit1, struct rapl_limit* limit2 );
119 static int (*core_config_ptr) (uint64_t * coresPerSocket, uint64_t * threadsPerCore, uint64_t * sysSockets, int * HTenabled);
120 static int (*rapl_storage_ptr) (struct rapl_data ** data, uint64_t ** flags);
121 static int (*get_rapl_power_info_ptr) ( const unsigned socket, struct rapl_power_info *info);
122 
123 /* Local wrappers for function pointers */
124 static int libmsr_init_msr () { return ((*init_msr_ptr)()); }
125 static int libmsr_finalize_msr () { return ((*finalize_msr_ptr)()); }
126 static int libmsr_rapl_init (struct rapl_data ** rapl_data, uint64_t ** rapl_flags) { return (*rapl_init_ptr)( rapl_data, rapl_flags ); }
127 static int libmsr_poll_rapl_data ( ) { return (*poll_rapl_data_ptr) (); }
128 static void libmsr_set_pkg_rapl_limit ( const int socket, struct rapl_limit* limit1, struct rapl_limit* limit2 ) { return (*set_pkg_rapl_limit_ptr) ( socket, limit1, limit2 ); }
129 static void libmsr_get_pkg_rapl_limit ( const int socket, struct rapl_limit* limit1, struct rapl_limit* limit2 ) { return (*get_pkg_rapl_limit_ptr) ( socket, limit1, limit2 ); }
130 static int libmsr_core_config(uint64_t * coresPerSocket, uint64_t * threadsPerCore, uint64_t * sysSockets, int * HTenabled) { return (*core_config_ptr) ( coresPerSocket, threadsPerCore, sysSockets, HTenabled ); }
131 static int libmsr_rapl_storage(struct rapl_data ** data, uint64_t ** flags) { return (*rapl_storage_ptr) (data, flags); }
132 static int libmsr_get_rapl_power_info( const unsigned socket, struct rapl_power_info *info) { return (*get_rapl_power_info_ptr) ( socket, info); }
133 
134 
135 #define CHECK_DL_STATUS( err, str ) if( err ) { strncpy( _libmsr_vector.cmp_info.disabled_reason, str, PAPI_MAX_STR_LEN ); return ( PAPI_ENOSUPP ); }
137 {
138  if ( _dl_non_dynamic_init != NULL ) {
139  strncpy( _libmsr_vector.cmp_info.disabled_reason, "The libmsr component REQUIRES dynamic linking capabilities.", PAPI_MAX_STR_LEN);
140  return PAPI_ENOSUPP;
141  }
142  dllib1 = dlopen("libmsr.so", RTLD_NOW | RTLD_GLOBAL);
143  CHECK_DL_STATUS( !dllib1 , "Component library libmsr.so not found." );
144  init_msr_ptr = dlsym( dllib1, "init_msr" );
145  CHECK_DL_STATUS( dlerror()!=NULL , "libmsr function init_msr not found." );
146  finalize_msr_ptr = dlsym( dllib1, "finalize_msr" );
147  CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function finalize_msr not found." );
148  rapl_init_ptr = dlsym( dllib1, "rapl_init" );
149  CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function rapl_init not found." );
150  poll_rapl_data_ptr = dlsym( dllib1, "poll_rapl_data" );
151  CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function poll_rapl_data not found." );
152  set_pkg_rapl_limit_ptr = dlsym( dllib1, "set_pkg_rapl_limit" );
153  CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function set_pkg_rapl_limit not found." );
154  get_pkg_rapl_limit_ptr = dlsym( dllib1, "get_pkg_rapl_limit" );
155  CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function get_pkg_rapl_limit not found." );
156  core_config_ptr = dlsym( dllib1, "core_config" );
157  CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function core_config not found." );
158  rapl_storage_ptr = dlsym( dllib1, "rapl_storage" );
159  CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function rapl_storage not found." );
160  get_rapl_power_info_ptr = dlsym( dllib1, "get_rapl_power_info" );
161  CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function get_rapl_power_info not found." );
162  return( PAPI_OK);
163 }
164 
165 /***************************************************************************/
166 /****** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT *******/
167 /***************************************************************************/
168 
169 /* Null terminated version of strncpy */
170 static char * _local_strlcpy( char *dst, const char *src, size_t size )
171 {
172  char *retval = strncpy( dst, src, size );
173  if ( size>0 ) dst[size-1] = '\0';
174  return( retval );
175 }
176 
177 
179 {
180  uint64_t socket, numSockets;
181  struct rapl_power_info raplinfo;
182  struct rapl_limit socketlim, socketlim2;
183 
184  SUBDBG("Enter: Resetting the sockets to defaults\n");
185  libmsr_core_config( NULL, NULL, &numSockets, NULL);
186  for (socket = 0; socket < numSockets; socket++) {
187  libmsr_get_rapl_power_info(socket, &raplinfo);
188  socketlim.bits = 0;
189  socketlim.watts = raplinfo.pkg_therm_power;
190  socketlim.seconds = 1;
191  socketlim2.bits = 0;
192  socketlim2.watts = raplinfo.pkg_therm_power * 1.2;
193  socketlim2.seconds = 3;
194  SUBDBG("Resetting socket %ld to defaults (%f,%f) (%f,%f)\n", socket, socketlim.watts, socketlim.seconds, socketlim2.watts, socketlim2.seconds);
195  libmsr_set_pkg_rapl_limit(socket, &socketlim, &socketlim2);
196  }
197 }
198 
199 
200 /************************* PAPI Functions **********************************/
201 
202 /*
203  * This is called whenever a thread is initialized
204  */
206 {
207  ( void ) ctx;
208  return PAPI_OK;
209 }
210 
211 
212 /*
213  * Called when PAPI process is initialized (i.e. PAPI_library_init)
214  */
216 {
217  SUBDBG( "Enter: cidx: %d\n", cidx );
218  int i, j;
219  /* int package; */
220  /* FILE *fff; */
221  /* char filename[BUFSIZ]; */
222  int num_packages;
223  /* int num_cpus; */
224  const PAPI_hw_info_t *hw_info;
225  int retval;
226  struct rapl_data * libmsr_rapl_data;
227  uint64_t * libmsr_rapl_flags;
228  uint64_t coresPerSocket, threadsPerCore, numSockets;
229  int HTenabled;
230 
231  /* check if Intel processor */
233  /* Can't use PAPI_get_hardware_info() if PAPI library not done initializing yet */
234  if( hw_info->vendor != PAPI_VENDOR_INTEL ) {
235  strncpy( _libmsr_vector.cmp_info.disabled_reason, "Not an Intel processor", PAPI_MAX_STR_LEN );
236  return PAPI_ENOSUPP;
237  }
238 
239  /* Dynamically load libmsr API and libraries */
241  if ( retval!=PAPI_OK ) {
242  SUBDBG ("Dynamic link of libmsr.so libraries failed, component will be disabled.\n");
243  SUBDBG ("See disable reason in papi_component_avail output for more details.\n");
244  return (PAPI_ENOSUPP);
245  }
246 
247  /* initialize libmsr */
248  if ( libmsr_init_msr() != 0 ) {
249  strncpy( _libmsr_vector.cmp_info.disabled_reason, "Library libmsr could not initialize (libmsr/init_msr failed)", PAPI_MAX_STR_LEN );
250  SUBDBG( "init_msr (libmsr) returned error. Possible problems accessing /dev/cpu/<n>/msr_safe or /dev/cpu/<n>/msr");
251  return PAPI_ENOSUPP;
252  }
253 
254  /* Initialize libmsr RAPL */
256  if ( libmsr_rapl_init( &libmsr_rapl_data, &libmsr_rapl_flags ) < 0 ) {
257  strncpy( _libmsr_vector.cmp_info.disabled_reason, "Library libmsr could not initialize RAPL (libmsr/rapl_init failed)", PAPI_MAX_STR_LEN );
258  SUBDBG( "Library libmsr could not initialize RAPL (libmsr/rapl_init failed)");
259  return PAPI_ENOSUPP;
260  }
262  }
263 
264  /* Get the numbers of cores, threads, sockets, ht */
265  libmsr_core_config(&coresPerSocket, &threadsPerCore, &numSockets, &HTenabled);
266 
267  /* Fill packages and cpus with sentinel values */
268  /* int packages[numSockets]; */
269  /* for( i = 0; i < numSockets; ++i ) packages[i] = -1; */
270  /* num_cpus = numSockets*coresPerSocket; */
271  num_packages = numSockets;
272 
273  /* /\* Detect how many packages and count num_cpus *\/ */
274  /* num_cpus = 0; */
275  /* while( 1 ) { */
276  /* int num_read; */
277  /* sprintf( filename, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", num_cpus ); */
278  /* fff = fopen( filename, "r" ); */
279  /* if( fff == NULL ) break; */
280  /* num_read = fscanf( fff, "%d", &package ); */
281  /* fclose( fff ); */
282  /* if( num_read != 1 ) { */
283  /* strcpy( _libmsr_vector.cmp_info.disabled_reason, "Error reading file: " ); */
284  /* strncat( _libmsr_vector.cmp_info.disabled_reason, filename, PAPI_MAX_STR_LEN - strlen( _libmsr_vector.cmp_info.disabled_reason ) - 1 ); */
285  /* _libmsr_vector.cmp_info.disabled_reason[PAPI_MAX_STR_LEN - 1] = '\0'; */
286  /* return PAPI_ESYS; */
287  /* } */
288  /* /\* Check if a new package *\/ */
289  /* if( ( package >= 0 ) && ( package < nr_cpus ) ) { */
290  /* if( packages[package] == -1 ) { */
291  /* SUBDBG( "Found package %d out of total %d\n", package, num_packages ); */
292  /* packages[package] = package; */
293  /* num_packages++; */
294  /* } */
295  /* } else { */
296  /* SUBDBG( "Package outside of allowed range\n" ); */
297  /* strncpy( _libmsr_vector.cmp_info.disabled_reason, "Package outside of allowed range", PAPI_MAX_STR_LEN ); */
298  /* return PAPI_ESYS; */
299  /* } */
300  /* num_cpus++; */
301  /* } */
302 
303  /* /\* Error if no accessible packages *\/ */
304  /* if( num_packages == 0 ) { */
305  /* SUBDBG( "Can't access any physical packages\n" ); */
306  /* strncpy( _libmsr_vector.cmp_info.disabled_reason, "Can't access /sys/devices/system/cpu/cpu<d>/topology/physical_package_id", PAPI_MAX_STR_LEN ); */
307  /* return PAPI_ESYS; */
308  /* } */
309  /* SUBDBG( "Found %d packages with %d cpus\n", num_packages, num_cpus ); */
310 
311  int max_num_events = ( NUM_OF_EVENTTYPES * num_packages );
312  /* Allocate space for events */
313  libmsr_native_events = ( _libmsr_native_event_entry_t * ) calloc( sizeof( _libmsr_native_event_entry_t ), max_num_events );
314  if ( !libmsr_native_events ) SUBDBG("Could not allocate memory\n" );
315 
316  /* Create events for package power info */
317  num_events_global = 0;
318  i = 0;
319  for( j = 0; j < num_packages; j++ ) {
320 
321  sprintf( libmsr_native_events[i].name, "PKG_ENERGY:PACKAGE%d", j );
322  strncpy( libmsr_native_events[i].units, "J", PAPI_MIN_STR_LEN );
323  sprintf(libmsr_native_events[i].description,"Number of Joules consumed by all cores and last level cache on package. Unit is Joules (double precision).");
328  i++;
329 
330  sprintf( libmsr_native_events[i].name, "PKG_WATTS:PACKAGE%d", j );
331  strncpy( libmsr_native_events[i].units, "W", PAPI_MIN_STR_LEN );
332  sprintf( libmsr_native_events[i].description, "Watts consumed by package. Unit is Watts (double precision).");
337  i++;
338 
339  sprintf( libmsr_native_events[i].name, "PKG_ELAPSED:PACKAGE%d", j );
340  strncpy( libmsr_native_events[i].units, "S", PAPI_MIN_STR_LEN );
341  sprintf( libmsr_native_events[i].description, "Time elapsed since last LIBMSR data reading from package. Unit is seconds (double precision).");
346  i++;
347 
348  sprintf( libmsr_native_events[i].name, "PKG_DELTA_ENERGY:PACKAGE%d", j );
349  strncpy( libmsr_native_events[i].units, "J", PAPI_MIN_STR_LEN );
350  sprintf( libmsr_native_events[i].description, "Number of Joules consumed by package since last LIBMSR data reading. Unit is Joules (double precision).");
355  i++;
356 
357  sprintf( libmsr_native_events[i].name, "PKG_POWER_LIMIT_1:PACKAGE%d", j );
358  strncpy( libmsr_native_events[i].units, "W", PAPI_MIN_STR_LEN );
359  sprintf( libmsr_native_events[i].description, "Average power limit over PKG_TIME_WINDOW_POWER_LIMIT_1 for package. Read/Write. Unit is Watts (double precision).");
364  i++;
365 
366  sprintf( libmsr_native_events[i].name, "PKG_TIME_WINDOW_POWER_LIMIT_1:PACKAGE%d", j );
367  strncpy( libmsr_native_events[i].units, "S", PAPI_MIN_STR_LEN );
368  sprintf( libmsr_native_events[i].description, "Time window used for averaging PACKAGE_POWER_LIMIT_1 for package. Read/Write. Unit is seconds (double precision).");
373  i++;
374 
375  sprintf( libmsr_native_events[i].name, "PKG_POWER_LIMIT_2:PACKAGE%d", j );
376  strncpy( libmsr_native_events[i].units, "W", PAPI_MIN_STR_LEN );
377  sprintf( libmsr_native_events[i].description, "Average power limit over PKG_TIME_WINDOW_POWER_LIMIT_2 for package. Read/Write. Unit is Watts (double precision).");
382  i++;
383 
384  sprintf( libmsr_native_events[i].name, "PKG_TIME_WINDOW_POWER_LIMIT_2:PACKAGE%d", j );
385  strncpy( libmsr_native_events[i].units, "S", PAPI_MIN_STR_LEN );
386  sprintf( libmsr_native_events[i].description, "Time window used for averaging PACKAGE_POWER_LIMIT_2 for package. Read/Write. Unit is seconds (double precision).");
391  i++;
392 
393  // TODO Add DRAM values
394  // DRAM_ENERGY
395  // DRAM_DELTA_ENERGY
396  // DRAM_WATTS
397  // TODO Add PP0, PP1 events
398  }
400 
401  /* Export the total number of events available */
405 
406  /* Export the component id */
408 
409  return PAPI_OK;
410 }
411 
412 
413 /*
414  * Control of counters (Reading/Writing/Starting/Stopping/Setup)
415  */
417 {
418  SUBDBG( "Enter: ctl: %p\n", ctl );
420  int i;
421 
422  for( i = 0; i < LIBMSR_MAX_COUNTERS; i++ )
423  control->which_counter[i] = 0;
424  for( i = 0; i < LIBMSR_MAX_PACKAGES; i++ )
425  control->package_being_measured[i] = 0;
426  control->num_events_measured = 0;
427 
428  return PAPI_OK;
429 }
430 
431 
433 {
434  SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
435  int nn, index;
436  ( void ) ctx;
438 
439  control->num_events_measured = 0;
440  /* Track which events need to be measured */
441  for( nn = 0; nn < count; nn++ ) {
442  index = native[nn].ni_event & PAPI_NATIVE_AND_MASK;
443  native[nn].ni_position = nn;
444  control->which_counter[nn] = index;
445  control->count[nn] = 0;
446  /* Track (on/off vector) which packages/sockets need to be measured for these events */
448  control->num_events_measured++;
449  }
450  return PAPI_OK;
451 }
452 
453 
455 {
456  SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
457  ( void ) ctx;
458  ( void ) ctl;
459 
460  /* Read once to get initial data */
461  if ( libmsr_poll_rapl_data() < 0 ) {
462  strncpy( _libmsr_vector.cmp_info.disabled_reason, "Function libmsr.so:poll_rapl_data failed. ", PAPI_MAX_STR_LEN );
463  return PAPI_ESYS;
464  }
465  return PAPI_OK;
466 }
467 
468 
469 int _libmsr_read( hwd_context_t * ctx, hwd_control_state_t * ctl, long long **events, int flags )
470 {
471  SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
472  ( void ) flags;
473  ( void ) ctx;
475  int nn, pp, ee; /* native, package, event indices */
476  union { long long ll; double dbl; } event_value_union;
477  struct rapl_limit limit1, limit2;
478  eventtype_enum eventtype;
479  struct rapl_data * libmsr_rapl_data;
480  uint64_t * libmsr_rapl_flags;
481 
482  /* Get a pointer to the rapl_data data storage */
483  if ( libmsr_rapl_storage( &libmsr_rapl_data, &libmsr_rapl_flags)!=0 ) {
484  strncpy( _libmsr_vector.cmp_info.disabled_reason, "Function libmsr.so:rapl_storage failed. ", PAPI_MAX_STR_LEN );
485  return PAPI_ESYS;
486  }
487 
488  /* If any socket/package needs to be read, call the poll once to read all packages */
489  for ( pp = 0; pp < LIBMSR_MAX_PACKAGES; pp++ ) {
490  if ( control->package_being_measured[pp] ) {
491  SUBDBG("Calling poll_rapl_data to read state from all sockets\n");
492  if ( libmsr_poll_rapl_data()!= 0 ) {
493  strncpy( _libmsr_vector.cmp_info.disabled_reason, "Function libmsr.so:poll_rapl_data failed. ", PAPI_MAX_STR_LEN );
494  return PAPI_ESYS;
495  }
496  break;
497  }
498  }
499 
500  /* Go thru events, assign package data to events as needed */
501  SUBDBG("Go thru events, assign package data to events as needed\n");
502  for( nn = 0; nn < control->num_events_measured; nn++ ) {
503  ee = control->which_counter[nn];
505  event_value_union.ll = 0LL;
506  eventtype = libmsr_native_events[ee].eventtype;
507  SUBDBG("nn %d ee %d pp %d eventtype %d\n", nn, ee, pp, eventtype);
508  switch (eventtype) {
509  case PKG_ENERGY:
510  event_value_union.dbl = libmsr_rapl_data->pkg_joules[pp];
511  break;
512  case PKG_ELAPSED:
513  event_value_union.dbl = libmsr_rapl_data->elapsed;
514  break;
515  case PKG_DELTA_ENERGY:
516  event_value_union.dbl = libmsr_rapl_data->pkg_delta_joules[pp];
517  break;
518  case PKG_WATTS:
519  event_value_union.dbl = libmsr_rapl_data->pkg_watts[pp];
520  break;
521  case PKG_POWER_LIMIT_1:
522  limit1.bits = 0; limit1.watts = 0; limit1.seconds = 0;
523  libmsr_get_pkg_rapl_limit( pp, &limit1, NULL );
524  event_value_union.dbl = limit1.watts;
525  break;
527  limit1.bits = 0; limit1.watts = 0; limit1.seconds = 0;
528  libmsr_get_pkg_rapl_limit( pp, &limit1, NULL );
529  event_value_union.dbl = limit1.seconds;
530  break;
531  case PKG_POWER_LIMIT_2:
532  limit2.bits = 0; limit2.watts = 0; limit2.seconds = 0;
533  libmsr_get_pkg_rapl_limit( pp, NULL, &limit2 );
534  event_value_union.dbl = limit2.watts;
535  break;
537  limit2.bits = 0; limit2.watts = 0; limit2.seconds = 0;
538  libmsr_get_pkg_rapl_limit( pp, NULL, &limit2 );
539  event_value_union.dbl = limit2.seconds;
540  break;
541  default:
542  SUBDBG("This LIBMSR event is unknown\n");
543  /* error here */
544  }
545  control->count[nn] = event_value_union.ll;
546  }
547  /* Pass back a pointer to our results */
548  if ( events!=NULL ) *events = ( ( _libmsr_control_state_t * ) ctl )->count;
549  return PAPI_OK;
550 }
551 
552 
553 static long long _local_get_eventval_from_values( _libmsr_control_state_t *control, long long *invalues, int package_num, eventtype_enum eventtype, long long defaultval )
554 {
555  int nn, pp, ee; /* native, package, event indices */
556  /* Loop thru all the events, if package and repltype match, return the value */
557  for( nn = 0; nn < control->num_events_measured; nn++ ) {
558  ee = control->which_counter[nn];
560  if ( pp == package_num && libmsr_native_events[ee].eventtype == eventtype )
561  return invalues[ee];
562  }
563  return defaultval;
564 }
565 
566 
567 int _libmsr_write( hwd_context_t * ctx, hwd_control_state_t * ctl, long long *values )
568 {
569  SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
570  /* write values */
571  ( void ) ctx;
573  //long long now = PAPI_get_real_usec();
574  int nn, pp, ee; /* native, package, event indices */
575  union { long long ll; double dbl; } event_value_union;
576  union { long long ll; double dbl; } timewin_union;
577  struct rapl_limit limit1, limit2;
578  eventtype_enum eventtype;
579 
580  /* Go thru events, assign package data to events as needed */
581  for( nn = 0; nn < control->num_events_measured; nn++ ) {
582  ee = control->which_counter[nn];
584  /* grab value and put into the union structure */
585  event_value_union.ll = values[nn];
586  /* If this is a NULL value, it means that the user does not want to write this value */
587  if ( event_value_union.ll == PAPI_NULL ) continue;
588  eventtype = libmsr_native_events[ee].eventtype;
589  SUBDBG("nn %d ee %d pp %d eventtype %d\n", nn, ee, pp, eventtype);
590  switch (eventtype) {
591  case PKG_ENERGY:
592  case PKG_ELAPSED:
593  case PKG_WATTS:
594  case PKG_DELTA_ENERGY:
595  /* Read only so do nothing */
596  break;
597  case PKG_POWER_LIMIT_1:
598  timewin_union.ll = _local_get_eventval_from_values( control, values, pp, PKG_TIME_WINDOW_POWER_LIMIT_1, -1 );
599  if ( timewin_union.ll > 0 ) {
600  limit1.watts = event_value_union.dbl;
601  limit1.seconds = timewin_union.dbl;
602  limit1.bits = 0;
603  //printf("set_libmsr_limit package %d limit1 %lf %lf\n", pp, limit1.watts, limit1.seconds);
604  libmsr_set_pkg_rapl_limit( pp, &limit1, NULL );
605  } else {
606  // Note error - power limit1 is not updated
607  SUBDBG("PACKAGE_POWER_LIMIT_1 needs PKG_TIME_WINDOW_POWER_LIMIT_1: Power cap not updated. ");
608  }
609  break;
610  case PKG_POWER_LIMIT_2:
611  timewin_union.ll = _local_get_eventval_from_values( control, values, pp, PKG_TIME_WINDOW_POWER_LIMIT_2, -1 );
612  if ( timewin_union.ll > 0 ) {
613  limit2.watts = event_value_union.dbl;
614  limit2.seconds = timewin_union.dbl;
615  limit2.bits = 0;
616  //printf("set_libmsr_limit package %d limit2 %lf %lf \n", pp, limit2.watts, limit2.seconds);
617  libmsr_set_pkg_rapl_limit( pp, NULL, &limit2 );
618  } else {
619  // Write error
620  PAPIERROR("PACKAGE_POWER_LIMIT_1 needs PKG_TIME_WINDOW_POWER_LIMIT_1: Powercap not updated.");
621  }
622  break;
625  /* These are only meaningful (and looked up) if the power limits are set */
626  break;
627  default:
628  SUBDBG("This LIBMSR information type is unknown\n");
629  /* error here */
630  }
631  }
632  return PAPI_OK;
633 }
634 
635 
637 {
638  SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
639  ( void ) ctx;
640  ( void ) ctl;
642  return PAPI_OK;
643 }
644 
645 
646 /* Shutdown a thread */
648 {
649  SUBDBG( "Enter: ctl: %p\n", ctx );
650  ( void ) ctx;
651  return PAPI_OK;
652 }
653 
654 
655 /*
656  * Clean up what was setup in libmsr_init_component().
657  */
659 {
660  SUBDBG( "Enter\n" );
661 
663 
664  if ( libmsr_finalize_msr()!=0 ) {
665  strncpy( _libmsr_vector.cmp_info.disabled_reason, "Function libmsr.so:finalize_msr failed. ", PAPI_MAX_STR_LEN );
666  return PAPI_ESYS;
667  }
668  if( libmsr_native_events ) {
669  free( libmsr_native_events );
670  libmsr_native_events = NULL;
671  }
672  dlclose( dllib1 );
673  return PAPI_OK;
674 }
675 
676 
677 /* This function sets various options in the component The valid codes
678  * being passed in are PAPI_SET_DEFDOM, PAPI_SET_DOMAIN,
679  * PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT */
680 int _libmsr_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
681 {
682  SUBDBG( "Enter: ctx: %p\n", ctx );
683  ( void ) ctx;
684  ( void ) code;
685  ( void ) option;
686 
687  return PAPI_OK;
688 }
689 
690 
691 /*
692  * This function has to set the bits needed to count different domains
693  * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
694  * By default return PAPI_EINVAL if none of those are specified
695  * and PAPI_OK with success
696  * PAPI_DOM_USER is only user context is counted
697  * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
698  * PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses)
699  * PAPI_DOM_ALL is all of the domains
700  */
701 int _libmsr_set_domain( hwd_control_state_t * ctl, int domain )
702 {
703  SUBDBG( "Enter: ctl: %p\n", ctl );
704  ( void ) ctl;
705  /* In theory we only support system-wide mode */
706  /* How to best handle that? */
707  if( domain != PAPI_DOM_ALL )
708  return PAPI_EINVAL;
709  return PAPI_OK;
710 }
711 
712 
714 {
715  SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
716  ( void ) ctx;
717  ( void ) ctl;
718 
719  return PAPI_OK;
720 }
721 
722 
723 /*
724  * Native Event functions
725  */
726 int _libmsr_ntv_enum_events( unsigned int *EventCode, int modifier )
727 {
728  SUBDBG( "Enter: EventCode: %d\n", *EventCode );
729  int index;
730  if ( num_events_global == 0 )
731  return PAPI_ENOEVNT;
732 
733  switch ( modifier ) {
734  case PAPI_ENUM_FIRST:
735  *EventCode = 0;
736  return PAPI_OK;
737  break;
738  case PAPI_ENUM_EVENTS:
739  index = *EventCode & PAPI_NATIVE_AND_MASK;
740  if ( index < num_events_global - 1 ) {
741  *EventCode = *EventCode + 1;
742  return PAPI_OK;
743  } else {
744  return PAPI_ENOEVNT;
745  }
746  break;
747  // case PAPI_NTV_ENUM_UMASKS:
748  default:
749  return PAPI_EINVAL;
750  }
751 
752  return PAPI_EINVAL;
753 }
754 
755 
756 /*
757  *
758  */
759 int _libmsr_ntv_code_to_name( unsigned int EventCode, char *name, int len )
760 {
761  SUBDBG( "Enter: EventCode: %d\n", EventCode );
762  int index = EventCode & PAPI_NATIVE_AND_MASK;
763 
764  if( index >= 0 && index < num_events_global ) {
766  return PAPI_OK;
767  }
768  return PAPI_ENOEVNT;
769 }
770 
771 
772 int _libmsr_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
773 {
774  SUBDBG( "Enter: EventCode: %d\n", EventCode );
775  int index = EventCode;
776 
777  if( ( index < 0 ) || ( index >= num_events_global ) )
778  return PAPI_ENOEVNT;
779 
780  _local_strlcpy( name, libmsr_native_events[index].description, len );
781  return PAPI_OK;
782 }
783 
784 
785 int _libmsr_ntv_code_to_info( unsigned int EventCode, PAPI_event_info_t * info )
786 {
787  SUBDBG( "Enter: EventCode: %d\n", EventCode );
788  int index = EventCode;
789 
790  if( ( index < 0 ) || ( index >= num_events_global ) )
791  return PAPI_ENOEVNT;
792 
793  _local_strlcpy( info->symbol, libmsr_native_events[index].name, sizeof( info->symbol ) );
794  _local_strlcpy( info->long_descr, libmsr_native_events[index].description, sizeof( info->long_descr ) );
795  _local_strlcpy( info->units, libmsr_native_events[index].units, sizeof( info->units ) );
797  return PAPI_OK;
798 }
799 
800 
802  .cmp_info = { /* (unspecified values are initialized to 0) */
803  .name = "libmsr",
804  .short_name = "libmsr",
805  .description = "PAPI component for libmsr from LANL for power (RAPL) read/write",
806  .version = "5.3.0",
807  .default_domain = PAPI_DOM_ALL,
808  .default_granularity = PAPI_GRN_SYS,
809  .available_granularities = PAPI_GRN_SYS,
810  .hardware_intr_sig = PAPI_INT_SIGNAL,
811  .available_domains = PAPI_DOM_ALL,
812  },
813  /* sizes of framework-opaque component-private structures */
814  .size = {
815  .context = sizeof( _libmsr_context_t ),
816  .control_state = sizeof( _libmsr_control_state_t ),
817  .reg_value = sizeof( _libmsr_register_t ),
818  .reg_alloc = sizeof( _libmsr_reg_alloc_t ),
819  },
820  /* function pointers in this component */
821  .start = _libmsr_start,
822  .stop = _libmsr_stop,
823  .read = _libmsr_read,
824  .reset = _libmsr_reset,
825  .write = _libmsr_write,
826  .init_component = _libmsr_init_component,
827  .init_thread = _libmsr_init_thread,
828  .init_control_state = _libmsr_init_control_state,
829  .update_control_state = _libmsr_update_control_state,
830  .ctl = _libmsr_ctl,
831  .set_domain = _libmsr_set_domain,
832  .ntv_enum_events = _libmsr_ntv_enum_events,
833  .ntv_code_to_name = _libmsr_ntv_code_to_name,
834  .ntv_code_to_descr = _libmsr_ntv_code_to_descr,
835  .ntv_code_to_info = _libmsr_ntv_code_to_info,
836  .shutdown_thread = _libmsr_shutdown_thread,
837  .shutdown_component = _libmsr_shutdown_component,
838 };
static int libmsr_poll_rapl_data()
Definition: linux-libmsr.c:127
#define PAPI_OK
Definition: fpapi.h:105
int return_type
Definition: linux-libmsr.c:67
char disabled_reason[PAPI_MAX_STR_LEN]
Definition: papi.h:637
int _libmsr_init_control_state(hwd_control_state_t *ctl)
Definition: linux-libmsr.c:416
static void libmsr_set_pkg_rapl_limit(const int socket, struct rapl_limit *limit1, struct rapl_limit *limit2)
Definition: linux-libmsr.c:128
static const char * name
Definition: fork_overflow.c:31
int _libmsr_shutdown_component(void)
Definition: linux-libmsr.c:658
static char * _local_strlcpy(char *dst, const char *src, size_t size)
Definition: linux-libmsr.c:170
#define PAPI_EINVAL
Definition: fpapi.h:106
Hardware info structure.
Definition: papi.h:781
static int _local_linkDynamicLibraries()
Definition: linux-libmsr.c:136
char units[PAPI_MIN_STR_LEN]
Definition: papi.h:976
static int libmsr_core_config(uint64_t *coresPerSocket, uint64_t *threadsPerCore, uint64_t *sysSockets, int *HTenabled)
Definition: linux-libmsr.c:130
eventtype_enum
Definition: linux-libmsr.c:45
#define PAPI_ENOSUPP
Definition: fpapi.h:123
static _libmsr_native_event_entry_t * libmsr_native_events
Definition: linux-libmsr.c:99
#define CHECK_DL_STATUS(err, str)
Definition: linux-libmsr.c:135
int _libmsr_init_component(int cidx)
Definition: linux-libmsr.c:215
_libmsr_register_t resources
Definition: linux-libmsr.c:68
int _libmsr_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
Definition: linux-libmsr.c:785
int _libmsr_ntv_code_to_name(unsigned int EventCode, char *name, int len)
Definition: linux-libmsr.c:759
static int num_packages
Definition: linux-rapl.c:150
#define PAPI_GRN_SYS
Definition: fpapi.h:71
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:970
static int libmsr_get_rapl_power_info(const unsigned socket, struct rapl_power_info *info)
Definition: linux-libmsr.c:132
_libmsr_register_t ra_bits
Definition: linux-libmsr.c:72
int retval
Definition: zero_fork.c:53
char units[MAX_EVENTS][BUFSIZ]
Definition: powercap_plot.c:15
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
Return codes and api definitions.
char events[MAX_EVENTS][BUFSIZ]
static int libmsr_finalize_msr()
Definition: linux-libmsr.c:125
#define PAPI_ESYS
Definition: fpapi.h:108
papi_vector_t _libmsr_vector
Definition: linux-libmsr.c:97
static int cidx
int _libmsr_init_thread(hwd_context_t *ctx)
Definition: linux-libmsr.c:205
_libmsr_control_state_t state
Definition: linux-libmsr.c:94
static long long _local_get_eventval_from_values(_libmsr_control_state_t *control, long long *invalues, int package_num, eventtype_enum eventtype, long long defaultval)
Definition: linux-libmsr.c:553
static int already_called_libmsr_rapl_initialized_global
Definition: linux-libmsr.c:101
#define LIBMSR_MAX_COUNTERS
Definition: linux-libmsr.c:76
#define LIBMSR_MAX_PACKAGES
Definition: linux-libmsr.c:77
int package_num
Definition: linux-libmsr.c:65
int _libmsr_write(hwd_context_t *ctx, hwd_control_state_t *ctl, long long *values)
Definition: linux-libmsr.c:567
static void libmsr_get_pkg_rapl_limit(const int socket, struct rapl_limit *limit1, struct rapl_limit *limit2)
Definition: linux-libmsr.c:129
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:967
#define PAPI_MIN_STR_LEN
Definition: fpapi.h:41
eventtype_enum eventtype
Definition: linux-libmsr.c:66
int which_counter[LIBMSR_MAX_COUNTERS]
Definition: linux-libmsr.c:87
int _libmsr_shutdown_thread(hwd_context_t *ctx)
Definition: linux-libmsr.c:647
int _libmsr_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-libmsr.c:713
__attribute__((constructor))
Definition: init_fini.c:12
static int libmsr_rapl_storage(struct rapl_data **data, uint64_t **flags)
Definition: linux-libmsr.c:131
static int native
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
#define PAPI_NULL
Definition: fpapi.h:13
int _libmsr_set_domain(hwd_control_state_t *ctl, int domain)
Definition: linux-libmsr.c:701
void PAPIERROR(char *format,...)
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:630
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:53
char name[PAPI_MAX_STR_LEN]
Definition: linux-libmsr.c:62
int _libmsr_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
Definition: linux-libmsr.c:680
unsigned int selector
Definition: linux-libmsr.c:58
int _libmsr_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
Definition: linux-libmsr.c:469
int package_being_measured[LIBMSR_MAX_PACKAGES]
Definition: linux-libmsr.c:90
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:56
PAPI_hw_info_t hw_info
#define PAPI_VENDOR_INTEL
Definition: papi.h:349
static int libmsr_rapl_init(struct rapl_data **rapl_data, uint64_t **rapl_flags)
Definition: linux-libmsr.c:126
static void * dllib1
Definition: linux-libmsr.c:109
int vendor
Definition: papi.h:788
static int num_events_global
Definition: linux-libmsr.c:100
int _libmsr_ntv_enum_events(unsigned int *EventCode, int modifier)
Definition: linux-libmsr.c:726
#define PAPI_ENOEVNT
Definition: fpapi.h:112
int _libmsr_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-libmsr.c:454
Definition: linux-libmsr.c:61
#define PAPI_NATIVE_AND_MASK
int _libmsr_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
Definition: linux-libmsr.c:432
long long count[LIBMSR_MAX_COUNTERS]
Definition: linux-libmsr.c:88
int _libmsr_ntv_code_to_descr(unsigned int EventCode, char *name, int len)
Definition: linux-libmsr.c:772
void _local_set_to_defaults()
Definition: linux-libmsr.c:178
char description[PAPI_MAX_STR_LEN]
Definition: linux-libmsr.c:64
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
void(* _dl_non_dynamic_init)(void)
Definition: linux-libmsr.c:110
static const PAPI_hw_info_t * hw_info
Definition: byte_profile.c:28
#define PAPI_DOM_ALL
Definition: fpapi.h:25
int _libmsr_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-libmsr.c:636
static long count
int i
Definition: fileop.c:140
#define PAPI_MAX_STR_LEN
Definition: fpapi.h:43
char units[PAPI_MIN_STR_LEN]
Definition: linux-libmsr.c:63