2020-03-30 19:48:56 +00:00
|
|
|
#include <iostream>
|
2020-03-20 13:26:37 +00:00
|
|
|
#include <cstring>
|
|
|
|
#include <sstream>
|
|
|
|
#include <unordered_map>
|
2020-04-20 19:51:55 +00:00
|
|
|
#include <memory>
|
|
|
|
#include <functional>
|
2021-07-16 00:28:46 +00:00
|
|
|
#include <spdlog/spdlog.h>
|
2020-03-20 11:54:08 +00:00
|
|
|
#include "nvctrl.h"
|
|
|
|
#include "loaders/loader_nvctrl.h"
|
2020-04-20 19:51:55 +00:00
|
|
|
#include "loaders/loader_x11.h"
|
2020-03-20 13:26:37 +00:00
|
|
|
#include "string_utils.h"
|
2020-05-09 23:36:09 +00:00
|
|
|
#include "overlay.h"
|
2020-03-20 13:26:37 +00:00
|
|
|
|
|
|
|
typedef std::unordered_map<std::string, std::string> string_map;
|
2020-04-20 19:51:55 +00:00
|
|
|
static std::unique_ptr<Display, std::function<void(Display*)>> display;
|
2020-03-20 11:54:08 +00:00
|
|
|
|
|
|
|
struct nvctrlInfo nvctrl_info;
|
2020-03-20 14:33:43 +00:00
|
|
|
bool nvctrlSuccess = false;
|
|
|
|
|
2020-08-04 18:27:12 +00:00
|
|
|
static bool find_nv_x11(libnvctrl_loader& nvctrl, Display*& dpy)
|
2020-03-20 14:33:43 +00:00
|
|
|
{
|
2020-04-20 19:51:55 +00:00
|
|
|
char buf[8] {};
|
2023-05-25 06:27:20 +00:00
|
|
|
auto libx11 = get_libx11();
|
2020-04-20 19:51:55 +00:00
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
snprintf(buf, sizeof(buf), ":%d", i);
|
2023-05-25 06:27:20 +00:00
|
|
|
Display *d = libx11->XOpenDisplay(buf);
|
2020-04-20 19:51:55 +00:00
|
|
|
if (d) {
|
2023-05-04 23:48:43 +00:00
|
|
|
if (nvctrl.XNVCTRLIsNvScreen(d, i)) {
|
2020-04-20 19:51:55 +00:00
|
|
|
dpy = d;
|
2021-07-21 16:48:45 +00:00
|
|
|
SPDLOG_DEBUG("XNVCtrl is using display {}", buf);
|
2020-04-20 19:51:55 +00:00
|
|
|
return true;
|
|
|
|
}
|
2023-05-25 06:27:20 +00:00
|
|
|
libx11->XCloseDisplay(d);
|
2020-04-13 21:25:27 +00:00
|
|
|
}
|
2020-03-20 14:33:43 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2020-03-20 11:54:08 +00:00
|
|
|
|
2020-04-20 19:51:55 +00:00
|
|
|
bool checkXNVCtrl()
|
|
|
|
{
|
2023-05-25 06:27:20 +00:00
|
|
|
if (!get_libx11()->IsLoaded())
|
2020-04-20 19:51:55 +00:00
|
|
|
return false;
|
|
|
|
|
2020-08-04 18:27:12 +00:00
|
|
|
auto& nvctrl = get_libnvctrl_loader();
|
2020-04-20 19:51:55 +00:00
|
|
|
if (!nvctrl.IsLoaded()) {
|
2021-07-21 16:48:45 +00:00
|
|
|
SPDLOG_ERROR("XNVCtrl loader failed to load");
|
2020-04-20 19:51:55 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Display *dpy;
|
2020-08-04 18:27:12 +00:00
|
|
|
nvctrlSuccess = find_nv_x11(nvctrl, dpy);
|
2020-04-20 19:51:55 +00:00
|
|
|
|
|
|
|
if (!nvctrlSuccess) {
|
2021-07-21 16:48:45 +00:00
|
|
|
SPDLOG_ERROR("XNVCtrl didn't find the correct display");
|
2020-04-20 19:51:55 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2023-05-25 06:27:20 +00:00
|
|
|
auto local_x11 = get_libx11();
|
2020-04-20 19:51:55 +00:00
|
|
|
display = { dpy,
|
|
|
|
[local_x11](Display *dpy) {
|
|
|
|
local_x11->XCloseDisplay(dpy);
|
|
|
|
}
|
|
|
|
};
|
2020-05-09 23:36:09 +00:00
|
|
|
// get device id at init
|
|
|
|
int64_t pci_id;
|
|
|
|
nvctrl.XNVCTRLQueryTargetAttribute64(display.get(),
|
|
|
|
NV_CTRL_TARGET_TYPE_GPU,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
NV_CTRL_PCI_ID,
|
|
|
|
&pci_id);
|
2020-05-10 00:31:58 +00:00
|
|
|
deviceID = (pci_id & 0xFFFF);
|
2020-04-20 19:51:55 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void parse_token(std::string token, string_map& options) {
|
2020-03-20 13:26:37 +00:00
|
|
|
std::string param, value;
|
|
|
|
|
|
|
|
size_t equal = token.find("=");
|
|
|
|
if (equal == std::string::npos)
|
|
|
|
return;
|
|
|
|
|
|
|
|
value = token.substr(equal+1);
|
|
|
|
|
|
|
|
param = token.substr(0, equal);
|
|
|
|
trim(param);
|
|
|
|
trim(value);
|
|
|
|
if (!param.empty())
|
|
|
|
options[param] = value;
|
|
|
|
}
|
|
|
|
|
2023-03-03 10:43:59 +00:00
|
|
|
static char* get_attr_target_string(libnvctrl_loader& nvctrl, int attr, int target_type, int target_id) {
|
2020-03-30 19:48:56 +00:00
|
|
|
char* c = nullptr;
|
2020-04-20 19:51:55 +00:00
|
|
|
if (!nvctrl.XNVCTRLQueryTargetStringAttribute(display.get(), target_type, target_id, 0, attr, &c)) {
|
2021-07-21 16:48:45 +00:00
|
|
|
SPDLOG_ERROR("Failed to query attribute '{}'", attr);
|
2020-03-30 19:48:56 +00:00
|
|
|
}
|
|
|
|
return c;
|
2020-03-20 11:54:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void getNvctrlInfo(){
|
2020-03-20 13:26:37 +00:00
|
|
|
string_map params;
|
|
|
|
std::string token;
|
2020-08-04 18:27:12 +00:00
|
|
|
auto& nvctrl = get_libnvctrl_loader();
|
2020-03-20 11:54:08 +00:00
|
|
|
|
2020-04-20 19:51:55 +00:00
|
|
|
if (!display)
|
2020-04-01 19:52:12 +00:00
|
|
|
return;
|
|
|
|
|
2020-03-20 13:26:37 +00:00
|
|
|
int enums[] = {
|
|
|
|
NV_CTRL_STRING_GPU_UTILIZATION,
|
|
|
|
NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS,
|
|
|
|
0 // keep null
|
|
|
|
};
|
|
|
|
|
|
|
|
for (size_t i=0; enums[i]; i++) {
|
2020-08-04 18:27:12 +00:00
|
|
|
char* str = get_attr_target_string(nvctrl, enums[i], NV_CTRL_TARGET_TYPE_GPU, 0);
|
2020-03-20 13:26:37 +00:00
|
|
|
if (!str)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
std::stringstream ss (str);
|
|
|
|
while (std::getline(ss, token, ',')) {
|
|
|
|
parse_token(token, params);
|
2020-03-20 11:54:08 +00:00
|
|
|
}
|
2020-03-20 13:26:37 +00:00
|
|
|
free(str);
|
2020-03-20 11:54:08 +00:00
|
|
|
}
|
|
|
|
|
2020-03-20 13:26:37 +00:00
|
|
|
if (!try_stoi(nvctrl_info.load, params["graphics"]))
|
|
|
|
nvctrl_info.load = 0;
|
|
|
|
if (!try_stoi(nvctrl_info.CoreClock, params["nvclock"]))
|
|
|
|
nvctrl_info.CoreClock = 0;
|
|
|
|
if (!try_stoi(nvctrl_info.MemClock, params["memclock"]))
|
|
|
|
nvctrl_info.MemClock = 0;
|
|
|
|
|
|
|
|
int64_t temp = 0;
|
2020-04-20 19:51:55 +00:00
|
|
|
nvctrl.XNVCTRLQueryTargetAttribute64(display.get(),
|
2020-03-20 11:54:08 +00:00
|
|
|
NV_CTRL_TARGET_TYPE_GPU,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
NV_CTRL_GPU_CORE_TEMPERATURE,
|
|
|
|
&temp);
|
|
|
|
nvctrl_info.temp = temp;
|
|
|
|
|
2020-03-20 13:26:37 +00:00
|
|
|
int64_t memtotal = 0;
|
2020-04-20 19:51:55 +00:00
|
|
|
nvctrl.XNVCTRLQueryTargetAttribute64(display.get(),
|
2020-03-20 11:54:08 +00:00
|
|
|
NV_CTRL_TARGET_TYPE_GPU,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
NV_CTRL_TOTAL_DEDICATED_GPU_MEMORY,
|
|
|
|
&memtotal);
|
|
|
|
nvctrl_info.memoryTotal = memtotal;
|
|
|
|
|
2020-03-20 13:26:37 +00:00
|
|
|
int64_t memused = 0;
|
2020-04-20 19:51:55 +00:00
|
|
|
nvctrl.XNVCTRLQueryTargetAttribute64(display.get(),
|
2020-03-20 11:54:08 +00:00
|
|
|
NV_CTRL_TARGET_TYPE_GPU,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
NV_CTRL_USED_DEDICATED_GPU_MEMORY,
|
|
|
|
&memused);
|
2020-03-20 13:26:37 +00:00
|
|
|
nvctrl_info.memoryUsed = memused;
|
2023-04-20 01:10:21 +00:00
|
|
|
|
2023-05-04 23:48:43 +00:00
|
|
|
nvctrl_info.fan_speed = getNvctrlFanSpeed();
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t getNvctrlFanSpeed(){
|
|
|
|
auto& nvctrl = get_libnvctrl_loader();
|
2023-04-20 01:10:21 +00:00
|
|
|
int64_t fan_speed = 0;
|
|
|
|
nvctrl.XNVCTRLQueryTargetAttribute64(display.get(),
|
2023-05-04 23:48:43 +00:00
|
|
|
NV_CTRL_TARGET_TYPE_COOLER,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
NV_CTRL_THERMAL_COOLER_SPEED,
|
|
|
|
&fan_speed);
|
|
|
|
return fan_speed;
|
2020-04-01 19:52:12 +00:00
|
|
|
}
|