linux-rapl.c File Reference

rapl component More...

Include dependency graph for linux-rapl.c:

Go to the source code of this file.

Data Structures

struct  _rapl_register_t
struct  _rapl_native_event_entry_t
struct  _rapl_reg_alloc_t
struct  _rapl_control_state_t
struct  _rapl_context_t
struct  fd_array_t

Defines

#define MSR_RAPL_POWER_UNIT   0x606
#define MSR_PKG_RAPL_POWER_LIMIT   0x610
#define MSR_PKG_ENERGY_STATUS   0x611
#define MSR_PKG_PERF_STATUS   0x613
#define MSR_PKG_POWER_INFO   0x614
#define MSR_PP0_POWER_LIMIT   0x638
#define MSR_PP0_ENERGY_STATUS   0x639
#define MSR_PP0_POLICY   0x63A
#define MSR_PP0_PERF_STATUS   0x63B
#define MSR_PP1_POWER_LIMIT   0x640
#define MSR_PP1_ENERGY_STATUS   0x641
#define MSR_PP1_POLICY   0x642
#define MSR_DRAM_POWER_LIMIT   0x618
#define MSR_DRAM_ENERGY_STATUS   0x619
#define MSR_DRAM_PERF_STATUS   0x61B
#define MSR_DRAM_POWER_INFO   0x61C
#define POWER_UNIT_OFFSET   0
#define POWER_UNIT_MASK   0x0f
#define ENERGY_UNIT_OFFSET   0x08
#define ENERGY_UNIT_MASK   0x1f
#define TIME_UNIT_OFFSET   0x10
#define TIME_UNIT_MASK   0x0f
#define POWER_INFO_UNIT_MASK   0x7fff
#define THERMAL_SHIFT   0
#define MINIMUM_POWER_SHIFT   16
#define MAXIMUM_POWER_SHIFT   32
#define MAXIMUM_TIME_WINDOW_SHIFT   48
#define RAPL_MAX_COUNTERS   64
#define PACKAGE_ENERGY   0
#define PACKAGE_THERMAL   1
#define PACKAGE_MINIMUM   2
#define PACKAGE_MAXIMUM   3
#define PACKAGE_TIME_WINDOW   4
#define PACKAGE_ENERGY_CNT   5
#define PACKAGE_THERMAL_CNT   6
#define PACKAGE_MINIMUM_CNT   7
#define PACKAGE_MAXIMUM_CNT   8
#define PACKAGE_TIME_WINDOW_CNT   9
#define DRAM_ENERGY   10

Functions

static long long read_msr (int fd, int which)
static int open_fd (int offset)
static long long read_rapl_value (int index)
static long long convert_rapl_energy (int index, long long value)
static int get_kernel_nr_cpus (void)
static int _rapl_init_thread (hwd_context_t *ctx)
static int _rapl_init_component (int cidx)
static int _rapl_init_control_state (hwd_control_state_t *ctl)
static int _rapl_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _rapl_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _rapl_shutdown_thread (hwd_context_t *ctx)
int _rapl_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
static int _rapl_shutdown_component (void)
static int _rapl_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
static int _rapl_update_control_state (hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
static int _rapl_set_domain (hwd_control_state_t *ctl, int domain)
static int _rapl_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _rapl_ntv_enum_events (unsigned int *EventCode, int modifier)
static int _rapl_ntv_code_to_name (unsigned int EventCode, char *name, int len)
static int _rapl_ntv_code_to_descr (unsigned int EventCode, char *name, int len)
static int _rapl_ntv_code_to_info (unsigned int EventCode, PAPI_event_info_t *info)

Variables

papi_vector_t _rapl_vector
static _rapl_native_event_entry_trapl_native_events = NULL
static int num_events = 0
struct fd_array_tfd_array = NULL
static int num_packages = 0
static int num_cpus = 0
int power_divisor
int time_divisor
int cpu_energy_divisor
int dram_energy_divisor

Detailed Description

Author:
Vince Weaver

This component enables RAPL (Running Average Power Level) energy measurements on Intel SandyBridge/IvyBridge/Haswell

To work, either msr_safe kernel module from LLNL (https://github.com/scalability-llnl/msr-safe), or the x86 generic MSR driver must be installed (CONFIG_X86_MSR) and the /dev/cpu/?/<msr_safe | msr> files must have read permissions

Definition in file linux-rapl.c.


Define Documentation

#define DRAM_ENERGY   10

Definition at line 150 of file linux-rapl.c.

#define ENERGY_UNIT_MASK   0x1f

Definition at line 71 of file linux-rapl.c.

#define ENERGY_UNIT_OFFSET   0x08

Definition at line 70 of file linux-rapl.c.

#define MAXIMUM_POWER_SHIFT   32

Definition at line 80 of file linux-rapl.c.

#define MAXIMUM_TIME_WINDOW_SHIFT   48

Definition at line 81 of file linux-rapl.c.

#define MINIMUM_POWER_SHIFT   16

Definition at line 79 of file linux-rapl.c.

#define MSR_DRAM_ENERGY_STATUS   0x619

Definition at line 62 of file linux-rapl.c.

#define MSR_DRAM_PERF_STATUS   0x61B

Definition at line 63 of file linux-rapl.c.

#define MSR_DRAM_POWER_INFO   0x61C

Definition at line 64 of file linux-rapl.c.

#define MSR_DRAM_POWER_LIMIT   0x618

Definition at line 61 of file linux-rapl.c.

#define MSR_PKG_ENERGY_STATUS   0x611

Definition at line 45 of file linux-rapl.c.

#define MSR_PKG_PERF_STATUS   0x613

Definition at line 46 of file linux-rapl.c.

#define MSR_PKG_POWER_INFO   0x614

Definition at line 47 of file linux-rapl.c.

#define MSR_PKG_RAPL_POWER_LIMIT   0x610

Definition at line 44 of file linux-rapl.c.

#define MSR_PP0_ENERGY_STATUS   0x639

Definition at line 51 of file linux-rapl.c.

#define MSR_PP0_PERF_STATUS   0x63B

Definition at line 53 of file linux-rapl.c.

#define MSR_PP0_POLICY   0x63A

Definition at line 52 of file linux-rapl.c.

#define MSR_PP0_POWER_LIMIT   0x638

Definition at line 50 of file linux-rapl.c.

#define MSR_PP1_ENERGY_STATUS   0x641

Definition at line 57 of file linux-rapl.c.

#define MSR_PP1_POLICY   0x642

Definition at line 58 of file linux-rapl.c.

#define MSR_PP1_POWER_LIMIT   0x640

Definition at line 56 of file linux-rapl.c.

#define MSR_RAPL_POWER_UNIT   0x606

Definition at line 41 of file linux-rapl.c.

#define PACKAGE_ENERGY   0

Definition at line 140 of file linux-rapl.c.

#define PACKAGE_ENERGY_CNT   5

Definition at line 145 of file linux-rapl.c.

#define PACKAGE_MAXIMUM   3

Definition at line 143 of file linux-rapl.c.

#define PACKAGE_MAXIMUM_CNT   8

Definition at line 148 of file linux-rapl.c.

#define PACKAGE_MINIMUM   2

Definition at line 142 of file linux-rapl.c.

#define PACKAGE_MINIMUM_CNT   7

Definition at line 147 of file linux-rapl.c.

#define PACKAGE_THERMAL   1

Definition at line 141 of file linux-rapl.c.

#define PACKAGE_THERMAL_CNT   6

Definition at line 146 of file linux-rapl.c.

#define PACKAGE_TIME_WINDOW   4

Definition at line 144 of file linux-rapl.c.

#define PACKAGE_TIME_WINDOW_CNT   9

Definition at line 149 of file linux-rapl.c.

#define POWER_INFO_UNIT_MASK   0x7fff

Definition at line 77 of file linux-rapl.c.

#define POWER_UNIT_MASK   0x0f

Definition at line 68 of file linux-rapl.c.

#define POWER_UNIT_OFFSET   0

Definition at line 67 of file linux-rapl.c.

#define RAPL_MAX_COUNTERS   64

Definition at line 107 of file linux-rapl.c.

#define THERMAL_SHIFT   0

Definition at line 78 of file linux-rapl.c.

#define TIME_UNIT_MASK   0x0f

Definition at line 74 of file linux-rapl.c.

#define TIME_UNIT_OFFSET   0x10

Definition at line 73 of file linux-rapl.c.


Function Documentation

static int _rapl_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
) [static]

Definition at line 874 of file linux-rapl.c.

00875 {
00876     ( void ) ctx;
00877     ( void ) code;
00878     ( void ) option;
00879 
00880     return PAPI_OK;
00881 }

static int _rapl_init_component ( int  cidx  )  [static]

Definition at line 299 of file linux-rapl.c.

00300 {
00301      int i,j,k,fd;
00302      FILE *fff;
00303      char filename[BUFSIZ];
00304 
00305      int package_avail, dram_avail, pp0_avail, pp1_avail;
00306 
00307      long long result;
00308      int package;
00309 
00310      const PAPI_hw_info_t *hw_info;
00311 
00312      int nr_cpus = get_kernel_nr_cpus();
00313      int packages[nr_cpus];
00314      int cpu_to_use[nr_cpus];
00315 
00316      /* Fill with sentinel values */
00317      for (i=0; i<nr_cpus; ++i) {
00318        packages[i] = -1;
00319        cpu_to_use[i] = -1;
00320      }
00321 
00322 
00323      /* check if Intel processor */
00324      hw_info=&(_papi_hwi_system_info.hw_info);
00325 
00326      /* Ugh can't use PAPI_get_hardware_info() if
00327     PAPI library not done initializing yet */
00328 
00329      if (hw_info->vendor!=PAPI_VENDOR_INTEL) {
00330         strncpy(_rapl_vector.cmp_info.disabled_reason,
00331         "Not an Intel processor",PAPI_MAX_STR_LEN);
00332         return PAPI_ENOSUPP;
00333      }
00334 
00335      /* check model to support */
00336      if (hw_info->cpuid_family==6) {
00337        if (hw_info->cpuid_model==42) {
00338       /* SandyBridge */
00339           package_avail=1;
00340           pp0_avail=1;
00341           pp1_avail=1;
00342           dram_avail=0;
00343        }
00344        else if (hw_info->cpuid_model==45) {
00345       /* SandyBridge-EP */
00346           package_avail=1;
00347           pp0_avail=1;
00348           pp1_avail=0;
00349           dram_avail=1;
00350        }
00351        else if (hw_info->cpuid_model==58) {
00352       /* IvyBridge */
00353           package_avail=1;
00354           pp0_avail=1;
00355           pp1_avail=1;
00356           dram_avail=0;
00357        }
00358        else if (hw_info->cpuid_model==62) {
00359       /* IvyBridge-EP */
00360           package_avail=1;
00361           pp0_avail=1;
00362           pp1_avail=0;
00363           dram_avail=1;
00364        }
00365        else if (hw_info->cpuid_model==60 || hw_info->cpuid_model==69 || hw_info->cpuid_model==70 ) {
00366         /* Haswell */
00367         package_avail=1;
00368         pp0_avail=1;
00369         pp1_avail=1;
00370         dram_avail=1;
00371        }
00372     else if ( hw_info->cpuid_model==63) {
00373         /* Haswell-EP */
00374         package_avail=1;
00375         pp0_avail=1;
00376         pp1_avail=0;
00377         dram_avail=1;
00378     }
00379     else if (hw_info->cpuid_model==61 || hw_info->cpuid_model==71) {
00380        /* Broadwell */
00381        package_avail=1;
00382        pp0_avail=1;
00383        pp1_avail=0;
00384        dram_avail=1;
00385     }
00386     else if (hw_info->cpuid_model==78 || hw_info->cpuid_model==94) {
00387         /* Skylake, Skylake H/S */
00388         package_avail=1;
00389         pp0_avail=1;
00390         pp1_avail=0;
00391         dram_avail=1;
00392     }
00393     else if (hw_info->cpuid_model==87) {
00394         /* Knights Landing (KNL) */
00395         package_avail=1;
00396         pp0_avail=0;
00397         pp1_avail=0;
00398         dram_avail=1;
00399     }
00400        else {
00401      /* not a supported model */
00402      strncpy(_rapl_vector.cmp_info.disabled_reason,
00403          "CPU model not supported",
00404          PAPI_MAX_STR_LEN);
00405      return PAPI_ENOIMPL;
00406        }
00407      }
00408      else {
00409        /* Not a family 6 machine */
00410        strncpy(_rapl_vector.cmp_info.disabled_reason,
00411            "CPU family not supported",PAPI_MAX_STR_LEN);
00412        return PAPI_ENOIMPL;
00413      }
00414 
00415 
00416      /* Detect how many packages */
00417      j=0;
00418      while(1) {
00419        int num_read;
00420 
00421        sprintf(filename,
00422            "/sys/devices/system/cpu/cpu%d/topology/physical_package_id",j);
00423        fff=fopen(filename,"r");
00424        if (fff==NULL) break;
00425        num_read=fscanf(fff,"%d",&package);
00426        fclose(fff);
00427        if (num_read!=1) {
00428              strcpy(_rapl_vector.cmp_info.disabled_reason, "Error reading file: ");
00429              strncat(_rapl_vector.cmp_info.disabled_reason, filename, PAPI_MAX_STR_LEN - strlen(_rapl_vector.cmp_info.disabled_reason) - 1);
00430              _rapl_vector.cmp_info.disabled_reason[PAPI_MAX_STR_LEN-1] = '\0';
00431              return PAPI_ESYS;
00432        }
00433 
00434        /* Check if a new package */
00435        if ((package >= 0) && (package < nr_cpus)) {
00436          if (packages[package] == -1) {
00437            SUBDBG("Found package %d out of total %d\n",package,num_packages);
00438        packages[package]=package;
00439        cpu_to_use[package]=j;
00440        num_packages++;
00441          }
00442        } else {
00443      SUBDBG("Package outside of allowed range\n");
00444      strncpy(_rapl_vector.cmp_info.disabled_reason,
00445         "Package outside of allowed range",PAPI_MAX_STR_LEN);
00446      return PAPI_ESYS;
00447        }
00448 
00449        j++;
00450      }
00451      num_cpus=j;
00452 
00453      if (num_packages==0) {
00454         SUBDBG("Can't access /dev/cpu/*/<msr_safe | msr>\n");
00455     strncpy(_rapl_vector.cmp_info.disabled_reason,
00456         "Can't access /dev/cpu/*/<msr_safe | msr>",PAPI_MAX_STR_LEN);
00457     return PAPI_ESYS;
00458      }
00459 
00460      SUBDBG("Found %d packages with %d cpus\n",num_packages,num_cpus);
00461 
00462      /* Init fd_array */
00463 
00464      fd_array=papi_calloc(sizeof(struct fd_array_t),num_cpus);
00465      if (fd_array==NULL) return PAPI_ENOMEM;
00466 
00467      fd=open_fd(cpu_to_use[0]);
00468      if (fd<0) {
00469         sprintf(_rapl_vector.cmp_info.disabled_reason,
00470         "Can't open fd for cpu0: %s",strerror(errno));
00471         return PAPI_ESYS;
00472      }
00473 
00474      /* Verify needed MSR is readable. In a guest VM it may not be readable*/
00475      if (pread(fd, &result, sizeof result, MSR_RAPL_POWER_UNIT) != sizeof result ) {
00476         strncpy(_rapl_vector.cmp_info.disabled_reason,
00477                "Unable to access RAPL registers",PAPI_MAX_STR_LEN);
00478         return PAPI_ESYS;
00479      }
00480 
00481      /* Calculate the units used */
00482      result=read_msr(fd,MSR_RAPL_POWER_UNIT);
00483 
00484      /* units are 0.5^UNIT_VALUE */
00485      /* which is the same as 1/(2^UNIT_VALUE) */
00486 
00487      power_divisor=1<<((result>>POWER_UNIT_OFFSET)&POWER_UNIT_MASK);
00488      cpu_energy_divisor=1<<((result>>ENERGY_UNIT_OFFSET)&ENERGY_UNIT_MASK);
00489      time_divisor=1<<((result>>TIME_UNIT_OFFSET)&TIME_UNIT_MASK);
00490 
00491     /* Note! On Haswell-EP DRAM energy is fixed at 15.3uJ   */
00492     /* see https://lkml.org/lkml/2015/3/20/582      */
00493     /* Knights Landing is the same */
00494     if (( hw_info->cpuid_model==63) ||  (hw_info->cpuid_model==87 )) {
00495         dram_energy_divisor=1<<16;
00496     }
00497     else {
00498         dram_energy_divisor=cpu_energy_divisor;
00499     }
00500 
00501      SUBDBG("Power units = %.3fW\n",1.0/power_divisor);
00502      SUBDBG("CPU Energy units = %.8fJ\n",1.0/cpu_energy_divisor);
00503      SUBDBG("DRAM Energy units = %.8fJ\n",1.0/dram_energy_divisor);
00504      SUBDBG("Time units = %.8fs\n",1.0/time_divisor);
00505 
00506      /* Allocate space for events */
00507      /* Include room for both counts and scaled values */
00508 
00509      num_events= ((package_avail*num_packages) +
00510                  (pp0_avail*num_packages) +
00511                  (pp1_avail*num_packages) +
00512                  (dram_avail*num_packages) +
00513                  (4*num_packages)) * 2;
00514 
00515      rapl_native_events = (_rapl_native_event_entry_t*)
00516           papi_calloc(sizeof(_rapl_native_event_entry_t),num_events);
00517 
00518 
00519      i = 0;
00520      k = num_events/2;
00521 
00522      /* Create events for package power info */
00523 
00524      for(j=0;j<num_packages;j++) {
00525         sprintf(rapl_native_events[i].name,
00526             "THERMAL_SPEC_CNT:PACKAGE%d",j);
00527         sprintf(rapl_native_events[i].description,
00528            "Thermal specification in counts; package %d",j);
00529         rapl_native_events[i].fd_offset=cpu_to_use[j];
00530         rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
00531         rapl_native_events[i].resources.selector = i + 1;
00532         rapl_native_events[i].type=PACKAGE_THERMAL_CNT;
00533         rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
00534 
00535         sprintf(rapl_native_events[k].name,
00536             "THERMAL_SPEC:PACKAGE%d",j);
00537         strncpy(rapl_native_events[k].units,"W",PAPI_MIN_STR_LEN);
00538         sprintf(rapl_native_events[k].description,
00539            "Thermal specification for package %d",j);
00540         rapl_native_events[k].fd_offset=cpu_to_use[j];
00541         rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
00542         rapl_native_events[k].resources.selector = k + 1;
00543         rapl_native_events[k].type=PACKAGE_THERMAL;
00544         rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
00545 
00546         i++;
00547         k++;
00548      }
00549 
00550      for(j=0;j<num_packages;j++) {
00551         sprintf(rapl_native_events[i].name,
00552             "MINIMUM_POWER_CNT:PACKAGE%d",j);
00553         sprintf(rapl_native_events[i].description,
00554            "Minimum power in counts; package %d",j);
00555         rapl_native_events[i].fd_offset=cpu_to_use[j];
00556         rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
00557         rapl_native_events[i].resources.selector = i + 1;
00558         rapl_native_events[i].type=PACKAGE_MINIMUM_CNT;
00559         rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
00560 
00561         sprintf(rapl_native_events[k].name,
00562             "MINIMUM_POWER:PACKAGE%d",j);
00563         strncpy(rapl_native_events[k].units,"W",PAPI_MIN_STR_LEN);
00564         sprintf(rapl_native_events[k].description,
00565            "Minimum power for package %d",j);
00566         rapl_native_events[k].fd_offset=cpu_to_use[j];
00567         rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
00568         rapl_native_events[k].resources.selector = k + 1;
00569         rapl_native_events[k].type=PACKAGE_MINIMUM;
00570         rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
00571 
00572         i++;
00573         k++;
00574      }
00575 
00576      for(j=0;j<num_packages;j++) {
00577         sprintf(rapl_native_events[i].name,
00578             "MAXIMUM_POWER_CNT:PACKAGE%d",j);
00579         sprintf(rapl_native_events[i].description,
00580            "Maximum power in counts; package %d",j);
00581         rapl_native_events[i].fd_offset=cpu_to_use[j];
00582         rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
00583         rapl_native_events[i].resources.selector = i + 1;
00584         rapl_native_events[i].type=PACKAGE_MAXIMUM_CNT;
00585         rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
00586 
00587         sprintf(rapl_native_events[k].name,
00588             "MAXIMUM_POWER:PACKAGE%d",j);
00589         strncpy(rapl_native_events[k].units,"W",PAPI_MIN_STR_LEN);
00590         sprintf(rapl_native_events[k].description,
00591            "Maximum power for package %d",j);
00592         rapl_native_events[k].fd_offset=cpu_to_use[j];
00593         rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
00594         rapl_native_events[k].resources.selector = k + 1;
00595         rapl_native_events[k].type=PACKAGE_MAXIMUM;
00596         rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
00597 
00598         i++;
00599         k++;
00600      }
00601 
00602      for(j=0;j<num_packages;j++) {
00603         sprintf(rapl_native_events[i].name,
00604             "MAXIMUM_TIME_WINDOW_CNT:PACKAGE%d",j);
00605         sprintf(rapl_native_events[i].description,
00606            "Maximum time window in counts; package %d",j);
00607         rapl_native_events[i].fd_offset=cpu_to_use[j];
00608         rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
00609         rapl_native_events[i].resources.selector = i + 1;
00610         rapl_native_events[i].type=PACKAGE_TIME_WINDOW_CNT;
00611         rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
00612 
00613         sprintf(rapl_native_events[k].name,
00614             "MAXIMUM_TIME_WINDOW:PACKAGE%d",j);
00615         strncpy(rapl_native_events[k].units,"s",PAPI_MIN_STR_LEN);
00616         sprintf(rapl_native_events[k].description,
00617            "Maximum time window for package %d",j);
00618         rapl_native_events[k].fd_offset=cpu_to_use[j];
00619         rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
00620         rapl_native_events[k].resources.selector = k + 1;
00621         rapl_native_events[k].type=PACKAGE_TIME_WINDOW;
00622         rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
00623 
00624         i++;
00625         k++;
00626      }
00627 
00628      /* Create Events for energy measurements */
00629 
00630      if (package_avail) {
00631         for(j=0;j<num_packages;j++) {
00632             sprintf(rapl_native_events[i].name,
00633                 "PACKAGE_ENERGY_CNT:PACKAGE%d",j);
00634             sprintf(rapl_native_events[i].description,
00635                 "Energy used in counts by chip package %d",j);
00636             rapl_native_events[i].fd_offset=cpu_to_use[j];
00637             rapl_native_events[i].msr=MSR_PKG_ENERGY_STATUS;
00638             rapl_native_events[i].resources.selector = i + 1;
00639             rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
00640             rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
00641 
00642             sprintf(rapl_native_events[k].name,
00643                 "PACKAGE_ENERGY:PACKAGE%d",j);
00644             strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
00645             sprintf(rapl_native_events[k].description,
00646                 "Energy used by chip package %d",j);
00647             rapl_native_events[k].fd_offset=cpu_to_use[j];
00648             rapl_native_events[k].msr=MSR_PKG_ENERGY_STATUS;
00649             rapl_native_events[k].resources.selector = k + 1;
00650             rapl_native_events[k].type=PACKAGE_ENERGY;
00651             rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
00652 
00653             i++;
00654             k++;
00655         }
00656      }
00657 
00658      if (pp1_avail) {
00659         for(j=0;j<num_packages;j++) {
00660             sprintf(rapl_native_events[i].name,
00661                 "PP1_ENERGY_CNT:PACKAGE%d",j);
00662             sprintf(rapl_native_events[i].description,
00663                 "Energy used in counts by Power Plane 1 (Often GPU) on package %d",j);
00664             rapl_native_events[i].fd_offset=cpu_to_use[j];
00665             rapl_native_events[i].msr=MSR_PP1_ENERGY_STATUS;
00666             rapl_native_events[i].resources.selector = i + 1;
00667             rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
00668             rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
00669 
00670             sprintf(rapl_native_events[k].name,
00671                 "PP1_ENERGY:PACKAGE%d",j);
00672             strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
00673             sprintf(rapl_native_events[k].description,
00674                 "Energy used by Power Plane 1 (Often GPU) on package %d",j);
00675             rapl_native_events[k].fd_offset=cpu_to_use[j];
00676             rapl_native_events[k].msr=MSR_PP1_ENERGY_STATUS;
00677             rapl_native_events[k].resources.selector = k + 1;
00678             rapl_native_events[k].type=PACKAGE_ENERGY;
00679             rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
00680 
00681             i++;
00682             k++;
00683         }
00684      }
00685 
00686      if (dram_avail) {
00687         for(j=0;j<num_packages;j++) {
00688             sprintf(rapl_native_events[i].name,
00689                 "DRAM_ENERGY_CNT:PACKAGE%d",j);
00690             sprintf(rapl_native_events[i].description,
00691                 "Energy used in counts by DRAM on package %d",j);
00692             rapl_native_events[i].fd_offset=cpu_to_use[j];
00693             rapl_native_events[i].msr=MSR_DRAM_ENERGY_STATUS;
00694             rapl_native_events[i].resources.selector = i + 1;
00695             rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
00696             rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
00697 
00698             sprintf(rapl_native_events[k].name,
00699                 "DRAM_ENERGY:PACKAGE%d",j);
00700             strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
00701             sprintf(rapl_native_events[k].description,
00702                 "Energy used by DRAM on package %d",j);
00703             rapl_native_events[k].fd_offset=cpu_to_use[j];
00704             rapl_native_events[k].msr=MSR_DRAM_ENERGY_STATUS;
00705             rapl_native_events[k].resources.selector = k + 1;
00706             rapl_native_events[k].type=DRAM_ENERGY;
00707             rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
00708 
00709             i++;
00710             k++;
00711         }
00712      }
00713 
00714      if (pp0_avail) {
00715         for(j=0;j<num_packages;j++) {
00716             sprintf(rapl_native_events[i].name,
00717                 "PP0_ENERGY_CNT:PACKAGE%d",j);
00718             sprintf(rapl_native_events[i].description,
00719                 "Energy used in counts by all cores in package %d",j);
00720             rapl_native_events[i].fd_offset=cpu_to_use[j];
00721             rapl_native_events[i].msr=MSR_PP0_ENERGY_STATUS;
00722             rapl_native_events[i].resources.selector = i + 1;
00723             rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
00724             rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
00725 
00726             sprintf(rapl_native_events[k].name,
00727                 "PP0_ENERGY:PACKAGE%d",j);
00728             strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
00729             sprintf(rapl_native_events[k].description,
00730                 "Energy used by all cores in package %d",j);
00731             rapl_native_events[k].fd_offset=cpu_to_use[j];
00732             rapl_native_events[k].msr=MSR_PP0_ENERGY_STATUS;
00733             rapl_native_events[k].resources.selector = k + 1;
00734             rapl_native_events[k].type=PACKAGE_ENERGY;
00735             rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
00736 
00737             i++;
00738             k++;
00739         }
00740      }
00741 
00742      /* Export the total number of events available */
00743      _rapl_vector.cmp_info.num_native_events = num_events;
00744 
00745      _rapl_vector.cmp_info.num_cntrs = num_events;
00746      _rapl_vector.cmp_info.num_mpx_cntrs = num_events;
00747 
00748 
00749      /* Export the component id */
00750      _rapl_vector.cmp_info.CmpIdx = cidx;
00751 
00752      return PAPI_OK;
00753 }

Here is the call graph for this function:

static int _rapl_init_control_state ( hwd_control_state_t ctl  )  [static]

Definition at line 761 of file linux-rapl.c.

00762 {
00763 
00764   _rapl_control_state_t* control = (_rapl_control_state_t*) ctl;
00765   int i;
00766   
00767   for(i=0;i<RAPL_MAX_COUNTERS;i++) {
00768      control->being_measured[i]=0;
00769   }
00770 
00771   return PAPI_OK;
00772 }

static int _rapl_init_thread ( hwd_context_t ctx  )  [static]

Definition at line 286 of file linux-rapl.c.

00287 {
00288   ( void ) ctx;
00289 
00290   return PAPI_OK;
00291 }

static int _rapl_ntv_code_to_descr ( unsigned int  EventCode,
char *  name,
int  len 
) [static]

Definition at line 1012 of file linux-rapl.c.

01013 {
01014      int index = EventCode;
01015 
01016      if ( index >= 0 && index < num_events ) {
01017     strncpy( name, rapl_native_events[index].description, len );
01018     return PAPI_OK;
01019      }
01020      return PAPI_ENOEVNT;
01021 }

static int _rapl_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info 
) [static]

Definition at line 1024 of file linux-rapl.c.

01025 {
01026 
01027   int index = EventCode;
01028 
01029   if ( ( index < 0) || (index >= num_events )) return PAPI_ENOEVNT;
01030 
01031   strncpy( info->symbol, rapl_native_events[index].name, sizeof(info->symbol)-1);
01032   info->symbol[sizeof(info->symbol)-1] = '\0';
01033 
01034   strncpy( info->long_descr, rapl_native_events[index].description, sizeof(info->long_descr)-1);
01035   info->long_descr[sizeof(info->long_descr)-1] = '\0';
01036 
01037   strncpy( info->units, rapl_native_events[index].units, sizeof(info->units)-1);
01038   info->units[sizeof(info->units)-1] = '\0';
01039 
01040   info->data_type = rapl_native_events[index].return_type;
01041 
01042   return PAPI_OK;
01043 }

static int _rapl_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
) [static]

Definition at line 995 of file linux-rapl.c.

00996 {
00997 
00998      int index = EventCode & PAPI_NATIVE_AND_MASK;
00999 
01000      if ( index >= 0 && index < num_events ) {
01001     strncpy( name, rapl_native_events[index].name, len );
01002     return PAPI_OK;
01003      }
01004 
01005      return PAPI_ENOEVNT;
01006 }

static int _rapl_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
) [static]

Definition at line 955 of file linux-rapl.c.

00956 {
00957 
00958      int index;
00959 
00960      switch ( modifier ) {
00961 
00962     case PAPI_ENUM_FIRST:
00963 
00964        if (num_events==0) {
00965           return PAPI_ENOEVNT;
00966        }
00967        *EventCode = 0;
00968 
00969        return PAPI_OK;
00970         
00971 
00972     case PAPI_ENUM_EVENTS:
00973     
00974        index = *EventCode & PAPI_NATIVE_AND_MASK;
00975 
00976        if ( index < num_events - 1 ) {
00977           *EventCode = *EventCode + 1;
00978           return PAPI_OK;
00979        } else {
00980           return PAPI_ENOEVNT;
00981        }
00982        break;
00983     
00984     default:
00985         return PAPI_EINVAL;
00986     }
00987 
00988     return PAPI_EINVAL;
00989 }

int _rapl_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
)

Definition at line 835 of file linux-rapl.c.

00837 {
00838     (void) flags;
00839 
00840     _rapl_stop( ctx, ctl );
00841 
00842     /* Pass back a pointer to our results */
00843     *events = ((_rapl_control_state_t*) ctl)->count;
00844 
00845     return PAPI_OK;
00846 }

Here is the call graph for this function:

static int _rapl_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
) [static]

Definition at line 942 of file linux-rapl.c.

00943 {
00944     ( void ) ctx;
00945     ( void ) ctl;
00946     
00947     return PAPI_OK;
00948 }

static int _rapl_set_domain ( hwd_control_state_t ctl,
int  domain 
) [static]

Definition at line 928 of file linux-rapl.c.

00929 {
00930     ( void ) ctl;
00931     
00932     /* In theory we only support system-wide mode */
00933     /* How to best handle that? */
00934     if ( PAPI_DOM_ALL != domain )
00935     return PAPI_EINVAL;
00936 
00937     return PAPI_OK;
00938 }

static int _rapl_shutdown_component ( void   )  [static]

Definition at line 853 of file linux-rapl.c.

00854 {
00855     int i;
00856 
00857     if (rapl_native_events) papi_free(rapl_native_events);
00858     if (fd_array) {
00859        for(i=0;i<num_cpus;i++) {
00860       if (fd_array[i].open) close(fd_array[i].fd);
00861        }
00862        papi_free(fd_array);
00863     }
00864 
00865     return PAPI_OK;
00866 }

Here is the call graph for this function:

static int _rapl_shutdown_thread ( hwd_context_t ctx  )  [static]

Definition at line 828 of file linux-rapl.c.

00829 {
00830   ( void ) ctx;
00831   return PAPI_OK;
00832 }

static int _rapl_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
) [static]

Definition at line 775 of file linux-rapl.c.

00776 {
00777   _rapl_context_t* context = (_rapl_context_t*) ctx;
00778   _rapl_control_state_t* control = (_rapl_control_state_t*) ctl;
00779   long long now = PAPI_get_real_usec();
00780   int i;
00781 
00782   for( i = 0; i < RAPL_MAX_COUNTERS; i++ ) {
00783      if ((control->being_measured[i]) && (control->need_difference[i])) {
00784         context->start_value[i]=read_rapl_value(i);
00785      }
00786   }
00787 
00788   control->lastupdate = now;
00789 
00790   return PAPI_OK;
00791 }

Here is the call graph for this function:

static int _rapl_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
) [static]

Definition at line 794 of file linux-rapl.c.

00795 {
00796 
00797     /* read values */
00798     _rapl_context_t* context = (_rapl_context_t*) ctx;
00799     _rapl_control_state_t* control = (_rapl_control_state_t*) ctl;
00800     long long now = PAPI_get_real_usec();
00801     int i;
00802     long long temp;
00803 
00804     for ( i = 0; i < RAPL_MAX_COUNTERS; i++ ) {
00805         if (control->being_measured[i]) {
00806             temp = read_rapl_value(i);
00807             if (context->start_value[i])
00808             if (control->need_difference[i]) {
00809                 /* test for wrap around */
00810                 if (temp < context->start_value[i] ) {
00811                     SUBDBG("Wraparound!\nstart:\t%#016x\ttemp:\t%#016x",
00812                         (unsigned)context->start_value[i], (unsigned)temp);
00813                     temp += (0x100000000 - context->start_value[i]);
00814                     SUBDBG("\tresult:\t%#016x\n", (unsigned)temp);
00815                 } else {
00816                     temp -= context->start_value[i];
00817                 }
00818             }
00819             control->count[i] = convert_rapl_energy( i, temp );
00820         }
00821     }
00822     control->lastupdate = now;
00823     return PAPI_OK;
00824 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int _rapl_update_control_state ( hwd_control_state_t ctl,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
) [static]

Definition at line 885 of file linux-rapl.c.

00888 {
00889   int i, index;
00890     ( void ) ctx;
00891 
00892     _rapl_control_state_t* control = (_rapl_control_state_t*) ctl;
00893 
00894     /* Ugh, what is this native[] stuff all about ?*/
00895     /* Mostly remap stuff in papi_internal */
00896 
00897     for(i=0;i<RAPL_MAX_COUNTERS;i++) {
00898        control->being_measured[i]=0;
00899     }
00900 
00901     for( i = 0; i < count; i++ ) {
00902        index=native[i].ni_event&PAPI_NATIVE_AND_MASK;
00903        native[i].ni_position=rapl_native_events[index].resources.selector - 1;
00904        control->being_measured[index]=1;
00905 
00906        /* Only need to subtract if it's a PACKAGE_ENERGY or ENERGY_CNT type */
00907        control->need_difference[index]=
00908         (rapl_native_events[index].type==PACKAGE_ENERGY ||
00909         rapl_native_events[index].type==DRAM_ENERGY ||
00910         rapl_native_events[index].type==PACKAGE_ENERGY_CNT);
00911     }
00912 
00913     return PAPI_OK;
00914 }

static long long convert_rapl_energy ( int  index,
long long  value 
) [static]

Definition at line 202 of file linux-rapl.c.

00202                                                                  {
00203 
00204    union {
00205       long long ll;
00206       double fp;
00207    } return_val;
00208 
00209    return_val.ll = value; /* default case: return raw input value */
00210 
00211    if (rapl_native_events[index].type==PACKAGE_ENERGY) {
00212       return_val.ll = (long long)(((double)value/cpu_energy_divisor)*1e9);
00213    }
00214 
00215    if (rapl_native_events[index].type==DRAM_ENERGY) {
00216       return_val.ll = (long long)(((double)value/dram_energy_divisor)*1e9);
00217    }
00218 
00219    if (rapl_native_events[index].type==PACKAGE_THERMAL) {
00220       return_val.fp = (double)
00221                       ((value>>THERMAL_SHIFT)&POWER_INFO_UNIT_MASK) /
00222                        (double)power_divisor;
00223    }
00224 
00225    if (rapl_native_events[index].type==PACKAGE_MINIMUM) {
00226        return_val.fp = (double)
00227                        ((value>>MINIMUM_POWER_SHIFT)&POWER_INFO_UNIT_MASK)/
00228                         (double)power_divisor;
00229    }
00230 
00231    if (rapl_native_events[index].type==PACKAGE_MAXIMUM) {
00232       return_val.fp = (double)
00233                       ((value>>MAXIMUM_POWER_SHIFT)&POWER_INFO_UNIT_MASK)/
00234                        (double)power_divisor;
00235    }
00236 
00237    if (rapl_native_events[index].type==PACKAGE_TIME_WINDOW) {
00238       return_val.fp =  (double)
00239                     ((value>>MAXIMUM_TIME_WINDOW_SHIFT)&POWER_INFO_UNIT_MASK)/
00240                      (double)time_divisor;
00241    }
00242 
00243    if (rapl_native_events[index].type==PACKAGE_THERMAL_CNT) {
00244       return_val.ll = ((value>>THERMAL_SHIFT)&POWER_INFO_UNIT_MASK);
00245    }
00246 
00247    if (rapl_native_events[index].type==PACKAGE_MINIMUM_CNT) {
00248        return_val.ll = ((value>>MINIMUM_POWER_SHIFT)&POWER_INFO_UNIT_MASK);
00249    }
00250 
00251    if (rapl_native_events[index].type==PACKAGE_MAXIMUM_CNT) {
00252       return_val.ll = ((value>>MAXIMUM_POWER_SHIFT)&POWER_INFO_UNIT_MASK);
00253    }
00254 
00255    if (rapl_native_events[index].type==PACKAGE_TIME_WINDOW_CNT) {
00256       return_val.ll = ((value>>MAXIMUM_TIME_WINDOW_SHIFT)&POWER_INFO_UNIT_MASK);
00257    }
00258 
00259    return return_val.ll;
00260 }

Here is the caller graph for this function:

static int get_kernel_nr_cpus ( void   )  [static]

Definition at line 263 of file linux-rapl.c.

00264 {
00265   FILE *fff;
00266   int num_read, nr_cpus = 1;
00267   fff=fopen("/sys/devices/system/cpu/kernel_max","r");
00268   if (fff==NULL) return nr_cpus;
00269   num_read=fscanf(fff,"%d",&nr_cpus);
00270   fclose(fff);
00271   if (num_read==1) {
00272     nr_cpus++;
00273   } else {
00274     nr_cpus = 1;
00275   }
00276   return nr_cpus;
00277 }

Here is the caller graph for this function:

static int open_fd ( int  offset  )  [static]

Definition at line 169 of file linux-rapl.c.

00169                                {
00170   
00171   int fd=-1;
00172   char filename[BUFSIZ];
00173 
00174   if (fd_array[offset].open==0) {
00175       sprintf(filename,"/dev/cpu/%d/msr_safe",offset);
00176       fd = open(filename, O_RDONLY);
00177       if (fd<0) {
00178           sprintf(filename,"/dev/cpu/%d/msr",offset);
00179           fd = open(filename, O_RDONLY);
00180       }
00181       if (fd>=0) {
00182           fd_array[offset].fd=fd;
00183           fd_array[offset].open=1;
00184       } 
00185   }
00186   else {
00187     fd=fd_array[offset].fd;
00188   }
00189 
00190   return fd;
00191 }

Here is the call graph for this function:

Here is the caller graph for this function:

static long long read_msr ( int  fd,
int  which 
) [static]

Definition at line 157 of file linux-rapl.c.

00157                                              {
00158 
00159   uint64_t data;
00160 
00161   if ( fd<0 || pread(fd, &data, sizeof data, which) != sizeof data ) {
00162     perror("rdmsr:pread");
00163     exit(127);
00164   }
00165 
00166   return (long long)data;
00167 }

Here is the call graph for this function:

Here is the caller graph for this function:

static long long read_rapl_value ( int  index  )  [static]

Definition at line 193 of file linux-rapl.c.

00193                                             {
00194 
00195    int fd;
00196 
00197    fd=open_fd(rapl_native_events[index].fd_offset);
00198    return read_msr(fd,rapl_native_events[index].msr);
00199 
00200 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 125 of file linux-rapl.c.

Definition at line 138 of file linux-rapl.c.

Definition at line 138 of file linux-rapl.c.

struct fd_array_t* fd_array = NULL

Definition at line 134 of file linux-rapl.c.

int num_cpus = 0 [static]

Definition at line 135 of file linux-rapl.c.

int num_events = 0 [static]

Definition at line 133 of file linux-rapl.c.

int num_packages = 0 [static]

Definition at line 135 of file linux-rapl.c.

Definition at line 137 of file linux-rapl.c.

Definition at line 132 of file linux-rapl.c.

Definition at line 137 of file linux-rapl.c.


Generated on 8 Sep 2016 for PAPI by  doxygen 1.6.1