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 881 of file linux-rapl.c.

00882 {
00883     ( void ) ctx;
00884     ( void ) code;
00885     ( void ) option;
00886 
00887     return PAPI_OK;
00888 }

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

Here is the call graph for this function:

static int _rapl_init_control_state ( hwd_control_state_t ctl  )  [static]

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

00769 {
00770 
00771   _rapl_control_state_t* control = (_rapl_control_state_t*) ctl;
00772   int i;
00773   
00774   for(i=0;i<RAPL_MAX_COUNTERS;i++) {
00775      control->being_measured[i]=0;
00776   }
00777 
00778   return PAPI_OK;
00779 }

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 1019 of file linux-rapl.c.

01020 {
01021      int index = EventCode;
01022 
01023      if ( index >= 0 && index < num_events ) {
01024     strncpy( name, rapl_native_events[index].description, len );
01025     return PAPI_OK;
01026      }
01027      return PAPI_ENOEVNT;
01028 }

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

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

01032 {
01033 
01034   int index = EventCode;
01035 
01036   if ( ( index < 0) || (index >= num_events )) return PAPI_ENOEVNT;
01037 
01038   strncpy( info->symbol, rapl_native_events[index].name, sizeof(info->symbol)-1);
01039   info->symbol[sizeof(info->symbol)-1] = '\0';
01040 
01041   strncpy( info->long_descr, rapl_native_events[index].description, sizeof(info->long_descr)-1);
01042   info->long_descr[sizeof(info->long_descr)-1] = '\0';
01043 
01044   strncpy( info->units, rapl_native_events[index].units, sizeof(info->units)-1);
01045   info->units[sizeof(info->units)-1] = '\0';
01046 
01047   info->data_type = rapl_native_events[index].return_type;
01048 
01049   return PAPI_OK;
01050 }

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

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

01003 {
01004 
01005      int index = EventCode & PAPI_NATIVE_AND_MASK;
01006 
01007      if ( index >= 0 && index < num_events ) {
01008     strncpy( name, rapl_native_events[index].name, len );
01009     return PAPI_OK;
01010      }
01011 
01012      return PAPI_ENOEVNT;
01013 }

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

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

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

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

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

00844 {
00845     (void) flags;
00846 
00847     _rapl_stop( ctx, ctl );
00848 
00849     /* Pass back a pointer to our results */
00850     *events = ((_rapl_control_state_t*) ctl)->count;
00851 
00852     return PAPI_OK;
00853 }

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 949 of file linux-rapl.c.

00950 {
00951     ( void ) ctx;
00952     ( void ) ctl;
00953     
00954     return PAPI_OK;
00955 }

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

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

00936 {
00937     ( void ) ctl;
00938     
00939     /* In theory we only support system-wide mode */
00940     /* How to best handle that? */
00941     if ( PAPI_DOM_ALL != domain )
00942     return PAPI_EINVAL;
00943 
00944     return PAPI_OK;
00945 }

static int _rapl_shutdown_component ( void   )  [static]

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

00861 {
00862     int i;
00863 
00864     if (rapl_native_events) papi_free(rapl_native_events);
00865     if (fd_array) {
00866        for(i=0;i<num_cpus;i++) {
00867       if (fd_array[i].open) close(fd_array[i].fd);
00868        }
00869        papi_free(fd_array);
00870     }
00871 
00872     return PAPI_OK;
00873 }

Here is the call graph for this function:

static int _rapl_shutdown_thread ( hwd_context_t ctx  )  [static]

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

00836 {
00837   ( void ) ctx;
00838   return PAPI_OK;
00839 }

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

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

00783 {
00784   _rapl_context_t* context = (_rapl_context_t*) ctx;
00785   _rapl_control_state_t* control = (_rapl_control_state_t*) ctl;
00786   long long now = PAPI_get_real_usec();
00787   int i;
00788 
00789   for( i = 0; i < RAPL_MAX_COUNTERS; i++ ) {
00790      if ((control->being_measured[i]) && (control->need_difference[i])) {
00791         context->start_value[i]=read_rapl_value(i);
00792      }
00793   }
00794 
00795   control->lastupdate = now;
00796 
00797   return PAPI_OK;
00798 }

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 801 of file linux-rapl.c.

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

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 892 of file linux-rapl.c.

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

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 17 Nov 2016 for PAPI by  doxygen 1.6.1