From 53a0b94810e1e0db696f16d9e5f12c186cbd69e3 Mon Sep 17 00:00:00 2001 From: Kevin Huck Date: Mon, 3 Jun 2019 11:45:58 -0700 Subject: [PATCH] Adding PAPI RAPL power measurement --- src/apex/apex_options.cpp | 1 + src/apex/proc_read.cpp | 117 ++++++++++++++++++++++++++++++++++++++ src/apex/proc_read.h | 15 +++++ 3 files changed, 133 insertions(+) diff --git a/src/apex/apex_options.cpp b/src/apex/apex_options.cpp index 2e2c557c..9e373caa 100644 --- a/src/apex/apex_options.cpp +++ b/src/apex/apex_options.cpp @@ -150,6 +150,7 @@ namespace apex void apex_options::make_default_config() { apex* instance = apex::instance(); + APEX_UNUSED(instance); apex_options& options = apex_options::instance(); std::ofstream conf_file(config_file_name, std::ofstream::out); if(conf_file.good()) { diff --git a/src/apex/proc_read.cpp b/src/apex/proc_read.cpp index 4611cd98..d56adb6b 100644 --- a/src/apex/proc_read.cpp +++ b/src/apex/proc_read.cpp @@ -46,6 +46,98 @@ using namespace std; namespace apex { +#if defined(APEX_HAVE_PAPI) + +#include "papi.h" + +static bool papi_initialized = false; +static int EventSet = PAPI_NULL; + +void initialize_papi_events(void) { + char events[6][BUFSIZ] = { + "PACKAGE_ENERGY:PACKAGE0", + "PACKAGE_ENERGY:PACKAGE1", + "DRAM_ENERGY:PACKAGE0", + "DRAM_ENERGY:PACKAGE1", + "PP0_ENERGY:PACKAGE0", + "PP0_ENERGY:PACKAGE1" + }; + // get the PAPI components + int num_components = PAPI_num_components(); + const PAPI_component_info_t *comp_info; + bool comp_found = false; + // are there any components? + for (int i = 0 ; i < num_components ; i++) { + comp_info = PAPI_get_component_info(i); + if (comp_info == NULL) { + fprintf(stderr, "PAPI component info unavailable, no power measurements will be done.\n"); + return; + } + // do we have the RAPL components? + if (strstr(comp_info->name, "linux-rapl")) { + printf("PAPI RAPL component found...\n"); + if (comp_info->num_native_events == 0) { + fprintf(stderr, "No RAPL events found.\n"); + return; + } + comp_found = true; + break; + } + } + if (!comp_found) { + return; + } + int retval = PAPI_create_eventset(&EventSet); + if (retval != PAPI_OK) { + fprintf(stderr, "Error creating PAPI eventset.\n"); + return; + } + for (int i = 0 ; i < 6 ; i++) { + retval = PAPI_add_named_event(EventSet, events[i]); + if (retval != PAPI_OK) { + fprintf(stderr, "Error adding PAPI event.\n"); + return; + } + } + retval = PAPI_start(EventSet); + if (retval != PAPI_OK) { + fprintf(stderr, "Error starting PAPI eventset.\n"); + return; + } + papi_initialized = true; +} + +void read_papi_power(ProcData * data) { + if (papi_initialized == false) { + data->package_energy_package0 = 0LL; + data->package_energy_package1 = 0LL; + data->dram_energy_package0 = 0LL; + data->dram_energy_package1 = 0LL; + data->pp0_energy_package0 = 0LL; + data->pp0_energy_package1 = 0LL; + data->uncore_energy_package0 = 0LL; + data->uncore_energy_package1 = 0LL; + return; + } + long long values[6]; + int retval = PAPI_stop(EventSet, values); + if (retval != PAPI_OK) { + fprintf(stderr, "Error stopping PAPI eventset.\n"); + return; + } + data->package_energy_package0 = values[0]; + data->package_energy_package1 = values[1]; + data->dram_energy_package0 = values[2]; + data->dram_energy_package1 = values[3]; + data->pp0_energy_package0 = values[4]; + data->pp0_energy_package1 = values[5]; + data->uncore_energy_package0 = values[0]-values[4]; + data->uncore_energy_package1 = values[1]-values[5]; + return; +} + +#endif // defined(APEX_HAVE_PAPI) + std::atomic proc_data_reader::done(false); @@ -132,6 +224,9 @@ ProcData* parse_proc_stat(void) { #if defined(APEX_HAVE_POWERCAP_POWER) procData->package0 = read_package0(); procData->dram = read_dram(); +#endif +#if defined(APEX_HAVE_PAPI) + read_papi_power(procData); #endif return procData; } @@ -175,6 +270,16 @@ ProcData* ProcData::diff(ProcData const& rhs) { #if defined(APEX_HAVE_POWERCAP_POWER) d->package0 = package0 - rhs.package0; d->dram = dram - rhs.dram; +#endif +#if defined(APEX_HAVE_PAPI) + d->package_energy_package0 = package_energy_package0 - rhs.package_energy_package0; + d->package_energy_package1 = package_energy_package1 - rhs.package_energy_package1; + d->dram_energy_package0 = dram_energy_package0 - rhs.dram_energy_package0; + d->dram_energy_package1 = dram_energy_package1 - rhs.dram_energy_package1; + d->pp0_energy_package0 = pp0_energy_package0 - rhs.pp0_energy_package0; + d->pp0_energy_package1 = pp0_energy_package1 - rhs.pp0_energy_package1; + d->uncore_energy_package0 = uncore_energy_package0 - rhs.uncore_energy_package0; + d->uncore_energy_package1 = uncore_energy_package1 - rhs.uncore_energy_package1; #endif return d; } @@ -315,6 +420,18 @@ void ProcData::sample_values(void) { sample_value("Package-0 Energy", package0); sample_value("DRAM Energy", dram); #endif +#if defined(APEX_HAVE_PAPI) + if (papi_initialized) { + sample_value("PACKAGE_ENERGY_PACKAGE_0", package_energy_package0); + sample_value("PACKAGE_ENERGY_PACKAGE_1", package_energy_package1); + sample_value("DRAM_ENERGY_PACKAGE_0", dram_energy_package0); + sample_value("DRAM_ENERGY_PACKAGE_1", dram_energy_package1); + sample_value("PP0_ENERGY_PACKAGE_0", pp0_energy_package0); + sample_value("PP0_ENERGY_PACKAGE_1", pp0_energy_package1); + sample_value("UNCORE_ENERGY_PACKAGE_0", uncore_energy_package0); + sample_value("UNCORE_ENERGY_PACKAGE_1", uncore_energy_package1); + } +#endif } bool parse_proc_cpuinfo() { diff --git a/src/apex/proc_read.h b/src/apex/proc_read.h index 56ecb92f..b17cdd33 100644 --- a/src/apex/proc_read.h +++ b/src/apex/proc_read.h @@ -86,6 +86,16 @@ class ProcData { #if defined(APEX_HAVE_POWERCAP_POWER) long long package0; long long dram; +#endif +#if defined(APEX_HAVE_PAPI) + long long package_energy_package0; + long long package_energy_package1; + long long dram_energy_package0; + long long dram_energy_package1; + long long pp0_energy_package0; + long long pp0_energy_package1; + long long uncore_energy_package0; + long long uncore_energy_package1; #endif //softirq 10953997190 0 1380880059 1495447920 1585783785 ... // 15525789 0 12 661586214 0 1519806115 @@ -198,6 +208,11 @@ inline long long read_dram (void) { #endif +#if defined(APEX_HAVE_PAPI) +void initialize_papi_events(void); +void read_papi_power(ProcData * data); +#endif + #ifdef APEX_HAVE_MSR void apex_init_msr(void); void apex_finalize_msr(void);