PAPI 7.1.0.0
Loading...
Searching...
No Matches
linux-micpower.c
Go to the documentation of this file.
1#include <string.h>
2#include <unistd.h>
3
4/* Headers required by PAPI */
5#include "papi.h"
6#include "papi_internal.h"
7#include "papi_vector.h"
8#include "papi_memory.h"
9
10#include "linux-micpower.h"
11
12/* Intel says
13----
14The power measurements can be obtained from the host as well as the MIC card
15over a 50msec interval. The SMC is designed to sample power consumption only
16every 50mSecs.
17----
18**/
19#define REFRESH_LAT 50000
20
21#define INVALID_RESULT -1000000L
22#define MICPOWER_NUMBER_OF_NATIVE_EVENTS 16
23
25
27 { .name = "tot0",
28 .units = "uW",
29 .description = "Total power, win 0",
30 .resources.selector = 1
31 },
32 { .name = "tot1",
33 .units = "uW",
34 .description = "Total power, win 1",
35 .resources.selector = 2
36 },
37 { .name = "pcie",
38 .units = "uW",
39 .description = "PCI-E connector power",
40 .resources.selector = 3
41 },
42 { .name = "inst",
43 .units = "uW",
44 .description = "Instantaneous power",
45 .resources.selector = 4
46 },
47 { .name = "imax",
48 .units = "uW",
49 .description = "Max Instantaneous power",
50 .resources.selector = 5
51 },
52 { .name = "c2x3",
53 .units = "uW",
54 .description = "2x3 connector power",
55 .resources.selector = 6
56 },
57 { .name = "c2x4",
58 .units = "uW",
59 .description = "2x4 connector power",
60 .resources.selector = 7
61 },
62 { .name = "vccp:pwr",
63 .units = "uW",
64 .description = "Core rail; Power reading",
65 .resources.selector = 8
66 },
67 { .name = "vccp:cur",
68 .units = "uA",
69 .description = "Core rail; Current",
70 .resources.selector = 9
71 },
72 { .name = "vccp:volt",
73 .units = "uV",
74 .description = "Core rail; Voltage",
75 .resources.selector = 10
76 },
77 { .name = "vddg:pwr",
78 .units = "uW",
79 .description = "Uncore rail; Power reading",
80 .resources.selector = 11
81 },
82 { .name = "vddg:cur",
83 .units = "uA",
84 .description = "Uncore rail; Current",
85 .resources.selector = 12
86 },
87 { .name = "vddg:volt",
88 .units = "uV",
89 .description = "Uncore rail; Voltage",
90 .resources.selector = 13
91 },
92 { .name = "vddq:pwr",
93 .units = "uW",
94 .description = "Memory subsystem rail; Power reading",
95 .resources.selector = 14
96 },
97 { .name = "vddq:cur",
98 .units = "uA",
99 .description = "Memory subsystem rail; Current",
100 .resources.selector = 15
101 },
102 { .name = "vddq:volt",
103 .units = "uV",
104 .description = "Memory subsystem rail; Voltage",
105 .resources.selector = 16
106 }
107};
108
109static int num_events = 0;
110static int is_initialized = 0;
111
112/***************************************************************************/
113/****** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT *******/
114/***************************************************************************/
115
116#if 0
117From Intel docs, power readings are exported via sysfs at
118/sys/class/micras/power
119
120typedeftruct mr_rsp_pws { /* Power status */
121 uint32_t prr; /* Current reading, in uW */
122 uint8_t p_val; /* Valid bits, power */
123} MrRspPws;
124
125typedef struct mr_rsp_vrr { /* Voltage regulator status */
126 uint32_t pwr; /* Power reading, in uW */
127 uint32_t cur; /* Current, in uA */
128 uint32_t volt; /* Voltage, in uV */
129 uint8_t p_val; /* Valid bits, power */
130 uint8_t c_val; /* Valid bits, current */
131 uint8_t v_val; /* Valid bits, voltage */
132} MrRspVrr;
133
134
135I am assuming for the purposes of this component that only
136the readings are exported.
137typedef struct mr_rsp_power {
138 MrRspPws tot0; /* Total power, win 0 */
139 MrRspPws tot1; /* Total power, win 1 */
140 MrRspPws pcie; /* PCI-E connector power */
141 MrRspPws inst; /* Instantaneous power */
142 MrRspPws imax; /* Max Instantaneous power */
143 MrRspPws c2x3; /* 2x3 connector power */
144 MrRspPws c2x4; /* 2x4 connector power */
145 MrRspVrr vccp; /* Core rail */
146 MrRspVrr vddg; /* Uncore rail */
147 MrRspVrr vddq; /* Memory subsystem rail */
148} MrRspPower;
149
150#endif
151static int
152read_sysfs_file( long long* counts)
153{
154 FILE* fp = NULL;
155 int i;
156 int retval = 1;
157 fp = fopen( "/sys/class/micras/power", "r" );
158 if (!fp)
159 return 0;
160
161 for (i=0; i < MICPOWER_MAX_COUNTERS-9; i++) {
162 retval&= fscanf(fp, "%lld", &counts[i]);
163 }
165 retval&= fscanf(fp, "%lld %lld %lld", &counts[i], &counts[i+1], &counts[i+2] );
166 }
167
168 fclose(fp);
169 return retval;
170}
171
172/*****************************************************************************
173 ******************* BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS *************
174 *****************************************************************************/
175
176/*
177 * This is called whenever a thread is initialized
178 */
179static int
181{
182 ( void ) ctx;
183 return PAPI_OK;
184}
185
186
187
188/* Initialize hardware counters, setup the function vector table
189 * and get hardware information, this routine is called when the
190 * PAPI process is initialized (IE PAPI_library_init)
191 */
192static int
194{
195 int retval = PAPI_OK;
196 if ( is_initialized )
197 return (PAPI_OK );
198
199 is_initialized = 1;
200
201 /* Check that /sys/class/micras/power is readable */
202 if ( 0 != access( "/sys/class/micras/power", R_OK ) ) {
204 "Cannot read /sys/class/micras/power",PAPI_MAX_STR_LEN);
206 goto fn_fail;
207 }
208
209
210 /* Export the total number of events available */
211 num_events =
213
214 /* Export the component id */
216
217 fn_exit:
218 _papi_hwd[cidx]->cmp_info.disabled = retval;
219 return retval;
220 fn_fail:
221 goto fn_exit;
222}
223
224
225
226
227/*
228 * Control of counters (Reading/Writing/Starting/Stopping/Setup)
229 * functions
230 */
231static int
233{
234 int retval = 0;
236
237 retval = read_sysfs_file(micpower_ctl->counts);
238
239 /* Set last access time for caching results */
240 micpower_ctl->lastupdate = PAPI_get_real_usec();
241
242 return (retval)?PAPI_OK:PAPI_ESYS;
243}
244
245static int
247{
248 ( void ) ctx;
249 ( void ) ctl;
250
251 return PAPI_OK;
252}
253
254static int
256 long long ** events, int flags)
257{
258 (void) flags;
259 (void) ctx;
260 int retval = 1;
261
263 long long now = PAPI_get_real_usec();
264
265 /* Only read the values from the kernel if enough time has passed */
266 /* since the last read. Otherwise return cached values. */
267
268 if ( now - control->lastupdate > REFRESH_LAT ) {
269 retval = read_sysfs_file(control->counts);
270 control->lastupdate = now;
271 }
272
273 /* Pass back a pointer to our results */
274 *events = control->counts;
275
276 return (retval)?PAPI_OK:PAPI_ESYS;
277}
278
279static int
281{
282 (void) ctx;
283 int retval = 1;
284 long long now = PAPI_get_real_usec();
285 /* read values */
287
288 if ( now - control->lastupdate > REFRESH_LAT ) {
289 retval = read_sysfs_file(control->counts);
290 control->lastupdate = now;
291 }
292 return (retval)?PAPI_OK:PAPI_ESYS;
293}
294
295/* Shutdown a thread */
296static int
298{
299 ( void ) ctx;
300 return PAPI_OK;
301}
302
303
304/*
305 * Clean up what was setup in micpower_init_component().
306 */
307static int
309{
310 if ( is_initialized ) {
311 is_initialized = 0;
312 num_events = 0;
313 }
314 return PAPI_OK;
315}
316
317
318/* This function sets various options in the component
319 * The valid codes being passed in are PAPI_SET_DEFDOM,
320 * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
321 */
322static int
324{
325 ( void ) ctx;
326 ( void ) code;
327 ( void ) option;
328
329 return PAPI_OK;
330}
331
332
333static int
336 hwd_context_t * ctx )
337{
338 int i, index;
339 ( void ) ctx;
340 ( void ) ptr;
341
342 for ( i = 0; i < count; i++ ) {
343 index = native[i].ni_event&PAPI_NATIVE_AND_MASK;
344 native[i].ni_position = _micpower_native_events[index].resources.selector - 1;
345 }
346 return PAPI_OK;
347}
348
349
350/*
351 * This function has to set the bits needed to count different domains
352 * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
353 * By default return PAPI_EINVAL if none of those are specified
354 * and PAPI_OK with success
355 * PAPI_DOM_USER is only user context is counted
356 * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
357 * PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses)
358 * PAPI_DOM_ALL is all of the domains
359 */
360static int
362{
363 ( void ) cntl;
364
365 if ( PAPI_DOM_ALL != domain )
366 return PAPI_EINVAL;
367
368 return PAPI_OK;
369}
370
371
372static int
374{
375 ( void ) ctx;
376 ( void ) ctl;
377
378 return PAPI_OK;
379}
380
381
382/*
383 * Native Event functions
384 */
385static int
386_micpower_ntv_enum_events( unsigned int *EventCode, int modifier )
387{
388
389 int index;
390
391 switch ( modifier ) {
392
393 case PAPI_ENUM_FIRST:
394
395 if (num_events==0) {
396 return PAPI_ENOEVNT;
397 }
398 *EventCode = 0;
399
400 return PAPI_OK;
401
402
403 case PAPI_ENUM_EVENTS:
404
405 index = *EventCode&PAPI_NATIVE_AND_MASK;
406
407 if ( index < num_events - 1 ) {
408 *EventCode = *EventCode + 1;
409 return PAPI_OK;
410 } else {
411 return PAPI_ENOEVNT;
412 }
413 break;
414
415 default:
416 return PAPI_EINVAL;
417 }
418 return PAPI_EINVAL;
419}
420
421/*
422 *
423 */
424static int
425_micpower_ntv_code_to_name( unsigned int EventCode, char *name, int len )
426{
427 int index = EventCode&PAPI_NATIVE_AND_MASK;
428
429 if ( index >= 0 && index < num_events ) {
430 strncpy( name, _micpower_native_events[index].name, len );
431 return PAPI_OK;
432 }
433 return PAPI_ENOEVNT;
434}
435
436/*
437 *
438 */
439static int
440_micpower_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
441{
442 int index = EventCode&PAPI_NATIVE_AND_MASK;
443
444 if ( index >= 0 && index < num_events ) {
445 strncpy( name, _micpower_native_events[index].description, len );
446 return PAPI_OK;
447 }
448 return PAPI_ENOEVNT;
449}
450
451static int
452_micpower_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
453{
454
455 int index = EventCode&PAPI_NATIVE_AND_MASK;
456
457 if ( ( index < 0) || (index >= num_events )) return PAPI_ENOEVNT;
458
459 strncpy( info->symbol, _micpower_native_events[index].name, sizeof(info->symbol));
460 strncpy( info->long_descr, _micpower_native_events[index].description, sizeof(info->long_descr));
461 strncpy( info->units, _micpower_native_events[index].units, sizeof(info->units));
462 info->units[sizeof(info->units)-1] = '\0';
463
464 return PAPI_OK;
465}
466
467
468
469/*
470 *
471 */
473 .cmp_info = {
474 /* default component information (unspecified values are initialized to 0) */
475 .name = "micpower",
476 .short_name = "micpower",
477 .description = "Component for reading power on Intel Xeon Phi (MIC)",
478 .version = "5.1",
479 .num_mpx_cntrs = MICPOWER_NUMBER_OF_NATIVE_EVENTS,
481 .default_domain = PAPI_DOM_ALL,
482 .available_domains = PAPI_DOM_ALL,
483 .default_granularity = PAPI_GRN_SYS,
484 .available_granularities = PAPI_GRN_SYS,
485 .hardware_intr_sig = PAPI_INT_SIGNAL,
486
487 /* component specific cmp_info initializations */
488 .fast_real_timer = 0,
489 .fast_virtual_timer = 0,
490 .attach = 0,
491 .attach_must_ptrace = 0,
492 }
493 ,
494
495 /* sizes of framework-opaque component-private structures */
496 .size = {
497 .context = sizeof ( MICPOWER_context_t ),
498 .control_state = sizeof ( MICPOWER_control_state_t ),
499 .reg_value = sizeof ( MICPOWER_register_t ),
500 .reg_alloc = sizeof ( MICPOWER_reg_alloc_t ),
501 }
502 ,
503 /* function pointers in this component */
504 .init_thread = _micpower_init_thread,
505 .init_component = _micpower_init_component,
506 .init_control_state = _micpower_init_control_state,
507 .start = _micpower_start,
508 .stop = _micpower_stop,
509 .read = _micpower_read,
510 .shutdown_thread = _micpower_shutdown_thread,
511 .shutdown_component = _micpower_shutdown_component,
512 .ctl = _micpower_ctl,
513
514 .update_control_state = _micpower_update_control_state,
515 .set_domain = _micpower_set_domain,
516 .reset = _micpower_reset,
517
518 .ntv_enum_events = _micpower_ntv_enum_events,
519 .ntv_code_to_name = _micpower_ntv_code_to_name,
520 .ntv_code_to_descr = _micpower_ntv_code_to_descr,
521 .ntv_code_to_info = _micpower_ntv_code_to_info,
522};
int i
static long count
get real time counter value in microseconds
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_ENOEVNT
Definition: f90papi.h:139
#define PAPI_EINVAL
Definition: f90papi.h:115
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_ESYS
Definition: f90papi.h:136
#define PAPI_ECMP
Definition: f90papi.h:214
#define PAPI_GRN_SYS
Definition: f90papi.h:43
#define PAPI_DOM_ALL
Definition: f90papi.h:261
char events[MAX_EVENTS][BUFSIZ]
static int _micpower_update_control_state(hwd_control_state_t *ptr, NativeInfo_t *native, int count, hwd_context_t *ctx)
static int _micpower_ntv_code_to_name(unsigned int EventCode, char *name, int len)
static int num_events
static int _micpower_shutdown_component()
static int _micpower_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
#define REFRESH_LAT
papi_vector_t _micpower_vector
static int _micpower_init_control_state(hwd_control_state_t *ctl)
static int _micpower_ntv_enum_events(unsigned int *EventCode, int modifier)
static int is_initialized
static int _micpower_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _micpower_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
static int _micpower_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _micpower_init_component(int cidx)
#define MICPOWER_NUMBER_OF_NATIVE_EVENTS
static int _micpower_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
static int _micpower_init_thread(hwd_context_t *ctx)
static int _micpower_shutdown_thread(hwd_context_t *ctx)
static int _micpower_ntv_code_to_descr(unsigned int EventCode, char *name, int len)
static int _micpower_set_domain(hwd_control_state_t *cntl, int domain)
static int read_sysfs_file(long long *counts)
static MICPOWER_native_event_entry_t _micpower_native_events[]
static int _micpower_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
Mic power component This file has the source code for a component that enables PAPI-C to access hardw...
#define MICPOWER_MAX_COUNTERS
#define PAPI_NATIVE_AND_MASK
Return codes and api definitions.
int fclose(FILE *__stream)
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:52
static FILE * fp
static int native
static int cidx
const char * name
Definition: rocs.c:225
long long counts[MICPOWER_MAX_COUNTERS]
char units[PAPI_MIN_STR_LEN]
MICPOWER_register_t resources
char name[PAPI_MAX_STR_LEN]
char description[PAPI_MAX_STR_LEN]
unsigned int selector
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
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
int retval
Definition: zero_fork.c:53