144 lines
5.1 KiB
C++
144 lines
5.1 KiB
C++
#include <cstdint>
|
|
#include <fstream>
|
|
#include <gpu.hpp>
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <utils.hpp>
|
|
|
|
struct GpuMetrics_v1_1_t {
|
|
uint16_t temperature_edge;
|
|
uint16_t temperature_hotspot;
|
|
uint16_t temperature_mem;
|
|
uint16_t temperature_vrgfx;
|
|
uint16_t temperature_vrsoc;
|
|
uint16_t temperature_vrmem;
|
|
uint16_t average_gfx_activity;
|
|
uint16_t average_umc_activity;
|
|
uint16_t average_mm_activity;
|
|
uint16_t average_socket_power;
|
|
uint64_t energy_accumulator;
|
|
uint64_t system_clock_counter;
|
|
uint16_t average_gfxclk_frequency;
|
|
uint16_t average_socclk_frequency;
|
|
uint16_t average_uclk_frequency;
|
|
uint16_t average_vclk0_frequency;
|
|
uint16_t average_dclk0_frequency;
|
|
uint16_t average_vclk1_frequency;
|
|
uint16_t average_dclk1_frequency;
|
|
uint16_t current_gfxclk;
|
|
uint16_t current_socclk;
|
|
uint16_t current_uclk;
|
|
uint16_t current_vclk0;
|
|
uint16_t current_dclk0;
|
|
uint16_t current_vclk1;
|
|
uint16_t current_dclk1;
|
|
uint32_t throttle_status;
|
|
uint16_t current_fan_speed;
|
|
uint16_t pcie_link_width;
|
|
uint16_t pcie_link_speed;
|
|
uint16_t padding;
|
|
uint32_t gfx_activity_acc;
|
|
uint32_t mem_activity_acc;
|
|
uint16_t temperature_hbm;
|
|
};
|
|
|
|
struct GpuMetrics_v1_3_t {
|
|
uint16_t temperature_edge;
|
|
uint16_t temperature_hotspot;
|
|
uint16_t temperature_mem;
|
|
uint16_t temperature_vrgfx;
|
|
uint16_t temperature_vrsoc;
|
|
uint16_t temperature_vrmem;
|
|
uint16_t average_gfx_activity;
|
|
uint16_t average_umc_activity;
|
|
uint16_t average_mm_activity;
|
|
uint16_t average_socket_power;
|
|
uint64_t energy_accumulator;
|
|
uint64_t system_clock_counter;
|
|
uint16_t average_gfxclk_frequency;
|
|
uint16_t average_socclk_frequency;
|
|
uint16_t average_uclk_frequency;
|
|
uint16_t average_vclk0_frequency;
|
|
uint16_t average_dclk0_frequency;
|
|
uint16_t average_vclk1_frequency;
|
|
uint16_t average_dclk1_frequency;
|
|
uint16_t current_gfxclk;
|
|
uint16_t current_socclk;
|
|
uint16_t current_uclk;
|
|
uint16_t current_vclk0;
|
|
uint16_t current_dclk0;
|
|
uint16_t current_vclk1;
|
|
uint16_t current_dclk1;
|
|
uint32_t throttle_status;
|
|
uint16_t current_fan_speed;
|
|
uint16_t pcie_link_width;
|
|
uint16_t pcie_link_speed;
|
|
uint16_t padding;
|
|
uint32_t gfx_activity_acc;
|
|
uint32_t mem_activity_acc;
|
|
uint16_t temperature_hbm;
|
|
uint64_t firmware_timestamp;
|
|
uint16_t voltage_soc;
|
|
uint16_t voltage_gfx;
|
|
uint16_t voltage_mem;
|
|
uint8_t padding1;
|
|
};
|
|
|
|
GpuMetricsHeader_t getGpuMetricsHeader(std::string path) {
|
|
GpuMetricsHeader_t header;
|
|
std::ifstream f(path, std::ios::binary);
|
|
if (f.good()) {
|
|
f.read(reinterpret_cast<char *>(&header), sizeof(header));
|
|
std::cout << "[GpuMetrics] header at path " + path + " read, GpuMetrics_v" << std::to_string(header.format_revision) << "_" << std::to_string(header.content_revision);
|
|
std::cout << ", size " << std::to_string(header.structure_size) << std::endl;
|
|
f.close();
|
|
} else {
|
|
std::cerr << "[GpuMetrics] error reading header at path " + path + " (wrong card # ?)" << std::endl;
|
|
}
|
|
|
|
return header;
|
|
}
|
|
|
|
auto getGpuMetrics(GpuMetricsHeader_t h, std::string path) {
|
|
GpuMetrics_v1_3_t metrics;
|
|
if (h.format_revision == 1 && h.content_revision == 3) {
|
|
std::ifstream f(path, std::ios::binary);
|
|
if (f.good()) {
|
|
f.ignore(sizeof(h)); // skip header
|
|
f.read(reinterpret_cast<char *>(&metrics), sizeof(metrics));
|
|
f.close();
|
|
}
|
|
} else {
|
|
std::cout << "[GpuMetrics] read failed, unsupported format" << std::endl;
|
|
}
|
|
|
|
return metrics;
|
|
}
|
|
|
|
// clean abstraction of gpu_metrics + extra metrics from fs
|
|
gpu_t getGpu(GpuMetricsHeader_t header, std::string hw) {
|
|
gpu_t gpu;
|
|
auto metrics = getGpuMetrics(header, hw + "/gpu_metrics");
|
|
|
|
// we want as much data as posible from gpu_metrics so we dont read filesystem as much
|
|
gpu.fan_speed = std::stol(readFile(hw + "/hwmon/hwmon2/fan1_input"));
|
|
gpu.core_clock = metrics.average_vclk1_frequency; // why not gfxclock?
|
|
gpu.mem_clock = metrics.average_gfxclk_frequency; // why gfxclock? min mem clock seems to be 96mhz, this is probably including time sleeping
|
|
gpu.vcore = std::stod(readFile(hw + "/hwmon/hwmon2/in0_input")) / 1000.0;
|
|
gpu.power_avg = metrics.average_socket_power;
|
|
gpu.power_cap = std::stol(readFile(hw + "/hwmon/hwmon2/power1_cap", 6));
|
|
gpu.power_max = std::stol(readFile(hw + "/hwmon/hwmon2/power1_cap_max", 6));
|
|
// gpu.fan_pwm = std::stoi(readFile(hw + "/hwmon/hwmon2/pwm1")); // not super useful
|
|
gpu.edge_temp = metrics.temperature_edge;
|
|
gpu.hotspot_temp = metrics.temperature_hotspot;
|
|
gpu.mem_temp = metrics.temperature_mem;
|
|
gpu.gfx_vrm_temp = metrics.temperature_vrgfx;
|
|
gpu.soc_vrm_temp = metrics.temperature_vrsoc;
|
|
gpu.mem_vrm_temp = metrics.temperature_vrmem;
|
|
gpu.vram_used = std::stoul(readFile(hw + "/mem_info_vram_used"));
|
|
gpu.vram_total = std::stoul(readFile(hw + "/mem_info_vram_total"));
|
|
gpu.core_usage = metrics.average_gfx_activity;
|
|
gpu.media_usage = metrics.average_mm_activity;
|
|
gpu.umc_usage = metrics.average_umc_activity;
|
|
return gpu;
|
|
} |