Skip to content

Commit

Permalink
api: use MHz for all clocks and show plimit
Browse files Browse the repository at this point in the history
plimit value is reported in mW like the power, or % on Windows x86 (via nvapi)

+ the monitor thread will no more report 0W if the device doesnt support it

also upgrade nvml and sample php api.

some more changes may come in this temporary API 1.9 (for the final 2.0)
  • Loading branch information
tpruvot committed Feb 6, 2017
1 parent 3fab279 commit 4da35e0
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 23 deletions.
25 changes: 17 additions & 8 deletions api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,16 @@ static void gpustatus(int thr_id)
char* card;

cuda_gpu_info(cgpu);
cgpu->gpu_plimit = device_plimit[cgpu->gpu_id];

#ifdef USE_WRAPNVML
cgpu->has_monitoring = true;
cgpu->gpu_bus = gpu_busid(cgpu);
cgpu->gpu_temp = gpu_temp(cgpu);
cgpu->gpu_fan = (uint16_t) gpu_fanpercent(cgpu);
cgpu->gpu_fan_rpm = (uint16_t) gpu_fanrpm(cgpu);
cgpu->gpu_power = gpu_power(cgpu); // mWatts
cgpu->gpu_plimit = gpu_plimit(cgpu); // mW or %
#endif

// todo: per gpu
Expand All @@ -143,13 +146,14 @@ static void gpustatus(int thr_id)

snprintf(buf, sizeof(buf), "GPU=%d;BUS=%hd;CARD=%s;TEMP=%.1f;"
"POWER=%u;FAN=%hu;RPM=%hu;"
"FREQ=%u;CORE=%u;MEM=%u;"
"KHS=%.2f;KHW=%.5f;"
"FREQ=%u;MEMFREQ=%u;GPUF=%u;MEMF=%u;"
"KHS=%.2f;KHW=%.5f;PLIM=%u;"
"HWF=%d;I=%.1f;THR=%u|",
gpuid, cgpu->gpu_bus, card, cgpu->gpu_temp,
cgpu->gpu_power, cgpu->gpu_fan, cgpu->gpu_fan_rpm,
cgpu->gpu_clock, cgpu->monitor.gpu_clock, cgpu->monitor.gpu_memclock,
cgpu->khashes, khashes_per_watt,
cgpu->gpu_clock/1000, cgpu->gpu_memclock/1000, // base freqs in MHz
cgpu->monitor.gpu_clock, cgpu->monitor.gpu_memclock, // current
cgpu->khashes, khashes_per_watt, cgpu->gpu_plimit,
cgpu->hw_errors, cgpu->intensity, cgpu->throughput);

// append to buffer for multi gpus
Expand Down Expand Up @@ -266,6 +270,8 @@ static void gpuhwinfos(int gpu_id)
return;

cuda_gpu_info(cgpu);
cgpu->gpu_plimit = device_plimit[cgpu->gpu_id];

#ifdef USE_WRAPNVML
cgpu->has_monitoring = true;
cgpu->gpu_bus = gpu_busid(cgpu);
Expand All @@ -274,6 +280,7 @@ static void gpuhwinfos(int gpu_id)
cgpu->gpu_fan_rpm = (uint16_t) gpu_fanrpm(cgpu);
cgpu->gpu_pstate = (int16_t) gpu_pstate(cgpu);
cgpu->gpu_power = gpu_power(cgpu);
cgpu->gpu_plimit = gpu_plimit(cgpu);
gpu_info(cgpu);
#ifdef WIN32
if (opt_debug) nvapi_pstateinfo(cgpu->gpu_id);
Expand All @@ -287,12 +294,14 @@ static void gpuhwinfos(int gpu_id)
card = device_name[gpu_id];

snprintf(buf, sizeof(buf), "GPU=%d;BUS=%hd;CARD=%s;SM=%hu;MEM=%u;"
"TEMP=%.1f;FAN=%hu;RPM=%hu;FREQ=%d;MEMFREQ=%d;PST=%s;POWER=%u;"
"TEMP=%.1f;FAN=%hu;RPM=%hu;FREQ=%u;MEMFREQ=%u;GPUF=%u;MEMF=%u;"
"PST=%s;POWER=%u;PLIM=%u;"
"VID=%hx;PID=%hx;NVML=%d;NVAPI=%d;SN=%s;BIOS=%s|",
gpu_id, cgpu->gpu_bus, card, cgpu->gpu_arch, (uint32_t) cgpu->gpu_mem,
cgpu->gpu_temp, cgpu->gpu_fan, cgpu->gpu_fan_rpm,
cgpu->gpu_clock, cgpu->gpu_memclock,
pstate, cgpu->gpu_power,
cgpu->gpu_clock/1000U, cgpu->gpu_memclock/1000U, // base clocks
cgpu->monitor.gpu_clock, cgpu->monitor.gpu_memclock, // current
pstate, cgpu->gpu_power, cgpu->gpu_plimit,
cgpu->gpu_vid, cgpu->gpu_pid, cgpu->nvml_id, cgpu->nvapi_id,
cgpu->gpu_sn, cgpu->gpu_desc);

Expand Down Expand Up @@ -329,7 +338,7 @@ static void syshwinfos()

memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf), "OS=%s;NVDRIVER=%s;CPUS=%d;CPUTEMP=%d;CPUFREQ=%d|",
os_name(), driver_version, num_cpus, cputc, cpuclk);
os_name(), driver_version, num_cpus, cputc, cpuclk/1000);
strcat(buffer, buf);
}

Expand Down
19 changes: 16 additions & 3 deletions api/index.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?php
/* ccminer API sample UI (API 1.7) */
/* ccminer API sample UI (API 1.9) */

$host = 'http://localhost/api/'; // 'http://'.$_SERVER['SERVER_NAME'].'/api/';
$configs = array(
Expand Down Expand Up @@ -65,8 +65,14 @@ function translateField($key)

$intl['TEMP'] = 'T°c';
$intl['FAN'] = 'Fan %';
$intl['FREQ'] = 'Freq.';
$intl['CPUFREQ'] = 'CPU Freq.';
$intl['FREQ'] = 'Base Freq.';
$intl['MEMFREQ'] = 'Mem. Freq.';
$intl['GPUF'] = 'Curr Freq.';
$intl['MEMF'] = 'Mem. Freq.';
$intl['KHW'] = 'Efficiency';
$intl['POWER'] = 'Power';
$intl['PLIM'] = 'P.Limit';
$intl['PST'] = 'P-State';

// pool infos
Expand Down Expand Up @@ -98,8 +104,12 @@ function translateValue($key,$val,$data=array())
case 'NAME':
$val = $data['NAME'].'&nbsp;'.$data['VER'];
break;
case 'CPUFREQ':
case 'FREQ':
$val = sprintf("%d MHz", round(floatval($val)/1000.0));
case 'MEMFREQ':
case 'GPUF':
case 'MEMF':
$val = sprintf("%d MHz", $val);
break;
case 'POWER':
$val = sprintf("%d W", round(floatval($val)/1000.0));
Expand All @@ -111,6 +121,9 @@ function translateValue($key,$val,$data=array())
case 'NETKHS':
$val = '<span class="bold">'.$val.'</span> kH/s';
break;
case 'KHW':
$val = $val.' kH/W';
break;
case 'NAME':
case 'POOL';
case 'USER':
Expand Down
2 changes: 2 additions & 0 deletions miner.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ struct cgpu_info {
uint64_t gpu_mem;
uint64_t gpu_memfree;
uint32_t gpu_power;
uint32_t gpu_plimit;
double gpu_vddc;
int16_t gpu_pstate;
int16_t gpu_bus;
Expand Down Expand Up @@ -521,6 +522,7 @@ extern char* device_name[MAX_GPUS];
extern short device_map[MAX_GPUS];
extern short device_mpcount[MAX_GPUS];
extern long device_sm[MAX_GPUS];
extern uint32_t device_plimit[MAX_GPUS];
extern uint32_t gpus_intensity[MAX_GPUS];
extern int opt_cudaschedule;

Expand Down
54 changes: 43 additions & 11 deletions nvml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ static uint32_t device_bus_ids[MAX_GPUS] = { 0 };

extern uint32_t device_gpu_clocks[MAX_GPUS];
extern uint32_t device_mem_clocks[MAX_GPUS];
extern uint32_t device_plimit[MAX_GPUS];
extern uint8_t device_tlimit[MAX_GPUS];
extern int8_t device_pstate[MAX_GPUS];
extern int32_t device_led[MAX_GPUS];
Expand Down Expand Up @@ -539,6 +538,19 @@ int nvml_set_plimit(nvml_handle *nvmlh, int dev_id)
return 1;
}

uint32_t nvml_get_plimit(nvml_handle *nvmlh, int dev_id)
{
uint32_t plimit = 0;
int n = nvmlh ? nvmlh->cuda_nvml_device_id[dev_id] : -1;
if (n < 0 || n >= nvmlh->nvml_gpucount)
return 0;

if (nvmlh->nvmlDeviceGetPowerManagementLimit) {
nvmlh->nvmlDeviceGetPowerManagementLimit(nvmlh->devs[n], &plimit);
}
return plimit;
}

// ccminer -D -n
#define LSTDEV_PFX " "
void nvml_print_device_info(int dev_id)
Expand Down Expand Up @@ -1788,7 +1800,7 @@ int nvapi_init_settings()

for (int n=0; n < opt_n_threads; n++) {
int dev_id = device_map[n % MAX_GPUS];
if (device_plimit[dev_id]) {
if (device_plimit[dev_id] && !hnvml) {
if (nvapi_set_plimit(nvapi_dev_map[dev_id], device_plimit[dev_id]) == NVAPI_OK) {
uint32_t res = nvapi_get_plimit(nvapi_dev_map[dev_id]);
gpulog(LOG_INFO, n, "Power limit is set to %u%%", res);
Expand Down Expand Up @@ -1952,6 +1964,23 @@ unsigned int gpu_power(struct cgpu_info *gpu)
return mw;
}

unsigned int gpu_plimit(struct cgpu_info *gpu)
{
unsigned int mw = 0;
int support = -1;
if (hnvml) {
mw = nvml_get_plimit(hnvml, gpu->gpu_id);
support = (mw > 0);
}
#ifdef WIN32
// NVAPI value is in % (< 100 so)
if (support == -1) {
mw = nvapi_get_plimit(nvapi_dev_map[gpu->gpu_id]);
}
#endif
return mw;
}

static int translate_vendor_id(uint16_t vid, char *vendorname)
{
struct VENDORS {
Expand Down Expand Up @@ -2116,15 +2145,18 @@ void *monitor_thread(void *userdata)
do {
unsigned int tmp_clock=0, tmp_memclock=0;
nvml_get_current_clocks(dev_id, &tmp_clock, &tmp_memclock);
if (tmp_clock < 200) {
#ifdef WIN32
// workaround for buggy driver 378.49 (real clock)
if (tmp_clock < 200) {
// workaround for buggy drivers 378.x (real clock)
tmp_clock = nvapi_get_gpu_clock(nvapi_dev_map[dev_id]);
#else
}
#endif
if (tmp_clock < 200) {
// some older cards only report a base clock with cuda props.
if (cuda_gpu_info(cgpu) == 0)
if (cuda_gpu_info(cgpu) == 0) {
tmp_clock = cgpu->gpu_clock/1000;
#endif
tmp_memclock = cgpu->gpu_memclock/1000;
}
}
clock += tmp_clock;
mem_clock += tmp_memclock;
Expand All @@ -2148,14 +2180,14 @@ void *monitor_thread(void *userdata)
khs_per_watt = stats_get_speed(thr_id, thr_hashrates[thr_id]);
khs_per_watt = khs_per_watt / ((double)power / counter);
format_hashrate(khs_per_watt * 1000, khw);
if (strlen(khw)) khw[strlen(khw)-1] = 'W';
if (strlen(khw))
sprintf(&khw[strlen(khw)-1], "W %uW ", cgpu->monitor.gpu_power / 1000);
}

if (opt_hwmonitor && (time(NULL) - cgpu->monitor.tm_displayed) > 60) {
gpulog(LOG_INFO, thr_id, "%u MHz %s %uW %uC FAN %u%%",
gpulog(LOG_INFO, thr_id, "%u MHz %s%uC FAN %u%%",
cgpu->monitor.gpu_clock/*, cgpu->monitor.gpu_memclock*/,
khw, cgpu->monitor.gpu_power / 1000,
cgpu->monitor.gpu_temp, cgpu->monitor.gpu_fan
khw, cgpu->monitor.gpu_temp, cgpu->monitor.gpu_fan
);
cgpu->monitor.tm_displayed = (uint32_t)time(NULL);
}
Expand Down
1 change: 1 addition & 0 deletions nvml.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ unsigned int gpu_fanpercent(struct cgpu_info *gpu);
unsigned int gpu_fanrpm(struct cgpu_info *gpu);
float gpu_temp(struct cgpu_info *gpu);
unsigned int gpu_power(struct cgpu_info *gpu);
unsigned int gpu_plimit(struct cgpu_info *gpu);
int gpu_pstate(struct cgpu_info *gpu);
int gpu_busid(struct cgpu_info *gpu);

Expand Down
1 change: 0 additions & 1 deletion util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1627,7 +1627,6 @@ static bool stratum_get_algo(struct stratum_ctx *sctx, json_t *id, json_t *param
#include "nvml.h"
extern char driver_version[32];
extern int cuda_arch[MAX_GPUS];
extern uint32_t device_plimit[MAX_GPUS];

static bool json_object_set_error(json_t *result, int code, const char *msg)
{
Expand Down

0 comments on commit 4da35e0

Please sign in to comment.