Skip to content

Commit

Permalink
adapt RAPL to Mac OS X (#43)
Browse files Browse the repository at this point in the history
  • Loading branch information
ranocha authored Sep 26, 2019
1 parent 4bbdc7c commit d30ea04
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 71 deletions.
27 changes: 16 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ PROJECT(toolkitICL)
option(BUILDREL "Official release build" OFF)

if(DEFINED ENV{AMDPROFILERPATH})
message(STATUS "Found AMD profiling driver")
option(USEAMDP "Use AMD Profiling" ON)
add_definitions(-DUSEAMDP)
message(STATUS "Found AMD profiling driver")
option(USEAMDP "Use AMD Profiling" ON)
add_definitions(-DUSEAMDP)
ELSE()
option(USEAMDP "Use AMD Profiling" OFF)
option(USEAMDP "Use AMD Profiling" OFF)
endif()

find_package(CUDA)
Expand All @@ -21,23 +21,24 @@ ELSE()
option(USENVML "Use NVML" OFF)
ENDIF()

IF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
option(USEIRAPL "Use RAPL" OFF)

IF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR APPLE)
option(USEIRAPL "Use RAPL" OFF)
ELSE()
option(USEIRAPL "Use RAPL" ON)
option(USEIRAPL "Use RAPL" ON)
ENDIF()

if(DEFINED ENV{IPG_Dir})
message(STATUS "Found Intel Power Gadget Driver")
IF(DEFINED ENV{IPG_Dir} OR EXISTS "/Library/Frameworks/IntelPowerGadget.framework")
message(STATUS "Found Intel Power Gadget Driver")
option(USEIPG "Use Intel Power Gadget" ON)
option(USEIRAPL "Use RAPL" OFF)
ELSE()
option(USEIPG "Use Intel Power Gadget" OFF)
endif()
ENDIF()

IF(USEIPG)
MESSAGE(STATUS "Using Intel Power Gadget")
add_definitions(-DUSEIPG)
option(USEIRAPL "Use RAPL" OFF)
ENDIF()


Expand Down Expand Up @@ -110,6 +111,10 @@ IF(APPLE)
# Apple does not distribute a cl2.hpp include file and uses another default path for OpenCL
FILE(DOWNLOAD ${CL2_URL} ${CMAKE_CURRENT_SOURCE_DIR}/include/OpenCL/cl2.hpp)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -framework OpenCL")

IF(USEIPG)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -F/Library/Frameworks -framework IntelPowerGadget")
ENDIF()
ENDIF()


Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ To build toolkitCL the following needs to be installed:

For optional power and temperature logging, the following is needed:
- CUDA Toolkit (only for NVidia GPU power/temperature logging)
- Intel Power Gadget (only for Intel CPU/GPU power/temperature logging on Windows systems)
- Intel Power Gadget (only for Intel CPU/GPU power/temperature logging on Windows and Mac OS X systems)
- AMD µProf (only for AMD CPU/GPU power/temperature logging on Windows and Linux systems)

This project uses the common CMake build system. Thus, the following commands can be used on Linux.
Expand Down
25 changes: 24 additions & 1 deletion include/rapl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,30 @@ class Rapl {
bool GetPowerData(int iNode, int iMSR, double *results, int *nResult);
};

#else
#elif defined(USEIPG) /* Mac OS */

#include <unistd.h>

class Rapl {
private:
bool pp1_supported = false;
bool socket1_detected = false;

public:
Rapl();
bool detect_igp();
bool detect_socket1();
uint32_t get_TDP();
int32_t get_NumMSR();
bool GetMsrName(int iMsr, char *pszName);
bool GetMsrFunc(int iMsr, int *funcID);
void sample();
int32_t get_temp0();
int32_t get_temp1();
bool GetPowerData(int iNode, int iMSR, double *results, int *nResult);
};

#else /* probably Linux */

#include <unistd.h>
#include <cstdint>
Expand Down
119 changes: 64 additions & 55 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,17 +339,24 @@ void intel_log_temp_func()
#endif // USEIRAPL


#if defined(_WIN32)
#if defined(USEIPG)
#include "rapl.hpp"

Rapl *rapl;

#if defined(_WIN32)
std::string utf16ToUtf8(const std::wstring& utf16Str)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv;
return conv.to_bytes(utf16Str);
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv;
return conv.to_bytes(utf16Str);
}
#else
#define MAX_PATH 260 /* defined by windows and used below */
std::string utf16ToUtf8(const std::string& utf16Str)
{
return utf16Str;
}
#endif

std::vector<double> intel_power_time;
std::vector<double> intel_temp_time;
Expand Down Expand Up @@ -410,7 +417,6 @@ void intel_log_power_func()
}


#endif
#endif // USEIPG


Expand Down Expand Up @@ -1053,64 +1059,67 @@ int main(int argc, char *argv[]) {
#endif

#if defined(USEIPG)
if (intel_log_power || intel_log_temp)
{
cout << "Using Intel Power Gadget interface..." << endl;
h5_create_dir(out_name, "/housekeeping");
h5_create_dir(out_name, "/housekeeping/intel");
rapl = new Rapl();
}
if (intel_log_power || intel_log_temp) {
cout << "Using Intel Power Gadget interface..." << endl;
h5_create_dir(out_name, "/housekeeping");
h5_create_dir(out_name, "/housekeeping/intel");
rapl = new Rapl();
}

if (intel_log_power)
{
h5_write_single<float>(out_name, "/housekeeping/intel/TDP" , (float)rapl->get_TDP(),
"Thermal Design Power in watt");
if (intel_log_power)
{
h5_write_single<float>(out_name, "/housekeeping/intel/TDP" , (float)rapl->get_TDP(),
"Thermal Design Power in watt");

int numMsrs = rapl->get_NumMSR();
int numMsrs = rapl->get_NumMSR();

//This is necesarry for initalization
rapl->sample();
rapl->sample();
rapl->sample();
//This is necesarry for initalization
rapl->sample();
rapl->sample();
rapl->sample();

for (int j = 0; j < numMsrs; j++)
{
int funcID;
double data[3];
int nData;
wchar_t szName[MAX_PATH];

rapl->GetMsrFunc(j, &funcID);
rapl->GetMsrName(j, szName);

if ((funcID == 1)) {
MSR.push_back(j);
if (utf16ToUtf8(szName) == "Processor") {
MSR_names.push_back("package");
}
else {
if (utf16ToUtf8(szName) == "IA") {
MSR_names.push_back("cores");
}
else {
MSR_names.push_back(utf16ToUtf8(szName));
}
}
}
for (int j = 0; j < numMsrs; j++)
{
int funcID;
double data[3];
int nData;
#if defined(_WIN32)
wchar_t szName[MAX_PATH];
#else
char szName[MAX_PATH];
#endif

//Get Package Power Limit
if ((funcID == 3) ) {
double data[3];
int nData;
rapl->GetPowerData(0, j, data, &nData);
std::string varname = "/housekeeping/intel/" + utf16ToUtf8(szName) + "_power_limit";
h5_write_single<double>(out_name, varname.c_str() , data[0]);
}
rapl->GetMsrFunc(j, &funcID);
rapl->GetMsrName(j, szName);

if ((funcID == 1)) {
MSR.push_back(j);
if (utf16ToUtf8(szName) == "Processor") {
MSR_names.push_back("package");
}
else {
if (utf16ToUtf8(szName) == "IA") {
MSR_names.push_back("cores");
}
else {
MSR_names.push_back(utf16ToUtf8(szName));
}
}
}

//Get Package Power Limit
if ((funcID == 3) ) {
double data[3];
int nData;
rapl->GetPowerData(0, j, data, &nData);
std::string varname = "/housekeeping/intel/" + utf16ToUtf8(szName) + "_power_limit";
h5_write_single<double>(out_name, varname.c_str() , data[0]);
}

}
}
}
std::thread intel_log_power_thread(intel_log_power_func);
std::thread intel_log_temp_thread(intel_log_temp_func);
std::thread intel_log_power_thread(intel_log_power_func);
std::thread intel_log_temp_thread(intel_log_temp_func);
#endif

#if defined(USEIRAPL)
Expand Down
79 changes: 76 additions & 3 deletions src/rapl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@
#define IVYBRIDGE_E 0x306F0
#define SANDYBRIDGE_E 0x206D0

#if defined(_WIN32)

#if defined(_WIN32)

#pragma once
#include <Windows.h>
Expand All @@ -76,7 +76,6 @@
#include <codecvt>



std::wstring Rapl::utf8ToUtf16(const std::string& utf8Str)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv;
Expand Down Expand Up @@ -198,7 +197,81 @@ bool Rapl::GetMsrFunc(int iMsr, int *funcID)
return pGetMsrFunc(iMsr, funcID);
}

#else
#elif defined(USEIPG) /* Mac OS */

#include <unistd.h>

#include <IntelPowerGadget/EnergyLib.h>

Rapl::Rapl()
{
if (IntelEnergyLibInitialize() == false) {
std::cout << "Library error!" << std::endl;
return;
}

pp1_supported = true; /* TODO: Is this assumption reasonable? How can we chack it? */
int numCPUnodes = 99;
GetNumNodes(&numCPUnodes);
if (numCPUnodes > 1) {
socket1_detected = true;
}
}

bool Rapl::detect_igp() {
return pp1_supported;
}

bool Rapl::detect_socket1() {
return socket1_detected;
}

uint32_t Rapl::get_TDP() {
double CPU_TDP=0;
GetTDP(0, &CPU_TDP); /* hardcoded to Socket 0 */
return (uint32_t)round(CPU_TDP);
}

int32_t Rapl::get_NumMSR() {
int32_t nMsrs = 0;
GetNumMsrs(&nMsrs);
return nMsrs;
}


void Rapl::sample() {
ReadSample();
}


int32_t Rapl::get_temp0() {
int degC;
GetTemperature(0, &degC);
return degC;
}

int32_t Rapl::get_temp1() {
int degC;
GetTemperature(1, &degC);
return degC;
}

bool Rapl::GetPowerData(int iNode, int iMSR, double *results, int *nResult)
{
return GetPowerData(iNode, iMSR, results, nResult);
}

bool Rapl::GetMsrName(int iMsr, char *pszName)
{
return GetMsrName(iMsr, pszName);
}

bool Rapl::GetMsrFunc(int iMsr, int *funcID)
{
return GetMsrFunc(iMsr, funcID);
}

#else /* probably Linux */

#include <unistd.h>
#include <sys/time.h>
Expand Down

0 comments on commit d30ea04

Please sign in to comment.