Skip to content
Snippets Groups Projects
Commit a4721bf7 authored by Stefano Corda's avatar Stefano Corda
Browse files

Merge branch 'cray-new' into 'master'

Cray System support

See merge request !30
parents 26f5b534 4a53521e
No related branches found
No related tags found
1 merge request!30Cray System support
Pipeline #56314 passed
...@@ -12,6 +12,11 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) ...@@ -12,6 +12,11 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
CACHE STRING "Default build type." FORCE) CACHE STRING "Default build type." FORCE)
endif() endif()
#Set CXX Standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Set debug print info # Set debug print info
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
...@@ -96,6 +101,9 @@ add_subdirectory(common) ...@@ -96,6 +101,9 @@ add_subdirectory(common)
# PMT library # PMT library
add_library(pmt SHARED $<TARGET_OBJECTS:pmt-common>) add_library(pmt SHARED $<TARGET_OBJECTS:pmt-common>)
#Cray
add_subdirectory(cray)
# PowerSensor # PowerSensor
if(${BUILD_POWERSENSOR2_PMT}) if(${BUILD_POWERSENSOR2_PMT})
add_subdirectory(powersensor2) add_subdirectory(powersensor2)
......
project(cray)
add_library(pmt-cray OBJECT Cray.cpp FilenamesHelper.cpp)
target_link_libraries(pmt-cray Threads::Threads)
target_include_directories(pmt-cray PRIVATE)
install(FILES Cray.h DESTINATION include/pmt)
add_executable(Cray-test Cray-test.cpp)
target_link_libraries(Cray-test $<TARGET_OBJECTS:pmt-common> pmt-cray)
install(TARGETS Cray-test RUNTIME DESTINATION bin)
target_link_libraries(pmt PUBLIC pmt-cray)
#include "../common/pmt-test.h"
#include "Cray.h"
int main(int argc, char *argv[]) {
auto sensor = pmt::cray::Cray::Create();
run(*sensor, argc, argv);
}
#include "Cray.h"
namespace {
double GetPower(const std::string& filePath) {
std::ifstream powerFile(filePath);
if (!powerFile.is_open()) {
throw std::runtime_error("Failed to open power file");
}
std::string line;
if (!std::getline(powerFile, line)) {
throw std::runtime_error("Failed to read power value");
}
double power;
try {
power = std::stod(line);
} catch (const std::exception& e) {
throw std::runtime_error("Failed to parse power value");
}
powerFile.close();
return power;
}
} // namespace
namespace pmt::cray {
class CrayImpl : public Cray {
public:
CrayImpl();
~CrayImpl();
State GetState() override;
private:
std::vector<std::string> filenames;
std::string cray_pm_counters_path = "/sys/cray/pm_counters";
double previous_timestamp_;
std::vector<CrayMeasurement> previous_measurements_;
// Mutex used to guard GetMeasurements()
std::mutex mutex_;
virtual const char* GetDumpFilename() { return "/tmp/pmt_cray.out"; }
virtual int GetMeasurementInterval() {
return 100; // milliseconds
}
unsigned int device_number_;
std::vector<CrayMeasurement> GetMeasurements();
};
std::unique_ptr<Cray> Cray::Create() { return std::make_unique<CrayImpl>(); }
CrayImpl::CrayImpl() {
filenames = filenames_helper::GetFilenames(cray_pm_counters_path);
filenames = filenames_helper::ReorderFilenames(filenames);
#if defined(DEBUG)
filenames_helper::PrintFilenames(filenames);
#endif
previous_timestamp_ = GetTime();
previous_measurements_ = GetMeasurements();
}
std::vector<CrayMeasurement> CrayImpl::GetMeasurements() {
std::lock_guard<std::mutex> lock(mutex_);
std::vector<CrayMeasurement> measurements;
std::string file_path = "";
for (const auto& filename : filenames) {
file_path = cray_pm_counters_path + "/" + filename;
CrayMeasurement measurement;
measurement.name = filename;
measurement.watt = GetPower(file_path);
measurements.push_back(measurement);
}
return measurements;
}
State CrayImpl::GetState() {
std::vector<CrayMeasurement> measurements = GetMeasurements();
State state(measurements.size());
state.timestamp_ = GetTime();
const double duration = (state.timestamp_ - previous_timestamp_);
for (size_t i = 0; i < measurements.size(); i++) {
state.name_[i] = measurements[i].name;
state.watt_[i] = measurements[i].watt;
const double watt =
(measurements[i].watt + previous_measurements_[i].watt) / 2;
state.joules_[i] += watt * duration;
}
return state;
}
} // end namespace pmt::cray
#ifndef CRAY_PMT_H
#define CRAY_PMT_H
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>
#include "FilenamesHelper.h"
#include "pmt.h"
namespace pmt {
namespace cray {
struct CrayMeasurement {
std::string name;
size_t watt;
};
class Cray : public PMT {
public:
static std::unique_ptr<Cray> Create();
};
} // end namespace cray
} // end namespace pmt
#endif
#include "FilenamesHelper.h"
namespace filenames_helper {
void PrintFilenames(std::vector<std::string> filenames) {
for (const auto& filename : filenames) {
std::cout << filename << "\t";
}
std::cout << std::endl;
}
std::vector<std::string> GetFilenames(std::string folder_path) {
std::vector<std::string> filenames;
if (std::filesystem::is_directory(folder_path)) {
for (const auto& entry : std::filesystem::directory_iterator(folder_path)) {
if (std::filesystem::is_regular_file(entry)) {
std::string filename = entry.path().filename().string();
if (filename.find("power") != std::string::npos &&
filename.find("cap") == std::string::npos) {
filenames.push_back(filename);
}
}
}
} else {
std::cerr << "Not a valid directory: " << folder_path << std::endl;
}
return filenames;
}
std::vector<std::string> OrderStringsAlphabetically(
const std::vector<std::string>& input_strings) {
std::vector<std::string> ordered_strings =
input_strings; // Make a copy to preserve the original
// Use the sort function to order the strings alphabetically
std::sort(ordered_strings.begin(), ordered_strings.end());
return ordered_strings;
}
std::vector<std::string> ExtractStringsContainingSubstring(
const std::vector<std::string>& string_vector,
const std::string& substring) {
std::vector<std::string> extracted_strings;
for (const std::string& str : string_vector) {
if (str.find(substring) != std::string::npos) {
extracted_strings.push_back(str);
}
}
return extracted_strings;
}
std::string PopString(std::vector<std::string>& string_vector,
const std::string& string_to_pop) {
auto it =
std::find(string_vector.begin(), string_vector.end(), string_to_pop);
if (it != string_vector.end()) {
std::string popped_value = *it;
string_vector.erase(it);
return popped_value;
} else {
return ""; // Return an empty string if string_to_pop is not found
}
}
void HandleFilenamesWithSubstring(std::vector<std::string>& ordered_filenames,
std::vector<std::string>& filenames,
const std::string& substring) {
std::vector<std::string> matching_filenames =
ExtractStringsContainingSubstring(filenames, substring);
std::vector<std::string> ordered_matching_filenames =
OrderStringsAlphabetically(matching_filenames);
for (const auto& matching_filename : ordered_matching_filenames) {
ordered_filenames.push_back(PopString(filenames, matching_filename));
}
}
std::vector<std::string> ReorderFilenames(std::vector<std::string> filenames) {
std::vector<std::string> ordered_filenames;
// Handle "power" filenames
std::string tmp_string = PopString(filenames, "power");
if (!tmp_string.empty()) {
ordered_filenames.push_back(tmp_string);
}
// Define the substrings to look for and corresponding sorting priority
std::vector<std::string> substrings = {"cpu", "memory", "accel"};
// Handle filenames with each substring
for (const auto& substring : substrings) {
HandleFilenamesWithSubstring(ordered_filenames, filenames, substring);
}
// Add any remaining filenames to the ordered list
for (const auto& filename : filenames) {
ordered_filenames.push_back(filename);
}
return ordered_filenames;
}
} // end namespace filenames_helper
\ No newline at end of file
#ifndef FILENAMES_HELPER_PMT_H
#define FILENAMES_HELPER_PMT_H
#include <algorithm>
#include <iostream>
#include <filesystem>
#include <vector>
namespace filenames_helper {
//For debug only
void PrintFilenames(std::vector<std::string> filenames);
std::vector<std::string> GetFilenames(std::string folder_path);
std::vector<std::string> OrderStringsAlphabetically(const std::vector<std::string>& input_strings);
std::vector<std::string> ExtractStringsContainingSubstring(const std::vector<std::string>& string_vector, const std::string& substring);
std::string PopString(std::vector<std::string>& string_vector, const std::string& string_to_pop);
void HandleFilenamesWithSubstring(std::vector<std::string>& ordered_filenames, std::vector<std::string>& filenames, const std::string& substring);
std::vector<std::string> ReorderFilenames(std::vector<std::string> filenames);
} // end namespace filenames_helper
#endif
...@@ -8,6 +8,7 @@ target_link_libraries( ...@@ -8,6 +8,7 @@ target_link_libraries(
pybind11::lto pybind11::lto
pybind11::windows_extras pybind11::windows_extras
$<TARGET_OBJECTS:pmt-common> $<TARGET_OBJECTS:pmt-common>
pmt-cray
pmt-dummy pmt-dummy
pmt-tegra pmt-tegra
pmt-rapl pmt-rapl
......
...@@ -2,7 +2,9 @@ import pypmt ...@@ -2,7 +2,9 @@ import pypmt
def get_pmt(platform, device_id=0): def get_pmt(platform, device_id=0):
if platform in ['powersensor2', 'powersensor3']: if platform == "cray":
return pypmt.Cray.create()
elif platform in ['powersensor2', 'powersensor3']:
try: try:
return pypmt.PowerSensor_.create(device_id, 2) return pypmt.PowerSensor_.create(device_id, 2)
except AttributeError: except AttributeError:
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
#include <../common/pmt.h> #include <../common/pmt.h>
#include <../cray/Cray.h>
#ifdef BUILD_POWERSENSOR2 #ifdef BUILD_POWERSENSOR2
#include <../powersensor2/PowerSensor2.h> #include <../powersensor2/PowerSensor2.h>
#endif #endif
...@@ -37,6 +39,12 @@ PYBIND11_MODULE(pypmt, m) { ...@@ -37,6 +39,12 @@ PYBIND11_MODULE(pypmt, m) {
py::class_<pmt::State>(m, "State"); py::class_<pmt::State>(m, "State");
py::class_<pmt::cray::Cray>(m, "Cray")
.def("create", &pmt::cray::Cray::Create)
.def("read", &pmt::cray::Cray::Read)
.def("startDump", &pmt::cray::Cray::StartDump)
.def("stopDump", &pmt::cray::Cray::StopDump);
#ifdef BUILD_POWERSENSOR2 #ifdef BUILD_POWERSENSOR2
py::class_<pmt::powersensor2::PowerSensor2>(m, "PowerSensor2") py::class_<pmt::powersensor2::PowerSensor2>(m, "PowerSensor2")
.def("create", &pmt::powersensor2::PowerSensor2::Create) .def("create", &pmt::powersensor2::PowerSensor2::Create)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment