PAPI 7.1.0.0
Loading...
Searching...
No Matches
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_core.h>
42#include <msr_rapl.h>
43#include <msr_counters.h>
44
45typedef enum {
56
57typedef struct _libmsr_register {
58 unsigned int selector;
60
61typedef struct _libmsr_native_event_entry {
64 char description[PAPI_MAX_STR_LEN];
65 int package_num; /* which package/socket for this event */
70
71typedef 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// The following macro follows if a string function has an error. It should
80// never happen; but it is necessary to prevent compiler warnings. We print
81// something just in case there is programmer error in invoking the function.
82#define HANDLE_STRING_ERROR {fprintf(stderr,"%s:%i unexpected string function error.\n",__FILE__,__LINE__); exit(-1);}
83
84typedef struct _libmsr_control_state {
85 /* The following are one per event being measured */
87 /* int domain; */
88 /* int multiplexed; */
89 /* int overflow; */
90 /* int inherit; */
91 int being_measured[LIBMSR_MAX_COUNTERS];
92 int which_counter[LIBMSR_MAX_COUNTERS];
94 /* The following is boolean: Is package NN active in for event */
95 int package_being_measured[LIBMSR_MAX_PACKAGES];
97
98typedef struct _libmsr_context {
101
103
105static int num_events_global = 0;
107
108/***************************************************************************/
109
110/* For dynamic linking to libmsr */
111/* Using weak symbols allows PAPI to be built with the component, but
112 * installed in a system without the required library */
113#include <dlfcn.h>
114static void* dl1 = NULL;
115
116// string macro defined within Rules.libmsr
117static char libmsr_main[]=PAPI_LIBMSR_MAIN;
118
119//-----------------------------------------------------------------------------
120// Using weak symbols (global declared without a value, so it defers to any
121// other global declared in another file WITH a value) allows PAPI to be built
122// with the component, but PAPI can still be installed in a system without the
123// required library.
124//-----------------------------------------------------------------------------
125
126void (*_dl_non_dynamic_init)(void) __attribute__((weak)); // declare a weak dynamic-library init routine pointer.
127
128/* Functions pointers */
129static int (*init_msr_ptr)();
130static int (*finalize_msr_ptr)();
131static int (*rapl_init_ptr)(struct rapl_data ** rapl, uint64_t ** rapl_flags);
132static int (*poll_rapl_data_ptr) ( );
133static void (*set_pkg_rapl_limit_ptr) ( const int socket, struct rapl_limit* limit1, struct rapl_limit* limit2 );
134static void (*get_pkg_rapl_limit_ptr) ( const int socket, struct rapl_limit* limit1, struct rapl_limit* limit2 );
135static int (*core_config_ptr) (uint64_t * coresPerSocket, uint64_t * threadsPerCore, uint64_t * sysSockets, int * HTenabled);
136static int (*rapl_storage_ptr) (struct rapl_data ** data, uint64_t ** flags);
137static int (*get_rapl_power_info_ptr) ( const unsigned socket, struct rapl_power_info *info);
138
139/* Local wrappers for function pointers */
140static int libmsr_init_msr () { return ((*init_msr_ptr)()); }
141static int libmsr_finalize_msr () { return ((*finalize_msr_ptr)()); }
142static int libmsr_rapl_init (struct rapl_data ** rapl_data, uint64_t ** rapl_flags) { return (*rapl_init_ptr)( rapl_data, rapl_flags ); }
143static int libmsr_poll_rapl_data ( ) { return (*poll_rapl_data_ptr) (); }
144static 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 ); }
145static 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 ); }
146static int libmsr_core_config(uint64_t * coresPerSocket, uint64_t * threadsPerCore, uint64_t * sysSockets, int * HTenabled) { return (*core_config_ptr) ( coresPerSocket, threadsPerCore, sysSockets, HTenabled ); }
147static int libmsr_rapl_storage(struct rapl_data ** data, uint64_t ** flags) { return (*rapl_storage_ptr) (data, flags); }
148static int libmsr_get_rapl_power_info( const unsigned socket, struct rapl_power_info *info) { return (*get_rapl_power_info_ptr) ( socket, info); }
149
150
151#define CHECK_DL_STATUS( err, str ) if( err ) { \
152 char* strCpy=strncpy(_libmsr_vector.cmp_info.disabled_reason, str, PAPI_MAX_STR_LEN); \
153 _libmsr_vector.cmp_info.disabled_reason[PAPI_MAX_STR_LEN-1]=0; \
154 if (strCpy == NULL) HANDLE_STRING_ERROR; \
155 return ( PAPI_ENOSUPP ); }
156
158{
159 if ( _dl_non_dynamic_init != NULL ) {
160 // If weak var present, statically linked insted of dynamic.
161 char *strCpy = strncpy( _libmsr_vector.cmp_info.disabled_reason, "The libmsr component REQUIRES dynamic linking capabilities.", PAPI_MAX_STR_LEN);
163 if (strCpy == NULL) HANDLE_STRING_ERROR;
164 // EXIT not supported.
165 return PAPI_ENOSUPP;
166 }
167
168 char path_name[1024];
169 char *libmsr_root = getenv("PAPI_LIBMSR_ROOT");
170
171 dl1 = NULL;
172 // Step 1: Process override if given.
173 if (strlen(libmsr_main) > 0) { // If override given, it has to work.
174 dl1 = dlopen(libmsr_main, RTLD_NOW | RTLD_GLOBAL); // Try to open that path.
175 if (dl1 == NULL) {
176 int strErr=snprintf(_libmsr_vector.cmp_info.disabled_reason, PAPI_MAX_STR_LEN, "PAPI_LIBMSR_MAIN override '%s' given in Rules.libmsr not found.", libmsr_main);
179 return(PAPI_ENOSUPP); // Override given but not found.
180 }
181 }
182
183 // Step 2: Try system paths, will work with Spack, LD_LIBRARY_PATH, default paths.
184 if (dl1 == NULL) { // No override,
185 dl1 = dlopen("libmsr.so", RTLD_NOW | RTLD_GLOBAL); // Try system paths.
186 }
187
188 // Step 3: Try the explicit install default.
189 if (dl1 == NULL && libmsr_root != NULL) { // if root given, try it.
190 int strErr=snprintf(path_name, 1024-2, "%s/lib/libmsr.so", libmsr_root); // PAPI Root check.
191 path_name[1023]=0;
192 if (strErr > 1024-2) HANDLE_STRING_ERROR;
193 dl1 = dlopen(path_name, RTLD_NOW | RTLD_GLOBAL); // Try to open that path.
194 }
195
196 // Check for failure.
197 if (dl1 == NULL) {
198 int strErr=snprintf(_libmsr_vector.cmp_info.disabled_reason, PAPI_MAX_STR_LEN, "%s", dlerror());
201 return(PAPI_ENOSUPP);
202 }
203
204 // We have dl1.
205
206 CHECK_DL_STATUS( !dl1 , "Component library libmsr.so not found." );
207 init_msr_ptr = dlsym( dl1, "init_msr" );
208 CHECK_DL_STATUS( dlerror()!=NULL , "libmsr function init_msr not found." );
209 finalize_msr_ptr = dlsym( dl1, "finalize_msr" );
210 CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function finalize_msr not found." );
211 rapl_init_ptr = dlsym( dl1, "rapl_init" );
212 CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function rapl_init not found." );
213 poll_rapl_data_ptr = dlsym( dl1, "poll_rapl_data" );
214 CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function poll_rapl_data not found." );
215 set_pkg_rapl_limit_ptr = dlsym( dl1, "set_pkg_rapl_limit" );
216 CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function set_pkg_rapl_limit not found." );
217 get_pkg_rapl_limit_ptr = dlsym( dl1, "get_pkg_rapl_limit" );
218 CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function get_pkg_rapl_limit not found." );
219 core_config_ptr = dlsym( dl1, "core_config" );
220 CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function core_config not found." );
221 rapl_storage_ptr = dlsym( dl1, "rapl_storage" );
222 CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function rapl_storage not found." );
223 get_rapl_power_info_ptr = dlsym( dl1, "get_rapl_power_info" );
224 CHECK_DL_STATUS( dlerror()!=NULL, "libmsr function get_rapl_power_info not found." );
225 return( PAPI_OK);
226}
227
228/***************************************************************************/
229/****** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT *******/
230/***************************************************************************/
231
232/* Null terminated version of strncpy */
233static char * _local_strlcpy( char *dst, const char *src, size_t size )
234{
235 char *retval = strncpy( dst, src, size );
236 if ( size>0 ) dst[size-1] = '\0';
237 return( retval );
238}
239
240
242{
243 uint64_t socket, numSockets;
244 struct rapl_power_info raplinfo;
245 struct rapl_limit socketlim, socketlim2;
246
247 SUBDBG("Enter: Resetting the sockets to defaults\n");
248 libmsr_core_config( NULL, NULL, &numSockets, NULL);
249 for (socket = 0; socket < numSockets; socket++) {
250 libmsr_get_rapl_power_info(socket, &raplinfo);
251 socketlim.bits = 0;
252 socketlim.watts = raplinfo.pkg_therm_power;
253 socketlim.seconds = 1;
254 socketlim2.bits = 0;
255 socketlim2.watts = raplinfo.pkg_therm_power * 1.2;
256 socketlim2.seconds = 3;
257 SUBDBG("Resetting socket %ld to defaults (%f,%f) (%f,%f)\n", socket, socketlim.watts, socketlim.seconds, socketlim2.watts, socketlim2.seconds);
258 libmsr_set_pkg_rapl_limit(socket, &socketlim, &socketlim2);
259 }
260}
261
262
263/************************* PAPI Functions **********************************/
264
265/*
266 * This is called whenever a thread is initialized
267 */
269{
270 ( void ) ctx;
271 return PAPI_OK;
272}
273
274
275/*
276 * Called when PAPI process is initialized (i.e. PAPI_library_init)
277 */
279{
280 SUBDBG( "Enter: cidx: %d\n", cidx );
281 int i, j;
282 /* int package; */
283 /* FILE *fff; */
284 /* char filename[BUFSIZ]; */
285 int num_packages;
286 /* int num_cpus; */
287 const PAPI_hw_info_t *hw_info;
288 int retval = PAPI_OK;
289 struct rapl_data * libmsr_rapl_data;
290 uint64_t * libmsr_rapl_flags;
291 uint64_t coresPerSocket, threadsPerCore, numSockets;
292 int HTenabled;
293
294 /* check if Intel processor */
296 /* Can't use PAPI_get_hardware_info() if PAPI library not done initializing yet */
298 char *strCpy = strncpy( _libmsr_vector.cmp_info.disabled_reason, "Not an Intel processor", PAPI_MAX_STR_LEN);
300 if (strCpy == NULL) HANDLE_STRING_ERROR;
302 goto fn_fail;
303 }
304
305 /* Dynamically load libmsr API and libraries */
307 if ( retval!=PAPI_OK ) {
308 SUBDBG ("Dynamic link of libmsr.so libraries failed, component will be disabled.\n");
309 SUBDBG ("See disable reason in papi_component_avail output for more details.\n");
311 goto fn_fail;
312 }
313
314 /* initialize libmsr */
315 if ( libmsr_init_msr() != 0 ) {
316 SUBDBG( "init_msr (libmsr) returned error. Possible permission problem accessing /dev/cpu/<n>/msr_safe or /dev/cpu/<n>/msr");
317 char* strCpy=strncpy( _libmsr_vector.cmp_info.disabled_reason, "Library libmsr init failed; possible permission issue accessing /dev/cpu/<n>/msr)", PAPI_MAX_STR_LEN);
319 if (strCpy == NULL) HANDLE_STRING_ERROR;
321 goto fn_fail;
322 }
323
324 /* Initialize libmsr RAPL */
326 if ( libmsr_rapl_init( &libmsr_rapl_data, &libmsr_rapl_flags ) < 0 ) {
327 SUBDBG( "Library libmsr could not initialize RAPL (libmsr/rapl_init failed)");
328 char* strCpy=strncpy( _libmsr_vector.cmp_info.disabled_reason, "Library libmsr could not initialize RAPL (libmsr/rapl_init failed)", PAPI_MAX_STR_LEN);
330 if (strCpy == NULL) HANDLE_STRING_ERROR;
332 goto fn_fail;
333 }
335 }
336
337 /* Get the numbers of cores, threads, sockets, ht */
338 libmsr_core_config(&coresPerSocket, &threadsPerCore, &numSockets, &HTenabled);
339
340 /* Fill packages and cpus with sentinel values */
341 /* int packages[numSockets]; */
342 /* for( i = 0; i < numSockets; ++i ) packages[i] = -1; */
343 /* num_cpus = numSockets*coresPerSocket; */
344 num_packages = numSockets;
345
346 /* /\* Detect how many packages and count num_cpus *\/ */
347 /* num_cpus = 0; */
348 /* while( 1 ) { */
349 /* int num_read; */
350 /* sprintf( filename, "/sys/devices/system/cpu/cpu%d/topology/physical_package_id", num_cpus ); */
351 /* fff = fopen( filename, "r" ); */
352 /* if( fff == NULL ) break; */
353 /* num_read = fscanf( fff, "%d", &package ); */
354 /* fclose( fff ); */
355 /* if( num_read != 1 ) { */
356 /* strcpy( _libmsr_vector.cmp_info.disabled_reason, "Error reading file: " ); */
357 /* strncat( _libmsr_vector.cmp_info.disabled_reason, filename, PAPI_MAX_STR_LEN - strlen( _libmsr_vector.cmp_info.disabled_reason ) - 1 ); */
358 /* _libmsr_vector.cmp_info.disabled_reason[PAPI_MAX_STR_LEN - 1] = '\0'; */
359 /* return PAPI_ESYS; */
360 /* } */
361 /* /\* Check if a new package *\/ */
362 /* if( ( package >= 0 ) && ( package < nr_cpus ) ) { */
363 /* if( packages[package] == -1 ) { */
364 /* SUBDBG( "Found package %d out of total %d\n", package, num_packages ); */
365 /* packages[package] = package; */
366 /* num_packages++; */
367 /* } */
368 /* } else { */
369 /* SUBDBG( "Package outside of allowed range\n" ); */
370 /* strncpy( _libmsr_vector.cmp_info.disabled_reason, "Package outside of allowed range", PAPI_MAX_STR_LEN ); */
371 /* return PAPI_ESYS; */
372 /* } */
373 /* num_cpus++; */
374 /* } */
375
376 /* /\* Error if no accessible packages *\/ */
377 /* if( num_packages == 0 ) { */
378 /* SUBDBG( "Can't access any physical packages\n" ); */
379 /* strncpy( _libmsr_vector.cmp_info.disabled_reason, "Can't access /sys/devices/system/cpu/cpu<d>/topology/physical_package_id", PAPI_MAX_STR_LEN ); */
380 /* return PAPI_ESYS; */
381 /* } */
382 /* SUBDBG( "Found %d packages with %d cpus\n", num_packages, num_cpus ); */
383
384 int max_num_events = ( NUM_OF_EVENTTYPES * num_packages );
385 /* Allocate space for events */
387 if ( !libmsr_native_events ) {
389 "Could not allocate %lu bytes of memory for libmsr native event array.", max_num_events*sizeof(_libmsr_native_event_entry_t));
390 _libmsr_vector.cmp_info.disabled_reason[PAPI_MAX_STR_LEN-1]=0; // force null termination.
392 SUBDBG("Could not allocate memory\n" );
394 goto fn_fail;
395 }
396
397 /* Create events for package power info */
399 i = 0;
400 for( j = 0; j < num_packages; j++ ) {
401
402 sprintf( libmsr_native_events[i].name, "PKG_ENERGY:PACKAGE%d", j );
404 sprintf(libmsr_native_events[i].description,"Number of Joules consumed by all cores and last level cache on package. Unit is Joules (double precision).");
409 i++;
410
411 sprintf( libmsr_native_events[i].name, "PKG_WATTS:PACKAGE%d", j );
413 sprintf( libmsr_native_events[i].description, "Watts consumed by package. Unit is Watts (double precision).");
418 i++;
419
420 sprintf( libmsr_native_events[i].name, "PKG_ELAPSED:PACKAGE%d", j );
422 sprintf( libmsr_native_events[i].description, "Time elapsed since last LIBMSR data reading from package. Unit is seconds (double precision).");
427 i++;
428
429 sprintf( libmsr_native_events[i].name, "PKG_DELTA_ENERGY:PACKAGE%d", j );
431 sprintf( libmsr_native_events[i].description, "Number of Joules consumed by package since last LIBMSR data reading. Unit is Joules (double precision).");
436 i++;
437
438 sprintf( libmsr_native_events[i].name, "PKG_POWER_LIMIT_1:PACKAGE%d", j );
440 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).");
445 i++;
446
447 sprintf( libmsr_native_events[i].name, "PKG_TIME_WINDOW_POWER_LIMIT_1:PACKAGE%d", j );
449 sprintf( libmsr_native_events[i].description, "Time window used for averaging PACKAGE_POWER_LIMIT_1 for package. Read/Write. Unit is seconds (double precision).");
454 i++;
455
456 sprintf( libmsr_native_events[i].name, "PKG_POWER_LIMIT_2:PACKAGE%d", j );
458 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).");
463 i++;
464
465 sprintf( libmsr_native_events[i].name, "PKG_TIME_WINDOW_POWER_LIMIT_2:PACKAGE%d", j );
467 sprintf( libmsr_native_events[i].description, "Time window used for averaging PACKAGE_POWER_LIMIT_2 for package. Read/Write. Unit is seconds (double precision).");
472 i++;
473
474 // TODO Add DRAM values
475 // DRAM_ENERGY
476 // DRAM_DELTA_ENERGY
477 // DRAM_WATTS
478 // TODO Add PP0, PP1 events
479 }
481
482 /* Export the total number of events available */
486
487 /* Export the component id */
489
490 fn_exit:
491 _papi_hwd[cidx]->cmp_info.disabled = retval;
492 return retval;
493 fn_fail:
494 goto fn_exit;
495}
496
497
498/*
499 * Control of counters (Reading/Writing/Starting/Stopping/Setup)
500 */
502{
503 SUBDBG( "Enter: ctl: %p\n", ctl );
505 int i;
506
507 for( i = 0; i < LIBMSR_MAX_COUNTERS; i++ )
508 control->which_counter[i] = 0;
509 for( i = 0; i < LIBMSR_MAX_PACKAGES; i++ )
510 control->package_being_measured[i] = 0;
511 control->num_events_measured = 0;
512
513 return PAPI_OK;
514}
515
516
518{
519 SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
520 int nn, index;
521 ( void ) ctx;
523
524 control->num_events_measured = 0;
525 /* Track which events need to be measured */
526 for( nn = 0; nn < count; nn++ ) {
527 index = native[nn].ni_event & PAPI_NATIVE_AND_MASK;
528 native[nn].ni_position = nn;
529 control->which_counter[nn] = index;
530 control->count[nn] = 0;
531 /* Track (on/off vector) which packages/sockets need to be measured for these events */
533 control->num_events_measured++;
534 }
535 return PAPI_OK;
536}
537
538
540{
541 SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
542 ( void ) ctx;
543 ( void ) ctl;
544
545 /* Read once to get initial data */
546 if ( libmsr_poll_rapl_data() < 0 ) {
547 SUBDBG("Function libmsr.so:poll_rapl_data failed.\n");
548 return PAPI_ESYS;
549 }
550 return PAPI_OK;
551}
552
553
554int _libmsr_read( hwd_context_t * ctx, hwd_control_state_t * ctl, long long **events, int flags )
555{
556 SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
557 ( void ) flags;
558 ( void ) ctx;
560 int nn, pp, ee; /* native, package, event indices */
561 union { long long ll; double dbl; } event_value_union;
562 struct rapl_limit limit1, limit2;
563 eventtype_enum eventtype;
564 struct rapl_data * libmsr_rapl_data;
565 uint64_t * libmsr_rapl_flags;
566
567 /* Get a pointer to the rapl_data data storage */
568 if ( libmsr_rapl_storage( &libmsr_rapl_data, &libmsr_rapl_flags)!=0 ) {
569 SUBDBG("Function libmsr.so:rapl_storage failed.\n");
570 return PAPI_ESYS;
571 }
572
573 /* If any socket/package needs to be read, call the poll once to read all packages */
574 for ( pp = 0; pp < LIBMSR_MAX_PACKAGES; pp++ ) {
575 if ( control->package_being_measured[pp] ) {
576 SUBDBG("Calling poll_rapl_data to read state from all sockets\n");
577 if ( libmsr_poll_rapl_data()!= 0 ) {
578 SUBDBG("Function libmsr.so:poll_rapl_data failed.\n");
579 return PAPI_ESYS;
580 }
581 break;
582 }
583 }
584
585 /* Go thru events, assign package data to events as needed */
586 SUBDBG("Go thru events, assign package data to events as needed\n");
587 for( nn = 0; nn < control->num_events_measured; nn++ ) {
588 ee = control->which_counter[nn];
590 event_value_union.ll = 0LL;
591 eventtype = libmsr_native_events[ee].eventtype;
592 SUBDBG("nn %d ee %d pp %d eventtype %d\n", nn, ee, pp, eventtype);
593 switch (eventtype) {
594 case PKG_ENERGY:
595 event_value_union.dbl = libmsr_rapl_data->pkg_joules[pp];
596 break;
597 case PKG_ELAPSED:
598 event_value_union.dbl = libmsr_rapl_data->elapsed;
599 break;
600 case PKG_DELTA_ENERGY:
601 event_value_union.dbl = libmsr_rapl_data->pkg_delta_joules[pp];
602 break;
603 case PKG_WATTS:
604 event_value_union.dbl = libmsr_rapl_data->pkg_watts[pp];
605 break;
607 limit1.bits = 0; limit1.watts = 0; limit1.seconds = 0;
608 libmsr_get_pkg_rapl_limit( pp, &limit1, NULL );
609 event_value_union.dbl = limit1.watts;
610 break;
612 limit1.bits = 0; limit1.watts = 0; limit1.seconds = 0;
613 libmsr_get_pkg_rapl_limit( pp, &limit1, NULL );
614 event_value_union.dbl = limit1.seconds;
615 break;
617 limit2.bits = 0; limit2.watts = 0; limit2.seconds = 0;
618 libmsr_get_pkg_rapl_limit( pp, NULL, &limit2 );
619 event_value_union.dbl = limit2.watts;
620 break;
622 limit2.bits = 0; limit2.watts = 0; limit2.seconds = 0;
623 libmsr_get_pkg_rapl_limit( pp, NULL, &limit2 );
624 event_value_union.dbl = limit2.seconds;
625 break;
626 default:
627 SUBDBG("This LIBMSR event is unknown\n");
628 /* error here */
629 }
630 control->count[nn] = event_value_union.ll;
631 }
632 /* Pass back a pointer to our results */
633 if ( events!=NULL ) *events = ( ( _libmsr_control_state_t * ) ctl )->count;
634 return PAPI_OK;
635}
636
637
638static long long _local_get_eventval_from_values( _libmsr_control_state_t *control, long long *invalues, int package_num, eventtype_enum eventtype, long long defaultval )
639{
640 int nn, pp, ee; /* native, package, event indices */
641 /* Loop thru all the events, if package and repltype match, return the value */
642 for( nn = 0; nn < control->num_events_measured; nn++ ) {
643 ee = control->which_counter[nn];
645 if ( pp == package_num && libmsr_native_events[ee].eventtype == eventtype )
646 return invalues[ee];
647 }
648 return defaultval;
649}
650
651
653{
654 SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
655 /* write values */
656 ( void ) ctx;
658 //long long now = PAPI_get_real_usec();
659 int nn, pp, ee; /* native, package, event indices */
660 union { long long ll; double dbl; } event_value_union;
661 union { long long ll; double dbl; } timewin_union;
662 struct rapl_limit limit1, limit2;
663 eventtype_enum eventtype;
664
665 /* Go thru events, assign package data to events as needed */
666 for( nn = 0; nn < control->num_events_measured; nn++ ) {
667 ee = control->which_counter[nn];
669 /* grab value and put into the union structure */
670 event_value_union.ll = values[nn];
671 /* If this is a NULL value, it means that the user does not want to write this value */
672 if ( event_value_union.ll == PAPI_NULL ) continue;
673 eventtype = libmsr_native_events[ee].eventtype;
674 SUBDBG("nn %d ee %d pp %d eventtype %d\n", nn, ee, pp, eventtype);
675 switch (eventtype) {
676 case PKG_ENERGY:
677 case PKG_ELAPSED:
678 case PKG_WATTS:
679 case PKG_DELTA_ENERGY:
680 /* Read only so do nothing */
681 break;
683 timewin_union.ll = _local_get_eventval_from_values( control, values, pp, PKG_TIME_WINDOW_POWER_LIMIT_1, -1 );
684 if ( timewin_union.ll > 0 ) {
685 limit1.watts = event_value_union.dbl;
686 limit1.seconds = timewin_union.dbl;
687 limit1.bits = 0;
688 //printf("set_libmsr_limit package %d limit1 %lf %lf\n", pp, limit1.watts, limit1.seconds);
689 libmsr_set_pkg_rapl_limit( pp, &limit1, NULL );
690 } else {
691 // Note error - power limit1 is not updated
692 SUBDBG("PACKAGE_POWER_LIMIT_1 needs PKG_TIME_WINDOW_POWER_LIMIT_1: Power cap not updated. ");
693 }
694 break;
696 timewin_union.ll = _local_get_eventval_from_values( control, values, pp, PKG_TIME_WINDOW_POWER_LIMIT_2, -1 );
697 if ( timewin_union.ll > 0 ) {
698 limit2.watts = event_value_union.dbl;
699 limit2.seconds = timewin_union.dbl;
700 limit2.bits = 0;
701 //printf("set_libmsr_limit package %d limit2 %lf %lf \n", pp, limit2.watts, limit2.seconds);
702 libmsr_set_pkg_rapl_limit( pp, NULL, &limit2 );
703 } else {
704 // Write error
705 PAPIERROR("PACKAGE_POWER_LIMIT_1 needs PKG_TIME_WINDOW_POWER_LIMIT_1: Powercap not updated.");
706 }
707 break;
710 /* These are only meaningful (and looked up) if the power limits are set */
711 break;
712 default:
713 SUBDBG("This LIBMSR information type is unknown\n");
714 /* error here */
715 }
716 }
717 return PAPI_OK;
718}
719
720
722{
723 SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
724 ( void ) ctx;
725 ( void ) ctl;
727 return PAPI_OK;
728}
729
730
731/* Shutdown a thread */
733{
734 SUBDBG( "Enter: ctl: %p\n", ctx );
735 ( void ) ctx;
736 return PAPI_OK;
737}
738
739
740/*
741 * Clean up what was setup in libmsr_init_component().
742 */
744{
745 SUBDBG( "Enter\n" );
746
748
749 if ( libmsr_finalize_msr()!=0 ) {
750 SUBDBG("Function libmsr.so:finalize_msr failed.\n");
751 return PAPI_ESYS;
752 }
754 free( libmsr_native_events );
756 }
757 dlclose( dl1 );
758 return PAPI_OK;
759}
760
761
762/* This function sets various options in the component The valid codes
763 * being passed in are PAPI_SET_DEFDOM, PAPI_SET_DOMAIN,
764 * PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT */
765int _libmsr_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
766{
767 SUBDBG( "Enter: ctx: %p\n", ctx );
768 ( void ) ctx;
769 ( void ) code;
770 ( void ) option;
771
772 return PAPI_OK;
773}
774
775
776/*
777 * This function has to set the bits needed to count different domains
778 * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
779 * By default return PAPI_EINVAL if none of those are specified
780 * and PAPI_OK with success
781 * PAPI_DOM_USER is only user context is counted
782 * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
783 * PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses)
784 * PAPI_DOM_ALL is all of the domains
785 */
787{
788 SUBDBG( "Enter: ctl: %p\n", ctl );
789 ( void ) ctl;
790 /* In theory we only support system-wide mode */
791 /* How to best handle that? */
792 if( domain != PAPI_DOM_ALL )
793 return PAPI_EINVAL;
794 return PAPI_OK;
795}
796
797
799{
800 SUBDBG( "Enter: ctl: %p, ctx: %p\n", ctl, ctx );
801 ( void ) ctx;
802 ( void ) ctl;
803
804 return PAPI_OK;
805}
806
807
808/*
809 * Native Event functions
810 */
811int _libmsr_ntv_enum_events( unsigned int *EventCode, int modifier )
812{
813 SUBDBG( "Enter: EventCode: %d\n", *EventCode );
814 int index;
815 if ( num_events_global == 0 )
816 return PAPI_ENOEVNT;
817
818 switch ( modifier ) {
819 case PAPI_ENUM_FIRST:
820 *EventCode = 0;
821 return PAPI_OK;
822 break;
823 case PAPI_ENUM_EVENTS:
824 index = *EventCode & PAPI_NATIVE_AND_MASK;
825 if ( index < num_events_global - 1 ) {
826 *EventCode = *EventCode + 1;
827 return PAPI_OK;
828 } else {
829 return PAPI_ENOEVNT;
830 }
831 break;
832 // case PAPI_NTV_ENUM_UMASKS:
833 default:
834 return PAPI_EINVAL;
835 }
836
837 return PAPI_EINVAL;
838}
839
840
841/*
842 *
843 */
844int _libmsr_ntv_code_to_name( unsigned int EventCode, char *name, int len )
845{
846 SUBDBG( "Enter: EventCode: %d\n", EventCode );
847 int index = EventCode & PAPI_NATIVE_AND_MASK;
848
849 if( index >= 0 && index < num_events_global ) {
851 return PAPI_OK;
852 }
853 return PAPI_ENOEVNT;
854}
855
856
857int _libmsr_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
858{
859 SUBDBG( "Enter: EventCode: %d\n", EventCode );
860 int index = EventCode;
861
862 if( ( index < 0 ) || ( index >= num_events_global ) )
863 return PAPI_ENOEVNT;
864
865 _local_strlcpy( name, libmsr_native_events[index].description, len );
866 return PAPI_OK;
867}
868
869
870int _libmsr_ntv_code_to_info( unsigned int EventCode, PAPI_event_info_t * info )
871{
872 SUBDBG( "Enter: EventCode: %d\n", EventCode );
873 int index = EventCode;
874
875 if( ( index < 0 ) || ( index >= num_events_global ) )
876 return PAPI_ENOEVNT;
877
878 _local_strlcpy( info->symbol, libmsr_native_events[index].name, sizeof( info->symbol ) );
879 _local_strlcpy( info->long_descr, libmsr_native_events[index].description, sizeof( info->long_descr ) );
880 _local_strlcpy( info->units, libmsr_native_events[index].units, sizeof( info->units ) );
882 return PAPI_OK;
883}
884
885
887 .cmp_info = { /* (unspecified values are initialized to 0) */
888 .name = "libmsr",
889 .short_name = "libmsr",
890 .description = "PAPI component for libmsr from LANL for power (RAPL) read/write",
891 .version = "5.3.0",
892 .default_domain = PAPI_DOM_ALL,
893 .default_granularity = PAPI_GRN_SYS,
894 .available_granularities = PAPI_GRN_SYS,
895 .hardware_intr_sig = PAPI_INT_SIGNAL,
896 .available_domains = PAPI_DOM_ALL,
897 },
898 /* sizes of framework-opaque component-private structures */
899 .size = {
900 .context = sizeof( _libmsr_context_t ),
901 .control_state = sizeof( _libmsr_control_state_t ),
902 .reg_value = sizeof( _libmsr_register_t ),
903 .reg_alloc = sizeof( _libmsr_reg_alloc_t ),
904 },
905 /* function pointers in this component */
906 .start = _libmsr_start,
907 .stop = _libmsr_stop,
908 .read = _libmsr_read,
909 .reset = _libmsr_reset,
910 .write = _libmsr_write,
911 .init_component = _libmsr_init_component,
912 .init_thread = _libmsr_init_thread,
913 .init_control_state = _libmsr_init_control_state,
914 .update_control_state = _libmsr_update_control_state,
915 .ctl = _libmsr_ctl,
916 .set_domain = _libmsr_set_domain,
917 .ntv_enum_events = _libmsr_ntv_enum_events,
918 .ntv_code_to_name = _libmsr_ntv_code_to_name,
919 .ntv_code_to_descr = _libmsr_ntv_code_to_descr,
920 .ntv_code_to_info = _libmsr_ntv_code_to_info,
921 .shutdown_thread = _libmsr_shutdown_thread,
922 .shutdown_component = _libmsr_shutdown_component,
923};
int i
static const PAPI_hw_info_t * hw_info
Definition: byte_profile.c:28
static long count
struct papi_vectors * _papi_hwd[]
#define PAPI_ENUM_EVENTS
Definition: f90papi.h:224
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_MIN_STR_LEN
Definition: f90papi.h:208
#define PAPI_NULL
Definition: f90papi.h:78
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_DATATYPE_FP64
Definition: f90papi.h:171
#define PAPI_VENDOR_INTEL
Definition: f90papi.h:275
#define PAPI_EINVAL
Definition: f90papi.h:115
#define PAPI_ENOSUPP
Definition: f90papi.h:244
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_ESYS
Definition: f90papi.h:136
#define PAPI_GRN_SYS
Definition: f90papi.h:43
#define PAPI_ENOMEM
Definition: f90papi.h:16
#define PAPI_DOM_ALL
Definition: f90papi.h:261
char events[MAX_EVENTS][BUFSIZ]
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
int _libmsr_shutdown_component(void)
Definition: linux-libmsr.c:743
#define LIBMSR_MAX_PACKAGES
Definition: linux-libmsr.c:77
papi_vector_t _libmsr_vector
Definition: linux-libmsr.c:102
static void libmsr_get_pkg_rapl_limit(const int socket, struct rapl_limit *limit1, struct rapl_limit *limit2)
Definition: linux-libmsr.c:145
eventtype_enum
Definition: linux-libmsr.c:45
@ PKG_ENERGY
Definition: linux-libmsr.c:46
@ PKG_WATTS
Definition: linux-libmsr.c:49
@ PKG_POWER_LIMIT_2
Definition: linux-libmsr.c:52
@ PKG_TIME_WINDOW_POWER_LIMIT_1
Definition: linux-libmsr.c:51
@ PKG_POWER_LIMIT_1
Definition: linux-libmsr.c:50
@ PKG_DELTA_ENERGY
Definition: linux-libmsr.c:48
@ PKG_TIME_WINDOW_POWER_LIMIT_2
Definition: linux-libmsr.c:53
@ PKG_ELAPSED
Definition: linux-libmsr.c:47
@ NUM_OF_EVENTTYPES
Definition: linux-libmsr.c:54
int _libmsr_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
Definition: linux-libmsr.c:765
static int already_called_libmsr_rapl_initialized_global
Definition: linux-libmsr.c:106
int _libmsr_shutdown_thread(hwd_context_t *ctx)
Definition: linux-libmsr.c:732
int _libmsr_set_domain(hwd_control_state_t *ctl, int domain)
Definition: linux-libmsr.c:786
int _libmsr_ntv_code_to_name(unsigned int EventCode, char *name, int len)
Definition: linux-libmsr.c:844
int _libmsr_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-libmsr.c:798
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:638
int _libmsr_write(hwd_context_t *ctx, hwd_control_state_t *ctl, long long *values)
Definition: linux-libmsr.c:652
int _libmsr_ntv_code_to_descr(unsigned int EventCode, char *name, int len)
Definition: linux-libmsr.c:857
int _libmsr_init_thread(hwd_context_t *ctx)
Definition: linux-libmsr.c:268
void _local_set_to_defaults()
Definition: linux-libmsr.c:241
static void libmsr_set_pkg_rapl_limit(const int socket, struct rapl_limit *limit1, struct rapl_limit *limit2)
Definition: linux-libmsr.c:144
static char * _local_strlcpy(char *dst, const char *src, size_t size)
Definition: linux-libmsr.c:233
static int libmsr_core_config(uint64_t *coresPerSocket, uint64_t *threadsPerCore, uint64_t *sysSockets, int *HTenabled)
Definition: linux-libmsr.c:146
#define CHECK_DL_STATUS(err, str)
Definition: linux-libmsr.c:151
static int libmsr_rapl_init(struct rapl_data **rapl_data, uint64_t **rapl_flags)
Definition: linux-libmsr.c:142
static void * dl1
Definition: linux-libmsr.c:114
int _libmsr_init_control_state(hwd_control_state_t *ctl)
Definition: linux-libmsr.c:501
static int libmsr_rapl_storage(struct rapl_data **data, uint64_t **flags)
Definition: linux-libmsr.c:147
int _libmsr_ntv_enum_events(unsigned int *EventCode, int modifier)
Definition: linux-libmsr.c:811
static _libmsr_native_event_entry_t * libmsr_native_events
Definition: linux-libmsr.c:104
int _libmsr_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
Definition: linux-libmsr.c:870
static int libmsr_finalize_msr()
Definition: linux-libmsr.c:141
int _libmsr_init_component(int cidx)
Definition: linux-libmsr.c:278
static int _local_linkDynamicLibraries()
Definition: linux-libmsr.c:157
#define LIBMSR_MAX_COUNTERS
Definition: linux-libmsr.c:76
int _libmsr_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
Definition: linux-libmsr.c:517
static int libmsr_get_rapl_power_info(const unsigned socket, struct rapl_power_info *info)
Definition: linux-libmsr.c:148
static int num_events_global
Definition: linux-libmsr.c:105
void(* _dl_non_dynamic_init)(void)
Definition: linux-libmsr.c:126
static char libmsr_main[]
Definition: linux-libmsr.c:117
int _libmsr_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
Definition: linux-libmsr.c:554
int _libmsr_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-libmsr.c:539
static int libmsr_poll_rapl_data()
Definition: linux-libmsr.c:143
#define HANDLE_STRING_ERROR
Definition: linux-libmsr.c:82
int _libmsr_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-libmsr.c:721
static int num_packages
Definition: linux-rapl.c:161
unsigned long AO_t __attribute__((__aligned__(4)))
Definition: m68k.h:21
#define PAPI_NATIVE_AND_MASK
Return codes and api definitions.
#define SUBDBG(format, args...)
Definition: papi_debug.h:64
void PAPIERROR(char *format,...)
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:52
static int native
static int cidx
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:56
char units[MAX_EVENTS][BUFSIZ]
Definition: powercap_plot.c:15
const char * name
Definition: rocs.c:225
int
Definition: sde_internal.h:89
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:627
char disabled_reason[PAPI_HUGE_STR_LEN]
Definition: papi.h:634
char units[PAPI_MIN_STR_LEN]
Definition: papi.h:969
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:960
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:963
Hardware info structure.
Definition: papi.h:774
int vendor
Definition: papi.h:781
_libmsr_control_state_t state
Definition: linux-libmsr.c:99
int which_counter[LIBMSR_MAX_COUNTERS]
Definition: linux-libmsr.c:92
long long count[LIBMSR_MAX_COUNTERS]
Definition: linux-libmsr.c:93
int package_being_measured[LIBMSR_MAX_PACKAGES]
Definition: linux-libmsr.c:95
Definition: linux-libmsr.c:61
char description[PAPI_MAX_STR_LEN]
Definition: linux-libmsr.c:64
int package_num
Definition: linux-libmsr.c:65
char name[PAPI_MAX_STR_LEN]
Definition: linux-libmsr.c:62
char units[PAPI_MIN_STR_LEN]
Definition: linux-libmsr.c:63
_libmsr_register_t resources
Definition: linux-libmsr.c:68
int return_type
Definition: linux-libmsr.c:67
eventtype_enum eventtype
Definition: linux-libmsr.c:66
_libmsr_register_t ra_bits
Definition: linux-libmsr.c:72
unsigned int selector
Definition: linux-libmsr.c:58
PAPI_hw_info_t hw_info
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
int retval
Definition: zero_fork.c:53