Implemented NvmlLib.
This commit is contained in:
parent
175a7b06b7
commit
83f437f979
8 changed files with 203 additions and 12 deletions
|
@ -163,6 +163,8 @@ public:
|
||||||
# ifdef XMRIG_FEATURE_NVML
|
# ifdef XMRIG_FEATURE_NVML
|
||||||
if (cuda.isNvmlEnabled()) {
|
if (cuda.isNvmlEnabled()) {
|
||||||
if (NvmlLib::init(cuda.nvmlLoader())) {
|
if (NvmlLib::init(cuda.nvmlLoader())) {
|
||||||
|
NvmlLib::assign(devices);
|
||||||
|
|
||||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") "/" GREEN_BOLD("%s"), kNvmlLabel,
|
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") "/" GREEN_BOLD("%s"), kNvmlLabel,
|
||||||
NvmlLib::version(), NvmlLib::driverVersion());
|
NvmlLib::version(), NvmlLib::driverVersion());
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ if (WITH_CUDA)
|
||||||
|
|
||||||
list(APPEND HEADERS_BACKEND_CUDA
|
list(APPEND HEADERS_BACKEND_CUDA
|
||||||
src/backend/cuda/wrappers/nvml_lite.h
|
src/backend/cuda/wrappers/nvml_lite.h
|
||||||
|
src/backend/cuda/wrappers/NvmlHealth.h
|
||||||
src/backend/cuda/wrappers/NvmlLib.h
|
src/backend/cuda/wrappers/NvmlLib.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
#include "crypto/common/Algorithm.h"
|
#include "crypto/common/Algorithm.h"
|
||||||
#include "rapidjson/document.h"
|
#include "rapidjson/document.h"
|
||||||
|
|
||||||
|
#ifdef XMRIG_FEATURE_NVML
|
||||||
|
# include "backend/cuda/wrappers/NvmlLib.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -125,5 +128,25 @@ void xmrig::CudaDevice::toJSON(rapidjson::Value &out, rapidjson::Document &doc)
|
||||||
out.AddMember("global_mem", static_cast<uint64_t>(globalMemSize()), allocator);
|
out.AddMember("global_mem", static_cast<uint64_t>(globalMemSize()), allocator);
|
||||||
out.AddMember("clock", clock(), allocator);
|
out.AddMember("clock", clock(), allocator);
|
||||||
out.AddMember("memory_clock", memoryClock(), allocator);
|
out.AddMember("memory_clock", memoryClock(), allocator);
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_NVML
|
||||||
|
if (m_nvmlDevice) {
|
||||||
|
auto data = NvmlLib::health(m_nvmlDevice);
|
||||||
|
|
||||||
|
Value health(kObjectType);
|
||||||
|
health.AddMember("temperature", data.temperature, allocator);
|
||||||
|
health.AddMember("power", data.power, allocator);
|
||||||
|
health.AddMember("clock", data.clock, allocator);
|
||||||
|
health.AddMember("mem_clock", data.memClock, allocator);
|
||||||
|
|
||||||
|
Value fanSpeed(kArrayType);
|
||||||
|
for (auto speed : data.fanSpeed) {
|
||||||
|
fanSpeed.PushBack(speed, allocator);
|
||||||
|
}
|
||||||
|
health.AddMember("fan_speed", fanSpeed, allocator);
|
||||||
|
|
||||||
|
out.AddMember("health", health, allocator);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
#include "base/tools/String.h"
|
#include "base/tools/String.h"
|
||||||
|
|
||||||
|
|
||||||
using nvid_ctx = struct nvid_ctx;
|
using nvid_ctx = struct nvid_ctx;
|
||||||
|
using nvmlDevice_t = struct nvmlDevice_st *;
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
@ -57,11 +58,16 @@ public:
|
||||||
uint32_t smx() const;
|
uint32_t smx() const;
|
||||||
void generate(const Algorithm &algorithm, CudaThreads &threads) const;
|
void generate(const Algorithm &algorithm, CudaThreads &threads) const;
|
||||||
|
|
||||||
inline bool isValid() const { return m_ctx != nullptr; }
|
inline bool isValid() const { return m_ctx != nullptr; }
|
||||||
inline const PciTopology &topology() const { return m_topology; }
|
inline const PciTopology &topology() const { return m_topology; }
|
||||||
inline const String &name() const { return m_name; }
|
inline const String &name() const { return m_name; }
|
||||||
inline uint32_t arch() const { return (computeCapability(true) * 10) + computeCapability(false); }
|
inline uint32_t arch() const { return (computeCapability(true) * 10) + computeCapability(false); }
|
||||||
inline uint32_t index() const { return m_index; }
|
inline uint32_t index() const { return m_index; }
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_NVML
|
||||||
|
inline nvmlDevice_t nvmlDevice() const { return m_nvmlDevice; }
|
||||||
|
inline void setNvmlDevice(nvmlDevice_t device) { m_nvmlDevice = device; }
|
||||||
|
# endif
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_API
|
# ifdef XMRIG_FEATURE_API
|
||||||
void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const;
|
void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const;
|
||||||
|
@ -75,6 +81,10 @@ private:
|
||||||
nvid_ctx *m_ctx = nullptr;
|
nvid_ctx *m_ctx = nullptr;
|
||||||
PciTopology m_topology;
|
PciTopology m_topology;
|
||||||
String m_name;
|
String m_name;
|
||||||
|
|
||||||
|
# ifdef XMRIG_FEATURE_NVML
|
||||||
|
nvmlDevice_t m_nvmlDevice = nullptr;
|
||||||
|
# endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
43
src/backend/cuda/wrappers/NvmlHealth.h
Normal file
43
src/backend/cuda/wrappers/NvmlHealth.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMRIG_NVMLHEALTH_H
|
||||||
|
#define XMRIG_NVMLHEALTH_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
struct NvmlHealth
|
||||||
|
{
|
||||||
|
std::vector<uint32_t> fanSpeed;
|
||||||
|
uint32_t clock = 0;
|
||||||
|
uint32_t memClock = 0;
|
||||||
|
uint32_t power = 0;
|
||||||
|
uint32_t temperature = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_NVMLHEALTH_H */
|
|
@ -39,6 +39,14 @@ namespace xmrig {
|
||||||
static uv_lib_t nvmlLib;
|
static uv_lib_t nvmlLib;
|
||||||
|
|
||||||
|
|
||||||
|
static const char *kNvmlDeviceGetClockInfo = "nvmlDeviceGetClockInfo";
|
||||||
|
static const char *kNvmlDeviceGetCount = "nvmlDeviceGetCount_v2";
|
||||||
|
static const char *kNvmlDeviceGetFanSpeed = "nvmlDeviceGetFanSpeed";
|
||||||
|
static const char *kNvmlDeviceGetFanSpeed_v2 = "nvmlDeviceGetFanSpeed_v2";
|
||||||
|
static const char *kNvmlDeviceGetHandleByIndex = "nvmlDeviceGetHandleByIndex_v2";
|
||||||
|
static const char *kNvmlDeviceGetPciInfo = "nvmlDeviceGetPciInfo_v2";
|
||||||
|
static const char *kNvmlDeviceGetPowerUsage = "nvmlDeviceGetPowerUsage";
|
||||||
|
static const char *kNvmlDeviceGetTemperature = "nvmlDeviceGetTemperature";
|
||||||
static const char *kNvmlInit = "nvmlInit_v2";
|
static const char *kNvmlInit = "nvmlInit_v2";
|
||||||
static const char *kNvmlShutdown = "nvmlShutdown";
|
static const char *kNvmlShutdown = "nvmlShutdown";
|
||||||
static const char *kNvmlSystemGetDriverVersion = "nvmlSystemGetDriverVersion";
|
static const char *kNvmlSystemGetDriverVersion = "nvmlSystemGetDriverVersion";
|
||||||
|
@ -46,10 +54,18 @@ static const char *kNvmlSystemGetNVMLVersion = "nvmlSyste
|
||||||
static const char *kSymbolNotFound = "symbol not found";
|
static const char *kSymbolNotFound = "symbol not found";
|
||||||
|
|
||||||
|
|
||||||
static nvmlReturn_t (*pNvmlInit)() = nullptr;
|
static nvmlReturn_t (*pNvmlDeviceGetClockInfo)(nvmlDevice_t device, uint32_t type, uint32_t *clock) = nullptr;
|
||||||
static nvmlReturn_t (*pNvmlShutdown)() = nullptr;
|
static nvmlReturn_t (*pNvmlDeviceGetCount)(uint32_t *deviceCount) = nullptr;
|
||||||
static nvmlReturn_t (*pNvmlSystemGetDriverVersion)(char *version, unsigned int length) = nullptr;
|
static nvmlReturn_t (*pNvmlDeviceGetFanSpeed_v2)(nvmlDevice_t device, uint32_t fan, uint32_t *speed) = nullptr;
|
||||||
static nvmlReturn_t (*pNvmlSystemGetNVMLVersion)(char *version, unsigned int length) = nullptr;
|
static nvmlReturn_t (*pNvmlDeviceGetFanSpeed)(nvmlDevice_t device, uint32_t *speed) = nullptr;
|
||||||
|
static nvmlReturn_t (*pNvmlDeviceGetHandleByIndex)(uint32_t index, nvmlDevice_t *device) = nullptr;
|
||||||
|
static nvmlReturn_t (*pNvmlDeviceGetPciInfo)(nvmlDevice_t device, nvmlPciInfo_t *pci) = nullptr;
|
||||||
|
static nvmlReturn_t (*pNvmlDeviceGetPowerUsage)(nvmlDevice_t device, uint32_t *power) = nullptr;
|
||||||
|
static nvmlReturn_t (*pNvmlDeviceGetTemperature)(nvmlDevice_t device, uint32_t sensorType, uint32_t *temp) = nullptr;
|
||||||
|
static nvmlReturn_t (*pNvmlInit)() = nullptr;
|
||||||
|
static nvmlReturn_t (*pNvmlShutdown)() = nullptr;
|
||||||
|
static nvmlReturn_t (*pNvmlSystemGetDriverVersion)(char *version, uint32_t length) = nullptr;
|
||||||
|
static nvmlReturn_t (*pNvmlSystemGetNVMLVersion)(char *version, uint32_t length) = nullptr;
|
||||||
|
|
||||||
|
|
||||||
#define DLSYM(x) if (uv_dlsym(&nvmlLib, k##x, reinterpret_cast<void**>(&p##x)) == -1) { throw std::runtime_error(kSymbolNotFound); }
|
#define DLSYM(x) if (uv_dlsym(&nvmlLib, k##x, reinterpret_cast<void**>(&p##x)) == -1) { throw std::runtime_error(kSymbolNotFound); }
|
||||||
|
@ -93,6 +109,72 @@ void xmrig::NvmlLib::close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::NvmlLib::assign(std::vector<CudaDevice> &devices)
|
||||||
|
{
|
||||||
|
uint32_t count = 0;
|
||||||
|
if (pNvmlDeviceGetCount(&count) != NVML_SUCCESS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < count; i++) {
|
||||||
|
nvmlDevice_t nvmlDevice;
|
||||||
|
if (pNvmlDeviceGetHandleByIndex(i, &nvmlDevice) != NVML_SUCCESS) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvmlPciInfo_t pci;
|
||||||
|
if (pNvmlDeviceGetPciInfo(nvmlDevice, &pci) != NVML_SUCCESS) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto &device : devices) {
|
||||||
|
if (device.topology().bus() == pci.bus && device.topology().device() == pci.device) {
|
||||||
|
device.setNvmlDevice(nvmlDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NvmlHealth xmrig::NvmlLib::health(nvmlDevice_t device)
|
||||||
|
{
|
||||||
|
if (!device) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
NvmlHealth health;
|
||||||
|
pNvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &health.temperature);
|
||||||
|
pNvmlDeviceGetPowerUsage(device, &health.power);
|
||||||
|
pNvmlDeviceGetClockInfo(device, NVML_CLOCK_SM, &health.clock);
|
||||||
|
pNvmlDeviceGetClockInfo(device, NVML_CLOCK_MEM, &health.memClock);
|
||||||
|
|
||||||
|
if (health.power) {
|
||||||
|
health.power /= 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t speed = 0;
|
||||||
|
|
||||||
|
if (pNvmlDeviceGetFanSpeed_v2) {
|
||||||
|
uint32_t i = 0;
|
||||||
|
|
||||||
|
while (pNvmlDeviceGetFanSpeed_v2(device, i, &speed) == NVML_SUCCESS) {
|
||||||
|
health.fanSpeed.push_back(speed);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pNvmlDeviceGetFanSpeed(device, &speed);
|
||||||
|
|
||||||
|
health.fanSpeed.push_back(speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
return health;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool xmrig::NvmlLib::dlopen()
|
bool xmrig::NvmlLib::dlopen()
|
||||||
{
|
{
|
||||||
if (!m_loader.isNull()) {
|
if (!m_loader.isNull()) {
|
||||||
|
@ -117,6 +199,13 @@ bool xmrig::NvmlLib::dlopen()
|
||||||
bool xmrig::NvmlLib::load()
|
bool xmrig::NvmlLib::load()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
DLSYM(NvmlDeviceGetClockInfo);
|
||||||
|
DLSYM(NvmlDeviceGetCount);
|
||||||
|
DLSYM(NvmlDeviceGetFanSpeed);
|
||||||
|
DLSYM(NvmlDeviceGetHandleByIndex);
|
||||||
|
DLSYM(NvmlDeviceGetPciInfo);
|
||||||
|
DLSYM(NvmlDeviceGetPowerUsage);
|
||||||
|
DLSYM(NvmlDeviceGetTemperature);
|
||||||
DLSYM(NvmlInit);
|
DLSYM(NvmlInit);
|
||||||
DLSYM(NvmlShutdown);
|
DLSYM(NvmlShutdown);
|
||||||
DLSYM(NvmlSystemGetDriverVersion);
|
DLSYM(NvmlSystemGetDriverVersion);
|
||||||
|
@ -125,6 +214,8 @@ bool xmrig::NvmlLib::load()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uv_dlsym(&nvmlLib, kNvmlDeviceGetFanSpeed_v2, reinterpret_cast<void**>(&pNvmlDeviceGetFanSpeed_v2));
|
||||||
|
|
||||||
if (pNvmlInit() != NVML_SUCCESS) {
|
if (pNvmlInit() != NVML_SUCCESS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
#define XMRIG_NVMLLIB_H
|
#define XMRIG_NVMLLIB_H
|
||||||
|
|
||||||
|
|
||||||
#include "base/tools/String.h"
|
#include "backend/cuda/wrappers/CudaDevice.h"
|
||||||
|
#include "backend/cuda/wrappers/NvmlHealth.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
@ -39,6 +40,9 @@ public:
|
||||||
static const char *lastError() noexcept;
|
static const char *lastError() noexcept;
|
||||||
static void close();
|
static void close();
|
||||||
|
|
||||||
|
static bool assign(std::vector<CudaDevice> &devices);
|
||||||
|
static NvmlHealth health(nvmlDevice_t device);
|
||||||
|
|
||||||
static inline bool isInitialized() noexcept { return m_initialized; }
|
static inline bool isInitialized() noexcept { return m_initialized; }
|
||||||
static inline bool isReady() noexcept { return m_ready; }
|
static inline bool isReady() noexcept { return m_ready; }
|
||||||
static inline const char *driverVersion() noexcept { return m_driverVersion; }
|
static inline const char *driverVersion() noexcept { return m_driverVersion; }
|
||||||
|
|
|
@ -29,10 +29,27 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
#define NVML_SUCCESS 0
|
#define NVML_SUCCESS 0
|
||||||
|
#define NVML_TEMPERATURE_GPU 0
|
||||||
|
#define NVML_CLOCK_SM 1
|
||||||
|
#define NVML_CLOCK_MEM 2
|
||||||
|
|
||||||
|
|
||||||
using nvmlReturn_t = uint32_t;
|
using nvmlReturn_t = uint32_t;
|
||||||
|
using nvmlDevice_t = struct nvmlDevice_st *;
|
||||||
|
|
||||||
|
|
||||||
|
struct nvmlPciInfo_t
|
||||||
|
{
|
||||||
|
char busIdLegacy[16]{};
|
||||||
|
unsigned int domain = 0;
|
||||||
|
unsigned int bus = 0;
|
||||||
|
unsigned int device = 0;
|
||||||
|
unsigned int pciDeviceId = 0;
|
||||||
|
unsigned int pciSubSystemId = 0;
|
||||||
|
|
||||||
|
char busId[32]{};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* XMRIG_NVML_LITE_H */
|
#endif /* XMRIG_NVML_LITE_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue