Blame src/components/rapl/linux-rapl.c

Packit 577717
/**
Packit 577717
 * @file    linux-rapl.c
Packit 577717
 * @author  Vince Weaver
Packit 577717
 *
Packit 577717
 * @ingroup papi_components
Packit 577717
 *
Packit 577717
 * @brief rapl component
Packit 577717
 *
Packit 577717
 *  This component enables RAPL (Running Average Power Level)
Packit 577717
 *  energy measurements on Intel SandyBridge/IvyBridge/Haswell
Packit 577717
 *
Packit 577717
 *  To work, either msr_safe kernel module from LLNL
Packit 577717
 *  (https://github.com/scalability-llnl/msr-safe), or
Packit 577717
 *  the x86 generic MSR driver must be installed
Packit 577717
 *    (CONFIG_X86_MSR) and the /dev/cpu/?/<msr_safe | msr> files must have read permissions
Packit 577717
 */
Packit 577717
Packit 577717
#include <stdio.h>
Packit 577717
#include <unistd.h>
Packit 577717
#include <dirent.h>
Packit 577717
#include <fcntl.h>
Packit 577717
#include <string.h>
Packit 577717
#include <stdint.h>
Packit 577717
#include <errno.h>
Packit 577717
Packit 577717
/* Headers required by PAPI */
Packit 577717
#include "papi.h"
Packit 577717
#include "papi_internal.h"
Packit 577717
#include "papi_vector.h"
Packit 577717
#include "papi_memory.h"
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Platform specific RAPL Domains.
Packit 577717
 * Note that PP1 RAPL Domain is supported on 062A only
Packit 577717
 * And DRAM RAPL Domain is supported on 062D only
Packit 577717
 */
Packit 577717
Packit 577717
Packit 577717
/* RAPL defines */
Packit 577717
#define MSR_RAPL_POWER_UNIT             0x606
Packit 577717
Packit 577717
/* Package */
Packit 577717
#define MSR_PKG_RAPL_POWER_LIMIT        0x610
Packit 577717
#define MSR_PKG_ENERGY_STATUS           0x611
Packit 577717
#define MSR_PKG_PERF_STATUS             0x613
Packit 577717
#define MSR_PKG_POWER_INFO              0x614
Packit 577717
Packit 577717
/* PP0 */
Packit 577717
#define MSR_PP0_POWER_LIMIT             0x638
Packit 577717
#define MSR_PP0_ENERGY_STATUS           0x639
Packit 577717
#define MSR_PP0_POLICY                  0x63A
Packit 577717
#define MSR_PP0_PERF_STATUS             0x63B
Packit 577717
Packit 577717
/* PP1 */
Packit 577717
#define MSR_PP1_POWER_LIMIT             0x640
Packit 577717
#define MSR_PP1_ENERGY_STATUS           0x641
Packit 577717
#define MSR_PP1_POLICY                  0x642
Packit 577717
Packit 577717
/* DRAM */
Packit 577717
#define MSR_DRAM_POWER_LIMIT            0x618
Packit 577717
#define MSR_DRAM_ENERGY_STATUS          0x619
Packit 577717
#define MSR_DRAM_PERF_STATUS            0x61B
Packit 577717
#define MSR_DRAM_POWER_INFO             0x61C
Packit 577717
Packit 577717
/* PSYS RAPL Domain */
Packit 577717
#define MSR_PLATFORM_ENERGY_STATUS	0x64d
Packit 577717
Packit 577717
/* RAPL bitsmasks */
Packit 577717
#define POWER_UNIT_OFFSET          0
Packit 577717
#define POWER_UNIT_MASK         0x0f
Packit 577717
Packit 577717
#define ENERGY_UNIT_OFFSET      0x08
Packit 577717
#define ENERGY_UNIT_MASK        0x1f
Packit 577717
Packit 577717
#define TIME_UNIT_OFFSET        0x10
Packit 577717
#define TIME_UNIT_MASK          0x0f
Packit 577717
Packit 577717
/* RAPL POWER UNIT MASKS */
Packit 577717
#define POWER_INFO_UNIT_MASK     0x7fff
Packit 577717
#define THERMAL_SHIFT                 0
Packit 577717
#define MINIMUM_POWER_SHIFT          16
Packit 577717
#define MAXIMUM_POWER_SHIFT          32
Packit 577717
#define MAXIMUM_TIME_WINDOW_SHIFT    48
Packit 577717
Packit 577717
Packit 577717
typedef struct _rapl_register
Packit 577717
{
Packit 577717
	unsigned int selector;
Packit 577717
} _rapl_register_t;
Packit 577717
Packit 577717
typedef struct _rapl_native_event_entry
Packit 577717
{
Packit 577717
  char name[PAPI_MAX_STR_LEN];
Packit 577717
  char units[PAPI_MIN_STR_LEN];
Packit 577717
  char description[PAPI_MAX_STR_LEN];
Packit 577717
  int fd_offset;
Packit 577717
  int msr;
Packit 577717
  int type;
Packit 577717
  int return_type;
Packit 577717
  _rapl_register_t resources;
Packit 577717
} _rapl_native_event_entry_t;
Packit 577717
Packit 577717
typedef struct _rapl_reg_alloc
Packit 577717
{
Packit 577717
	_rapl_register_t ra_bits;
Packit 577717
} _rapl_reg_alloc_t;
Packit 577717
Packit 577717
/* actually 32?  But setting this to be safe? */
Packit 577717
#define RAPL_MAX_COUNTERS 64
Packit 577717
Packit 577717
typedef struct _rapl_control_state
Packit 577717
{
Packit 577717
  int being_measured[RAPL_MAX_COUNTERS];
Packit 577717
  long long count[RAPL_MAX_COUNTERS];
Packit 577717
  int need_difference[RAPL_MAX_COUNTERS];
Packit 577717
  long long lastupdate;
Packit 577717
} _rapl_control_state_t;
Packit 577717
Packit 577717
Packit 577717
typedef struct _rapl_context
Packit 577717
{
Packit 577717
  long long start_value[RAPL_MAX_COUNTERS];
Packit 577717
  _rapl_control_state_t state;
Packit 577717
} _rapl_context_t;
Packit 577717
Packit 577717
Packit 577717
papi_vector_t _rapl_vector;
Packit 577717
Packit 577717
struct fd_array_t {
Packit 577717
  int fd;
Packit 577717
  int open;
Packit 577717
};
Packit 577717
Packit 577717
static _rapl_native_event_entry_t * rapl_native_events=NULL;
Packit 577717
static int num_events		= 0;
Packit 577717
struct fd_array_t *fd_array=NULL;
Packit 577717
static int num_packages=0,num_cpus=0;
Packit 577717
Packit 577717
int power_divisor,time_divisor;
Packit 577717
int cpu_energy_divisor,dram_energy_divisor;
Packit 577717
Packit 577717
#define PACKAGE_ENERGY      	0
Packit 577717
#define PACKAGE_THERMAL     	1
Packit 577717
#define PACKAGE_MINIMUM     	2
Packit 577717
#define PACKAGE_MAXIMUM     	3
Packit 577717
#define PACKAGE_TIME_WINDOW 	4
Packit 577717
#define PACKAGE_ENERGY_CNT      5
Packit 577717
#define PACKAGE_THERMAL_CNT     6
Packit 577717
#define PACKAGE_MINIMUM_CNT     7
Packit 577717
#define PACKAGE_MAXIMUM_CNT     8
Packit 577717
#define PACKAGE_TIME_WINDOW_CNT 9
Packit 577717
#define DRAM_ENERGY		10
Packit 577717
#define PLATFORM_ENERGY		11
Packit 577717
Packit 577717
/***************************************************************************/
Packit 577717
/******  BEGIN FUNCTIONS  USED INTERNALLY SPECIFIC TO THIS COMPONENT *******/
Packit 577717
/***************************************************************************/
Packit 577717
Packit 577717
Packit 577717
static long long read_msr(int fd, int which) {
Packit 577717
Packit 577717
  uint64_t data;
Packit 577717
Packit 577717
  if ( fd<0 || pread(fd, &data, sizeof data, which) != sizeof data ) {
Packit 577717
    perror("rdmsr:pread");
Packit 577717
    exit(127);
Packit 577717
  }
Packit 577717
Packit 577717
  return (long long)data;
Packit 577717
}
Packit 577717
Packit 577717
static int open_fd(int offset) {
Packit 577717
  
Packit 577717
  int fd=-1;
Packit 577717
  char filename[BUFSIZ];
Packit 577717
Packit 577717
  if (fd_array[offset].open==0) {
Packit 577717
	  sprintf(filename,"/dev/cpu/%d/msr_safe",offset);
Packit 577717
      fd = open(filename, O_RDONLY);
Packit 577717
	  if (fd<0) {
Packit 577717
		  sprintf(filename,"/dev/cpu/%d/msr",offset);
Packit 577717
          fd = open(filename, O_RDONLY);
Packit 577717
	  }
Packit 577717
	  if (fd>=0) {
Packit 577717
		  fd_array[offset].fd=fd;
Packit 577717
	      fd_array[offset].open=1;
Packit 577717
      } 
Packit 577717
  }
Packit 577717
  else {
Packit 577717
    fd=fd_array[offset].fd;
Packit 577717
  }
Packit 577717
Packit 577717
  return fd;
Packit 577717
}
Packit 577717
Packit 577717
static long long read_rapl_value(int index) {
Packit 577717
Packit 577717
   int fd;
Packit 577717
Packit 577717
   fd=open_fd(rapl_native_events[index].fd_offset);
Packit 577717
   return read_msr(fd,rapl_native_events[index].msr);
Packit 577717
Packit 577717
}
Packit 577717
Packit 577717
static long long convert_rapl_energy(int index, long long value) {
Packit 577717
Packit 577717
   union {
Packit 577717
      long long ll;
Packit 577717
      double fp;
Packit 577717
   } return_val;
Packit 577717
Packit 577717
   return_val.ll = value; /* default case: return raw input value */
Packit 577717
Packit 577717
   if (rapl_native_events[index].type==PACKAGE_ENERGY) {
Packit 577717
      return_val.ll = (long long)(((double)value/cpu_energy_divisor)*1e9);
Packit 577717
   }
Packit 577717
Packit 577717
   if (rapl_native_events[index].type==DRAM_ENERGY) {
Packit 577717
      return_val.ll = (long long)(((double)value/dram_energy_divisor)*1e9);
Packit 577717
   }
Packit 577717
Packit 577717
   if (rapl_native_events[index].type==PLATFORM_ENERGY) {
Packit 577717
      return_val.ll = (long long)(((double)value/cpu_energy_divisor)*1e9);
Packit 577717
   }
Packit 577717
Packit 577717
   if (rapl_native_events[index].type==PACKAGE_THERMAL) {
Packit 577717
      return_val.fp = (double)
Packit 577717
                      ((value>>THERMAL_SHIFT)&POWER_INFO_UNIT_MASK) /
Packit 577717
                       (double)power_divisor;
Packit 577717
   }
Packit 577717
Packit 577717
   if (rapl_native_events[index].type==PACKAGE_MINIMUM) {
Packit 577717
       return_val.fp = (double)
Packit 577717
                       ((value>>MINIMUM_POWER_SHIFT)&POWER_INFO_UNIT_MASK)/
Packit 577717
                        (double)power_divisor;
Packit 577717
   }
Packit 577717
Packit 577717
   if (rapl_native_events[index].type==PACKAGE_MAXIMUM) {
Packit 577717
      return_val.fp = (double)
Packit 577717
                      ((value>>MAXIMUM_POWER_SHIFT)&POWER_INFO_UNIT_MASK)/
Packit 577717
                       (double)power_divisor;
Packit 577717
   }
Packit 577717
Packit 577717
   if (rapl_native_events[index].type==PACKAGE_TIME_WINDOW) {
Packit 577717
      return_val.fp =  (double)
Packit 577717
                    ((value>>MAXIMUM_TIME_WINDOW_SHIFT)&POWER_INFO_UNIT_MASK)/
Packit 577717
                     (double)time_divisor;
Packit 577717
   }
Packit 577717
Packit 577717
   if (rapl_native_events[index].type==PACKAGE_THERMAL_CNT) {
Packit 577717
      return_val.ll = ((value>>THERMAL_SHIFT)&POWER_INFO_UNIT_MASK);
Packit 577717
   }
Packit 577717
Packit 577717
   if (rapl_native_events[index].type==PACKAGE_MINIMUM_CNT) {
Packit 577717
       return_val.ll = ((value>>MINIMUM_POWER_SHIFT)&POWER_INFO_UNIT_MASK);
Packit 577717
   }
Packit 577717
Packit 577717
   if (rapl_native_events[index].type==PACKAGE_MAXIMUM_CNT) {
Packit 577717
      return_val.ll = ((value>>MAXIMUM_POWER_SHIFT)&POWER_INFO_UNIT_MASK);
Packit 577717
   }
Packit 577717
Packit 577717
   if (rapl_native_events[index].type==PACKAGE_TIME_WINDOW_CNT) {
Packit 577717
      return_val.ll = ((value>>MAXIMUM_TIME_WINDOW_SHIFT)&POWER_INFO_UNIT_MASK);
Packit 577717
   }
Packit 577717
Packit 577717
   return return_val.ll;
Packit 577717
}
Packit 577717
Packit 577717
static int
Packit 577717
get_kernel_nr_cpus(void)
Packit 577717
{
Packit 577717
  FILE *fff;
Packit 577717
  int num_read, nr_cpus = 1;
Packit 577717
  fff=fopen("/sys/devices/system/cpu/kernel_max","r");
Packit 577717
  if (fff==NULL) return nr_cpus;
Packit 577717
  num_read=fscanf(fff,"%d",&nr_cpus);
Packit 577717
  fclose(fff);
Packit 577717
  if (num_read==1) {
Packit 577717
    nr_cpus++;
Packit 577717
  } else {
Packit 577717
    nr_cpus = 1;
Packit 577717
  }
Packit 577717
  return nr_cpus;
Packit 577717
}
Packit 577717
Packit 577717
/************************* PAPI Functions **********************************/
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * This is called whenever a thread is initialized
Packit 577717
 */
Packit 577717
static int
Packit 577717
_rapl_init_thread( hwd_context_t *ctx )
Packit 577717
{
Packit 577717
  ( void ) ctx;
Packit 577717
Packit 577717
  return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Called when PAPI process is initialized (i.e. PAPI_library_init)
Packit 577717
 */
Packit 577717
static int
Packit 577717
_rapl_init_component( int cidx )
Packit 577717
{
Packit 577717
     int i,j,k,fd;
Packit 577717
     FILE *fff;
Packit 577717
     char filename[BUFSIZ];
Packit 577717
Packit 577717
	int package_avail, dram_avail, pp0_avail, pp1_avail, psys_avail;
Packit 577717
	int different_units;
Packit 577717
Packit 577717
     long long result;
Packit 577717
     int package;
Packit 577717
Packit 577717
     const PAPI_hw_info_t *hw_info;
Packit 577717
Packit 577717
     int nr_cpus = get_kernel_nr_cpus();
Packit 577717
     int packages[nr_cpus];
Packit 577717
     int cpu_to_use[nr_cpus];
Packit 577717
Packit 577717
     /* Fill with sentinel values */
Packit 577717
     for (i=0; i
Packit 577717
       packages[i] = -1;
Packit 577717
       cpu_to_use[i] = -1;
Packit 577717
     }
Packit 577717
Packit 577717
Packit 577717
     /* check if Intel processor */
Packit 577717
     hw_info=&(_papi_hwi_system_info.hw_info);
Packit 577717
Packit 577717
     /* Ugh can't use PAPI_get_hardware_info() if
Packit 577717
	PAPI library not done initializing yet */
Packit 577717
Packit 577717
     if (hw_info->vendor!=PAPI_VENDOR_INTEL) {
Packit 577717
        strncpy(_rapl_vector.cmp_info.disabled_reason,
Packit 577717
		"Not an Intel processor",PAPI_MAX_STR_LEN);
Packit 577717
        return PAPI_ENOSUPP;
Packit 577717
     }
Packit 577717
Packit 577717
	/* Make sure it is a family 6 Intel Chip */
Packit 577717
	if (hw_info->cpuid_family!=6) {
Packit 577717
		/* Not a family 6 machine */
Packit 577717
		strncpy(_rapl_vector.cmp_info.disabled_reason,
Packit 577717
			"CPU family not supported",PAPI_MAX_STR_LEN);
Packit 577717
		return PAPI_ENOIMPL;
Packit 577717
	}
Packit 577717
Packit 577717
	/* Detect RAPL support */
Packit 577717
	switch(hw_info->cpuid_model) {
Packit 577717
Packit 577717
		/* Desktop / Laptops */
Packit 577717
Packit 577717
		case 42:	/* SandyBridge */
Packit 577717
		case 58:	/* IvyBridge */
Packit 577717
			package_avail=1;
Packit 577717
			pp0_avail=1;
Packit 577717
			pp1_avail=1;
Packit 577717
			dram_avail=0;
Packit 577717
			psys_avail=0;
Packit 577717
			different_units=0;
Packit 577717
			break;
Packit 577717
Packit 577717
		case 60:	/* Haswell */
Packit 577717
		case 69:	/* Haswell ULT */
Packit 577717
		case 70:	/* Haswell GT3E */
Packit 577717
		case 92:	/* Atom Goldmont */
Packit 577717
		case 122:	/* Atom Gemini Lake */
Packit 577717
		case 95:	/* Atom Denverton */
Packit 577717
			package_avail=1;
Packit 577717
			pp0_avail=1;
Packit 577717
			pp1_avail=1;
Packit 577717
			dram_avail=1;
Packit 577717
			psys_avail=0;
Packit 577717
			different_units=0;
Packit 577717
			break;
Packit 577717
Packit 577717
		case 61:	/* Broadwell */
Packit 577717
		case 71:	/* Broadwell-H (GT3E) */
Packit 577717
		case 86:	/* Broadwell XEON_D */
Packit 577717
			package_avail=1;
Packit 577717
			pp0_avail=1;
Packit 577717
			pp1_avail=0;
Packit 577717
			dram_avail=1;
Packit 577717
			psys_avail=0;
Packit 577717
			different_units=0;
Packit 577717
			break;
Packit 577717
Packit 577717
		case 78:	/* Skylake Mobile */
Packit 577717
		case 94:	/* Skylake Desktop (H/S) */
Packit 577717
		case 142:	/* Kabylake Mobile */
Packit 577717
		case 158:	/* Kabylake Desktop */
Packit 577717
			package_avail=1;
Packit 577717
			pp0_avail=1;
Packit 577717
			pp1_avail=0;
Packit 577717
			dram_avail=1;
Packit 577717
			psys_avail=1;
Packit 577717
			different_units=0;
Packit 577717
			break;
Packit 577717
Packit 577717
		/* Server Class Machines */
Packit 577717
Packit 577717
		case 45:	/* SandyBridge-EP */
Packit 577717
		case 62:	/* IvyBridge-EP */
Packit 577717
			package_avail=1;
Packit 577717
			pp0_avail=1;
Packit 577717
			pp1_avail=0;
Packit 577717
			dram_avail=1;
Packit 577717
			psys_avail=0;
Packit 577717
			different_units=0;
Packit 577717
			break;
Packit 577717
Packit 577717
		case 63:	/* Haswell-EP */
Packit 577717
		case 79:	/* Broadwell-EP */
Packit 577717
		case 85:	/* Skylake-X */
Packit 577717
			package_avail=1;
Packit 577717
			pp0_avail=1;
Packit 577717
			pp1_avail=0;
Packit 577717
			dram_avail=1;
Packit 577717
			psys_avail=0;
Packit 577717
			different_units=1;
Packit 577717
			break;
Packit 577717
Packit 577717
Packit 577717
		case 87:	/* Knights Landing (KNL) */
Packit 577717
		case 133:	/* Knights Mill (KNM) */
Packit 577717
			package_avail=1;
Packit 577717
			pp0_avail=0;
Packit 577717
			pp1_avail=0;
Packit 577717
			dram_avail=1;
Packit 577717
			psys_avail=0;
Packit 577717
			different_units=1;
Packit 577717
			break;
Packit 577717
Packit 577717
		default:	/* not a supported model */
Packit 577717
			strncpy(_rapl_vector.cmp_info.disabled_reason,
Packit 577717
				"CPU model not supported",
Packit 577717
				PAPI_MAX_STR_LEN);
Packit 577717
			return PAPI_ENOIMPL;
Packit 577717
	}
Packit 577717
Packit 577717
     /* Detect how many packages */
Packit 577717
     j=0;
Packit 577717
     while(1) {
Packit 577717
       int num_read;
Packit 577717
Packit 577717
       sprintf(filename,
Packit 577717
	       "/sys/devices/system/cpu/cpu%d/topology/physical_package_id",j);
Packit 577717
       fff=fopen(filename,"r");
Packit 577717
       if (fff==NULL) break;
Packit 577717
       num_read=fscanf(fff,"%d",&package);
Packit 577717
       fclose(fff);
Packit 577717
       if (num_read!=1) {
Packit 577717
    		 strcpy(_rapl_vector.cmp_info.disabled_reason, "Error reading file: ");
Packit 577717
    		 strncat(_rapl_vector.cmp_info.disabled_reason, filename, PAPI_MAX_STR_LEN - strlen(_rapl_vector.cmp_info.disabled_reason) - 1);
Packit 577717
    		 _rapl_vector.cmp_info.disabled_reason[PAPI_MAX_STR_LEN-1] = '\0';
Packit 577717
    		 return PAPI_ESYS;
Packit 577717
       }
Packit 577717
Packit 577717
       /* Check if a new package */
Packit 577717
       if ((package >= 0) && (package < nr_cpus)) {
Packit 577717
         if (packages[package] == -1) {
Packit 577717
           SUBDBG("Found package %d out of total %d\n",package,num_packages);
Packit 577717
	   packages[package]=package;
Packit 577717
	   cpu_to_use[package]=j;
Packit 577717
	   num_packages++;
Packit 577717
         }
Packit 577717
       } else {
Packit 577717
	 SUBDBG("Package outside of allowed range\n");
Packit 577717
	 strncpy(_rapl_vector.cmp_info.disabled_reason,
Packit 577717
		"Package outside of allowed range",PAPI_MAX_STR_LEN);
Packit 577717
	 return PAPI_ESYS;
Packit 577717
       }
Packit 577717
Packit 577717
       j++;
Packit 577717
     }
Packit 577717
     num_cpus=j;
Packit 577717
Packit 577717
     if (num_packages==0) {
Packit 577717
        SUBDBG("Can't access /dev/cpu/*/<msr_safe | msr>\n");
Packit 577717
	strncpy(_rapl_vector.cmp_info.disabled_reason,
Packit 577717
		"Can't access /dev/cpu/*/<msr_safe | msr>",PAPI_MAX_STR_LEN);
Packit 577717
	return PAPI_ESYS;
Packit 577717
     }
Packit 577717
Packit 577717
     SUBDBG("Found %d packages with %d cpus\n",num_packages,num_cpus);
Packit 577717
Packit 577717
     /* Init fd_array */
Packit 577717
Packit 577717
     fd_array=papi_calloc(num_cpus, sizeof(struct fd_array_t));
Packit 577717
     if (fd_array==NULL) return PAPI_ENOMEM;
Packit 577717
Packit 577717
     fd=open_fd(cpu_to_use[0]);
Packit 577717
     if (fd<0) {
Packit 577717
        sprintf(_rapl_vector.cmp_info.disabled_reason,
Packit 577717
		"Can't open fd for cpu0: %s",strerror(errno));
Packit 577717
        return PAPI_ESYS;
Packit 577717
     }
Packit 577717
Packit 577717
     /* Verify needed MSR is readable. In a guest VM it may not be readable*/
Packit 577717
     if (pread(fd, &result, sizeof result, MSR_RAPL_POWER_UNIT) != sizeof result ) {
Packit 577717
        strncpy(_rapl_vector.cmp_info.disabled_reason,
Packit 577717
               "Unable to access RAPL registers",PAPI_MAX_STR_LEN);
Packit 577717
        return PAPI_ESYS;
Packit 577717
     }
Packit 577717
Packit 577717
     /* Calculate the units used */
Packit 577717
     result=read_msr(fd,MSR_RAPL_POWER_UNIT);
Packit 577717
Packit 577717
     /* units are 0.5^UNIT_VALUE */
Packit 577717
     /* which is the same as 1/(2^UNIT_VALUE) */
Packit 577717
Packit 577717
     power_divisor=1<<((result>>POWER_UNIT_OFFSET)&POWER_UNIT_MASK);
Packit 577717
     cpu_energy_divisor=1<<((result>>ENERGY_UNIT_OFFSET)&ENERGY_UNIT_MASK);
Packit 577717
     time_divisor=1<<((result>>TIME_UNIT_OFFSET)&TIME_UNIT_MASK);
Packit 577717
Packit 577717
	/* Note! On Haswell-EP DRAM energy is fixed at 15.3uJ	*/
Packit 577717
	/* see https://lkml.org/lkml/2015/3/20/582		*/
Packit 577717
	/* Knights Landing is the same */
Packit 577717
	/* so is Broadwell-EP */
Packit 577717
	if ( different_units ) {
Packit 577717
		dram_energy_divisor=1<<16;
Packit 577717
	}
Packit 577717
	else {
Packit 577717
		dram_energy_divisor=cpu_energy_divisor;
Packit 577717
	}
Packit 577717
Packit 577717
     SUBDBG("Power units = %.3fW\n",1.0/power_divisor);
Packit 577717
     SUBDBG("CPU Energy units = %.8fJ\n",1.0/cpu_energy_divisor);
Packit 577717
     SUBDBG("DRAM Energy units = %.8fJ\n",1.0/dram_energy_divisor);
Packit 577717
     SUBDBG("Time units = %.8fs\n",1.0/time_divisor);
Packit 577717
Packit 577717
     /* Allocate space for events */
Packit 577717
     /* Include room for both counts and scaled values */
Packit 577717
Packit 577717
     num_events= ((package_avail*num_packages) +
Packit 577717
                 (pp0_avail*num_packages) +
Packit 577717
                 (pp1_avail*num_packages) +
Packit 577717
                 (dram_avail*num_packages) +
Packit 577717
		(psys_avail*num_packages) +
Packit 577717
                 (4*num_packages)) * 2;
Packit 577717
Packit 577717
     rapl_native_events = (_rapl_native_event_entry_t*)
Packit 577717
          papi_calloc(num_events, sizeof(_rapl_native_event_entry_t));
Packit 577717
Packit 577717
Packit 577717
     i = 0;
Packit 577717
     k = num_events/2;
Packit 577717
Packit 577717
     /* Create events for package power info */
Packit 577717
Packit 577717
     for(j=0;j
Packit 577717
     	sprintf(rapl_native_events[i].name,
Packit 577717
			"THERMAL_SPEC_CNT:PACKAGE%d",j);
Packit 577717
		sprintf(rapl_native_events[i].description,
Packit 577717
		   "Thermal specification in counts; package %d",j);
Packit 577717
		rapl_native_events[i].fd_offset=cpu_to_use[j];
Packit 577717
		rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
Packit 577717
		rapl_native_events[i].resources.selector = i + 1;
Packit 577717
		rapl_native_events[i].type=PACKAGE_THERMAL_CNT;
Packit 577717
		rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
     	sprintf(rapl_native_events[k].name,
Packit 577717
			"THERMAL_SPEC:PACKAGE%d",j);
Packit 577717
		strncpy(rapl_native_events[k].units,"W",PAPI_MIN_STR_LEN);
Packit 577717
		sprintf(rapl_native_events[k].description,
Packit 577717
		   "Thermal specification for package %d",j);
Packit 577717
		rapl_native_events[k].fd_offset=cpu_to_use[j];
Packit 577717
		rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
Packit 577717
		rapl_native_events[k].resources.selector = k + 1;
Packit 577717
		rapl_native_events[k].type=PACKAGE_THERMAL;
Packit 577717
		rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
Packit 577717
Packit 577717
		i++;
Packit 577717
		k++;
Packit 577717
     }
Packit 577717
Packit 577717
     for(j=0;j
Packit 577717
		sprintf(rapl_native_events[i].name,
Packit 577717
			"MINIMUM_POWER_CNT:PACKAGE%d",j);
Packit 577717
		sprintf(rapl_native_events[i].description,
Packit 577717
		   "Minimum power in counts; package %d",j);
Packit 577717
		rapl_native_events[i].fd_offset=cpu_to_use[j];
Packit 577717
		rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
Packit 577717
		rapl_native_events[i].resources.selector = i + 1;
Packit 577717
		rapl_native_events[i].type=PACKAGE_MINIMUM_CNT;
Packit 577717
		rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
		sprintf(rapl_native_events[k].name,
Packit 577717
			"MINIMUM_POWER:PACKAGE%d",j);
Packit 577717
		strncpy(rapl_native_events[k].units,"W",PAPI_MIN_STR_LEN);
Packit 577717
		sprintf(rapl_native_events[k].description,
Packit 577717
		   "Minimum power for package %d",j);
Packit 577717
		rapl_native_events[k].fd_offset=cpu_to_use[j];
Packit 577717
		rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
Packit 577717
		rapl_native_events[k].resources.selector = k + 1;
Packit 577717
		rapl_native_events[k].type=PACKAGE_MINIMUM;
Packit 577717
		rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
Packit 577717
Packit 577717
		i++;
Packit 577717
		k++;
Packit 577717
     }
Packit 577717
Packit 577717
     for(j=0;j
Packit 577717
		sprintf(rapl_native_events[i].name,
Packit 577717
			"MAXIMUM_POWER_CNT:PACKAGE%d",j);
Packit 577717
		sprintf(rapl_native_events[i].description,
Packit 577717
		   "Maximum power in counts; package %d",j);
Packit 577717
		rapl_native_events[i].fd_offset=cpu_to_use[j];
Packit 577717
		rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
Packit 577717
		rapl_native_events[i].resources.selector = i + 1;
Packit 577717
		rapl_native_events[i].type=PACKAGE_MAXIMUM_CNT;
Packit 577717
		rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
		sprintf(rapl_native_events[k].name,
Packit 577717
			"MAXIMUM_POWER:PACKAGE%d",j);
Packit 577717
		strncpy(rapl_native_events[k].units,"W",PAPI_MIN_STR_LEN);
Packit 577717
		sprintf(rapl_native_events[k].description,
Packit 577717
		   "Maximum power for package %d",j);
Packit 577717
		rapl_native_events[k].fd_offset=cpu_to_use[j];
Packit 577717
		rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
Packit 577717
		rapl_native_events[k].resources.selector = k + 1;
Packit 577717
		rapl_native_events[k].type=PACKAGE_MAXIMUM;
Packit 577717
		rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
Packit 577717
Packit 577717
		i++;
Packit 577717
		k++;
Packit 577717
     }
Packit 577717
Packit 577717
     for(j=0;j
Packit 577717
		sprintf(rapl_native_events[i].name,
Packit 577717
			"MAXIMUM_TIME_WINDOW_CNT:PACKAGE%d",j);
Packit 577717
		sprintf(rapl_native_events[i].description,
Packit 577717
		   "Maximum time window in counts; package %d",j);
Packit 577717
		rapl_native_events[i].fd_offset=cpu_to_use[j];
Packit 577717
		rapl_native_events[i].msr=MSR_PKG_POWER_INFO;
Packit 577717
		rapl_native_events[i].resources.selector = i + 1;
Packit 577717
		rapl_native_events[i].type=PACKAGE_TIME_WINDOW_CNT;
Packit 577717
		rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
		sprintf(rapl_native_events[k].name,
Packit 577717
			"MAXIMUM_TIME_WINDOW:PACKAGE%d",j);
Packit 577717
		strncpy(rapl_native_events[k].units,"s",PAPI_MIN_STR_LEN);
Packit 577717
		sprintf(rapl_native_events[k].description,
Packit 577717
		   "Maximum time window for package %d",j);
Packit 577717
		rapl_native_events[k].fd_offset=cpu_to_use[j];
Packit 577717
		rapl_native_events[k].msr=MSR_PKG_POWER_INFO;
Packit 577717
		rapl_native_events[k].resources.selector = k + 1;
Packit 577717
		rapl_native_events[k].type=PACKAGE_TIME_WINDOW;
Packit 577717
		rapl_native_events[k].return_type=PAPI_DATATYPE_FP64;
Packit 577717
Packit 577717
		i++;
Packit 577717
		k++;
Packit 577717
     }
Packit 577717
Packit 577717
     /* Create Events for energy measurements */
Packit 577717
Packit 577717
     if (package_avail) {
Packit 577717
        for(j=0;j
Packit 577717
	   		sprintf(rapl_native_events[i].name,
Packit 577717
		   		"PACKAGE_ENERGY_CNT:PACKAGE%d",j);
Packit 577717
	   		sprintf(rapl_native_events[i].description,
Packit 577717
		   		"Energy used in counts by chip package %d",j);
Packit 577717
	   		rapl_native_events[i].fd_offset=cpu_to_use[j];
Packit 577717
	   		rapl_native_events[i].msr=MSR_PKG_ENERGY_STATUS;
Packit 577717
	   		rapl_native_events[i].resources.selector = i + 1;
Packit 577717
	   		rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
Packit 577717
	   		rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
	   		sprintf(rapl_native_events[k].name,
Packit 577717
		   		"PACKAGE_ENERGY:PACKAGE%d",j);
Packit 577717
	   		strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
Packit 577717
	   		sprintf(rapl_native_events[k].description,
Packit 577717
		   		"Energy used by chip package %d",j);
Packit 577717
	   		rapl_native_events[k].fd_offset=cpu_to_use[j];
Packit 577717
	   		rapl_native_events[k].msr=MSR_PKG_ENERGY_STATUS;
Packit 577717
	   		rapl_native_events[k].resources.selector = k + 1;
Packit 577717
	   		rapl_native_events[k].type=PACKAGE_ENERGY;
Packit 577717
	   		rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
	   		i++;
Packit 577717
			k++;
Packit 577717
		}
Packit 577717
     }
Packit 577717
Packit 577717
     if (pp1_avail) {
Packit 577717
        for(j=0;j
Packit 577717
	   		sprintf(rapl_native_events[i].name,
Packit 577717
		   		"PP1_ENERGY_CNT:PACKAGE%d",j);
Packit 577717
	   		sprintf(rapl_native_events[i].description,
Packit 577717
		   		"Energy used in counts by Power Plane 1 (Often GPU) on package %d",j);
Packit 577717
           	rapl_native_events[i].fd_offset=cpu_to_use[j];
Packit 577717
	   		rapl_native_events[i].msr=MSR_PP1_ENERGY_STATUS;
Packit 577717
	   		rapl_native_events[i].resources.selector = i + 1;
Packit 577717
	   		rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
Packit 577717
	   		rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
	   		sprintf(rapl_native_events[k].name,
Packit 577717
		   		"PP1_ENERGY:PACKAGE%d",j);
Packit 577717
	   		strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
Packit 577717
	   		sprintf(rapl_native_events[k].description,
Packit 577717
		   		"Energy used by Power Plane 1 (Often GPU) on package %d",j);
Packit 577717
           	rapl_native_events[k].fd_offset=cpu_to_use[j];
Packit 577717
	   		rapl_native_events[k].msr=MSR_PP1_ENERGY_STATUS;
Packit 577717
	   		rapl_native_events[k].resources.selector = k + 1;
Packit 577717
	   		rapl_native_events[k].type=PACKAGE_ENERGY;
Packit 577717
	   		rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
	   		i++;
Packit 577717
			k++;
Packit 577717
		}
Packit 577717
     }
Packit 577717
Packit 577717
     if (dram_avail) {
Packit 577717
        for(j=0;j
Packit 577717
	   		sprintf(rapl_native_events[i].name,
Packit 577717
		   		"DRAM_ENERGY_CNT:PACKAGE%d",j);
Packit 577717
           	sprintf(rapl_native_events[i].description,
Packit 577717
		   		"Energy used in counts by DRAM on package %d",j);
Packit 577717
	   		rapl_native_events[i].fd_offset=cpu_to_use[j];
Packit 577717
	   		rapl_native_events[i].msr=MSR_DRAM_ENERGY_STATUS;
Packit 577717
	   		rapl_native_events[i].resources.selector = i + 1;
Packit 577717
	   		rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
Packit 577717
	   		rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
	   		sprintf(rapl_native_events[k].name,
Packit 577717
		   		"DRAM_ENERGY:PACKAGE%d",j);
Packit 577717
	   		strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
Packit 577717
           	sprintf(rapl_native_events[k].description,
Packit 577717
		   		"Energy used by DRAM on package %d",j);
Packit 577717
	   		rapl_native_events[k].fd_offset=cpu_to_use[j];
Packit 577717
	   		rapl_native_events[k].msr=MSR_DRAM_ENERGY_STATUS;
Packit 577717
	   		rapl_native_events[k].resources.selector = k + 1;
Packit 577717
	   		rapl_native_events[k].type=DRAM_ENERGY;
Packit 577717
	   		rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
	   		i++;
Packit 577717
			k++;
Packit 577717
		}
Packit 577717
     }
Packit 577717
Packit 577717
     if (psys_avail) {
Packit 577717
        for(j=0;j
Packit 577717
Packit 577717
	   		sprintf(rapl_native_events[i].name,
Packit 577717
		   		"PSYS_ENERGY_CNT:PACKAGE%d",j);
Packit 577717
           	sprintf(rapl_native_events[i].description,
Packit 577717
		   		"Energy used in counts by SoC on package %d",j);
Packit 577717
	   		rapl_native_events[i].fd_offset=cpu_to_use[j];
Packit 577717
	   		rapl_native_events[i].msr=MSR_PLATFORM_ENERGY_STATUS;
Packit 577717
	   		rapl_native_events[i].resources.selector = i + 1;
Packit 577717
	   		rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
Packit 577717
	   		rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
	   		sprintf(rapl_native_events[k].name,
Packit 577717
		   		"PSYS_ENERGY:PACKAGE%d",j);
Packit 577717
	   		strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
Packit 577717
           	sprintf(rapl_native_events[k].description,
Packit 577717
		   		"Energy used by SoC on package %d",j);
Packit 577717
	   		rapl_native_events[k].fd_offset=cpu_to_use[j];
Packit 577717
	   		rapl_native_events[k].msr=MSR_PLATFORM_ENERGY_STATUS;
Packit 577717
	   		rapl_native_events[k].resources.selector = k + 1;
Packit 577717
	   		rapl_native_events[k].type=PLATFORM_ENERGY;
Packit 577717
	   		rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
			i++;
Packit 577717
			k++;
Packit 577717
		}
Packit 577717
     }
Packit 577717
Packit 577717
     if (pp0_avail) {
Packit 577717
        for(j=0;j
Packit 577717
			sprintf(rapl_native_events[i].name,
Packit 577717
		   		"PP0_ENERGY_CNT:PACKAGE%d",j);
Packit 577717
	   		sprintf(rapl_native_events[i].description,
Packit 577717
		   		"Energy used in counts by all cores in package %d",j);
Packit 577717
	   		rapl_native_events[i].fd_offset=cpu_to_use[j];
Packit 577717
	   		rapl_native_events[i].msr=MSR_PP0_ENERGY_STATUS;
Packit 577717
	   		rapl_native_events[i].resources.selector = i + 1;
Packit 577717
	   		rapl_native_events[i].type=PACKAGE_ENERGY_CNT;
Packit 577717
	   		rapl_native_events[i].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
			sprintf(rapl_native_events[k].name,
Packit 577717
		   		"PP0_ENERGY:PACKAGE%d",j);
Packit 577717
	   		strncpy(rapl_native_events[k].units,"nJ",PAPI_MIN_STR_LEN);
Packit 577717
	   		sprintf(rapl_native_events[k].description,
Packit 577717
		   		"Energy used by all cores in package %d",j);
Packit 577717
	   		rapl_native_events[k].fd_offset=cpu_to_use[j];
Packit 577717
	   		rapl_native_events[k].msr=MSR_PP0_ENERGY_STATUS;
Packit 577717
	   		rapl_native_events[k].resources.selector = k + 1;
Packit 577717
	   		rapl_native_events[k].type=PACKAGE_ENERGY;
Packit 577717
	   		rapl_native_events[k].return_type=PAPI_DATATYPE_UINT64;
Packit 577717
Packit 577717
	   		i++;
Packit 577717
			k++;
Packit 577717
		}
Packit 577717
     }
Packit 577717
Packit 577717
     /* Export the total number of events available */
Packit 577717
     _rapl_vector.cmp_info.num_native_events = num_events;
Packit 577717
Packit 577717
     _rapl_vector.cmp_info.num_cntrs = num_events;
Packit 577717
     _rapl_vector.cmp_info.num_mpx_cntrs = num_events;
Packit 577717
Packit 577717
Packit 577717
     /* Export the component id */
Packit 577717
     _rapl_vector.cmp_info.CmpIdx = cidx;
Packit 577717
Packit 577717
     return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Control of counters (Reading/Writing/Starting/Stopping/Setup)
Packit 577717
 * functions
Packit 577717
 */
Packit 577717
static int
Packit 577717
_rapl_init_control_state( hwd_control_state_t *ctl)
Packit 577717
{
Packit 577717
Packit 577717
  _rapl_control_state_t* control = (_rapl_control_state_t*) ctl;
Packit 577717
  int i;
Packit 577717
Packit 577717
  for(i=0;i
Packit 577717
     control->being_measured[i]=0;
Packit 577717
  }
Packit 577717
Packit 577717
  return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
static int
Packit 577717
_rapl_start( hwd_context_t *ctx, hwd_control_state_t *ctl)
Packit 577717
{
Packit 577717
  _rapl_context_t* context = (_rapl_context_t*) ctx;
Packit 577717
  _rapl_control_state_t* control = (_rapl_control_state_t*) ctl;
Packit 577717
  long long now = PAPI_get_real_usec();
Packit 577717
  int i;
Packit 577717
Packit 577717
  for( i = 0; i < RAPL_MAX_COUNTERS; i++ ) {
Packit 577717
     if ((control->being_measured[i]) && (control->need_difference[i])) {
Packit 577717
        context->start_value[i]=read_rapl_value(i);
Packit 577717
     }
Packit 577717
  }
Packit 577717
Packit 577717
  control->lastupdate = now;
Packit 577717
Packit 577717
  return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
static int
Packit 577717
_rapl_stop( hwd_context_t *ctx, hwd_control_state_t *ctl )
Packit 577717
{
Packit 577717
Packit 577717
    /* read values */
Packit 577717
    _rapl_context_t* context = (_rapl_context_t*) ctx;
Packit 577717
    _rapl_control_state_t* control = (_rapl_control_state_t*) ctl;
Packit 577717
    long long now = PAPI_get_real_usec();
Packit 577717
    int i;
Packit 577717
    long long temp;
Packit 577717
Packit 577717
    for ( i = 0; i < RAPL_MAX_COUNTERS; i++ ) {
Packit 577717
		if (control->being_measured[i]) {
Packit 577717
			temp = read_rapl_value(i);
Packit 577717
			if (context->start_value[i])
Packit 577717
			if (control->need_difference[i]) {
Packit 577717
				/* test for wrap around */
Packit 577717
				if (temp < context->start_value[i] ) {
Packit 577717
	        		SUBDBG("Wraparound!\nstart:\t%#016x\ttemp:\t%#016x",
Packit 577717
	        			(unsigned)context->start_value[i], (unsigned)temp);
Packit 577717
	           		temp += (0x100000000 - context->start_value[i]);
Packit 577717
	           		SUBDBG("\tresult:\t%#016x\n", (unsigned)temp);
Packit 577717
		  		} else {
Packit 577717
					temp -= context->start_value[i];
Packit 577717
		  		}
Packit 577717
			}
Packit 577717
			control->count[i] = convert_rapl_energy( i, temp );
Packit 577717
		}
Packit 577717
    }
Packit 577717
    control->lastupdate = now;
Packit 577717
    return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
/* Shutdown a thread */
Packit 577717
static int
Packit 577717
_rapl_shutdown_thread( hwd_context_t *ctx )
Packit 577717
{
Packit 577717
  ( void ) ctx;
Packit 577717
  return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
_rapl_read( hwd_context_t *ctx, hwd_control_state_t *ctl,
Packit 577717
	    long long **events, int flags)
Packit 577717
{
Packit 577717
    (void) flags;
Packit 577717
Packit 577717
    _rapl_stop( ctx, ctl );
Packit 577717
Packit 577717
    /* Pass back a pointer to our results */
Packit 577717
    *events = ((_rapl_control_state_t*) ctl)->count;
Packit 577717
Packit 577717
    return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Clean up what was setup in  rapl_init_component().
Packit 577717
 */
Packit 577717
static int
Packit 577717
_rapl_shutdown_component( void )
Packit 577717
{
Packit 577717
    int i;
Packit 577717
Packit 577717
    if (rapl_native_events) papi_free(rapl_native_events);
Packit 577717
    if (fd_array) {
Packit 577717
       for(i=0;i
Packit 577717
	  if (fd_array[i].open) close(fd_array[i].fd);
Packit 577717
       }
Packit 577717
       papi_free(fd_array);
Packit 577717
    }
Packit 577717
Packit 577717
    return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/* This function sets various options in the component
Packit 577717
 * The valid codes being passed in are PAPI_SET_DEFDOM,
Packit 577717
 * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
Packit 577717
 */
Packit 577717
static int
Packit 577717
_rapl_ctl( hwd_context_t *ctx, int code, _papi_int_option_t *option )
Packit 577717
{
Packit 577717
    ( void ) ctx;
Packit 577717
    ( void ) code;
Packit 577717
    ( void ) option;
Packit 577717
Packit 577717
    return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
static int
Packit 577717
_rapl_update_control_state( hwd_control_state_t *ctl,
Packit 577717
			    NativeInfo_t *native, int count,
Packit 577717
			    hwd_context_t *ctx )
Packit 577717
{
Packit 577717
  int i, index;
Packit 577717
    ( void ) ctx;
Packit 577717
Packit 577717
    _rapl_control_state_t* control = (_rapl_control_state_t*) ctl;
Packit 577717
Packit 577717
    /* Ugh, what is this native[] stuff all about ?*/
Packit 577717
    /* Mostly remap stuff in papi_internal */
Packit 577717
Packit 577717
    for(i=0;i
Packit 577717
       control->being_measured[i]=0;
Packit 577717
    }
Packit 577717
Packit 577717
    for( i = 0; i < count; i++ ) {
Packit 577717
       index=native[i].ni_event&PAPI_NATIVE_AND_MASK;
Packit 577717
       native[i].ni_position=rapl_native_events[index].resources.selector - 1;
Packit 577717
       control->being_measured[index]=1;
Packit 577717
Packit 577717
       /* Only need to subtract if it's a PACKAGE_ENERGY or ENERGY_CNT type */
Packit 577717
       control->need_difference[index]=
Packit 577717
	 	(rapl_native_events[index].type==PACKAGE_ENERGY ||
Packit 577717
		rapl_native_events[index].type==DRAM_ENERGY ||
Packit 577717
		rapl_native_events[index].type==PLATFORM_ENERGY ||
Packit 577717
	 	rapl_native_events[index].type==PACKAGE_ENERGY_CNT);
Packit 577717
    }
Packit 577717
Packit 577717
    return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * This function has to set the bits needed to count different domains
Packit 577717
 * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
Packit 577717
 * By default return PAPI_EINVAL if none of those are specified
Packit 577717
 * and PAPI_OK with success
Packit 577717
 * PAPI_DOM_USER is only user context is counted
Packit 577717
 * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
Packit 577717
 * PAPI_DOM_OTHER  is Exception/transient mode (like user TLB misses)
Packit 577717
 * PAPI_DOM_ALL   is all of the domains
Packit 577717
 */
Packit 577717
static int
Packit 577717
_rapl_set_domain( hwd_control_state_t *ctl, int domain )
Packit 577717
{
Packit 577717
    ( void ) ctl;
Packit 577717
Packit 577717
    /* In theory we only support system-wide mode */
Packit 577717
    /* How to best handle that? */
Packit 577717
    if ( PAPI_DOM_ALL != domain )
Packit 577717
	return PAPI_EINVAL;
Packit 577717
Packit 577717
    return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
static int
Packit 577717
_rapl_reset( hwd_context_t *ctx, hwd_control_state_t *ctl )
Packit 577717
{
Packit 577717
    ( void ) ctx;
Packit 577717
    ( void ) ctl;
Packit 577717
Packit 577717
    return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Native Event functions
Packit 577717
 */
Packit 577717
static int
Packit 577717
_rapl_ntv_enum_events( unsigned int *EventCode, int modifier )
Packit 577717
{
Packit 577717
Packit 577717
     int index;
Packit 577717
Packit 577717
     switch ( modifier ) {
Packit 577717
Packit 577717
	case PAPI_ENUM_FIRST:
Packit 577717
Packit 577717
	   if (num_events==0) {
Packit 577717
	      return PAPI_ENOEVNT;
Packit 577717
	   }
Packit 577717
	   *EventCode = 0;
Packit 577717
Packit 577717
	   return PAPI_OK;
Packit 577717
Packit 577717
Packit 577717
	case PAPI_ENUM_EVENTS:
Packit 577717
Packit 577717
	   index = *EventCode & PAPI_NATIVE_AND_MASK;
Packit 577717
Packit 577717
	   if ( index < num_events - 1 ) {
Packit 577717
	      *EventCode = *EventCode + 1;
Packit 577717
	      return PAPI_OK;
Packit 577717
	   } else {
Packit 577717
	      return PAPI_ENOEVNT;
Packit 577717
	   }
Packit 577717
	   break;
Packit 577717
Packit 577717
	default:
Packit 577717
		return PAPI_EINVAL;
Packit 577717
	}
Packit 577717
Packit 577717
	return PAPI_EINVAL;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
static int
Packit 577717
_rapl_ntv_code_to_name( unsigned int EventCode, char *name, int len )
Packit 577717
{
Packit 577717
Packit 577717
     int index = EventCode & PAPI_NATIVE_AND_MASK;
Packit 577717
Packit 577717
     if ( index >= 0 && index < num_events ) {
Packit 577717
	strncpy( name, rapl_native_events[index].name, len );
Packit 577717
	return PAPI_OK;
Packit 577717
     }
Packit 577717
Packit 577717
     return PAPI_ENOEVNT;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 *
Packit 577717
 */
Packit 577717
static int
Packit 577717
_rapl_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
Packit 577717
{
Packit 577717
     int index = EventCode;
Packit 577717
Packit 577717
     if ( index >= 0 && index < num_events ) {
Packit 577717
	strncpy( name, rapl_native_events[index].description, len );
Packit 577717
	return PAPI_OK;
Packit 577717
     }
Packit 577717
     return PAPI_ENOEVNT;
Packit 577717
}
Packit 577717
Packit 577717
static int
Packit 577717
_rapl_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info) 
Packit 577717
{
Packit 577717
Packit 577717
  int index = EventCode;
Packit 577717
Packit 577717
  if ( ( index < 0) || (index >= num_events )) return PAPI_ENOEVNT;
Packit 577717
Packit 577717
  strncpy( info->symbol, rapl_native_events[index].name, sizeof(info->symbol)-1);
Packit 577717
  info->symbol[sizeof(info->symbol)-1] = '\0';
Packit 577717
Packit 577717
  strncpy( info->long_descr, rapl_native_events[index].description, sizeof(info->long_descr)-1);
Packit 577717
  info->long_descr[sizeof(info->long_descr)-1] = '\0';
Packit 577717
Packit 577717
  strncpy( info->units, rapl_native_events[index].units, sizeof(info->units)-1);
Packit 577717
  info->units[sizeof(info->units)-1] = '\0';
Packit 577717
Packit 577717
  info->data_type = rapl_native_events[index].return_type;
Packit 577717
Packit 577717
  return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
Packit 577717
papi_vector_t _rapl_vector = {
Packit 577717
    .cmp_info = { /* (unspecified values are initialized to 0) */
Packit 577717
       .name = "rapl",
Packit 577717
       .short_name = "rapl",
Packit 577717
       .description = "Linux RAPL energy measurements",
Packit 577717
       .version = "5.3.0",
Packit 577717
       .default_domain = PAPI_DOM_ALL,
Packit 577717
       .default_granularity = PAPI_GRN_SYS,
Packit 577717
       .available_granularities = PAPI_GRN_SYS,
Packit 577717
       .hardware_intr_sig = PAPI_INT_SIGNAL,
Packit 577717
       .available_domains = PAPI_DOM_ALL,
Packit 577717
    },
Packit 577717
Packit 577717
	/* sizes of framework-opaque component-private structures */
Packit 577717
    .size = {
Packit 577717
	.context = sizeof ( _rapl_context_t ),
Packit 577717
	.control_state = sizeof ( _rapl_control_state_t ),
Packit 577717
	.reg_value = sizeof ( _rapl_register_t ),
Packit 577717
	.reg_alloc = sizeof ( _rapl_reg_alloc_t ),
Packit 577717
    },
Packit 577717
	/* function pointers in this component */
Packit 577717
    .init_thread =          _rapl_init_thread,
Packit 577717
    .init_component =       _rapl_init_component,
Packit 577717
    .init_control_state =   _rapl_init_control_state,
Packit 577717
    .start =                _rapl_start,
Packit 577717
    .stop =                 _rapl_stop,
Packit 577717
    .read =                 _rapl_read,
Packit 577717
    .shutdown_thread =      _rapl_shutdown_thread,
Packit 577717
    .shutdown_component =   _rapl_shutdown_component,
Packit 577717
    .ctl =                  _rapl_ctl,
Packit 577717
Packit 577717
    .update_control_state = _rapl_update_control_state,
Packit 577717
    .set_domain =           _rapl_set_domain,
Packit 577717
    .reset =                _rapl_reset,
Packit 577717
Packit 577717
    .ntv_enum_events =      _rapl_ntv_enum_events,
Packit 577717
    .ntv_code_to_name =     _rapl_ntv_code_to_name,
Packit 577717
    .ntv_code_to_descr =    _rapl_ntv_code_to_descr,
Packit 577717
    .ntv_code_to_info =     _rapl_ntv_code_to_info,
Packit 577717
};