From 062a5f9cae9011d90cbb882adea3b91ba4e9663d Mon Sep 17 00:00:00 2001 From: Federico Sarrocco Date: Fri, 29 Sep 2023 11:20:09 +0200 Subject: [PATCH 01/10] Added NVML functionality test --- CMakeLists.txt | 1 + README.md | 2 + testnvml.zip | Bin 0 -> 87731 bytes testnvml/CMakeLists.txt | 12 +++ testnvml/testnvml.cpp | 195 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 210 insertions(+) create mode 100644 testnvml.zip create mode 100644 testnvml/CMakeLists.txt create mode 100644 testnvml/testnvml.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d4c18fe..a33f933 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ add_subdirectory (konrolib) add_subdirectory (testplatformcontrol) add_subdirectory (testthreadsafequeue) add_subdirectory (testsensors) +add_subdirectory (testnvml) add_subdirectory (testhwloc) add_subdirectory (testkonrolib) add_subdirectory (testtimer) diff --git a/README.md b/README.md index 9e289a5..f9d7b83 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,12 @@ A modern resource manager - libhwloc-dev - libsensors-dev - libopencv-dev +- Cuda Toolkit OpenCV is required only for the peopledetect demo. If it is not installed, peopledetect is not compiled. +Cuda Toolkit is required for the gpu plugin. It can be installed following this link https://developer.nvidia.com/cuda-downloads # Development QtCreator has been used as IDE for development on Ubuntu 22.04.2 LTS. diff --git a/testnvml.zip b/testnvml.zip new file mode 100644 index 0000000000000000000000000000000000000000..82ee4093b7d0d2e8c377d9ccca5e42413f4d4461 GIT binary patch literal 87731 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 z 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 literal 0 HcmV?d00001 diff --git a/testnvml/CMakeLists.txt b/testnvml/CMakeLists.txt new file mode 100644 index 0000000..f1a3770 --- /dev/null +++ b/testnvml/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.21) +set(CMAKE_CXX_STANDARD 14) +file(GLOB testnvml_SOURCES "*.cpp") +file(GLOB testnvml_HEADERS "*.h") + +# Find NVML library without specifying the name +#find_library(NVML_LIBRARY REQUIRED PATHS "/usr/lib/nvidia") +find_package(CUDAToolkit REQUIRED) + +add_executable(testnvml ${testnvml_SOURCES} ${testnvml_HEADERS}) +#target_include_directories(testnvml PRIVATE ${CUDA_INCLUDE_DIRS}) +target_link_libraries(testnvml PRIVATE CUDA::nvml) diff --git a/testnvml/testnvml.cpp b/testnvml/testnvml.cpp new file mode 100644 index 0000000..12092b6 --- /dev/null +++ b/testnvml/testnvml.cpp @@ -0,0 +1,195 @@ +#include +#include + +// Function to handle device-specific operations +void performDeviceOperations(nvmlDevice_t device, unsigned int index) +{ + nvmlReturn_t result; + + char name[NVML_DEVICE_NAME_BUFFER_SIZE]; + result = nvmlDeviceGetName(device, name, NVML_DEVICE_NAME_BUFFER_SIZE); + if (result != NVML_SUCCESS) + { + std::cout << "Device " << index << " - Failed to get device name: " << nvmlErrorString(result) << std::endl; + } + else + { + std::cout << "Device " << index << " name: " << name << std::endl; + +// // turn on the GPU +// result = nvmlDeviceSetPersistenceMode(device, nvmlEnableState_enum::NVML_FEATURE_DISABLED); + + + unsigned int temperature; + result = nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &temperature); + if (result != NVML_SUCCESS) + { + std::cout << "Device " << index << " - Failed to get device temperature: " << nvmlErrorString(result) << std::endl; + } + else + { + std::cout << "Device " << index << " temperature: " << temperature << " [C]" << std::endl; + } + + // Fan speed + unsigned int speed; + result = nvmlDeviceGetFanSpeed(device, &speed); + if (result != NVML_SUCCESS) + { + std::cout << "Device " << index << " - Failed to get device fan speed: " << nvmlErrorString(result) << std::endl; + } + else + { + std::cout << "Device " << index << " fan speed: " << speed << std::endl; + } + // Utilization rate + nvmlUtilization_t utilization; + result = nvmlDeviceGetUtilizationRates(device, &utilization); + if (result != NVML_SUCCESS) + { + std::cout << "Device " << index << " - Failed to get device utilization: " << nvmlErrorString(result) << std::endl; + } + else + { + std::cout << "Device " << index << " utilization: " << utilization.gpu << " [%GPU] " << utilization.memory << " [%memory]" << std::endl; + } + + // Battery info + nvmlPstates_t powerState; + nvmlDeviceGetPowerState(device, &powerState); + if (result != NVML_SUCCESS) + { + std::cout << "Device " << index << " - Failed to get device power state: " << nvmlErrorString(result) << std::endl; + } + else + { + std::cout << "Device " << index << " power state: " << powerState << " [0-15(minimum performance]" << std::endl; + } + + + unsigned int power; + result = nvmlDeviceGetPowerUsage(device, &power); + if (result != NVML_SUCCESS) + { + std::cout << "Device " << index << " - Failed to get device power usage: " << nvmlErrorString(result) << std::endl; + } + else + { + std::cout << "Device " << index << " power usage: " << power << "[mW]" << std::endl; + } + + unsigned int power_limit; + result = nvmlDeviceGetPowerManagementLimit(device, &power_limit); + if (result != NVML_SUCCESS) + { + std::cout << "Device " << index << " - Failed to get device power limit: " << nvmlErrorString(result) << std::endl; + } + else + { + std::cout << "Device " << index << " power limit: " << power_limit << "[mW]" << std::endl; + } + + unsigned int clock; + result = nvmlDeviceGetClockInfo(device, NVML_CLOCK_GRAPHICS, &clock); + if (result != NVML_SUCCESS) + { + std::cout << "Device " << index << " - Failed to get device clock: " << nvmlErrorString(result) << std::endl; + } + else + { + std::cout << "Device " << index << " clock: " << clock << "[MHz]" << std::endl; + } + + // PCI info + nvmlPciInfo_t pci; + result = nvmlDeviceGetPciInfo(device, &pci); + if (result != NVML_SUCCESS) + { + std::cout << "Device " << index << " - Failed to get device PCI info: " << nvmlErrorString(result) << std::endl; + } + else + { + std::cout << "Device " << index << " PCI BUS id: " << pci.busId << std::endl; + } + + // Compute mode + nvmlComputeMode_t compute_mode; + result = nvmlDeviceGetComputeMode(device, &compute_mode); + if (result == NVML_ERROR_NOT_SUPPORTED) + { + std::cout << "This is not a CUDA-capable device" << std::endl; + } + else if (result != NVML_SUCCESS) + { + std::cout << "Device " << index << " - Failed to get device compute mode: " << nvmlErrorString(result) << std::endl; + } + else + { + std::cout << "Device " << index << " compute mode: " << compute_mode << std::endl; + + // Try to change compute mode + std::cout<< "Changing device's compute mode from '" << compute_mode << "' to '" << NVML_COMPUTEMODE_PROHIBITED << "'" << std::endl; + + result = nvmlDeviceSetComputeMode(device, NVML_COMPUTEMODE_PROHIBITED); + if (NVML_ERROR_NO_PERMISSION == result) + std::cout<< "\t\t Need root privileges to do that: " << nvmlErrorString(result) << std::endl; + else if (NVML_ERROR_NOT_SUPPORTED == result) + std::cout<< " Compute mode prohibited not supported. You might be running on\n" + "windows in WDDM driver model or on non-CUDA capable GPU.\n"; + else if (NVML_SUCCESS != result) + { + std::cout << "\t\t Failed to set compute mode for device %i: %s\n" << index << nvmlErrorString(result) << std::endl; + } + else + { + std::cout << "\t\t restored compute mode to '" << compute_mode << "'" << std::endl; + result = nvmlDeviceSetComputeMode(device, compute_mode); + if (NVML_SUCCESS != result) + { + std::cout << "\t\t Failed to restore compute mode for device %i: %s\n" << index << nvmlErrorString(result) << std::endl; + } + } + } + } +} + +int main() +{ + nvmlReturn_t result; + + result = nvmlInit_v2(); + if (result != NVML_SUCCESS) + { + std::cout << "Failed to initialize NVML: " << nvmlErrorString(result) << std::endl; + return 1; + } + + // Get the number of devices + unsigned int nvml_devices; + result = nvmlDeviceGetCount(&nvml_devices); + std::cout << "Found " << nvml_devices << " devices" << std::endl; + + for (unsigned int i = 0; i < nvml_devices; i++) + { + nvmlDevice_t device; + result = nvmlDeviceGetHandleByIndex(i, &device); + if (result != NVML_SUCCESS) + { + std::cout << "Failed to get device handle: " << nvmlErrorString(result) << std::endl; + continue; // Continue with the next device on error + } + + // Perform device-specific operations + performDeviceOperations(device, i); + } + + result = nvmlShutdown(); + + if (result != NVML_SUCCESS) + { + std::cout << "Failed to initialize NVML: " << nvmlErrorString(result) << std::endl; + return 1; + } + + return 0; +} \ No newline at end of file From 1b92b86470084e1a57bddebf63fe4920829d7125 Mon Sep 17 00:00:00 2001 From: Federico Sarrocco Date: Fri, 29 Sep 2023 12:56:33 +0200 Subject: [PATCH 02/10] GPU Monitor implementation --- rm/CMakeLists.txt | 2 + rm/gpumonitor/CMakeLists.txt | 14 ++ rm/gpumonitor/gpumonitor.cpp | 184 ++++++++++++++++++++++++ rm/gpumonitor/gpumonitor.h | 49 +++++++ rm/librmcommon/events/monitorgpuevent.h | 52 +++++++ rm/librmcommon/gpuload.h | 46 ++++++ rm/librmcommon/gpupower.h | 42 ++++++ rm/librmcommon/gputemperature.h | 42 ++++++ rm/src/konromanager.cpp | 19 ++- rm/src/konromanager.h | 1 + testnvml.zip | Bin 87731 -> 0 bytes 11 files changed, 448 insertions(+), 3 deletions(-) create mode 100644 rm/gpumonitor/CMakeLists.txt create mode 100644 rm/gpumonitor/gpumonitor.cpp create mode 100644 rm/gpumonitor/gpumonitor.h create mode 100644 rm/librmcommon/events/monitorgpuevent.h create mode 100644 rm/librmcommon/gpuload.h create mode 100644 rm/librmcommon/gpupower.h create mode 100644 rm/librmcommon/gputemperature.h delete mode 100644 testnvml.zip diff --git a/rm/CMakeLists.txt b/rm/CMakeLists.txt index 21aaab3..cbf9684 100644 --- a/rm/CMakeLists.txt +++ b/rm/CMakeLists.txt @@ -9,6 +9,7 @@ add_subdirectory (platformcontrol) add_subdirectory (workloadmanager) add_subdirectory (policymanager) add_subdirectory (platformmonitor) +add_subdirectory (gpumonitor) file(GLOB konro_SOURCES "src/*.cpp") file(GLOB konro_HEADERS "src/*.h") @@ -24,6 +25,7 @@ target_link_libraries(konro PUBLIC workloadmanager policymanager platformmonitor + gpumonitor ${LOG4CPP_LIBRARIES}) configure_file(konro.ini.in konro.ini) diff --git a/rm/gpumonitor/CMakeLists.txt b/rm/gpumonitor/CMakeLists.txt new file mode 100644 index 0000000..72866e2 --- /dev/null +++ b/rm/gpumonitor/CMakeLists.txt @@ -0,0 +1,14 @@ +set(CMAKE_CXX_STANDARD 14) + +find_package(CUDAToolkit REQUIRED) + +file(GLOB gpumonitor_SOURCES "*.cpp") +file(GLOB gpumonitor_HEADERS "*.h") +add_library(gpumonitor + ${gpumonitor_HEADERS} + ${gpumonitor_SOURCES} +) + +target_include_directories(gpumonitor INTERFACE .) +#target_include_directories(gpumonitor PRIVATE CUDA::nvml) +target_link_libraries(gpumonitor PUBLIC policymanager CUDA::nvml) diff --git a/rm/gpumonitor/gpumonitor.cpp b/rm/gpumonitor/gpumonitor.cpp new file mode 100644 index 0000000..f3d45f9 --- /dev/null +++ b/rm/gpumonitor/gpumonitor.cpp @@ -0,0 +1,184 @@ +#include "gpumonitor.h" +#include +#include +#include +#include +#include +#include +#include +#include "monitorevent.h" +#include "platformtemperature.h" +#include "platformpower.h" +#include "platformload.h" +#include "threadname.h" +#include "tsplit.h" +#include "monitorgpuevent.h" + +using namespace std; + +struct GpuMonitor::GpuMonitorImpl { + unsigned int nvml_devices_; + bool initialized = false; + vector gpuChips; + nvmlReturn_t result; + + + GpuMonitorImpl() { + init(); + } + + ~GpuMonitorImpl() { + fini(); + } + + void init() { + + result = nvmlInit_v2(); + if (result != NVML_SUCCESS) + { + log4cpp::Category::getRoot().info( "Failed to initialize NVML: %s", nvmlErrorString(result)); + this->initialized = false; + }else{ + this->initialized = true; + result = nvmlDeviceGetCount(&nvml_devices_); + for (unsigned int i = 0; i < nvml_devices_; i++) + { + nvmlDevice_t device; + result = nvmlDeviceGetHandleByIndex(i, &device); + if (result != NVML_SUCCESS) + { + log4cpp::Category::getRoot().info( "Failed to get device handle: %s", nvmlErrorString(result)); + continue; // Continue with the next device on error + } + char name[NVML_DEVICE_NAME_BUFFER_SIZE]; + result = nvmlDeviceGetName(device, name, NVML_DEVICE_NAME_BUFFER_SIZE); + + gpuChips.emplace_back(name); + } + } + } + + void fini() { + if (this->initialized){ + result = nvmlShutdown(); + if (result != NVML_SUCCESS) + { + log4cpp::Category::getRoot().info( "Failed to initialize NVML: %s", nvmlErrorString(result)); + } + } + } + +// void setCpuModuleNames(const std::string &names) { +// cpuChips = rmcommon::tsplit(names, ","); +// } + +// void setBatteryModuleNames(const std::string &names) { +// batteryChips = rmcommon::tsplit(names, ","); +// log4cpp::Category::getRoot().info("setBatteryModuleNames: %s", names.c_str()); +// if (batteryChips.empty()) { +// log4cpp::Category::getRoot().info("setBatteryModuleNames: no battery names"); +// } else { +// log4cpp::Category::getRoot().info("setBatteryModuleNames: %s", batteryChips[0].c_str()); +// } +// } + + bool isGpuChip(string chip) { + return find(begin(gpuChips), end(gpuChips), chip) != end(gpuChips); + } + + void handleGpuTemp(nvmlDevice_t device, rmcommon::GpuTemperature &gpuTemp) { + unsigned int temp; + result = nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &temp); + if (result == NVML_SUCCESS) { +// rmcommon::ComponentTemperature componentTemp; +// componentTemp.label_ = "GPU"; +// componentTemp.temp_ = temp; + gpuTemp.addGpuTemperature(temp); + } + } + + void handleGpuPower(nvmlDevice_t device, rmcommon::GpuPower &gpuPower) { + unsigned int power; + result = nvmlDeviceGetPowerUsage(device, &power); + if (result == NVML_SUCCESS) { + gpuPower.addGpuPower(power); + } + } + + void handleGpuLoad(nvmlDevice_t device, rmcommon::GpuLoad &gpuLoad) { + nvmlUtilization_t utilization; + result = nvmlDeviceGetUtilizationRates(device, &utilization); + if (result == NVML_SUCCESS) { + gpuLoad.addGpuLoad(utilization.gpu); + } + } + + + + + /*! + * Detect each gpu available on the machine and calls the + * appropriate handler function to store information about its + * current status. + */ + void handleGPUs(rmcommon::GpuLoad &gpuLoad, rmcommon::GpuPower &gpuPower, rmcommon::GpuTemperature &gpuTemperature){ + if (this->initialized){ + for (unsigned int i = 0; i < nvml_devices_; i++) + { + nvmlDevice_t device; + result = nvmlDeviceGetHandleByIndex(i, &device); + if (result != NVML_SUCCESS) + { + log4cpp::Category::getRoot().info( "Failed to get device handle: %s", nvmlErrorString(result)); + continue; // Continue with the next device on error + } + handleGpuTemp(device, gpuTemperature); + handleGpuPower(device, gpuPower); + handleGpuLoad(device, gpuLoad); + } + } + } +}; + +GpuMonitor::GpuMonitor(rmcommon::EventBus &eventBus, int monitorPeriod) : + pimpl_(new GpuMonitorImpl()), + cat_(log4cpp::Category::getRoot()), + monitorPeriod_(monitorPeriod), + bus_(eventBus) +{ +} + +GpuMonitor::~GpuMonitor() +{ +} + +//void PlatformMonitor::setCpuModuleNames(const std::string &names) +//{ +// pimpl_->setCpuModuleNames(names); +//} +// +//void PlatformMonitor::setBatteryModuleNames(const std::string &names) +//{ +// pimpl_->setBatteryModuleNames(names); +//} + +void GpuMonitor::run() +{ + setThreadName("GPUMONITOR"); + cat_.info("GPUMONITOR running"); + while (!stopped()) { + for (int i = 0; i < monitorPeriod_ && !stopped() ; ++i) { + this_thread::sleep_for(chrono::seconds(1)); + } + if (!stopped()) { + rmcommon::GpuTemperature gpuTemp; + rmcommon::GpuPower gpuPower; + rmcommon::GpuLoad gpuLoad; + for(int i = 0; i < 3; i++){ + pimpl_->handleGPUs(gpuLoad, gpuPower, gpuTemp); + } + bus_.publish(new rmcommon::MonitorGpuEvent(gpuTemp, gpuPower, gpuLoad)); + } + } + cat_.info("GPUMONITOR exiting"); +} diff --git a/rm/gpumonitor/gpumonitor.h b/rm/gpumonitor/gpumonitor.h new file mode 100644 index 0000000..565265a --- /dev/null +++ b/rm/gpumonitor/gpumonitor.h @@ -0,0 +1,49 @@ +#ifndef GPUMONITOR_H +#define GPUMONITOR_H + +#include "eventbus.h" +#include "basethread.h" +#include "gpuload.h" +#include "gpupower.h" +#include "gputemperature.h" +#include +#include +#include +#include +#include +#include + +/*! + * \class periodically samples information about the platform status. + * This information is then encapsulated in a MonitorEvent and published + * to the EventBus. + * GpuMonitor runs in a dedicated thread. + */ +class GpuMonitor : public rmcommon::BaseThread { + struct GpuMonitorImpl; + std::unique_ptr pimpl_; + log4cpp::Category &cat_; + int monitorPeriod_; + rmcommon::EventBus &bus_; + + virtual void run() override; +public: + GpuMonitor(rmcommon::EventBus &eventBus, int monitorPeriod); + ~GpuMonitor(); + +// /*! +// * \brief Sets the vector of possible CPU chip names. +// * \param names the comma separated list of module names +// */ +// void setCpuModuleNames(const std::string &names); +// +// /*! +// * \brief Sets the vector of possible battery module names. +// * \param names the comma separated list of module names +// */ +// void setBatteryModuleNames(const std::string &names); +}; + +#endif // #ifndef GPUMONITOR_H + + diff --git a/rm/librmcommon/events/monitorgpuevent.h b/rm/librmcommon/events/monitorgpuevent.h new file mode 100644 index 0000000..93f57f8 --- /dev/null +++ b/rm/librmcommon/events/monitorgpuevent.h @@ -0,0 +1,52 @@ +#ifndef MONITORGPUEVENT_H +#define MONITORGPUEVENT_H + +#include "baseevent.h" +#include "../gpuload.h" +#include "../gpupower.h" +#include "../gputemperature.h" +#include +#include + +namespace rmcommon { + +/*! + * \class event generated by the periodical sampling of machine status information. + */ +class MonitorGpuEvent : public BaseEvent { + GpuTemperature gpuTemp_; + GpuPower gpuActualPower_; + GpuLoad gpuLoad_; +public: + MonitorGpuEvent(GpuTemperature temp, GpuPower power, GpuLoad load) : + BaseEvent("MonitorEvent"), + gpuTemp_(temp), + gpuActualPower_(power), + gpuLoad_(load) + {} + virtual ~MonitorGpuEvent() = default; + + GpuTemperature getGpuTemperature() const { + return gpuTemp_; + } + + GpuPower getPlatformPower() const { + return gpuActualPower_; + } + + GpuLoad getPlatformLoad() const { + return gpuLoad_; + } + + virtual void printOnOstream(std::ostream &os) const { + os << "{"; + os << "\"platTemp\":" << gpuTemp_; + os << ",\"platPower\":" << gpuActualPower_; + os << ",\"platLoad\":" << gpuLoad_; + os << "}"; + } +}; + +} // namespace rmcommon + +#endif // MONITORGPUEVENT_H diff --git a/rm/librmcommon/gpuload.h b/rm/librmcommon/gpuload.h new file mode 100644 index 0000000..138ddd3 --- /dev/null +++ b/rm/librmcommon/gpuload.h @@ -0,0 +1,46 @@ +#ifndef GPULOAD_H +#define GPULOAD_H + +#include +#include + +namespace rmcommon { +/*! + * \class encapsulates cpu utilization information + */ +class GpuLoad { + /*! Usage of each CPU */ + std::vector gpu_; + +public: + void addGpuLoad(int load) { + gpu_.push_back(load); + } + + int getGpuLoad(int idx) { + return gpu_[idx]; + } + + + friend std::ostream &operator << (std::ostream &os, const GpuLoad &pt) { + bool first; + os << '{' + << "\"gpus\":"; + os << '['; + first = true; + for (const auto &gpu: pt.gpu_) { + if (first) + first = false; + else + os << ','; + os << gpu; + } + os << ']'; + os << '}'; + return os; + } +}; + +} // namespace rmcommon + +#endif // GPULOAD_H diff --git a/rm/librmcommon/gpupower.h b/rm/librmcommon/gpupower.h new file mode 100644 index 0000000..bad7193 --- /dev/null +++ b/rm/librmcommon/gpupower.h @@ -0,0 +1,42 @@ +#ifndef GPUPOWER_H +#define GPUPOWER_H + +#include + +namespace rmcommon { +/*! + * \class encapsulates power information about the machine + */ +class GpuPower { + /* Current power in mW */ + std::vector gpu_; +public: + + void addGpuPower(int val) { + gpu_.push_back(val); + } + + int getGpuPower(int index) { + return gpu_[index]; + } + + friend std::ostream &operator << (std::ostream &os, const GpuPower &pp) { + bool first; + os << '{' + << "\"gpus\":"; + os << '['; + first = true; + for (const auto &gpu: pp.gpu_) { + if (first) + first = false; + else + os << ','; + os << gpu; + } + return os; + } +}; + +} // namespace rmcommon + +#endif // GPUPOWER_H diff --git a/rm/librmcommon/gputemperature.h b/rm/librmcommon/gputemperature.h new file mode 100644 index 0000000..2c5c23a --- /dev/null +++ b/rm/librmcommon/gputemperature.h @@ -0,0 +1,42 @@ +#ifndef GPUTEMLERATURE_H +#define GPUTEMLERATURE_H + +#include + +namespace rmcommon { +/*! + * \class encapsulates temperature information about the machine + */ + class GpuTemperature { + /* Current power in mW */ + std::vector gpu_; + public: + + void addGpuTemperature(int val) { + gpu_.push_back(val); + } + + int getGpuTemperature(int index) { + return gpu_[index]; + } + + friend std::ostream &operator << (std::ostream &os, const GpuTemperature &pp) { + bool first; + os << '{' + << "\"gpus\":"; + os << '['; + first = true; + for (const auto &gpu: pp.gpu_) { + if (first) + first = false; + else + os << ','; + os << gpu; + } + return os; + } + }; + +} // namespace rmcommon + +#endif // GPUTEMLERATURE_H diff --git a/rm/src/konromanager.cpp b/rm/src/konromanager.cpp index e9f4c21..9ada1db 100644 --- a/rm/src/konromanager.cpp +++ b/rm/src/konromanager.cpp @@ -7,6 +7,7 @@ #include "policymanager.h" #include "workloadmanager.h" #include "platformmonitor.h" +#include "gpumonitor.h" #include "proclistener.h" #include "konrohttp.h" #include "policytimer.h" @@ -49,6 +50,7 @@ struct KonroManager::KonroManagerImpl { rp::PolicyManager *policyManager; rp::PolicyTimer *policyTimer; PlatformMonitor *platformMonitor; + GpuMonitor *gpuMonitor; KonroManagerImpl() { procListener = nullptr; @@ -57,6 +59,7 @@ struct KonroManager::KonroManagerImpl { policyManager = nullptr; policyTimer = nullptr; platformMonitor = nullptr; + gpuMonitor = nullptr; } ~KonroManagerImpl() { @@ -66,6 +69,7 @@ struct KonroManager::KonroManagerImpl { delete policyManager; delete policyTimer; delete platformMonitor; + delete gpuMonitor; } }; @@ -108,6 +112,7 @@ void KonroManager::loadConfiguration(std::string configFile) cfgMonitorPeriod_ = configRead(config, "platformmonitor", "monitorperiod", 20); cfgCpuModuleNames_ = configRead(config, "platformmonitor", "kernelcpumodulenames", std::string("coretemp,k10temp,k8temp,cputemp")); cfgBatteryModuleNames_ = configRead(config, "platformmonitor", "kernelbatterymodulenames", std::string("BAT")); + cfgGpuMonitorPeriod_ = configRead(config, "gpumonitor", "monitorperiod", 20); httpListenHost_ = configRead(config, "http", "listenhost", std::string("localhost")); httpListenPort_ = configRead(config, "http", "listenport", 8080); changeContainerCgroup_ = configRead(config, "container", "changecontainercgroup", 1); @@ -115,8 +120,9 @@ void KonroManager::loadConfiguration(std::string configFile) cat_.info("MAIN configuration: policy = %s", cfgPolicyName_.c_str()); cat_.info("MAIN configuration: policy timer seconds = %d", cfgTimerSeconds_); - cat_.info("MAIN configuration: monitor period seconds = %d", cfgMonitorPeriod_); + cat_.info("MAIN configuration: CPU monitor period seconds = %d", cfgMonitorPeriod_); cat_.info("MAIN configuration: CPU module names = %s", cfgCpuModuleNames_.c_str()); + cat_.info("MAIN configuration: GPU monitor period seconds = %d", cfgGpuMonitorPeriod_); cat_.info("MAIN configuration: battery module names = %s", cfgBatteryModuleNames_.c_str()); cat_.info("MAIN configuration: HTTP listen on %s:%d", httpListenHost_.c_str(), httpListenPort_); cat_.info("MAIN configuration: change container cgroup = %s", @@ -137,6 +143,7 @@ void KonroManager::run() pimpl_->workloadManager = new wm::WorkloadManager(pimpl_->eventBus, pimpl_->cgc); pimpl_->procListener = new wm::ProcListener(pimpl_->eventBus); pimpl_->platformMonitor = new PlatformMonitor(pimpl_->eventBus, pimpl_->platformDescription, cfgMonitorPeriod_); + pimpl_->gpuMonitor = new GpuMonitor(pimpl_->eventBus, cfgGpuMonitorPeriod_); pimpl_->policyTimer = new rp::PolicyTimer(pimpl_->eventBus, cfgTimerSeconds_); pimpl_->platformDescription.logTopology(); @@ -149,8 +156,9 @@ void KonroManager::run() // 2. WorkloadManager runs in a separate thread // 3. PolicyManager runs in a separate thread // 4. PlatformMonitor runs in a separate thread - // 5. KonroHttp runs in a separate thread - // 6. PolicyTimer runs in a separate thread + // 5. GPUMonitor runs in a separate thread + // 6. KonroHttp runs in a separate thread + // 7. PolicyTimer runs in a separate thread cat_.info("MAIN starting WorkloadManager thread"); pimpl_->workloadManager->start(); @@ -169,6 +177,9 @@ void KonroManager::run() cat_.info("MAIN starting PlatformMonitor thread"); pimpl_->platformMonitor->start(); + cat_.info("MAIN starting PlatformMonitor thread"); + pimpl_->gpuMonitor->start(); + cat_.info("MAIN starting HTTP thread"); pimpl_->http->start(); @@ -184,6 +195,7 @@ void KonroManager::run() pimpl_->policyTimer->stop(); } pimpl_->platformMonitor->stop(); + pimpl_->gpuMonitor->stop(); pimpl_->workloadManager->stop(); pimpl_->policyManager->stop(); @@ -196,6 +208,7 @@ void KonroManager::run() pimpl_->policyTimer->join(); } pimpl_->platformMonitor->join(); + pimpl_->gpuMonitor->join(); pimpl_->workloadManager->join(); pimpl_->policyManager->join(); diff --git a/rm/src/konromanager.h b/rm/src/konromanager.h index ead3be4..83e3093 100644 --- a/rm/src/konromanager.h +++ b/rm/src/konromanager.h @@ -14,6 +14,7 @@ class KonroManager { std::string cfgPolicyName_; int cfgTimerSeconds_; // 0 means "no timer" int cfgMonitorPeriod_; + int cfgGpuMonitorPeriod_; std::string cfgCpuModuleNames_; std::string cfgBatteryModuleNames_; std::string httpListenHost_; diff --git a/testnvml.zip b/testnvml.zip deleted file mode 100644 index 82ee4093b7d0d2e8c377d9ccca5e42413f4d4461..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 87731 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 z zLS5+xJT>-ttnPIEyN)ETrGxV}XJMn4Bq*`a#I=y&T88TBhw9ma@)?Hu>W7+k8W=WR z*>PffmSB6PWP8?NduC;O4q$s;XM1j8Yh@XmKJ3!NvspaH_)b4AZUGPEeP*&$ENvzVEyK z9sZIwd2LuSMhn^&)TTC{M2I+6Ya1bQ&9Kd^cr+0djH+u)R7z}xyln>mXt&q>8hlq7l)|c-I7Y6=VueYX<5}!jb|#-yuz%e0?d$I}@@DDY&kI`5|awyRiz$UhPDQJR{ zQG!U-)@@U9R@mlf5vF~GEEvh{P=L`ygQ zdQaNbAFyTvKkLK{JhUs~+8t+J3CuV$ZiMs7Bkq2mm$^52kz)gDkab3l_W16{tc~_EF6MH1ROgf6pQQ)W_j1 zS-oEEd+rqReEgQ=E{Gy5uN?zPQLLK*2pTDd(hbV$t{gQu^JyHm{Yw)u|v z))sXmm-lhSi^Ds;a_#1Kqu~4;43~rO@BUg2hX+mx5kGCk0gj2l*bn~Ih1|ksbyWQNw;e7;j!IXF#!+V-lO0?zW;SsO>tlPD7DtCGSA9GCGNg7N2KaEIp#ST76H>Hu7|%htc_fKIdzAwm%QuG4P662 z$MYEgJw$_*rq4eXuF}})9#bxmApZ+sGf z`0bLPYoeb7nAyS~#aw&yPx{Yoj%BH)LVR&RrPp!$A~-KRfX#UPfeP$bG^`IRpoaX7 zV?FqjJ2+()?Y#=the#>;%H&x+{^&P=YjjJ;z!kZwz=z?TtiAp#7}x?3~5%Irx~bp{`upu5(4ZEX~?j`jH?pDzOl zK2lw+@5=Px0S*wGhpA`B>`u|?!mW?HqsHOz(SP0>AZHv6pC1Ja~MMk~XZa^s@uo{S^au#QkF$+$SlZC;#C< zvUykG7TgQ#)8iH(gz3#$Re&2zAoj=?1x%2L7J(&5r5$&I{mNc4j0MWgbbhxh2l=Z4 zb4%j!&SQ)IC5jyLlL9!+@UB}J;)3Z-`%)K!`3b%%VGxe?6?;67=?xuaNdurSutQ_; z#JMRmYMnFXITAW+%mNZwx*7}J`mUT8d(d>$)#q#pz%gqvCan{W6d>Phg&8|Qj+9p?czLd~ z(zLaHeIE0ZBk74rYxSZDHb>~SC*}LwPt5Q1g51fn zyEg8|=<0oU`6IAkxk5Xyp=+K2zPb`LKK?g*D8QL`P5@T*KGvkI)3naOHN2)6GiLRE z=Jd6slTK~ikr9rY=D+>0m63*7(d>)wh92eLS?#Y{5>FFY?YGT~W`D5Va!+1IEnG># zsyRQf2UB;vPKZujeUHii)!LQ7L%p``p@lNpQpj5NeT;o4Wr?!yWF7my%U+D4td%Gf zB1KM&C1fxO*+K|0CJG^gFqWD5X6iVp@4UU7^FICl{-$5ebv^fU-OqME3;#)udihbt z?9&q`8oar>$)N%vO9Z5h*WO$@88_tnf%up$v_4bFmgEv_q_uqPTWdDdiOy-uv2@_* zULbsbn_70L$E1u6NB1%id48#`2~E*PIp&BFgC&KvqDvob$snw`aMobUEDB1oErX@* z(Mx8FlD(?d(46xhZGrIk$!>ehIxI;Wg5jg9N*4=LoQF#Q*_0Ri+wNu03BB|VSg1@y zF}1?8y3mUGRSE>HQB`?klNIC}(T=?f%fQH_Y5XhnnhQ4K75asP5>jl7yVuFiO900) zMRd!riSWa%Ns9r;fr0>a?l0Lvk?J2m0`c*aK=4+mx%Dgq zPIA6bjv*pydJX(u#Rr20E~sNdfoo3fOH)89UHDT))}T%TK_TTcwlE;gcp zOD2V2`IJe5%L=FB4?}abwx~d1r%KY37;!?)>zd&u7>}2Q$tY|6&9gxKwO6yY7z@rR z7a%@%`8OGGoa^{NX!otN^M=r% z)QBpvFrLo#5FmbENxA?dZvQPW2h62m_!ryi4aGhZC>wWVXfkR<6Tbis1I}|GMYpVS z7o-~Er;;PMMYjyfmJdSlDHu;XOu!_Mh$DubAK8MoHH=6>Q9Rm`Kqzrw*O;7}2UEw& z7$ZC?1-orAkV!Uws8=DjhEPO&l=3+!3(agf#;0FMtQ|1j4pT^weB9)mVrzVDtI~BF zj2ukZ*B$*Fh|e6DAZ4<2s=oVmrmB(9zJW@nN+dB4fl0dXO?Px0Lwy#e?ll@tjpIP* z=tf$Ky^Ehp!NrM%i7qlCypJUfh=!$H@@hhhaz@f4Hv4cjDJW#xokFp#fEC49lxmyj zs_2&X5|uS*OJ&Jk3A{zJglJPO#<0M~E{WE~&xMd9s(K^Dv-{F;S`77fUoSI6>?ZMl^UuT(|+YjnAbRb3}~&fN@m z6E)Zq7T$v1m+$0s`uI@L=%> zXp+E4Jid5K41qrv;mD8Zz8_E(gQD-NzEIgX!Z@aanE{q^hgQd+(%O{Xcc4A;<4PGl z>#Ug_n@b;TBJ_axsI3uZDEwSt^<_fameUE0%sf7(2o>R4_jJN2nkP|-ZLxPwECanb z;a_#2)@OrXc?;m!o1Yy3!jlG4?xK*XEE|j$m3=)OgIPN#9s(mTe_A{aE#=&pVyM40 zxh{vWaIt(!V{D0)3L~`3N3*-p4`3qN_SNz2^q{bPGbM?rW#<<;t?1Z%HYG$$s#S?& zu*eb*6GMdP`Z5_q_JzPra)dRvTqG3rnPR*Yyd`1wR?!Bd*aWx59OI;lXd8=()Qli> za75mOt=MA@_Tqz~aE&c32F0v_O?fE%{IXFq+U~=GQ*iP?4<8VzG3zgdVB=gbg#?FJ z3L?AFqWRfVjAJ>I>#0cz)1gUaAMU!;zY-&Kfu@>)ktvfdPQ>Qc6B>DLbF&1Pqq7m2 zilR!+g14;DTD%066UU`g{q{ zB$6$H2I0lMF(Pxpr&$#kd3SDE28z#mwRr+jm6ojp33ja%8GRDcg`)sOK-?QV5=uET9dBMSQ^w=#^jX$B9_r z3}Z%=vezY}K5r(ZG2)KQgd9XHyF}h=L1X>lhF$2P{3=%{z3x_D1DeLcM2it8xc=}M z&|2e?8w5iJTX46pzKdC~!;mbE(1W-3mraEOtxqq9iXlqV&(4!TdGxl>`w{Rw>}&{B zr=WWJ2-G^i-ntR((A!N9%+dI&B)a9^YjG~|SSe2=_$sQ_h1HMoDPdLKG8}%lWg4$C z>#3M$0xu5$=jEIYtcXWZr7G&!26L=0dt8TaShh~X*|FB`-Yc6NL14vhnw)e-90@9p zAxBkwY=I%W^uxT5u_E^Ef*B}G9@W> zPjY&437RfyIrKaU<@&;TJte?HPbWu^qeyCO&VJ)65O>GlFKRt=cA=@Ha-5w z@dy{~HGlu$0h%bKIsyEq^y|>fOxZ0r!TxMYokz`V&uki%TT3$=y4|Nj5rk{e&CDZs znOCMn9(i^ka+-71aK@O0&Ec)#$mz86vY+4}={S8{#U)(JQJvb=d)es;Fb)r(;{4kPMYo3L%Xm&ng$wvK{{)={ zJHD+fUwLdeT&>`o&V9JUyau-4Sv~QP;${)P`ML4EK4I95Ql3`9P@f&P_QO|rM*;p~ zn!|?dW}Ef}rZN{iMORM{b zslFmPF5sPx>L_+~JGOuAoWo$Be6_o~s#B6YBMn_%HE~&N!S}~Y+b|E;R$ykQLS5k* zs4#{11dgSb+3J zD7E3q5h0uS1H=PXZap}h7%Bq*5chlj=Y6lIe!uTk*xtj|4YJE4p8xJ_Y3^Npzpb~+ z9xyg+e%?OIw`+_*(eE%JFAqbupI>&Z{%2E(>;=Xr0OA|6%RK#hG&a$W|K&{XKg)$^ zH$tAigV}pIKs*SKyHFtbza4_Tk01#$av~5Z@dqLO*ev|(&D>IZ&$qp;y))#0Ohf)3 z&>)Ie&BYz!Clo09zck4|;NtJ)*D!uxDX5KSM~2nmc9^g_djL1t$*VCZ+(C$ z%bj4%WB`EvUJBtmn2VXutWZ&^KX4Nz8u%En0TA>xgbIC%SoQK3D#B% z2EafX7nxL$lr8%BL6SRuZDe+D$0c|On>2&e-U|#}ecsR1>k=_*%sG?AB7f*PyG`l* z9H}Wy-{&@|#4P1vF0$yaCyV!k%Acp(EIFo@1Q0s7VB^37TYm6 z3_M-q95pY~uIBr~^Te}&nhA22!@B;B8H^JlicNyB)TG?ylcGk;5qSR|?rYQ^`AS|x z-=4iyDBdj7>9o4?tXseJ(&rQO1);0qigO~*Sz-|f{VWzJIppHbnzjq+r|JT2v%#(W z1GX}Jgy=@edJ>$H|!cfD|!Q21rHu+40 zw19M%t7&0!`q|-e+P-odo)LIs(|B`sMRaM+AeGV`)u=Q#ZwVTmeOTxszi*CZua`~f zIKK|n>#+uboarjZfPso>#}&(zJvL_>u6bZ(xs;@OSyki1`ZX_1 z(NJ4^Vf*JScizm*Y;~m!QYB5LOOcJpjVa&dj4Jcmk#eEY>LG7W`j_^6uV|BK5f7^ZHoMC}zFb!Jr;bF0;sICbHHEWd*wyw;=3!>^FELy(%{)ze zl362|mygApYDncM^_#qz1UiKSqQN(FMK6Tu#JBL8E1e{)w>Q5TbCTPKwfv)<@UbP; zWqXpM`Y~gc&2G;bXexy|qdjxaQqoMM`I!ReWOiijO>YK+Yjh;haLt31_w$=nz^Q`M zs>(VKl<>-ncj}ACR0RWc->62aY&?DI{sjS)jFF0qQ&Pe!}ME}I)i$w50YqPJNA5}c$ez!%I9Yi!+apR5|Z+rpq@<3_Hak(^+` zADDJ%UMTOl(Q;Nq$lID0lExASH6KtGMkwesyuMMO0CniHuk6x7!N>P5#yV0r&iMp1 z1PvG5K0zXqbMwp_`x168gl)~ClZF|S_TxQNR%+h#c5w1T12@7CsWnC)h{SN_-dVl# zdj29^pHBk|o1u>izVMER`SZuZNCwC5fm;_J`c?pdVFL@BcXVl3N%H{eqP}K1%HH7I ztVqwQ2uS8^s&f{d^Jjkt)smVI7(jNS7Mi9;vjg_=SVXA$u>rQKF(=T+#E6Q9xL^g)Md7m+3Y3#XkG6O zPox}b`GD*_j9uT>qX}PtCSu6XhtgMlsjFr8oyRgc_zQ8G~rP6pcXzHt~ z`I*b6Yq+O9fSx1kqQ*9w$ryRDbxoAeWc_6t%!}XDxEA!>*X?j=R1=GuxcEx32`2M#d zwNV?YRbDePH9j7M-DnSU;rmC(ibQF-g8W&H&*E+gJgyCVdU4va|7pLXM zET}<%clzfT=EsA9g%_GLE*Y78e#u-k;hpz3aO7f)w>6W2M3Ak?O$lIMz2qh|vs+~| zmoMC+-qo$E!X?0=b{MoNFV1&_CbZFk^n+FIP4mqf-K%{AH@e?Gk@*t+PQ4L}I*6Jw zO$-yi7`xn*Qq7rhlp)z<(NL5j-NAp3W0C(peNxlMnR`vtbq9-5QB_xs24QnU9e#m9 zbEcPOz6N@0ouy%W;!PW;*|BiBu>SQa72Ye7mq|FII%TwwoWdU*EXw@y7&Ey>94pL3 z4l2Z7yPPD-NrL7IOixN`H)DOReVkivRI|e*u!QL`!t-#u)Cmv1$DS_nqfg{3rV_E- ze6X=pX^D^sCwb(3h=s{&az)<<>+ti3`qI9rAJ_J~ksGGFS+bRG^ep=Fg7P02N|tQ* z0ds+VA29)V%w^t#(G*;hJ+3OM``2tMDP%?~-No2K;Qgm!6|ZLG)R_pmL*Mj04p<$0 z_>y6hrlT`&NUyCVtmW01K=aIS)opH*yH2*{U*kQjVQfM}{h^7cBj5E)W>|nAS8!2) zCC=EzJIdo{H~W2f8EYQ}TeBnP&@l$GvKht|8Ep#psDrpB=$?frwKq3Em_+b>?dy4b zBUk!EMq#;&U*_%18}f0jDxGmJYgYqDX3U2xa1Zr0WM>CvilrSyQ<8PbJ}#zWfwm1x zM|`L!V6%lS9U8e?8Oy5-@FXjC-U=sKXj>TW#Ul^3JA(l)Jub`MH#4VS>15Bi&&%&E z5md42kMrg93~r|4z+9{++_P2D!KC#xShuB@VFUG0{J{Q2#nGRGi>7^Yp!4A>Vkh=|oR- zt{YQBmSI#00C{o3>+ZWOOY*0HaU6&LUEXZtOwZkXDP&sTBz zYc~4#Ymv`$KiOaO%eib-I^1G(*#Ugt==_sga>WUJs~7sJNz>odZCHucK6Fwn)JqFS zk2a$WPLfn0XR?JzL^5L5_d7llj$1k2RYPIkvn*)#D4}brR}N9UaGE5Z2Hj&_tKep4 z^ZxB9KC5f4D1E>{@P(TRmU;9x+HZZj{0{JV@pM_#B_#hmm?e!;^^2ig>C@t^(X*|P z+Ut3*^NOqC8hvaOU){=HgT=d!0`{|hjXSVkyL{MrsQMrkNz18tIO^O*lFFva=3g|bfpR5X?X~vymg(MdoKfo_ ziz>G`*U|i%Hrce?dG!%BqKmfV4c)~hE^r1Cq;oCDiloN=-qYjh+|~POR#Co8_SVBU z^M^hpz*H!Y=I~T4y3f$aQIg>d4D2Y*p9|tW7bUXt;ial+uaU=X-0_kKB|mC~%8MV1 z$4da4!7*B!R|b9WCX$SNt}cBo`3k2H&oYb?=(a#AgqM8eX0=h{*Y|&jtO$^e)*lY9 z*a(oI#~u)SN}oUZFmv2qTlwt=i06Zbm7`vvOqR4R@A+Q$rrl8Qr52deHko~KOxw@6 z+w{X}yW6kb+dlT0uO)J}&xVuGiaRUd*3y<|?60W9nDW?dy;7?gQS#E1q0i2dE$BqG zHfc;(D26+f&XwAoawOmPF#J^|n5QooU%y^|Y#;ct56n*K{rzeD&9gM3Qj8dO*Brl1 z{zi8-)jQ^&eFo9DQ4rnC5x*dMayMTJUpqCEyYEj(>s?unnxK(A#_k04N)T&&Nk2l* zWY>M?JRgGAM+$5gkPt?B0d|%$uHpsc9dEpypM9OHTPU>T`ZEZcbd^PM#O>iH%)JR( zW}18|iAI@5vIobvbfr)d-nkxkvZH1-RSza2c+VVvHLVV)JmF^*&!mTK?o3tL@G*z5 z3iRC8P#(vU7oRzC%3jai{@%MJdxzZdGe?A*a3MOQS}9sCbWB!ion-EtIl~*b8J@D! zRMejsuc0~20VKI*(}nIre^3iQ^B+Ep|vkeM`%qbCI$J!nnqjx{c6I=LIk$Tl;E zpySBT#7oE=R?RQB>*#v-H1I6XnAH(CPcctbnk!5LpH`XgRzJJp>MG{SL1WL<|LWW4 ztU{*BqZQY#KFg}OQpqIgW1sL@zC@<-5lByf!+2!G&zlP2D8K9VC$X zKp{me1!p=#W~Neyf@PY9HdQ) zW_BZ-x}e0nS^lp|MAZv<^A=7PtE!lV+6%^yoZtz3rB=Zq-E$$rx66ghg4G3B(5iZ0 zl&=eX2f8@nzOXvnYJA;2OZ!1d%B2GFJoWwD=kC#4_z0*qhHPxf$WoAXG@DB$4pr5L zj|@S~y0>0X=z+}LZ`8eON)|$jTjbs>ZNK@&q9ss40M3Jy3>OF`3xZut!Wv3g42&o^ zxy0T*ckBu1U~3X5$R^?35xoX3;mDD|01Nt~n;TnSW&4}W%pUqE}tJcExqt!84}|NduM zRs%;eHlzM$r1Qq%8L6j-h9X4VZzv6h_PCVwaWpK;6CO13(5R)}(C-q~lh7}TU;Fa<_M022pqHG9`JijB zN~q()R^H3gTBrw0HhA?(I{O4?D>PD)y8cLT#aqi!Q0>V}+ocrNDowVJ21h_U$1 zXQ#oWE)Ag7`>pAduHg)t!e7qe*E9nwIUOG8$_B3vMq&|4cv{07U zt?sfUbUwAvo6D>d%m2D8tV4j|!LsMHMNTYLPEw@XgIba!w?ldJ%BqeqF9_4~3$k@E z-TZhzCZyaUtI_S|_`4R=%sRR_U7Ib7Ok(cqTAlxiTGlsK6|BXdmZAu!5tn8pJB!O< z{hK~LGIPq(e0#oqcvP`Qy`9(}dH;WT&Z<{fRx_?pQ_jwePmL7Lnb z!*A&eMbQklLq(!bA!|yW-7PIwxsVdiYycm;uCInqz481HsJ7^wWD-eH$Cq-wlOyM5 z3ogdGzgBIz6M4pzj&7v2*46KNqM$YXic4|KOl2(s_6#p(CBMYk+%H;*3pmDq^sU5UaT0^j-ef@5uCt> z>07S96*q3!P>H=Z_@~{W2BWG(uqvwIitn1QXb9v* z3EjW0dK@8q!imrtxmP&-tn92I;IL?hp*fObij<)y z!>zG*7~F&92fAyeJho>y?&0K7{fp{a57G<}Pv5Hn9%7Ny}La#n<$+i;W>;4>Hc<@wtC*>vgC>~x(Z0@p63U1Y{y z%bPwMdCKt0B`|~j8Gf84I3E?xEVL=>dL%e+zm1(|KFJdM{Rm$NC^_n}V6;;kN5}HQ^56rc`?-1@B=|UP8mOJVJwx>_S)KnD^P>{k(MhA@ zW3Xc~2lrWLz&9giUnaofu;uMI`0bC66#x?CP5rfDGofLFUg!*8J1w_qR~8)msblFT~Ee#_+Zj z%LJ@mmti<$otBugoMo6VexLS;%y`Sp2}ymRS#0zXpR~p|JTs0?4G9MiYb6yV95{@6 z-rIbomGVO!jk=L~|HZ(Y!#NMV>fK}W{9`U8o-&glOgE5lB}?w9$mZ%2l0-KicI2Z-T1QFRiT#ZQ$3vgXF$uO^F{48cWS#P5Lq- z-w?pkDnsF>sardI3vAI*0FMk`-;h>aRE+o*H|l+J&K^Y2Hc`QUukB32EVTLFwM{s( z6k_l1hha;*wx7NwD~?bbbDM+o32BH2_&_)LP$6>fUhb zWy>e(E21gPBF}=3>V1_#fXGM>-F7=HxI!Il{b+_MW*>>hhKGHjozcWwV+p1w__?}E zj3~kQ>j~FN`cdu9Q?QpvQwMt^$mi*?GdWk@Ch>8|FOm{nU9$bCj1wWl#7zIaIr{bi z07iQ^$Ift#kf^Vpo=UXwXhL#*JEjqV$pU;37xmvb2$_ zVNu*Ug%$me$~IZa`>+1NQW3wj&}?H_==#=J!3Nmg)gg@FQ@+D*wiJ-3*?FrN-MPiB zTuO49M~vFha$m`^h5pSgy-!1-jxkTn{hn8HPUxB2R7I|`la*9L z*Y&``ZdA>RxwmyUcvI~CQN#@I=T%=>%7weDWyqM>{}@M&Cr<<{*Lmi3g* zgjvmO7Bt+bw$6H{)|n;9#7fnuJ?~xjR8X`3ai^IWPDpmLs5ZOp$2B$Ydk?zjJ9Lw) zTYEXPd+lC*xcpK1gO=FW=1uLe6)0K2!PP<``h{x$vLZY7jz7pT%Ad~BEyOK(&SeiB`J$O(-8s&$tAt> zvK7pqimD-=;LCn!5~5U?ql4D2k^lfiLHxZ`%n1|X|DcQWQ|w3xVlN4i5qAJNh=Cwd zl46cBQZjbC(#pJ{l@@}~8hA!Fx6UepRiqXJWUUQXPXVDCnXiPOoP2Vo zQwzeiVEft5rG<7qXZxD%X-QU6jnpwg~RT_W3=C)1ZsHx8$!bu6>03grj2Z$M_yY{w`XrXj$bZvs~|11!mp&<=LLu z=`uFol#f_thv4hyX$?9Kb8^`-1%l1+H>NtgT7iM=au-w~=;kPmJ`<%AUt6hpWP5HB zPWrje&gK&GSmWh@zC@_?+%wkdLXCFQOPPJ!L%S{o`?Inzy>$ZuN+5yj!TtF8JU(%=JW)&EI&%22{@c%Rg}#ar*!?UQHH$Sl z&wJh7YZDIXc%Pt0{l&Ng;)(O3-6e4xp^wpR?v7UGdI6U+C#*1PD;bvFp!n9>{cF}= z$6ucfVW}~P1t@(JkYY;KgDir8h%)&uAVQ@B*cmq=e&+anU1LZ%BHG2%>3i&XI|@R4 z{}KuL0kHFQXd-~n?f?uS9^PKQw%cKD;t9~OKM$k+TPR{YaVJzL0ZL}CP};VB{=^&# zyL&nPw*#mtgf#{E^>{Ufgxfl_s`SY(2U@2&A_YR)zT6c7N@=(VzWk1>*bvS>pTG z5^X^&*V#in%pxQJKsVu`-|@AuX!V_6`|YM{Z5Ka(KVko1|8M#JZOQ%sA#(R9q#p<+ zwCG9H0Kl=IKt>3#e{tXb<*!S$iTuk5&u{WU%>2$WC4Oew0fAL{zJCYAx3QX#U4VDTcGXS{Uw_JsMR0Fqb8Kl zDKQHf1Qh`A#RC8!E;QLruxN3`-vWNWot(H3;;%AmBzWQW^BZ9h4GOMmto%Y)ps}Bj zSK=C)?F5VVyzpCCVNVxNS6gcbh_~NgStS>_79n zvpU#Cc8Tj6a;&EAk`c1X$n~p}G(L@?42DK!n1Z)W5A+B!PPO#`P!e4E>r^x@WB6ei`I}M0upo_1Urw7E- z|0g2bHu((^qDMnSDjA;B0stT00|3N@JlhEt4R_ovk?+p!<>~0+6yOWdCRilI*2Ddq z8i)=~Gzszj8zw}P02>Sy3EoT?Jpcg2RaV;x7EO9-w@kj-OPEm0*t=POTOP4nNp8#I zm4cpQKS3VH2(^vqPbB(xO~N;Tu*Pa{93!Wux|U+7H1zf<}z zbUJL30#gnU%tDyzQ~im~&6s~g$JF%S5n@C&5AYlY03Hz(qP>F;L<=NbSTJqP<2_WAh&&TT&bfy>{OmBJ1q5y}ewFSzXPj;8P3(!Zm! zv(tiAdGRl(n40ccI6JRP)!ShcShQrrKeq{i$am@dsFaA}@%G-Ue0E;4MZB|hJ7J?u z-~KClKMUx;G-pKAU!9$JvDbFOsx*%MD>i$T(62+|pZgVx$la3J?j7&)+OMC7Ry#L> z>}*hB(WU>4z+Y^3bq&~dUxQc(zZMR0_sMo5OcgMa{B9iZ=YrtfN|X4#zvBHo7uenIUHKuiZE!-j?OWPe zRl=h6n09ODf3%lnTVUIrSt5gNB0rC+-v0w4yWGk0I}$$+GVPi7ZjHU{W7$2Eg}pQR zDH5?4PyE#@ewJq_%N}g9+dV8lJj(?F5SkNbH&C|0d-9E5)5rv!A6YAhl4l=nDMW>->2#sdIOLdx`G-sA-ANJHu!) lKS@Sfc2{}*0lk-KpRU#c!el-GAVK(3#smP&62Jg}{{yhN38er4 From 7b6aebd876a4a2787976193afdf13f44261dd8e4 Mon Sep 17 00:00:00 2001 From: Federico Date: Fri, 29 Sep 2023 13:39:42 +0200 Subject: [PATCH 03/10] Added PolicyManager GPU event handler --- rm/gpumonitor/gpumonitor.cpp | 5 ++--- rm/librmcommon/events/monitorgpuevent.h | 6 +++--- rm/librmcommon/gpupower.h | 2 ++ rm/librmcommon/gputemperature.h | 2 ++ rm/policymanager/policymanager.cpp | 11 +++++++++++ rm/policymanager/policymanager.h | 7 +++++++ 6 files changed, 27 insertions(+), 6 deletions(-) diff --git a/rm/gpumonitor/gpumonitor.cpp b/rm/gpumonitor/gpumonitor.cpp index f3d45f9..7c1a67b 100644 --- a/rm/gpumonitor/gpumonitor.cpp +++ b/rm/gpumonitor/gpumonitor.cpp @@ -41,6 +41,7 @@ struct GpuMonitor::GpuMonitorImpl { }else{ this->initialized = true; result = nvmlDeviceGetCount(&nvml_devices_); + log4cpp::Category::getRoot().info( "Found %d NVML devices", nvml_devices_); for (unsigned int i = 0; i < nvml_devices_; i++) { nvmlDevice_t device; @@ -174,9 +175,7 @@ void GpuMonitor::run() rmcommon::GpuTemperature gpuTemp; rmcommon::GpuPower gpuPower; rmcommon::GpuLoad gpuLoad; - for(int i = 0; i < 3; i++){ - pimpl_->handleGPUs(gpuLoad, gpuPower, gpuTemp); - } + pimpl_->handleGPUs(gpuLoad, gpuPower, gpuTemp); bus_.publish(new rmcommon::MonitorGpuEvent(gpuTemp, gpuPower, gpuLoad)); } } diff --git a/rm/librmcommon/events/monitorgpuevent.h b/rm/librmcommon/events/monitorgpuevent.h index 93f57f8..fcbb6ef 100644 --- a/rm/librmcommon/events/monitorgpuevent.h +++ b/rm/librmcommon/events/monitorgpuevent.h @@ -40,9 +40,9 @@ class MonitorGpuEvent : public BaseEvent { virtual void printOnOstream(std::ostream &os) const { os << "{"; - os << "\"platTemp\":" << gpuTemp_; - os << ",\"platPower\":" << gpuActualPower_; - os << ",\"platLoad\":" << gpuLoad_; + os << "\"gpuTemp\":" << gpuTemp_; + os << ",\"gpuPower\":" << gpuActualPower_; + os << ",\"gpuLoad\":" << gpuLoad_; os << "}"; } }; diff --git a/rm/librmcommon/gpupower.h b/rm/librmcommon/gpupower.h index bad7193..9e53153 100644 --- a/rm/librmcommon/gpupower.h +++ b/rm/librmcommon/gpupower.h @@ -33,6 +33,8 @@ class GpuPower { os << ','; os << gpu; } + os << ']'; + os << '}'; return os; } }; diff --git a/rm/librmcommon/gputemperature.h b/rm/librmcommon/gputemperature.h index 2c5c23a..4b40820 100644 --- a/rm/librmcommon/gputemperature.h +++ b/rm/librmcommon/gputemperature.h @@ -33,6 +33,8 @@ namespace rmcommon { os << ','; os << gpu; } + os << ']'; + os << '}'; return os; } }; diff --git a/rm/policymanager/policymanager.cpp b/rm/policymanager/policymanager.cpp index 40c56e6..595c613 100644 --- a/rm/policymanager/policymanager.cpp +++ b/rm/policymanager/policymanager.cpp @@ -74,6 +74,7 @@ void PolicyManager::subscribeToEvents() bus_.subscribe(this, &PolicyManager::addEvent); bus_.subscribe(this, &PolicyManager::addEvent); bus_.subscribe(this, &PolicyManager::addEvent); + bus_.subscribe(this, &PolicyManager::addEvent); } bool PolicyManager::processEvent(std::shared_ptr event) @@ -93,6 +94,8 @@ bool PolicyManager::processEvent(std::shared_ptr even processTimerEvent(static_pointer_cast(event)); } else if (const MonitorEvent *e = dynamic_cast(event.get())) { processMonitorEvent(static_pointer_cast(event)); + } else if (const MonitorGpuEvent *e = dynamic_cast(event.get())) { + processMonitorGpuEvent(static_pointer_cast(event)); } else if (const FeedbackEvent *e = dynamic_cast(event.get())) { processFeedbackEvent(static_pointer_cast(event)); } @@ -135,6 +138,14 @@ void PolicyManager::processMonitorEvent(std::shared_ptrmonitor(event); } +void PolicyManager::processMonitorGpuEvent(std::shared_ptr event) +{ + ostringstream os; + os << "POLICYMANAGER GPU monitor event received => " << *event; + cat_.info(os.str()); +// policy_->monitor(event); +} + void PolicyManager::processFeedbackEvent(std::shared_ptr event) { using namespace rmcommon; diff --git a/rm/policymanager/policymanager.h b/rm/policymanager/policymanager.h index e337873..ca283ad 100644 --- a/rm/policymanager/policymanager.h +++ b/rm/policymanager/policymanager.h @@ -8,6 +8,7 @@ #include "removeevent.h" #include "timerevent.h" #include "monitorevent.h" +#include "monitorgpuevent.h" #include "feedbackevent.h" #include "appmapping.h" #include "policies/ibasepolicy.h" @@ -78,6 +79,12 @@ class PolicyManager : public rmcommon::BaseEventReceiver { */ void processMonitorEvent(std::shared_ptr event); + /*! + * Processes a MonitorGpuEvent + * \param ev the event to process + */ + void processMonitorGpuEvent(std::shared_ptr event); + /*! * Processes a FeedbackEvent * \param ev the event to process From 8800084cf534193f0b19f9cca2a8074a02bbc34a Mon Sep 17 00:00:00 2001 From: Alessandro Vacca Date: Wed, 4 Oct 2023 11:06:36 +0200 Subject: [PATCH 04/10] Code cleanup --- rm/gpumonitor/gpumonitor.cpp | 26 -------------------------- rm/gpumonitor/gpumonitor.h | 13 +------------ 2 files changed, 1 insertion(+), 38 deletions(-) diff --git a/rm/gpumonitor/gpumonitor.cpp b/rm/gpumonitor/gpumonitor.cpp index 7c1a67b..2084813 100644 --- a/rm/gpumonitor/gpumonitor.cpp +++ b/rm/gpumonitor/gpumonitor.cpp @@ -69,20 +69,6 @@ struct GpuMonitor::GpuMonitorImpl { } } -// void setCpuModuleNames(const std::string &names) { -// cpuChips = rmcommon::tsplit(names, ","); -// } - -// void setBatteryModuleNames(const std::string &names) { -// batteryChips = rmcommon::tsplit(names, ","); -// log4cpp::Category::getRoot().info("setBatteryModuleNames: %s", names.c_str()); -// if (batteryChips.empty()) { -// log4cpp::Category::getRoot().info("setBatteryModuleNames: no battery names"); -// } else { -// log4cpp::Category::getRoot().info("setBatteryModuleNames: %s", batteryChips[0].c_str()); -// } -// } - bool isGpuChip(string chip) { return find(begin(gpuChips), end(gpuChips), chip) != end(gpuChips); } @@ -91,9 +77,6 @@ struct GpuMonitor::GpuMonitorImpl { unsigned int temp; result = nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &temp); if (result == NVML_SUCCESS) { -// rmcommon::ComponentTemperature componentTemp; -// componentTemp.label_ = "GPU"; -// componentTemp.temp_ = temp; gpuTemp.addGpuTemperature(temp); } } @@ -153,15 +136,6 @@ GpuMonitor::~GpuMonitor() { } -//void PlatformMonitor::setCpuModuleNames(const std::string &names) -//{ -// pimpl_->setCpuModuleNames(names); -//} -// -//void PlatformMonitor::setBatteryModuleNames(const std::string &names) -//{ -// pimpl_->setBatteryModuleNames(names); -//} void GpuMonitor::run() { diff --git a/rm/gpumonitor/gpumonitor.h b/rm/gpumonitor/gpumonitor.h index 565265a..3d22f6f 100644 --- a/rm/gpumonitor/gpumonitor.h +++ b/rm/gpumonitor/gpumonitor.h @@ -30,18 +30,7 @@ class GpuMonitor : public rmcommon::BaseThread { public: GpuMonitor(rmcommon::EventBus &eventBus, int monitorPeriod); ~GpuMonitor(); - -// /*! -// * \brief Sets the vector of possible CPU chip names. -// * \param names the comma separated list of module names -// */ -// void setCpuModuleNames(const std::string &names); -// -// /*! -// * \brief Sets the vector of possible battery module names. -// * \param names the comma separated list of module names -// */ -// void setBatteryModuleNames(const std::string &names); + }; #endif // #ifndef GPUMONITOR_H From f1647f1533a350a6fe11c75849262cb26f2ba453 Mon Sep 17 00:00:00 2001 From: Alessandro Vacca Date: Wed, 4 Oct 2023 11:48:10 +0200 Subject: [PATCH 05/10] Added dynamic makefile --- CMakeLists.txt | 5 +++++ rm/CMakeLists.txt | 5 ++++- rm/gpumonitor/CMakeLists.txt | 1 - rm/src/konromanager.cpp | 24 ++++++++++++++++++++++-- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a33f933..8de9b5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ project (konro) list (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/") option(TIMING "Enable low level timing" OFF) +option(NVIDIA "Enable NVIDIA GPU management" OFF) if (NOT DEFINED CGROUPBASEDIR) set(CGROUPBASEDIR "/sys/fs/cgroup" CACHE STRING "The cgroup base directory") @@ -22,6 +23,10 @@ if (TIMING) add_definitions(-DTIMING) endif() +if (NVIDIA) + add_definitions(-DNVIDIA) +endif() + add_subdirectory (common) add_subdirectory (lib) add_subdirectory (rm) diff --git a/rm/CMakeLists.txt b/rm/CMakeLists.txt index cbf9684..88dc0a3 100644 --- a/rm/CMakeLists.txt +++ b/rm/CMakeLists.txt @@ -9,7 +9,10 @@ add_subdirectory (platformcontrol) add_subdirectory (workloadmanager) add_subdirectory (policymanager) add_subdirectory (platformmonitor) -add_subdirectory (gpumonitor) +if(NVIDIA) + # Enable nvml code + add_subdirectory (gpumonitor) +endif(NVIDIA) file(GLOB konro_SOURCES "src/*.cpp") file(GLOB konro_HEADERS "src/*.h") diff --git a/rm/gpumonitor/CMakeLists.txt b/rm/gpumonitor/CMakeLists.txt index 72866e2..1428f56 100644 --- a/rm/gpumonitor/CMakeLists.txt +++ b/rm/gpumonitor/CMakeLists.txt @@ -10,5 +10,4 @@ add_library(gpumonitor ) target_include_directories(gpumonitor INTERFACE .) -#target_include_directories(gpumonitor PRIVATE CUDA::nvml) target_link_libraries(gpumonitor PUBLIC policymanager CUDA::nvml) diff --git a/rm/src/konromanager.cpp b/rm/src/konromanager.cpp index 9ada1db..ba73009 100644 --- a/rm/src/konromanager.cpp +++ b/rm/src/konromanager.cpp @@ -7,7 +7,9 @@ #include "policymanager.h" #include "workloadmanager.h" #include "platformmonitor.h" +#ifdef NVIDIA #include "gpumonitor.h" +#endif #include "proclistener.h" #include "konrohttp.h" #include "policytimer.h" @@ -50,7 +52,9 @@ struct KonroManager::KonroManagerImpl { rp::PolicyManager *policyManager; rp::PolicyTimer *policyTimer; PlatformMonitor *platformMonitor; +#ifdef NVIDIA GpuMonitor *gpuMonitor; +#endif KonroManagerImpl() { procListener = nullptr; @@ -59,7 +63,9 @@ struct KonroManager::KonroManagerImpl { policyManager = nullptr; policyTimer = nullptr; platformMonitor = nullptr; +#ifdef NVIDIA gpuMonitor = nullptr; +#endif } ~KonroManagerImpl() { @@ -69,7 +75,9 @@ struct KonroManager::KonroManagerImpl { delete policyManager; delete policyTimer; delete platformMonitor; +#ifdef NVIDIA delete gpuMonitor; +#endif } }; @@ -112,7 +120,9 @@ void KonroManager::loadConfiguration(std::string configFile) cfgMonitorPeriod_ = configRead(config, "platformmonitor", "monitorperiod", 20); cfgCpuModuleNames_ = configRead(config, "platformmonitor", "kernelcpumodulenames", std::string("coretemp,k10temp,k8temp,cputemp")); cfgBatteryModuleNames_ = configRead(config, "platformmonitor", "kernelbatterymodulenames", std::string("BAT")); +#ifdef NVIDIA cfgGpuMonitorPeriod_ = configRead(config, "gpumonitor", "monitorperiod", 20); +#endif httpListenHost_ = configRead(config, "http", "listenhost", std::string("localhost")); httpListenPort_ = configRead(config, "http", "listenport", 8080); changeContainerCgroup_ = configRead(config, "container", "changecontainercgroup", 1); @@ -122,7 +132,9 @@ void KonroManager::loadConfiguration(std::string configFile) cat_.info("MAIN configuration: policy timer seconds = %d", cfgTimerSeconds_); cat_.info("MAIN configuration: CPU monitor period seconds = %d", cfgMonitorPeriod_); cat_.info("MAIN configuration: CPU module names = %s", cfgCpuModuleNames_.c_str()); +#ifdef NVIDIA cat_.info("MAIN configuration: GPU monitor period seconds = %d", cfgGpuMonitorPeriod_); +#endif cat_.info("MAIN configuration: battery module names = %s", cfgBatteryModuleNames_.c_str()); cat_.info("MAIN configuration: HTTP listen on %s:%d", httpListenHost_.c_str(), httpListenPort_); cat_.info("MAIN configuration: change container cgroup = %s", @@ -143,7 +155,9 @@ void KonroManager::run() pimpl_->workloadManager = new wm::WorkloadManager(pimpl_->eventBus, pimpl_->cgc); pimpl_->procListener = new wm::ProcListener(pimpl_->eventBus); pimpl_->platformMonitor = new PlatformMonitor(pimpl_->eventBus, pimpl_->platformDescription, cfgMonitorPeriod_); +#ifdef NVIDIA pimpl_->gpuMonitor = new GpuMonitor(pimpl_->eventBus, cfgGpuMonitorPeriod_); +#endif pimpl_->policyTimer = new rp::PolicyTimer(pimpl_->eventBus, cfgTimerSeconds_); pimpl_->platformDescription.logTopology(); @@ -156,7 +170,7 @@ void KonroManager::run() // 2. WorkloadManager runs in a separate thread // 3. PolicyManager runs in a separate thread // 4. PlatformMonitor runs in a separate thread - // 5. GPUMonitor runs in a separate thread + // 5. GPUMonitor runs in a separate thread, if present // 6. KonroHttp runs in a separate thread // 7. PolicyTimer runs in a separate thread @@ -177,8 +191,10 @@ void KonroManager::run() cat_.info("MAIN starting PlatformMonitor thread"); pimpl_->platformMonitor->start(); - cat_.info("MAIN starting PlatformMonitor thread"); +#ifdef NVIDIA + cat_.info("MAIN starting GPUMonitor thread"); pimpl_->gpuMonitor->start(); +#endif cat_.info("MAIN starting HTTP thread"); pimpl_->http->start(); @@ -195,7 +211,9 @@ void KonroManager::run() pimpl_->policyTimer->stop(); } pimpl_->platformMonitor->stop(); +#ifdef NVIDIA pimpl_->gpuMonitor->stop(); +#endif pimpl_->workloadManager->stop(); pimpl_->policyManager->stop(); @@ -208,7 +226,9 @@ void KonroManager::run() pimpl_->policyTimer->join(); } pimpl_->platformMonitor->join(); +#ifdef NVIDIA pimpl_->gpuMonitor->join(); +#endif pimpl_->workloadManager->join(); pimpl_->policyManager->join(); From 1a64cf1f4a98e12641a07c64030508b3535b163c Mon Sep 17 00:00:00 2001 From: Federico Date: Wed, 4 Oct 2023 12:00:30 +0200 Subject: [PATCH 06/10] FIX: CMake --- rm/CMakeLists.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rm/CMakeLists.txt b/rm/CMakeLists.txt index 88dc0a3..8e3118b 100644 --- a/rm/CMakeLists.txt +++ b/rm/CMakeLists.txt @@ -21,6 +21,8 @@ include_directories(${PROJECT_SOURCE_DIR}/rm/include) add_executable (konro ${konro_SOURCES} ${konro_HEADERS}) target_compile_definitions(konro PUBLIC KONRO_RM) + +if(NVIDIA) target_link_libraries(konro PUBLIC konro-common rmcommon @@ -30,5 +32,15 @@ target_link_libraries(konro PUBLIC platformmonitor gpumonitor ${LOG4CPP_LIBRARIES}) +else(NVIDIA) +target_link_libraries(konro PUBLIC + konro-common + rmcommon + platformcontrol + workloadmanager + policymanager + platformmonitor + ${LOG4CPP_LIBRARIES}) +endif(NVIDIA) configure_file(konro.ini.in konro.ini) From 246ab31a1a1ac61340e5f8b509cf791620e3fa1f Mon Sep 17 00:00:00 2001 From: Alessandro Vacca <99895808+AlessandroVacca@users.noreply.github.com> Date: Wed, 4 Oct 2023 12:15:48 +0200 Subject: [PATCH 07/10] Update README.md --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f9d7b83..1cd64f0 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,15 @@ A modern resource manager OpenCV is required only for the peopledetect demo. If it is not installed, peopledetect is not compiled. +# Optional: Nvidia GPU support +nvidia-cuda-toolkit is required for the compilation with GPU monitoring. It can be installed from your package manager or by manually by following this link https://developer.nvidia.com/cuda-downloads. +In order to compile, you need to add the NVIDIA flag to cmake: +* `mkdir build && cd build` +* `cmake -DNVIDIA=ON ..` +* `make` -Cuda Toolkit is required for the gpu plugin. It can be installed following this link https://developer.nvidia.com/cuda-downloads +If no GPUs are present, the manager will still work, but the monitor will just skip them. +If nothing is specified, GPU support will be disabled. # Development QtCreator has been used as IDE for development on Ubuntu 22.04.2 LTS. From cbfa18634b96268fbcbd7301967d7a52e4d2fceb Mon Sep 17 00:00:00 2001 From: Alessandro Vacca Date: Thu, 5 Oct 2023 18:54:45 +0200 Subject: [PATCH 08/10] Renamed nvidia dependant code --- rm/CMakeLists.txt | 4 +- rm/gpumonitor/CMakeLists.txt | 13 --- rm/librmcommon/gpuload.h | 4 +- rm/librmcommon/gpupower.h | 2 +- rm/librmcommon/gputemperature.h | 10 +- rm/nvidiamonitor/CMakeLists.txt | 13 +++ .../nvidiamonitor.cpp} | 94 ++++++++----------- .../nvidiamonitor.h} | 22 ++--- rm/src/konromanager.cpp | 24 ++--- rm/src/konromanager.h | 2 +- 10 files changed, 87 insertions(+), 101 deletions(-) delete mode 100644 rm/gpumonitor/CMakeLists.txt create mode 100644 rm/nvidiamonitor/CMakeLists.txt rename rm/{gpumonitor/gpumonitor.cpp => nvidiamonitor/nvidiamonitor.cpp} (54%) rename rm/{gpumonitor/gpumonitor.h => nvidiamonitor/nvidiamonitor.h} (61%) diff --git a/rm/CMakeLists.txt b/rm/CMakeLists.txt index 8e3118b..7a7dcd6 100644 --- a/rm/CMakeLists.txt +++ b/rm/CMakeLists.txt @@ -11,7 +11,7 @@ add_subdirectory (policymanager) add_subdirectory (platformmonitor) if(NVIDIA) # Enable nvml code - add_subdirectory (gpumonitor) + add_subdirectory (nvidiamonitor) endif(NVIDIA) file(GLOB konro_SOURCES "src/*.cpp") @@ -30,7 +30,7 @@ target_link_libraries(konro PUBLIC workloadmanager policymanager platformmonitor - gpumonitor + nvidiamonitor ${LOG4CPP_LIBRARIES}) else(NVIDIA) target_link_libraries(konro PUBLIC diff --git a/rm/gpumonitor/CMakeLists.txt b/rm/gpumonitor/CMakeLists.txt deleted file mode 100644 index 1428f56..0000000 --- a/rm/gpumonitor/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -set(CMAKE_CXX_STANDARD 14) - -find_package(CUDAToolkit REQUIRED) - -file(GLOB gpumonitor_SOURCES "*.cpp") -file(GLOB gpumonitor_HEADERS "*.h") -add_library(gpumonitor - ${gpumonitor_HEADERS} - ${gpumonitor_SOURCES} -) - -target_include_directories(gpumonitor INTERFACE .) -target_link_libraries(gpumonitor PUBLIC policymanager CUDA::nvml) diff --git a/rm/librmcommon/gpuload.h b/rm/librmcommon/gpuload.h index 138ddd3..17f0025 100644 --- a/rm/librmcommon/gpuload.h +++ b/rm/librmcommon/gpuload.h @@ -6,10 +6,10 @@ namespace rmcommon { /*! - * \class encapsulates cpu utilization information + * \class encapsulates GPU utilization information */ class GpuLoad { - /*! Usage of each CPU */ + /*! % Usage of each GPU */ std::vector gpu_; public: diff --git a/rm/librmcommon/gpupower.h b/rm/librmcommon/gpupower.h index 9e53153..61eeb94 100644 --- a/rm/librmcommon/gpupower.h +++ b/rm/librmcommon/gpupower.h @@ -5,7 +5,7 @@ namespace rmcommon { /*! - * \class encapsulates power information about the machine + * \class encapsulates power information about the GPU */ class GpuPower { /* Current power in mW */ diff --git a/rm/librmcommon/gputemperature.h b/rm/librmcommon/gputemperature.h index 4b40820..2e8df81 100644 --- a/rm/librmcommon/gputemperature.h +++ b/rm/librmcommon/gputemperature.h @@ -1,14 +1,14 @@ -#ifndef GPUTEMLERATURE_H -#define GPUTEMLERATURE_H +#ifndef GPUTEMPERATURE_H +#define GPUTEMPERATURE_H #include namespace rmcommon { /*! - * \class encapsulates temperature information about the machine + * \class encapsulates temperature information about the GPU */ class GpuTemperature { - /* Current power in mW */ + /* Current temperature in CELSIUS */ std::vector gpu_; public: @@ -41,4 +41,4 @@ namespace rmcommon { } // namespace rmcommon -#endif // GPUTEMLERATURE_H +#endif // GPUTEMPERATURE_H diff --git a/rm/nvidiamonitor/CMakeLists.txt b/rm/nvidiamonitor/CMakeLists.txt new file mode 100644 index 0000000..8370273 --- /dev/null +++ b/rm/nvidiamonitor/CMakeLists.txt @@ -0,0 +1,13 @@ +set(CMAKE_CXX_STANDARD 14) + +find_package(CUDAToolkit REQUIRED) + +file(GLOB nvidiamonitor_SOURCES "*.cpp") +file(GLOB nvidiamonitor_HEADERS "*.h") +add_library(nvidiamonitor + ${nvidiamonitor_HEADERS} + ${nvidiamonitor_SOURCES} +) + +target_include_directories(nvidiamonitor INTERFACE .) +target_link_libraries(nvidiamonitor PUBLIC policymanager CUDA::nvml) diff --git a/rm/gpumonitor/gpumonitor.cpp b/rm/nvidiamonitor/nvidiamonitor.cpp similarity index 54% rename from rm/gpumonitor/gpumonitor.cpp rename to rm/nvidiamonitor/nvidiamonitor.cpp index 2084813..d62a623 100644 --- a/rm/gpumonitor/gpumonitor.cpp +++ b/rm/nvidiamonitor/nvidiamonitor.cpp @@ -1,4 +1,4 @@ -#include "gpumonitor.h" +#include "nvidiamonitor.h" #include #include #include @@ -16,64 +16,58 @@ using namespace std; -struct GpuMonitor::GpuMonitorImpl { +struct NvidiaMonitor::NvidiaMonitorImpl { unsigned int nvml_devices_; bool initialized = false; - vector gpuChips; + vector nvidiaChips; nvmlReturn_t result; - - GpuMonitorImpl() { + NvidiaMonitorImpl() { init(); } - ~GpuMonitorImpl() { + ~NvidiaMonitorImpl() { fini(); } void init() { - result = nvmlInit_v2(); - if (result != NVML_SUCCESS) - { - log4cpp::Category::getRoot().info( "Failed to initialize NVML: %s", nvmlErrorString(result)); + if (result != NVML_SUCCESS) { + log4cpp::Category::getRoot().info("Failed to initialize NVML: %s", nvmlErrorString(result)); this->initialized = false; - }else{ + } else { this->initialized = true; result = nvmlDeviceGetCount(&nvml_devices_); - log4cpp::Category::getRoot().info( "Found %d NVML devices", nvml_devices_); - for (unsigned int i = 0; i < nvml_devices_; i++) - { + log4cpp::Category::getRoot().info("Found %d NVML devices", nvml_devices_); + for (unsigned int i = 0; i < nvml_devices_; i++) { nvmlDevice_t device; result = nvmlDeviceGetHandleByIndex(i, &device); - if (result != NVML_SUCCESS) - { - log4cpp::Category::getRoot().info( "Failed to get device handle: %s", nvmlErrorString(result)); + if (result != NVML_SUCCESS) { + log4cpp::Category::getRoot().info("Failed to get device handle: %s", nvmlErrorString(result)); continue; // Continue with the next device on error } char name[NVML_DEVICE_NAME_BUFFER_SIZE]; result = nvmlDeviceGetName(device, name, NVML_DEVICE_NAME_BUFFER_SIZE); - gpuChips.emplace_back(name); + nvidiaChips.emplace_back(name); } } } void fini() { - if (this->initialized){ + if (this->initialized) { result = nvmlShutdown(); - if (result != NVML_SUCCESS) - { - log4cpp::Category::getRoot().info( "Failed to initialize NVML: %s", nvmlErrorString(result)); + if (result != NVML_SUCCESS) { + log4cpp::Category::getRoot().info("Failed to initialize NVML: %s", nvmlErrorString(result)); } } } - bool isGpuChip(string chip) { - return find(begin(gpuChips), end(gpuChips), chip) != end(gpuChips); + bool isNvidiaChip(string chip) { + return find(begin(nvidiaChips), end(nvidiaChips), chip) != end(nvidiaChips); } - void handleGpuTemp(nvmlDevice_t device, rmcommon::GpuTemperature &gpuTemp) { + void handleNvidiaTemp(nvmlDevice_t device, rmcommon::GpuTemperature &gpuTemp) { unsigned int temp; result = nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &temp); if (result == NVML_SUCCESS) { @@ -81,7 +75,7 @@ struct GpuMonitor::GpuMonitorImpl { } } - void handleGpuPower(nvmlDevice_t device, rmcommon::GpuPower &gpuPower) { + void handleNvidiaPower(nvmlDevice_t device, rmcommon::GpuPower &gpuPower) { unsigned int power; result = nvmlDeviceGetPowerUsage(device, &power); if (result == NVML_SUCCESS) { @@ -89,7 +83,7 @@ struct GpuMonitor::GpuMonitorImpl { } } - void handleGpuLoad(nvmlDevice_t device, rmcommon::GpuLoad &gpuLoad) { + void handleNvidiaLoad(nvmlDevice_t device, rmcommon::GpuLoad &gpuLoad) { nvmlUtilization_t utilization; result = nvmlDeviceGetUtilizationRates(device, &utilization); if (result == NVML_SUCCESS) { @@ -97,23 +91,19 @@ struct GpuMonitor::GpuMonitorImpl { } } - - - /*! - * Detect each gpu available on the machine and calls the + * Detect each nvidia gpu available on the machine and calls the * appropriate handler function to store information about its * current status. */ - void handleGPUs(rmcommon::GpuLoad &gpuLoad, rmcommon::GpuPower &gpuPower, rmcommon::GpuTemperature &gpuTemperature){ - if (this->initialized){ - for (unsigned int i = 0; i < nvml_devices_; i++) - { + void + handleNVGPUs(rmcommon::GpuLoad &gpuLoad, rmcommon::GpuPower &gpuPower, rmcommon::GpuTemperature &gpuTemperature) { + if (this->initialized) { + for (unsigned int i = 0; i < nvml_devices_; i++) { nvmlDevice_t device; result = nvmlDeviceGetHandleByIndex(i, &device); - if (result != NVML_SUCCESS) - { - log4cpp::Category::getRoot().info( "Failed to get device handle: %s", nvmlErrorString(result)); + if (result != NVML_SUCCESS) { + log4cpp::Category::getRoot().info("Failed to get device handle: %s", nvmlErrorString(result)); continue; // Continue with the next device on error } handleGpuTemp(device, gpuTemperature); @@ -121,28 +111,24 @@ struct GpuMonitor::GpuMonitorImpl { handleGpuLoad(device, gpuLoad); } } - } + } }; -GpuMonitor::GpuMonitor(rmcommon::EventBus &eventBus, int monitorPeriod) : - pimpl_(new GpuMonitorImpl()), - cat_(log4cpp::Category::getRoot()), - monitorPeriod_(monitorPeriod), - bus_(eventBus) -{ +NvidiaMonitor::NvidiaMonitor(rmcommon::EventBus &eventBus, int monitorPeriod) : + pimpl_(new NvidiaMonitorImpl()), + cat_(log4cpp::Category::getRoot()), + monitorPeriod_(monitorPeriod), + bus_(eventBus) { } -GpuMonitor::~GpuMonitor() -{ +NvidiaMonitor::~NvidiaMonitor() { } - -void GpuMonitor::run() -{ - setThreadName("GPUMONITOR"); - cat_.info("GPUMONITOR running"); +void NvidiaMonitor::run() { + setThreadName("NVIDIAMONITOR"); + cat_.info("NVIDIAMONITOR running"); while (!stopped()) { - for (int i = 0; i < monitorPeriod_ && !stopped() ; ++i) { + for (int i = 0; i < monitorPeriod_ && !stopped(); ++i) { this_thread::sleep_for(chrono::seconds(1)); } if (!stopped()) { @@ -153,5 +139,5 @@ void GpuMonitor::run() bus_.publish(new rmcommon::MonitorGpuEvent(gpuTemp, gpuPower, gpuLoad)); } } - cat_.info("GPUMONITOR exiting"); + cat_.info("NVIDIAMONITOR exiting"); } diff --git a/rm/gpumonitor/gpumonitor.h b/rm/nvidiamonitor/nvidiamonitor.h similarity index 61% rename from rm/gpumonitor/gpumonitor.h rename to rm/nvidiamonitor/nvidiamonitor.h index 3d22f6f..6588f34 100644 --- a/rm/gpumonitor/gpumonitor.h +++ b/rm/nvidiamonitor/nvidiamonitor.h @@ -1,5 +1,5 @@ -#ifndef GPUMONITOR_H -#define GPUMONITOR_H +#ifndef NVIDIAMONITOR_H +#define NVIDIAMONITOR_H #include "eventbus.h" #include "basethread.h" @@ -17,22 +17,22 @@ * \class periodically samples information about the platform status. * This information is then encapsulated in a MonitorEvent and published * to the EventBus. - * GpuMonitor runs in a dedicated thread. + * NvidiaMonitor runs in a dedicated thread. */ -class GpuMonitor : public rmcommon::BaseThread { - struct GpuMonitorImpl; - std::unique_ptr pimpl_; +class NvidiaMonitor : public rmcommon::BaseThread { + struct NvidiaMonitorImpl; + std::unique_ptr pimpl_; log4cpp::Category &cat_; int monitorPeriod_; rmcommon::EventBus &bus_; virtual void run() override; + public: - GpuMonitor(rmcommon::EventBus &eventBus, int monitorPeriod); - ~GpuMonitor(); - -}; + NvidiaMonitor(rmcommon::EventBus &eventBus, int monitorPeriod); -#endif // #ifndef GPUMONITOR_H + ~NvidiaMonitor(); +}; +#endif // NVIDIAMONITOR_H \ No newline at end of file diff --git a/rm/src/konromanager.cpp b/rm/src/konromanager.cpp index ba73009..9d87058 100644 --- a/rm/src/konromanager.cpp +++ b/rm/src/konromanager.cpp @@ -8,7 +8,7 @@ #include "workloadmanager.h" #include "platformmonitor.h" #ifdef NVIDIA -#include "gpumonitor.h" +#include "nvidiamonitor.h" #endif #include "proclistener.h" #include "konrohttp.h" @@ -53,7 +53,7 @@ struct KonroManager::KonroManagerImpl { rp::PolicyTimer *policyTimer; PlatformMonitor *platformMonitor; #ifdef NVIDIA - GpuMonitor *gpuMonitor; + NvidiaMonitor *nvidiaMonitor; #endif KonroManagerImpl() { @@ -64,7 +64,7 @@ struct KonroManager::KonroManagerImpl { policyTimer = nullptr; platformMonitor = nullptr; #ifdef NVIDIA - gpuMonitor = nullptr; + nvidiaMonitor = nullptr; #endif } @@ -76,7 +76,7 @@ struct KonroManager::KonroManagerImpl { delete policyTimer; delete platformMonitor; #ifdef NVIDIA - delete gpuMonitor; + delete nvidiaMonitor; #endif } }; @@ -121,7 +121,7 @@ void KonroManager::loadConfiguration(std::string configFile) cfgCpuModuleNames_ = configRead(config, "platformmonitor", "kernelcpumodulenames", std::string("coretemp,k10temp,k8temp,cputemp")); cfgBatteryModuleNames_ = configRead(config, "platformmonitor", "kernelbatterymodulenames", std::string("BAT")); #ifdef NVIDIA - cfgGpuMonitorPeriod_ = configRead(config, "gpumonitor", "monitorperiod", 20); + cfgNvidiaMonitorPeriod_ = configRead(config, "nvidiamonitor", "monitorperiod", 20); #endif httpListenHost_ = configRead(config, "http", "listenhost", std::string("localhost")); httpListenPort_ = configRead(config, "http", "listenport", 8080); @@ -133,7 +133,7 @@ void KonroManager::loadConfiguration(std::string configFile) cat_.info("MAIN configuration: CPU monitor period seconds = %d", cfgMonitorPeriod_); cat_.info("MAIN configuration: CPU module names = %s", cfgCpuModuleNames_.c_str()); #ifdef NVIDIA - cat_.info("MAIN configuration: GPU monitor period seconds = %d", cfgGpuMonitorPeriod_); + cat_.info("MAIN configuration: NVIDIA GPU monitor period seconds = %d", cfgNvidiaMonitorPeriod_); #endif cat_.info("MAIN configuration: battery module names = %s", cfgBatteryModuleNames_.c_str()); cat_.info("MAIN configuration: HTTP listen on %s:%d", httpListenHost_.c_str(), httpListenPort_); @@ -156,7 +156,7 @@ void KonroManager::run() pimpl_->procListener = new wm::ProcListener(pimpl_->eventBus); pimpl_->platformMonitor = new PlatformMonitor(pimpl_->eventBus, pimpl_->platformDescription, cfgMonitorPeriod_); #ifdef NVIDIA - pimpl_->gpuMonitor = new GpuMonitor(pimpl_->eventBus, cfgGpuMonitorPeriod_); + pimpl_->nvidiaMonitor = new NvidiaMonitor(pimpl_->eventBus, cfgGpuMonitorPeriod_); #endif pimpl_->policyTimer = new rp::PolicyTimer(pimpl_->eventBus, cfgTimerSeconds_); @@ -170,7 +170,7 @@ void KonroManager::run() // 2. WorkloadManager runs in a separate thread // 3. PolicyManager runs in a separate thread // 4. PlatformMonitor runs in a separate thread - // 5. GPUMonitor runs in a separate thread, if present + // 5. NvidiaMonitor runs in a separate thread, if present // 6. KonroHttp runs in a separate thread // 7. PolicyTimer runs in a separate thread @@ -192,8 +192,8 @@ void KonroManager::run() pimpl_->platformMonitor->start(); #ifdef NVIDIA - cat_.info("MAIN starting GPUMonitor thread"); - pimpl_->gpuMonitor->start(); + cat_.info("MAIN starting NvidiaMonitor thread"); + pimpl_->nvidiaMonitor->start(); #endif cat_.info("MAIN starting HTTP thread"); @@ -212,7 +212,7 @@ void KonroManager::run() } pimpl_->platformMonitor->stop(); #ifdef NVIDIA - pimpl_->gpuMonitor->stop(); + pimpl_->nvidiaMonitor->stop(); #endif pimpl_->workloadManager->stop(); pimpl_->policyManager->stop(); @@ -227,7 +227,7 @@ void KonroManager::run() } pimpl_->platformMonitor->join(); #ifdef NVIDIA - pimpl_->gpuMonitor->join(); + pimpl_->nvidiaMonitor->join(); #endif pimpl_->workloadManager->join(); pimpl_->policyManager->join(); diff --git a/rm/src/konromanager.h b/rm/src/konromanager.h index 83e3093..bc0466a 100644 --- a/rm/src/konromanager.h +++ b/rm/src/konromanager.h @@ -14,7 +14,7 @@ class KonroManager { std::string cfgPolicyName_; int cfgTimerSeconds_; // 0 means "no timer" int cfgMonitorPeriod_; - int cfgGpuMonitorPeriod_; + int cfgNvidiaMonitorPeriod_; std::string cfgCpuModuleNames_; std::string cfgBatteryModuleNames_; std::string httpListenHost_; From e94dddc8561a606a80a12e68e7726d85d51e5504 Mon Sep 17 00:00:00 2001 From: Alessandro Vacca <99895808+AlessandroVacca@users.noreply.github.com> Date: Thu, 5 Oct 2023 18:58:01 +0200 Subject: [PATCH 09/10] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1cd64f0..8c0a31f 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,14 @@ A modern resource manager OpenCV is required only for the peopledetect demo. If it is not installed, peopledetect is not compiled. # Optional: Nvidia GPU support -nvidia-cuda-toolkit is required for the compilation with GPU monitoring. It can be installed from your package manager or by manually by following this link https://developer.nvidia.com/cuda-downloads. +nvidia-cuda-toolkit is required in order to compile with NVIDIA GPU monitoring. It can be installed from your package manager or by manually by following this link https://developer.nvidia.com/cuda-downloads. In order to compile, you need to add the NVIDIA flag to cmake: * `mkdir build && cd build` * `cmake -DNVIDIA=ON ..` * `make` -If no GPUs are present, the manager will still work, but the monitor will just skip them. -If nothing is specified, GPU support will be disabled. +If no NVIDIA GPUs are present, the manager will still work, but the monitor will just skip them. +If nothing is specified, NVIDIA GPU support will be disabled. # Development QtCreator has been used as IDE for development on Ubuntu 22.04.2 LTS. From 3089f8017c5fb8df9cb42b68943844c4e5a7e8d9 Mon Sep 17 00:00:00 2001 From: Federico Date: Mon, 9 Oct 2023 20:31:34 +0200 Subject: [PATCH 10/10] NVIDIA: finished to rename instances --- rm/librmcommon/events/monitorgpuevent.h | 4 ++-- rm/nvidiamonitor/nvidiamonitor.cpp | 8 ++++---- rm/src/konromanager.cpp | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/rm/librmcommon/events/monitorgpuevent.h b/rm/librmcommon/events/monitorgpuevent.h index fcbb6ef..c768f97 100644 --- a/rm/librmcommon/events/monitorgpuevent.h +++ b/rm/librmcommon/events/monitorgpuevent.h @@ -30,11 +30,11 @@ class MonitorGpuEvent : public BaseEvent { return gpuTemp_; } - GpuPower getPlatformPower() const { + GpuPower getGpuPower() const { return gpuActualPower_; } - GpuLoad getPlatformLoad() const { + GpuLoad getGpuLoad() const { return gpuLoad_; } diff --git a/rm/nvidiamonitor/nvidiamonitor.cpp b/rm/nvidiamonitor/nvidiamonitor.cpp index d62a623..f0b38d9 100644 --- a/rm/nvidiamonitor/nvidiamonitor.cpp +++ b/rm/nvidiamonitor/nvidiamonitor.cpp @@ -106,9 +106,9 @@ struct NvidiaMonitor::NvidiaMonitorImpl { log4cpp::Category::getRoot().info("Failed to get device handle: %s", nvmlErrorString(result)); continue; // Continue with the next device on error } - handleGpuTemp(device, gpuTemperature); - handleGpuPower(device, gpuPower); - handleGpuLoad(device, gpuLoad); + handleNvidiaTemp(device, gpuTemperature); + handleNvidiaPower(device, gpuPower); + handleNvidiaLoad(device, gpuLoad); } } } @@ -135,7 +135,7 @@ void NvidiaMonitor::run() { rmcommon::GpuTemperature gpuTemp; rmcommon::GpuPower gpuPower; rmcommon::GpuLoad gpuLoad; - pimpl_->handleGPUs(gpuLoad, gpuPower, gpuTemp); + pimpl_->handleNVGPUs(gpuLoad, gpuPower, gpuTemp); bus_.publish(new rmcommon::MonitorGpuEvent(gpuTemp, gpuPower, gpuLoad)); } } diff --git a/rm/src/konromanager.cpp b/rm/src/konromanager.cpp index 9d87058..267ae2d 100644 --- a/rm/src/konromanager.cpp +++ b/rm/src/konromanager.cpp @@ -156,7 +156,7 @@ void KonroManager::run() pimpl_->procListener = new wm::ProcListener(pimpl_->eventBus); pimpl_->platformMonitor = new PlatformMonitor(pimpl_->eventBus, pimpl_->platformDescription, cfgMonitorPeriod_); #ifdef NVIDIA - pimpl_->nvidiaMonitor = new NvidiaMonitor(pimpl_->eventBus, cfgGpuMonitorPeriod_); + pimpl_->nvidiaMonitor = new NvidiaMonitor(pimpl_->eventBus, cfgNvidiaMonitorPeriod_); #endif pimpl_->policyTimer = new rp::PolicyTimer(pimpl_->eventBus, cfgTimerSeconds_);