PAPI  5.4.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
linux-rapl.c
Go to the documentation of this file.
1 
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <dirent.h>
21 #include <fcntl.h>
22 #include <string.h>
23 #include <stdint.h>
24 #include <errno.h>
25 
26 /* Headers required by PAPI */
27 #include "papi.h"
28 #include "papi_internal.h"
29 #include "papi_vector.h"
30 #include "papi_memory.h"
31 
32 
33 /*
34  * Platform specific RAPL Domains.
35  * Note that PP1 RAPL Domain is supported on 062A only
36  * And DRAM RAPL Domain is supported on 062D only
37  */
38 
39 
40 /* RAPL defines */
41 #define MSR_RAPL_POWER_UNIT 0x606
42 
43 /* Package */
44 #define MSR_PKG_RAPL_POWER_LIMIT 0x610
45 #define MSR_PKG_ENERGY_STATUS 0x611
46 #define MSR_PKG_PERF_STATUS 0x613
47 #define MSR_PKG_POWER_INFO 0x614
48 
49 /* PP0 */
50 #define MSR_PP0_POWER_LIMIT 0x638
51 #define MSR_PP0_ENERGY_STATUS 0x639
52 #define MSR_PP0_POLICY 0x63A
53 #define MSR_PP0_PERF_STATUS 0x63B
54 
55 /* PP1 */
56 #define MSR_PP1_POWER_LIMIT 0x640
57 #define MSR_PP1_ENERGY_STATUS 0x641
58 #define MSR_PP1_POLICY 0x642
59 
60 /* DRAM */
61 #define MSR_DRAM_POWER_LIMIT 0x618
62 #define MSR_DRAM_ENERGY_STATUS 0x619
63 #define MSR_DRAM_PERF_STATUS 0x61B
64 #define MSR_DRAM_POWER_INFO 0x61C
65 
66 /* RAPL bitsmasks */
67 #define POWER_UNIT_OFFSET 0
68 #define POWER_UNIT_MASK 0x0f
69 
70 #define ENERGY_UNIT_OFFSET 0x08
71 #define ENERGY_UNIT_MASK 0x1f
72 
73 #define TIME_UNIT_OFFSET 0x10
74 #define TIME_UNIT_MASK 0x0f
75 
76 /* RAPL POWER UNIT MASKS */
77 #define POWER_INFO_UNIT_MASK 0x7fff
78 #define THERMAL_SHIFT 0
79 #define MINIMUM_POWER_SHIFT 16
80 #define MAXIMUM_POWER_SHIFT 32
81 #define MAXIMUM_TIME_WINDOW_SHIFT 48
82 
83 
84 typedef struct _rapl_register
85 {
86  unsigned int selector;
88 
89 typedef struct _rapl_native_event_entry
90 {
92  char units[PAPI_MIN_STR_LEN];
93  char description[PAPI_MAX_STR_LEN];
94  int fd_offset;
95  int msr;
96  int type;
100 
101 typedef struct _rapl_reg_alloc
102 {
105 
106 /* actually 32? But setting this to be safe? */
107 #define RAPL_MAX_COUNTERS 64
108 
109 typedef struct _rapl_control_state
110 {
111  int being_measured[RAPL_MAX_COUNTERS];
113  int need_difference[RAPL_MAX_COUNTERS];
114  long long lastupdate;
116 
117 
118 typedef struct _rapl_context
119 {
120  long long start_value[RAPL_MAX_COUNTERS];
123 
124 
126 
127 struct fd_array_t {
128  int fd;
129  int open;
130 };
131 
133 static int num_events = 0;
134 struct fd_array_t *fd_array=NULL;
135 static int num_packages=0,num_cpus=0;
136 
138 
139 
140 #define PACKAGE_ENERGY 0
141 #define PACKAGE_THERMAL 1
142 #define PACKAGE_MINIMUM 2
143 #define PACKAGE_MAXIMUM 3
144 #define PACKAGE_TIME_WINDOW 4
145 #define PACKAGE_ENERGY_CNT 5
146 #define PACKAGE_THERMAL_CNT 6
147 #define PACKAGE_MINIMUM_CNT 7
148 #define PACKAGE_MAXIMUM_CNT 8
149 #define PACKAGE_TIME_WINDOW_CNT 9
150 
151 
152 /***************************************************************************/
153 /****** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT *******/
154 /***************************************************************************/
155 
156 
157 static long long read_msr(int fd, int which) {
158 
159  uint64_t data;
160 
161  if ( fd<0 || pread(fd, &data, sizeof data, which) != sizeof data ) {
162  perror("rdmsr:pread");
163  exit(127);
164  }
165 
166  return (long long)data;
167 }
168 
169 static int open_fd(int offset) {
170 
171  int fd=-1;
172  char filename[BUFSIZ];
173 
174  if (fd_array[offset].open==0) {
175  sprintf(filename,"/dev/cpu/%d/msr_safe",offset);
176  fd = open(filename, O_RDONLY);
177  if (fd<0) {
178  sprintf(filename,"/dev/cpu/%d/msr",offset);
179  fd = open(filename, O_RDONLY);
180  }
181  if (fd>=0) {
182  fd_array[offset].fd=fd;
183  fd_array[offset].open=1;
184  }
185  }
186  else {
187  fd=fd_array[offset].fd;
188  }
189 
190  return fd;
191 }
192 
193 static long long read_rapl_value(int index) {
194 
195  int fd;
196 
197  fd=open_fd(rapl_native_events[index].fd_offset);
198  return read_msr(fd,rapl_native_events[index].msr);
199 
200 }
201 
202 static long long convert_rapl_energy(int index, long long value) {
203 
204  union {
205  long long ll;
206  double fp;
207  } return_val;
208 
209  return_val.ll = value; /* default case: return raw input value */
210 
211  if (rapl_native_events[index].type==PACKAGE_ENERGY) {
212  return_val.ll = (long long)(((double)value/energy_divisor)*1e9);
213  }
214 
215  if (rapl_native_events[index].type==PACKAGE_THERMAL) {
216  return_val.fp = (double)
218  (double)power_divisor;
219  }
220 
221  if (rapl_native_events[index].type==PACKAGE_MINIMUM) {
222  return_val.fp = (double)
224  (double)power_divisor;
225  }
226 
227  if (rapl_native_events[index].type==PACKAGE_MAXIMUM) {
228  return_val.fp = (double)
230  (double)power_divisor;
231  }
232 
233  if (rapl_native_events[index].type==PACKAGE_TIME_WINDOW) {
234  return_val.fp = (double)
236  (double)time_divisor;
237  }
238 
239  if (rapl_native_events[index].type==PACKAGE_THERMAL_CNT) {
240  return_val.ll = ((value>>THERMAL_SHIFT)&POWER_INFO_UNIT_MASK);
241  }
242 
243  if (rapl_native_events[index].type==PACKAGE_MINIMUM_CNT) {
244  return_val.ll = ((value>>MINIMUM_POWER_SHIFT)&POWER_INFO_UNIT_MASK);
245  }
246 
247  if (rapl_native_events[index].type==PACKAGE_MAXIMUM_CNT) {
248  return_val.ll = ((value>>MAXIMUM_POWER_SHIFT)&POWER_INFO_UNIT_MASK);
249  }
250 
251  if (rapl_native_events[index].type==PACKAGE_TIME_WINDOW_CNT) {
252  return_val.ll = ((value>>MAXIMUM_TIME_WINDOW_SHIFT)&POWER_INFO_UNIT_MASK);
253  }
254 
255  return return_val.ll;
256 }
257 
258 static int
260 {
261  FILE *fff;
262  int num_read, nr_cpus = 1;
263  fff=fopen("/sys/devices/system/cpu/kernel_max","r");
264  if (fff==NULL) return nr_cpus;
265  num_read=fscanf(fff,"%d",&nr_cpus);
266  fclose(fff);
267  if (num_read==1) {
268  nr_cpus++;
269  } else {
270  nr_cpus = 1;
271  }
272  return nr_cpus;
273 }
274 
275 /************************* PAPI Functions **********************************/
276 
277 
278 /*
279  * This is called whenever a thread is initialized
280  */
281 int
283 {
284  ( void ) ctx;
285 
286  return PAPI_OK;
287 }
288 
289 
290 
291 /*
292  * Called when PAPI process is initialized (i.e. PAPI_library_init)
293  */
294 int
296 {
297  int i,j,k,fd;
298  FILE *fff;
299  char filename[BUFSIZ];
300 
301  int package_avail, dram_avail, pp0_avail, pp1_avail;
302 
303  long long result;
304  int package;
305 
306  const PAPI_hw_info_t *hw_info;
307 
308  int nr_cpus = get_kernel_nr_cpus();
309  int packages[nr_cpus];
310  int cpu_to_use[nr_cpus];
311 
312  /* Fill with sentinel values */
313  for (i=0; i<nr_cpus; ++i) {
314  packages[i] = -1;
315  cpu_to_use[i] = -1;
316  }
317 
318 
319  /* check if Intel processor */
320  hw_info=&(_papi_hwi_system_info.hw_info);
321 
322  /* Ugh can't use PAPI_get_hardware_info() if
323  PAPI library not done initializing yet */
324 
325  if (hw_info->vendor!=PAPI_VENDOR_INTEL) {
326  strncpy(_rapl_vector.cmp_info.disabled_reason,
327  "Not an Intel processor",PAPI_MAX_STR_LEN);
328  return PAPI_ENOSUPP;
329  }
330 
331  /* check model to support */
332  if (hw_info->cpuid_family==6) {
333  if (hw_info->cpuid_model==42) {
334  /* SandyBridge */
335  package_avail=1;
336  pp0_avail=1;
337  pp1_avail=1;
338  dram_avail=0;
339  }
340  else if (hw_info->cpuid_model==45) {
341  /* SandyBridge-EP */
342  package_avail=1;
343  pp0_avail=1;
344  pp1_avail=0;
345  dram_avail=1;
346  }
347  else if (hw_info->cpuid_model==58) {
348  /* IvyBridge */
349  package_avail=1;
350  pp0_avail=1;
351  pp1_avail=1;
352  dram_avail=0;
353  }
354  else if (hw_info->cpuid_model==62) {
355  /* IvyBridge-EP */
356  package_avail=1;
357  pp0_avail=1;
358  pp1_avail=0;
359  dram_avail=1;
360  }
361  else if (hw_info->cpuid_model==60 || hw_info->cpuid_model==69 || hw_info->cpuid_model==70 ) {
362  /* Haswell */
363  package_avail=1;
364  pp0_avail=1;
365  pp1_avail=1;
366  /* Not documented by Intel but seems to work */
367  dram_avail=1;
368  }
369  else if ( hw_info->cpuid_model==63) {
370  /* Haswell-EP */
371  package_avail=1;
372  pp0_avail=1;
373  pp1_avail=0;
374  dram_avail=1;
375  }
376  else {
377  /* not a supported model */
378  strncpy(_rapl_vector.cmp_info.disabled_reason,
379  "CPU model not supported",
381  return PAPI_ENOIMPL;
382  }
383  }
384  else {
385  /* Not a family 6 machine */
386  strncpy(_rapl_vector.cmp_info.disabled_reason,
387  "CPU family not supported",PAPI_MAX_STR_LEN);
388  return PAPI_ENOIMPL;
389  }
390 
391 
392  /* Detect how many packages */
393  j=0;
394  while(1) {
395  int num_read;
396 
397  sprintf(filename,
398  "/sys/devices/system/cpu/cpu%d/topology/physical_package_id",j);
399  fff=fopen(filename,"r");
400  if (fff==NULL) break;
401  num_read=fscanf(fff,"%d",&package);
402  fclose(fff);
403  if (num_read!=1) {
404  strcpy(_rapl_vector.cmp_info.disabled_reason, "Error reading file: ");
405  strncat(_rapl_vector.cmp_info.disabled_reason, filename, PAPI_MAX_STR_LEN - strlen(_rapl_vector.cmp_info.disabled_reason) - 1);
406  _rapl_vector.cmp_info.disabled_reason[PAPI_MAX_STR_LEN-1] = '\0';
407  return PAPI_ESYS;
408  }
409 
410  /* Check if a new package */
411  if ((package >= 0) && (package < nr_cpus)) {
412  if (packages[package] == -1) {
413  SUBDBG("Found package %d out of total %d\n",package,num_packages);
414  packages[package]=package;
415  cpu_to_use[package]=j;
416  num_packages++;
417  }
418  } else {
419  SUBDBG("Package outside of allowed range\n");
420  strncpy(_rapl_vector.cmp_info.disabled_reason,
421  "Package outside of allowed range",PAPI_MAX_STR_LEN);
422  return PAPI_ESYS;
423  }
424 
425  j++;
426  }
427  num_cpus=j;
428 
429  if (num_packages==0) {
430  SUBDBG("Can't access /dev/cpu/*/<msr_safe | msr>\n");
431  strncpy(_rapl_vector.cmp_info.disabled_reason,
432  "Can't access /dev/cpu/*/<msr_safe | msr>",PAPI_MAX_STR_LEN);
433  return PAPI_ESYS;
434  }
435 
436  SUBDBG("Found %d packages with %d cpus\n",num_packages,num_cpus);
437 
438  /* Init fd_array */
439 
440  fd_array=papi_calloc(sizeof(struct fd_array_t),num_cpus);
441  if (fd_array==NULL) return PAPI_ENOMEM;
442 
443  fd=open_fd(cpu_to_use[0]);
444  if (fd<0) {
445  sprintf(_rapl_vector.cmp_info.disabled_reason,
446  "Can't open fd for cpu0: %s",strerror(errno));
447  return PAPI_ESYS;
448  }
449 
450  /* Calculate the units used */
451  result=read_msr(fd,MSR_RAPL_POWER_UNIT);
452 
453  /* units are 0.5^UNIT_VALUE */
454  /* which is the same as 1/(2^UNIT_VALUE) */
455 
459 
460  SUBDBG("Power units = %.3fW\n",1.0/power_divisor);
461  SUBDBG("Energy units = %.8fJ\n",1.0/energy_divisor);
462  SUBDBG("Time units = %.8fs\n",1.0/time_divisor);
463 
464  /* Allocate space for events */
465  /* Include room for both counts and scaled values */
466 
467  num_events= ((package_avail*num_packages) +
468  (pp0_avail*num_packages) +
469  (pp1_avail*num_packages) +
470  (dram_avail*num_packages) +
471  (4*num_packages)) * 2;
472 
473  rapl_native_events = (_rapl_native_event_entry_t*)
475 
476 
477  i = 0;
478  k = num_events/2;
479 
480  /* Create events for package power info */
481 
482  for(j=0;j<num_packages;j++) {
483  sprintf(rapl_native_events[i].name,
484  "THERMAL_SPEC_CNT:PACKAGE%d",j);
485  sprintf(rapl_native_events[i].description,
486  "Thermal specification in counts; package %d",j);
487  rapl_native_events[i].fd_offset=cpu_to_use[j];
488  rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
489  rapl_native_events[i].resources.selector = i + 1;
490  rapl_native_events[i].type=PACKAGE_THERMAL_CNT;
491  rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
492 
493  sprintf(rapl_native_events[k].name,
494  "THERMAL_SPEC:PACKAGE%d",j);
495  strncpy(rapl_native_events[k].units,"W",PAPI_MIN_STR_LEN);
496  sprintf(rapl_native_events[k].description,
497  "Thermal specification for package %d",j);
498  rapl_native_events[k].fd_offset=cpu_to_use[j];
499  rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
500  rapl_native_events[k].resources.selector = k + 1;
501  rapl_native_events[k].type=PACKAGE_THERMAL;
502  rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
503 
504  i++;
505  k++;
506  }
507 
508  for(j=0;j<num_packages;j++) {
509  sprintf(rapl_native_events[i].name,
510  "MINIMUM_POWER_CNT:PACKAGE%d",j);
511  sprintf(rapl_native_events[i].description,
512  "Minimum power in counts; package %d",j);
513  rapl_native_events[i].fd_offset=cpu_to_use[j];
514  rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
515  rapl_native_events[i].resources.selector = i + 1;
516  rapl_native_events[i].type=PACKAGE_MINIMUM_CNT;
517  rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
518 
519  sprintf(rapl_native_events[k].name,
520  "MINIMUM_POWER:PACKAGE%d",j);
521  strncpy(rapl_native_events[k].units,"W",PAPI_MIN_STR_LEN);
522  sprintf(rapl_native_events[k].description,
523  "Minimum power for package %d",j);
524  rapl_native_events[k].fd_offset=cpu_to_use[j];
525  rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
526  rapl_native_events[k].resources.selector = k + 1;
527  rapl_native_events[k].type=PACKAGE_MINIMUM;
528  rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
529 
530  i++;
531  k++;
532  }
533 
534  for(j=0;j<num_packages;j++) {
535  sprintf(rapl_native_events[i].name,
536  "MAXIMUM_POWER_CNT:PACKAGE%d",j);
537  sprintf(rapl_native_events[i].description,
538  "Maximum power in counts; package %d",j);
539  rapl_native_events[i].fd_offset=cpu_to_use[j];
540  rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
541  rapl_native_events[i].resources.selector = i + 1;
542  rapl_native_events[i].type=PACKAGE_MAXIMUM_CNT;
543  rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
544 
545  sprintf(rapl_native_events[k].name,
546  "MAXIMUM_POWER:PACKAGE%d",j);
547  strncpy(rapl_native_events[k].units,"W",PAPI_MIN_STR_LEN);
548  sprintf(rapl_native_events[k].description,
549  "Maximum power for package %d",j);
550  rapl_native_events[k].fd_offset=cpu_to_use[j];
551  rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
552  rapl_native_events[k].resources.selector = k + 1;
553  rapl_native_events[k].type=PACKAGE_MAXIMUM;
554  rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
555 
556  i++;
557  k++;
558  }
559 
560  for(j=0;j<num_packages;j++) {
561  sprintf(rapl_native_events[i].name,
562  "MAXIMUM_TIME_WINDOW_CNT:PACKAGE%d",j);
563  sprintf(rapl_native_events[i].description,
564  "Maximum time window in counts; package %d",j);
565  rapl_native_events[i].fd_offset=cpu_to_use[j];
566  rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
567  rapl_native_events[i].resources.selector = i + 1;
568  rapl_native_events[i].type=PACKAGE_TIME_WINDOW_CNT;
569  rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
570 
571  sprintf(rapl_native_events[k].name,
572  "MAXIMUM_TIME_WINDOW:PACKAGE%d",j);
573  strncpy(rapl_native_events[k].units,"s",PAPI_MIN_STR_LEN);
574  sprintf(rapl_native_events[k].description,
575  "Maximum time window for package %d",j);
576  rapl_native_events[k].fd_offset=cpu_to_use[j];
577  rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
578  rapl_native_events[k].resources.selector = k + 1;
579  rapl_native_events[k].type=PACKAGE_TIME_WINDOW;
580  rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
581 
582  i++;
583  k++;
584  }
585 
586  /* Create Events for energy measurements */
587 
588  if (package_avail) {
589  for(j=0;j<num_packages;j++) {
590  sprintf(rapl_native_events[i].name,
591  "PACKAGE_ENERGY_CNT:PACKAGE%d",j);
592  sprintf(rapl_native_events[i].description,
593  "Energy used in counts by chip package %d",j);
594  rapl_native_events[i].fd_offset=cpu_to_use[j];
595  rapl_native_events[i].msr=MSR_PKG_ENERGY_STATUS;
596  rapl_native_events[i].resources.selector = i + 1;
597  rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
598  rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
599 
600  sprintf(rapl_native_events[k].name,
601  "PACKAGE_ENERGY:PACKAGE%d",j);
602  strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
603  sprintf(rapl_native_events[k].description,
604  "Energy used by chip package %d",j);
605  rapl_native_events[k].fd_offset=cpu_to_use[j];
606  rapl_native_events[k].msr=MSR_PKG_ENERGY_STATUS;
607  rapl_native_events[k].resources.selector = k + 1;
608  rapl_native_events[k].type=PACKAGE_ENERGY;
609  rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
610 
611  i++;
612  k++;
613  }
614  }
615 
616  if (pp1_avail) {
617  for(j=0;j<num_packages;j++) {
618  sprintf(rapl_native_events[i].name,
619  "PP1_ENERGY_CNT:PACKAGE%d",j);
620  sprintf(rapl_native_events[i].description,
621  "Energy used in counts by Power Plane 1 (Often GPU) on package %d",j);
622  rapl_native_events[i].fd_offset=cpu_to_use[j];
623  rapl_native_events[i].msr=MSR_PP1_ENERGY_STATUS;
624  rapl_native_events[i].resources.selector = i + 1;
625  rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
626  rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
627 
628  sprintf(rapl_native_events[k].name,
629  "PP1_ENERGY:PACKAGE%d",j);
630  strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
631  sprintf(rapl_native_events[k].description,
632  "Energy used by Power Plane 1 (Often GPU) on package %d",j);
633  rapl_native_events[k].fd_offset=cpu_to_use[j];
634  rapl_native_events[k].msr=MSR_PP1_ENERGY_STATUS;
635  rapl_native_events[k].resources.selector = k + 1;
636  rapl_native_events[k].type=PACKAGE_ENERGY;
637  rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
638 
639  i++;
640  k++;
641  }
642  }
643 
644  if (dram_avail) {
645  for(j=0;j<num_packages;j++) {
646  sprintf(rapl_native_events[i].name,
647  "DRAM_ENERGY_CNT:PACKAGE%d",j);
648  sprintf(rapl_native_events[i].description,
649  "Energy used in counts by DRAM on package %d",j);
650  rapl_native_events[i].fd_offset=cpu_to_use[j];
651  rapl_native_events[i].msr=MSR_DRAM_ENERGY_STATUS;
652  rapl_native_events[i].resources.selector = i + 1;
653  rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
654  rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
655 
656  sprintf(rapl_native_events[k].name,
657  "DRAM_ENERGY:PACKAGE%d",j);
658  strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
659  sprintf(rapl_native_events[k].description,
660  "Energy used by DRAM on package %d",j);
661  rapl_native_events[k].fd_offset=cpu_to_use[j];
662  rapl_native_events[k].msr=MSR_DRAM_ENERGY_STATUS;
663  rapl_native_events[k].resources.selector = k + 1;
664  rapl_native_events[k].type=PACKAGE_ENERGY;
665  rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
666 
667  i++;
668  k++;
669  }
670  }
671 
672  if (pp0_avail) {
673  for(j=0;j<num_packages;j++) {
674  sprintf(rapl_native_events[i].name,
675  "PP0_ENERGY_CNT:PACKAGE%d",j);
676  sprintf(rapl_native_events[i].description,
677  "Energy used in counts by all cores in package %d",j);
678  rapl_native_events[i].fd_offset=cpu_to_use[j];
679  rapl_native_events[i].msr=MSR_PP0_ENERGY_STATUS;
680  rapl_native_events[i].resources.selector = i + 1;
681  rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
682  rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
683 
684  sprintf(rapl_native_events[k].name,
685  "PP0_ENERGY:PACKAGE%d",j);
686  strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
687  sprintf(rapl_native_events[k].description,
688  "Energy used by all cores in package %d",j);
689  rapl_native_events[k].fd_offset=cpu_to_use[j];
690  rapl_native_events[k].msr=MSR_PP0_ENERGY_STATUS;
691  rapl_native_events[k].resources.selector = k + 1;
692  rapl_native_events[k].type=PACKAGE_ENERGY;
693  rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
694 
695  i++;
696  k++;
697  }
698  }
699 
700  /* Export the total number of events available */
701  _rapl_vector.cmp_info.num_native_events = num_events;
702 
703  _rapl_vector.cmp_info.num_cntrs = num_events;
704  _rapl_vector.cmp_info.num_mpx_cntrs = num_events;
705 
706 
707  /* Export the component id */
708  _rapl_vector.cmp_info.CmpIdx = cidx;
709 
710  return PAPI_OK;
711 }
712 
713 
714 /*
715  * Control of counters (Reading/Writing/Starting/Stopping/Setup)
716  * functions
717  */
718 int
720 {
721 
723  int i;
724 
725  for(i=0;i<RAPL_MAX_COUNTERS;i++) {
726  control->being_measured[i]=0;
727  }
728 
729  return PAPI_OK;
730 }
731 
732 int
734 {
735  _rapl_context_t* context = (_rapl_context_t*) ctx;
737  long long now = PAPI_get_real_usec();
738  int i;
739 
740  for( i = 0; i < RAPL_MAX_COUNTERS; i++ ) {
741  if ((control->being_measured[i]) && (control->need_difference[i])) {
742  context->start_value[i]=read_rapl_value(i);
743  }
744  }
745 
746  control->lastupdate = now;
747 
748  return PAPI_OK;
749 }
750 
751 int
753 {
754 
755  /* read values */
756  _rapl_context_t* context = (_rapl_context_t*) ctx;
758  long long now = PAPI_get_real_usec();
759  int i;
760  long long temp;
761 
762  for ( i = 0; i < RAPL_MAX_COUNTERS; i++ ) {
763  if (control->being_measured[i]) {
764  temp = read_rapl_value(i);
765  if (context->start_value[i])
766  if (control->need_difference[i]) {
767  /* test for wrap around */
768  if (temp < context->start_value[i] ) {
769  SUBDBG("Wraparound!\nstart:\t%#016x\ttemp:\t%#016x",
770  (unsigned)context->start_value[i], (unsigned)temp);
771  temp += (0x100000000 - context->start_value[i]);
772  SUBDBG("\tresult:\t%#016x\n", (unsigned)temp);
773  } else {
774  temp -= context->start_value[i];
775  }
776  }
777  control->count[i] = convert_rapl_energy( i, temp );
778  }
779  }
780  control->lastupdate = now;
781  return PAPI_OK;
782 }
783 
784 /* Shutdown a thread */
785 int
787 {
788  ( void ) ctx;
789  return PAPI_OK;
790 }
791 
792 int
794  long long **events, int flags)
795 {
796  (void) flags;
797 
798  _rapl_stop( ctx, ctl );
799 
800  /* Pass back a pointer to our results */
801  *events = ((_rapl_control_state_t*) ctl)->count;
802 
803  return PAPI_OK;
804 }
805 
806 
807 /*
808  * Clean up what was setup in rapl_init_component().
809  */
810 int
812 {
813  int i;
814 
815  if (rapl_native_events) papi_free(rapl_native_events);
816  if (fd_array) {
817  for(i=0;i<num_cpus;i++) {
818  if (fd_array[i].open) close(fd_array[i].fd);
819  }
820  papi_free(fd_array);
821  }
822 
823  return PAPI_OK;
824 }
825 
826 
827 /* This function sets various options in the component
828  * The valid codes being passed in are PAPI_SET_DEFDOM,
829  * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
830  */
831 int
832 _rapl_ctl( hwd_context_t *ctx, int code, _papi_int_option_t *option )
833 {
834  ( void ) ctx;
835  ( void ) code;
836  ( void ) option;
837 
838  return PAPI_OK;
839 }
840 
841 
842 int
844  NativeInfo_t *native, int count,
845  hwd_context_t *ctx )
846 {
847  int i, index;
848  ( void ) ctx;
849 
851 
852  /* Ugh, what is this native[] stuff all about ?*/
853  /* Mostly remap stuff in papi_internal */
854 
855  for(i=0;i<RAPL_MAX_COUNTERS;i++) {
856  control->being_measured[i]=0;
857  }
858 
859  for( i = 0; i < count; i++ ) {
860  index=native[i].ni_event&PAPI_NATIVE_AND_MASK;
861  native[i].ni_position=rapl_native_events[index].resources.selector - 1;
862  control->being_measured[index]=1;
863 
864  /* Only need to subtract if it's a PACKAGE_ENERGY or ENERGY_CNT type */
865  control->need_difference[index]=
866  (rapl_native_events[index].type==PACKAGE_ENERGY
867  || rapl_native_events[index].type==PACKAGE_ENERGY_CNT);
868  }
869 
870  return PAPI_OK;
871 }
872 
873 
874 /*
875  * This function has to set the bits needed to count different domains
876  * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
877  * By default return PAPI_EINVAL if none of those are specified
878  * and PAPI_OK with success
879  * PAPI_DOM_USER is only user context is counted
880  * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
881  * PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses)
882  * PAPI_DOM_ALL is all of the domains
883  */
884 int
886 {
887  ( void ) ctl;
888 
889  /* In theory we only support system-wide mode */
890  /* How to best handle that? */
891  if ( PAPI_DOM_ALL != domain )
892  return PAPI_EINVAL;
893 
894  return PAPI_OK;
895 }
896 
897 
898 int
900 {
901  ( void ) ctx;
902  ( void ) ctl;
903 
904  return PAPI_OK;
905 }
906 
907 
908 /*
909  * Native Event functions
910  */
911 int
912 _rapl_ntv_enum_events( unsigned int *EventCode, int modifier )
913 {
914 
915  int index;
916 
917  switch ( modifier ) {
918 
919  case PAPI_ENUM_FIRST:
920 
921  if (num_events==0) {
922  return PAPI_ENOEVNT;
923  }
924  *EventCode = 0;
925 
926  return PAPI_OK;
927 
928 
929  case PAPI_ENUM_EVENTS:
930 
931  index = *EventCode & PAPI_NATIVE_AND_MASK;
932 
933  if ( index < num_events - 1 ) {
934  *EventCode = *EventCode + 1;
935  return PAPI_OK;
936  } else {
937  return PAPI_ENOEVNT;
938  }
939  break;
940 
941  default:
942  return PAPI_EINVAL;
943  }
944 
945  return PAPI_EINVAL;
946 }
947 
948 /*
949  *
950  */
951 int
952 _rapl_ntv_code_to_name( unsigned int EventCode, char *name, int len )
953 {
954 
955  int index = EventCode & PAPI_NATIVE_AND_MASK;
956 
957  if ( index >= 0 && index < num_events ) {
958  strncpy( name, rapl_native_events[index].name, len );
959  return PAPI_OK;
960  }
961 
962  return PAPI_ENOEVNT;
963 }
964 
965 /*
966  *
967  */
968 int
969 _rapl_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
970 {
971  int index = EventCode;
972 
973  if ( index >= 0 && index < num_events ) {
974  strncpy( name, rapl_native_events[index].description, len );
975  return PAPI_OK;
976  }
977  return PAPI_ENOEVNT;
978 }
979 
980 int
981 _rapl_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
982 {
983 
984  int index = EventCode;
985 
986  if ( ( index < 0) || (index >= num_events )) return PAPI_ENOEVNT;
987 
988  strncpy( info->symbol, rapl_native_events[index].name, sizeof(info->symbol)-1);
989  info->symbol[sizeof(info->symbol)-1] = '\0';
990 
991  strncpy( info->long_descr, rapl_native_events[index].description, sizeof(info->long_descr)-1);
992  info->long_descr[sizeof(info->long_descr)-1] = '\0';
993 
994  strncpy( info->units, rapl_native_events[index].units, sizeof(info->units)-1);
995  info->units[sizeof(info->units)-1] = '\0';
996 
997  info->data_type = rapl_native_events[index].return_type;
998 
999  return PAPI_OK;
1000 }
1001 
1002 
1003 
1004 papi_vector_t _rapl_vector = {
1005  .cmp_info = { /* (unspecified values are initialized to 0) */
1006  .name = "rapl",
1007  .short_name = "rapl",
1008  .description = "Linux RAPL energy measurements",
1009  .version = "5.3.0",
1010  .default_domain = PAPI_DOM_ALL,
1011  .default_granularity = PAPI_GRN_SYS,
1012  .available_granularities = PAPI_GRN_SYS,
1013  .hardware_intr_sig = PAPI_INT_SIGNAL,
1014  .available_domains = PAPI_DOM_ALL,
1015  },
1016 
1017  /* sizes of framework-opaque component-private structures */
1018  .size = {
1019  .context = sizeof ( _rapl_context_t ),
1020  .control_state = sizeof ( _rapl_control_state_t ),
1021  .reg_value = sizeof ( _rapl_register_t ),
1022  .reg_alloc = sizeof ( _rapl_reg_alloc_t ),
1023  },
1024  /* function pointers in this component */
1025  .init_thread = _rapl_init_thread,
1026  .init_component = _rapl_init_component,
1027  .init_control_state = _rapl_init_control_state,
1028  .start = _rapl_start,
1029  .stop = _rapl_stop,
1030  .read = _rapl_read,
1031  .shutdown_thread = _rapl_shutdown_thread,
1032  .shutdown_component = _rapl_shutdown_component,
1033  .ctl = _rapl_ctl,
1034 
1035  .update_control_state = _rapl_update_control_state,
1036  .set_domain = _rapl_set_domain,
1037  .reset = _rapl_reset,
1038 
1039  .ntv_enum_events = _rapl_ntv_enum_events,
1040  .ntv_code_to_name = _rapl_ntv_code_to_name,
1041  .ntv_code_to_descr = _rapl_ntv_code_to_descr,
1042  .ntv_code_to_info = _rapl_ntv_code_to_info,
1043 };
int _rapl_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-rapl.c:752
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:626
#define PAPI_ENOEVNT
Definition: papi.h:258
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
int _rapl_init_component(int cidx)
Definition: linux-rapl.c:295
#define TIME_UNIT_MASK
Definition: linux-rapl.c:74
int errno
#define PACKAGE_MAXIMUM
Definition: linux-rapl.c:143
int close(int fd)
Definition: appio.c:175
static long long convert_rapl_energy(int index, long long value)
Definition: linux-rapl.c:202
_rapl_control_state_t state
Definition: linux-rapl.c:121
#define POWER_INFO_UNIT_MASK
Definition: linux-rapl.c:77
char name[PAPI_MAX_STR_LEN]
Definition: linux-rapl.c:91
Hardware info structure.
Definition: papi.h:777
int _rapl_init_control_state(hwd_control_state_t *ctl)
Definition: linux-rapl.c:719
long long flags
Definition: iozone.c:12330
static long long read_msr(int fd, int which)
Definition: linux-rapl.c:157
#define papi_free(a)
Definition: papi_memory.h:35
#define PACKAGE_MAXIMUM_CNT
Definition: linux-rapl.c:148
#define PACKAGE_THERMAL
Definition: linux-rapl.c:141
long which
Definition: iozone.c:19600
#define PAPI_ENOSUPP
Definition: papi.h:269
off64_t offset
Definition: iozone.c:1279
static int num_events
int _rapl_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
Definition: linux-rapl.c:832
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:966
int _rapl_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
Definition: linux-rapl.c:793
int fd
Definition: iozone.c:1291
char units[PAPI_MIN_STR_LEN]
Definition: linux-rapl.c:92
static int get_kernel_nr_cpus(void)
Definition: linux-rapl.c:259
static int num_packages
Definition: linux-rapl.c:135
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:963
#define PAPI_DOM_ALL
Definition: papi.h:301
#define ENERGY_UNIT_OFFSET
Definition: linux-rapl.c:70
return PAPI_OK
Definition: linux-nvml.c:458
int count
Definition: iozone.c:22422
int _rapl_ntv_code_to_descr(unsigned int EventCode, char *name, int len)
Definition: linux-rapl.c:969
char filename[MAXNAMESIZE]
Definition: iozone.c:1360
int type
Definition: linux-rapl.c:96
#define PACKAGE_ENERGY_CNT
Definition: linux-rapl.c:145
fclose(thread_wqfd)
void
Definition: iozone.c:18627
return PAPI_EINVAL
Definition: linux-nvml.c:408
int power_divisor
Definition: linux-rapl.c:137
#define PACKAGE_TIME_WINDOW_CNT
Definition: linux-rapl.c:149
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
#define MSR_RAPL_POWER_UNIT
Definition: linux-rapl.c:41
#define MSR_PP1_ENERGY_STATUS
Definition: linux-rapl.c:57
void double value
Definition: iozone.c:18781
static double
Definition: fileop.c:1281
int _rapl_ntv_code_to_name(unsigned int EventCode, char *name, int len)
Definition: linux-rapl.c:952
#define RAPL_MAX_COUNTERS
Definition: linux-rapl.c:107
int _rapl_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-rapl.c:899
int _rapl_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
Definition: linux-rapl.c:981
Return codes and api definitions.
FILE * fff[MAX_EVENTS]
char events[MAX_EVENTS][BUFSIZ]
#define PACKAGE_ENERGY
Definition: linux-rapl.c:140
struct fd_array_t * fd_array
Definition: linux-rapl.c:134
char disabled_reason[PAPI_MAX_STR_LEN]
Definition: papi.h:633
papi_vector_t _rapl_vector
Definition: linux-rapl.c:125
int open(const char *pathname, int flags, mode_t mode)
Definition: appio.c:184
#define PACKAGE_MINIMUM_CNT
Definition: linux-rapl.c:147
int _rapl_ntv_enum_events(unsigned int *EventCode, int modifier)
Definition: linux-rapl.c:912
int i
Definition: fileop.c:140
static long long read_rapl_value(int index)
Definition: linux-rapl.c:193
unsigned int selector
Definition: linux-rapl.c:86
int _rapl_shutdown_thread(hwd_context_t *ctx)
Definition: linux-rapl.c:786
static _rapl_native_event_entry_t * rapl_native_events
Definition: linux-rapl.c:132
int k
Definition: iozone.c:19136
static int cidx
Definition: event_info.c:40
static int open_fd(int offset)
Definition: linux-rapl.c:169
char description[PAPI_MAX_STR_LEN]
Definition: linux-rapl.c:93
#define PACKAGE_MINIMUM
Definition: linux-rapl.c:142
#define MSR_PP0_ENERGY_STATUS
Definition: linux-rapl.c:51
#define PAPI_ESYS
Definition: papi.h:253
static int native
Definition: event_info.c:39
int _rapl_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
Definition: linux-rapl.c:843
int cpuid_model
Definition: papi.h:790
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
long long
Definition: iozone.c:19827
#define PACKAGE_THERMAL_CNT
Definition: linux-rapl.c:146
static FILE * fp
#define ENERGY_UNIT_MASK
Definition: linux-rapl.c:71
#define POWER_UNIT_MASK
Definition: linux-rapl.c:68
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:53
int cpuid_family
Definition: papi.h:789
#define PAPI_ENOMEM
Definition: papi.h:252
#define PAPI_ENOIMPL
Definition: papi.h:270
#define MSR_PKG_ENERGY_STATUS
Definition: linux-rapl.c:45
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:57
strcpy(filename, default_filename)
_rapl_register_t ra_bits
Definition: linux-rapl.c:103
PAPI_hw_info_t hw_info
Definition: linux-rapl.c:89
#define MAXIMUM_TIME_WINDOW_SHIFT
Definition: linux-rapl.c:81
#define PAPI_VENDOR_INTEL
Definition: papi.h:346
static int num_cpus
Definition: linux-rapl.c:135
int vendor
Definition: papi.h:784
#define THERMAL_SHIFT
Definition: linux-rapl.c:78
long long PAPI_get_real_usec(void)
Definition: papi.c:6190
char * name
Definition: iozone.c:23648
int time_divisor
Definition: linux-rapl.c:137
_rapl_register_t resources
Definition: linux-rapl.c:98
long long count[RAPL_MAX_COUNTERS]
Definition: linux-rapl.c:112
int being_measured[RAPL_MAX_COUNTERS]
Definition: linux-rapl.c:111
int return_type
Definition: linux-rapl.c:97
#define PAPI_MIN_STR_LEN
Definition: papi.h:462
int temp
Definition: iozone.c:22158
int fd_offset
Definition: linux-rapl.c:94
#define PAPI_NATIVE_AND_MASK
int _rapl_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: linux-rapl.c:733
#define MAXIMUM_POWER_SHIFT
Definition: linux-rapl.c:80
#define MINIMUM_POWER_SHIFT
Definition: linux-rapl.c:79
#define TIME_UNIT_OFFSET
Definition: linux-rapl.c:73
#define PAPI_MAX_STR_LEN
Definition: papi.h:463
int msr
Definition: linux-rapl.c:95
int _rapl_shutdown_component(void)
Definition: linux-rapl.c:811
int _rapl_init_thread(hwd_context_t *ctx)
Definition: linux-rapl.c:282
#define PAPI_GRN_SYS
Definition: papi.h:364
long j
Definition: iozone.c:19135
#define MSR_DRAM_ENERGY_STATUS
Definition: linux-rapl.c:62
int need_difference[RAPL_MAX_COUNTERS]
Definition: linux-rapl.c:113
#define PACKAGE_TIME_WINDOW
Definition: linux-rapl.c:144
static const PAPI_hw_info_t * hw_info
Definition: byte_profile.c:23
void exit()
int energy_divisor
Definition: linux-rapl.c:137
#define POWER_UNIT_OFFSET
Definition: linux-rapl.c:67
char units[PAPI_MIN_STR_LEN]
Definition: papi.h:972
#define MSR_PKG_POWER_INFO
Definition: linux-rapl.c:47
#define papi_calloc(a, b)
Definition: papi_memory.h:37
long long start_value[RAPL_MAX_COUNTERS]
Definition: linux-rapl.c:120
int _rapl_set_domain(hwd_control_state_t *ctl, int domain)
Definition: linux-rapl.c:885