api: export gpu freq on linux too + hwinfo command
This commit is contained in:
parent
b24b65a9c9
commit
3ad4be7de0
91
api.cpp
91
api.cpp
@ -108,7 +108,7 @@ extern int opt_api_listen; /* port */
|
||||
extern uint64_t global_hashrate;
|
||||
extern uint32_t accepted_count;
|
||||
extern uint32_t rejected_count;
|
||||
|
||||
extern int num_processors;
|
||||
extern int device_map[8];
|
||||
extern char *device_name[8];
|
||||
|
||||
@ -128,8 +128,8 @@ static void gpustatus(int thr_id)
|
||||
cgpu->gpu_bus = gpu_busid(cgpu);
|
||||
cgpu->gpu_temp = gpu_temp(cgpu);
|
||||
cgpu->gpu_fan = gpu_fanpercent(cgpu);
|
||||
cgpu->gpu_pstate = gpu_pstate(cgpu);
|
||||
cgpu->gpu_clock = gpu_clock(cgpu);
|
||||
cgpu->gpu_pstate = gpu_pstate(cgpu);
|
||||
#endif
|
||||
|
||||
// todo: can be 0 if set by algo (auto)
|
||||
@ -149,14 +149,14 @@ static void gpustatus(int thr_id)
|
||||
|
||||
cgpu->khashes = stats_get_speed(cgpu->gpu_id, 0.0) / 1000.0;
|
||||
|
||||
snprintf(pstate, sizeof(pstate), "P%u", cgpu->gpu_pstate);
|
||||
snprintf(pstate, sizeof(pstate), "P%hu", cgpu->gpu_pstate);
|
||||
if (cgpu->gpu_pstate == -1)
|
||||
*pstate= '\0';
|
||||
(*pstate) = '\0';
|
||||
|
||||
card = device_name[gpuid];
|
||||
|
||||
snprintf(buf, sizeof(buf), "GPU=%d;BUS=%d;CARD=%s;TEMP=%.1f;FAN=%d;"
|
||||
"FREQ=%d;PST=%s;KHS=%.2f;HWF=%d;I=%d|",
|
||||
snprintf(buf, sizeof(buf), "GPU=%d;BUS=%hd;CARD=%s;"
|
||||
"TEMP=%.1f;FAN=%d;FREQ=%d;PST=%s;KHS=%.2f;HWF=%d;I=%d|",
|
||||
gpuid, cgpu->gpu_bus, card, cgpu->gpu_temp, cgpu->gpu_fan,
|
||||
cgpu->gpu_clock, pstate, cgpu->khashes,
|
||||
cgpu->hw_errors, cgpu->intensity);
|
||||
@ -166,6 +166,17 @@ static void gpustatus(int thr_id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns gpu/thread specific stats
|
||||
*/
|
||||
static char *getthreads(char *params)
|
||||
{
|
||||
*buffer = '\0';
|
||||
for (int i = 0; i < opt_n_threads; i++)
|
||||
gpustatus(i);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
@ -191,14 +202,71 @@ static char *getsummary(char *params)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void gpuhwinfos(int gpu_id)
|
||||
{
|
||||
char buf[256];
|
||||
char pstate[8];
|
||||
char* card;
|
||||
struct cgpu_info *cgpu = NULL;
|
||||
|
||||
for (int g = 0; g < opt_n_threads; g++) {
|
||||
if (device_map[g] == gpu_id) {
|
||||
cgpu = &thr_info[g].gpu;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cgpu == NULL)
|
||||
return;
|
||||
|
||||
#ifdef USE_WRAPNVML
|
||||
cgpu->has_monitoring = true;
|
||||
cgpu->gpu_bus = gpu_busid(cgpu);
|
||||
cgpu->gpu_temp = gpu_temp(cgpu);
|
||||
cgpu->gpu_fan = gpu_fanpercent(cgpu);
|
||||
cgpu->gpu_pstate = gpu_pstate(cgpu);
|
||||
cgpu->gpu_clock = gpu_clock(cgpu);
|
||||
gpu_info(cgpu);
|
||||
#endif
|
||||
|
||||
snprintf(pstate, sizeof(pstate), "P%hu", cgpu->gpu_pstate);
|
||||
if (cgpu->gpu_pstate == -1)
|
||||
(*pstate) = '\0';
|
||||
|
||||
card = device_name[gpu_id];
|
||||
|
||||
snprintf(buf, sizeof(buf), "GPU=%d;BUS=%hd;CARD=%s;"
|
||||
"TEMP=%.1f;FAN=%d;FREQ=%d;PST=%s;"
|
||||
"VID=%hx;PID=%hx;BIOS=%s|",
|
||||
gpu_id, cgpu->gpu_bus, card,
|
||||
cgpu->gpu_temp, cgpu->gpu_fan, cgpu->gpu_clock, pstate,
|
||||
cgpu->gpu_vid, cgpu->gpu_pid, cgpu->gpu_desc);
|
||||
|
||||
strcat(buffer, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns gpu/thread specific stats
|
||||
*/
|
||||
static char *getthreads(char *params)
|
||||
* To finish
|
||||
*/
|
||||
static void cpuhwinfos()
|
||||
{
|
||||
char buf[256];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
snprintf(buf, sizeof(buf), "CPU=|");
|
||||
strcat(buffer, buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns gpu and system (todo) informations
|
||||
*/
|
||||
static char *gethwinfos(char *params)
|
||||
{
|
||||
*buffer = '\0';
|
||||
for (int i = 0; i < opt_n_threads; i++)
|
||||
gpustatus(i);
|
||||
for (int i = 0; i < num_processors; i++)
|
||||
gpuhwinfos(i);
|
||||
cpuhwinfos();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -251,6 +319,7 @@ struct CMDS {
|
||||
{ "threads", getthreads },
|
||||
{ "histo", gethistory },
|
||||
{ "meminfo", getmeminfo },
|
||||
{ "hwinfo", gethwinfos },
|
||||
/* keep it the last */
|
||||
{ "help", gethelp },
|
||||
};
|
||||
|
@ -11,7 +11,7 @@ $configs = array(
|
||||
set_time_limit(3);
|
||||
error_reporting(0);
|
||||
|
||||
function getdataFromPears()
|
||||
function getdataFromPeers()
|
||||
{
|
||||
global $host, $configs;
|
||||
$data = array();
|
||||
@ -129,7 +129,7 @@ function displayData($data)
|
||||
return $htm;
|
||||
}
|
||||
|
||||
$data = getdataFromPears();
|
||||
$data = getdataFromPeers();
|
||||
|
||||
?>
|
||||
|
||||
|
9
miner.h
9
miner.h
@ -376,13 +376,18 @@ struct cgpu_info {
|
||||
double khashes;
|
||||
uint8_t intensity;
|
||||
uint8_t has_monitoring;
|
||||
int gpu_bus;
|
||||
float gpu_temp;
|
||||
int gpu_fan;
|
||||
int gpu_clock;
|
||||
int gpu_memclock;
|
||||
int gpu_pstate;
|
||||
uint32_t gpu_usage;
|
||||
double gpu_vddc;
|
||||
int16_t gpu_pstate;
|
||||
int16_t gpu_bus;
|
||||
|
||||
uint16_t gpu_vid;
|
||||
uint16_t gpu_pid;
|
||||
char gpu_desc[64];
|
||||
};
|
||||
|
||||
struct thr_api {
|
||||
|
118
nvml.cpp
118
nvml.cpp
@ -30,7 +30,6 @@
|
||||
|
||||
extern wrap_nvml_handle *hnvml;
|
||||
extern int num_processors; // gpus
|
||||
extern int device_map[8];
|
||||
|
||||
static uint32_t device_bus_ids[8] = { 0 };
|
||||
|
||||
@ -175,7 +174,8 @@ wrap_nvml_handle * wrap_nvml_create()
|
||||
nvmlh->devs = (wrap_nvmlDevice_t *) calloc(nvmlh->nvml_gpucount, sizeof(wrap_nvmlDevice_t));
|
||||
nvmlh->nvml_pci_domain_id = (unsigned int*) calloc(nvmlh->nvml_gpucount, sizeof(unsigned int));
|
||||
nvmlh->nvml_pci_bus_id = (unsigned int*) calloc(nvmlh->nvml_gpucount, sizeof(unsigned int));
|
||||
nvmlh->nvml_pci_device_id = (unsigned int*) calloc(nvmlh->nvml_gpucount, sizeof(unsigned int));
|
||||
nvmlh->nvml_pci_device_id = (unsigned int*)calloc(nvmlh->nvml_gpucount, sizeof(unsigned int));
|
||||
nvmlh->nvml_pci_subsys_id = (unsigned int*)calloc(nvmlh->nvml_gpucount, sizeof(unsigned int));
|
||||
nvmlh->nvml_cuda_device_id = (int*) calloc(nvmlh->nvml_gpucount, sizeof(int));
|
||||
nvmlh->cuda_nvml_device_id = (int*) calloc(nvmlh->cuda_gpucount, sizeof(int));
|
||||
|
||||
@ -192,6 +192,7 @@ wrap_nvml_handle * wrap_nvml_create()
|
||||
nvmlh->nvml_pci_domain_id[i] = pciinfo.domain;
|
||||
nvmlh->nvml_pci_bus_id[i] = pciinfo.bus;
|
||||
nvmlh->nvml_pci_device_id[i] = pciinfo.device;
|
||||
nvmlh->nvml_pci_subsys_id[i] = pciinfo.pci_subsystem_id;
|
||||
}
|
||||
|
||||
/* build mapping of NVML device IDs to CUDA IDs */
|
||||
@ -340,11 +341,33 @@ int wrap_nvml_get_busid(wrap_nvml_handle *nvmlh, int cudaindex, int *busid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wrap_nvml_get_info(wrap_nvml_handle *nvmlh, int cudaindex, uint16_t *vid, uint16_t *pid)
|
||||
{
|
||||
uint32_t subids = 0;
|
||||
int gpuindex = nvmlh->cuda_nvml_device_id[cudaindex];
|
||||
if (gpuindex < 0 || gpuindex >= nvmlh->nvml_gpucount)
|
||||
return -1;
|
||||
|
||||
subids = nvmlh->nvml_pci_subsys_id[gpuindex];
|
||||
(*vid) = subids >> 16;
|
||||
(*pid) = subids & 0xFFFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wrap_nvml_destroy(wrap_nvml_handle *nvmlh)
|
||||
{
|
||||
nvmlh->nvmlShutdown();
|
||||
|
||||
wrap_dlclose(nvmlh->nvml_dll);
|
||||
|
||||
free(nvmlh->nvml_pci_bus_id);
|
||||
free(nvmlh->nvml_pci_device_id);
|
||||
free(nvmlh->nvml_pci_domain_id);
|
||||
free(nvmlh->nvml_pci_subsys_id);
|
||||
free(nvmlh->nvml_cuda_device_id);
|
||||
free(nvmlh->cuda_nvml_device_id);
|
||||
free(nvmlh->devs);
|
||||
|
||||
free(nvmlh);
|
||||
return 0;
|
||||
}
|
||||
@ -455,6 +478,51 @@ int nvapi_getpstate(unsigned int devNum, unsigned int *power)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define UTIL_DOMAIN_GPU 0
|
||||
int nvapi_getusage(unsigned int devNum, unsigned int *pct)
|
||||
{
|
||||
NvAPI_Status ret;
|
||||
|
||||
if (devNum >= nvapi_dev_cnt)
|
||||
return -1;
|
||||
|
||||
NV_GPU_DYNAMIC_PSTATES_INFO_EX info;
|
||||
info.version = NV_GPU_DYNAMIC_PSTATES_INFO_EX_VER;
|
||||
ret = NvAPI_GPU_GetDynamicPstatesInfoEx(phys[devNum], &info);
|
||||
if (ret != NVAPI_OK) {
|
||||
NvAPI_ShortString string;
|
||||
NvAPI_GetErrorMessage(ret, string);
|
||||
if (opt_debug)
|
||||
applog(LOG_DEBUG, "NVAPI GetDynamicPstatesInfoEx: %s", string);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
if (info.utilization[UTIL_DOMAIN_GPU].bIsPresent)
|
||||
(*pct) = info.utilization[UTIL_DOMAIN_GPU].percentage;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nvapi_getinfo(unsigned int devNum, char *desc)
|
||||
{
|
||||
NvAPI_Status ret;
|
||||
|
||||
if (devNum >= nvapi_dev_cnt)
|
||||
return -1;
|
||||
|
||||
// bios rev
|
||||
ret = NvAPI_GPU_GetVbiosVersionString(phys[devNum], desc);
|
||||
if (ret != NVAPI_OK) {
|
||||
NvAPI_ShortString string;
|
||||
NvAPI_GetErrorMessage(ret, string);
|
||||
if (opt_debug)
|
||||
applog(LOG_DEBUG, "NVAPI GetVbiosVersionString: %s", string);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nvapi_getbusid(unsigned int devNum, int *busid)
|
||||
{
|
||||
if (devNum >= 0 && devNum <= 8) {
|
||||
@ -486,9 +554,10 @@ int wrap_nvapi_init()
|
||||
|
||||
for (int g = 0; g < num_processors; g++) {
|
||||
cudaDeviceProp props;
|
||||
if (cudaGetDeviceProperties(&props, g) == cudaSuccess)
|
||||
if (cudaGetDeviceProperties(&props, g) == cudaSuccess) {
|
||||
device_bus_ids[g] = props.pciBusID;
|
||||
nvapi_dev_map[g] = g;// default mapping
|
||||
}
|
||||
nvapi_dev_map[g] = g; // default mapping
|
||||
}
|
||||
|
||||
for (NvU8 i = 0; i < nvapi_dev_cnt; i++) {
|
||||
@ -532,7 +601,7 @@ int gpu_fanpercent(struct cgpu_info *gpu)
|
||||
{
|
||||
unsigned int pct = 0;
|
||||
if (hnvml) {
|
||||
wrap_nvml_get_fanpcnt(hnvml, device_map[gpu->thr_id], &pct);
|
||||
wrap_nvml_get_fanpcnt(hnvml, gpu->gpu_id, &pct);
|
||||
}
|
||||
#ifdef WIN32
|
||||
else {
|
||||
@ -553,7 +622,7 @@ float gpu_temp(struct cgpu_info *gpu)
|
||||
float tc = 0.0;
|
||||
unsigned int tmp = 0;
|
||||
if (hnvml) {
|
||||
wrap_nvml_get_tempC(hnvml, device_map[gpu->thr_id], &tmp);
|
||||
wrap_nvml_get_tempC(hnvml, gpu->gpu_id, &tmp);
|
||||
tc = (float)tmp;
|
||||
}
|
||||
#ifdef WIN32
|
||||
@ -570,13 +639,18 @@ int gpu_clock(struct cgpu_info *gpu)
|
||||
unsigned int freq = 0;
|
||||
int support = -1;
|
||||
if (hnvml) {
|
||||
support = wrap_nvml_get_clock(hnvml, device_map[gpu->thr_id], NVML_CLOCK_GRAPHICS, &freq);
|
||||
support = wrap_nvml_get_clock(hnvml, gpu->gpu_id, NVML_CLOCK_GRAPHICS, &freq);
|
||||
}
|
||||
#ifdef WIN32
|
||||
if (support == -1) {
|
||||
#ifdef WIN32
|
||||
nvapi_getclock(nvapi_dev_map[gpu->gpu_id], &freq);
|
||||
}
|
||||
#else
|
||||
cudaDeviceProp props;
|
||||
if (cudaGetDeviceProperties(&props, gpu->gpu_id) == cudaSuccess) {
|
||||
freq = props.clockRate;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (int) freq;
|
||||
}
|
||||
|
||||
@ -585,7 +659,7 @@ int gpu_pstate(struct cgpu_info *gpu)
|
||||
int pstate = -1;
|
||||
int support = -1;
|
||||
if (hnvml) {
|
||||
support = wrap_nvml_get_pstate(hnvml, device_map[gpu->thr_id], &pstate);
|
||||
support = wrap_nvml_get_pstate(hnvml, gpu->gpu_id, &pstate);
|
||||
}
|
||||
#ifdef WIN32
|
||||
if (support == -1) {
|
||||
@ -602,7 +676,7 @@ int gpu_busid(struct cgpu_info *gpu)
|
||||
int busid = -1;
|
||||
int support = -1;
|
||||
if (hnvml) {
|
||||
support = wrap_nvml_get_busid(hnvml, device_map[gpu->thr_id], &busid);
|
||||
support = wrap_nvml_get_busid(hnvml, gpu->gpu_id, &busid);
|
||||
}
|
||||
#ifdef WIN32
|
||||
if (support == -1) {
|
||||
@ -612,21 +686,39 @@ int gpu_busid(struct cgpu_info *gpu)
|
||||
return busid;
|
||||
}
|
||||
|
||||
|
||||
/* not used in api (too much variable) */
|
||||
unsigned int gpu_power(struct cgpu_info *gpu)
|
||||
{
|
||||
unsigned int mw = 0;
|
||||
int support = -1;
|
||||
if (hnvml) {
|
||||
support = wrap_nvml_get_power_usage(hnvml, device_map[gpu->thr_id], &mw);
|
||||
support = wrap_nvml_get_power_usage(hnvml, gpu->gpu_id, &mw);
|
||||
}
|
||||
#ifdef WIN32
|
||||
if (support == -1) {
|
||||
unsigned int pct = 0;
|
||||
nvapi_getusage(nvapi_dev_map[gpu->gpu_id], &pct);
|
||||
}
|
||||
#endif
|
||||
return mw;
|
||||
}
|
||||
|
||||
int gpu_info(struct cgpu_info *gpu)
|
||||
{
|
||||
if (hnvml) {
|
||||
wrap_nvml_get_info(hnvml, gpu->gpu_id, &gpu->gpu_vid, &gpu->gpu_pid);
|
||||
}
|
||||
#ifdef WIN32
|
||||
nvapi_getinfo(nvapi_dev_map[gpu->gpu_id], &gpu->gpu_desc[0]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* USE_WRAPNVML */
|
||||
|
||||
/* strings /usr/lib/nvidia-340/libnvidia-ml.so | grep nvmlDeviceGet | grep -v : | sort | uniq
|
||||
|
4
nvml.h
4
nvml.h
@ -60,6 +60,7 @@ typedef struct {
|
||||
unsigned int *nvml_pci_domain_id;
|
||||
unsigned int *nvml_pci_bus_id;
|
||||
unsigned int *nvml_pci_device_id;
|
||||
unsigned int *nvml_pci_subsys_id;
|
||||
int *nvml_cuda_device_id; /* map NVML dev to CUDA dev */
|
||||
int *cuda_nvml_device_id; /* map CUDA dev to NVML dev */
|
||||
wrap_nvmlDevice_t *devs;
|
||||
@ -144,9 +145,12 @@ int gpu_fanpercent(struct cgpu_info *gpu);
|
||||
float gpu_temp(struct cgpu_info *gpu);
|
||||
int gpu_clock(struct cgpu_info *gpu);
|
||||
unsigned int gpu_power(struct cgpu_info *gpu);
|
||||
unsigned int gpu_usage(struct cgpu_info *gpu);
|
||||
int gpu_pstate(struct cgpu_info *gpu);
|
||||
int gpu_busid(struct cgpu_info *gpu);
|
||||
|
||||
int gpu_info(struct cgpu_info *gpu);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user