win32: implement a nvapi.dll wrapper like nvml
Allow to get/set missing infos like the power limit on x86 squashed for a better min/max and device mapping Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>
This commit is contained in:
parent
7a8ae1ab7a
commit
0deb9a2aca
@ -6,9 +6,8 @@ extern "C" {
|
|||||||
#include "sph/sph_bmw.h"
|
#include "sph/sph_bmw.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "miner.h"
|
#include <miner.h>
|
||||||
|
#include <cuda_helper.h>
|
||||||
#include "cuda_helper.h"
|
|
||||||
|
|
||||||
static uint32_t *d_hash[MAX_GPUS];
|
static uint32_t *d_hash[MAX_GPUS];
|
||||||
|
|
||||||
|
@ -295,12 +295,15 @@ Options:\n\
|
|||||||
--max-rate=N[KMG] Only mine if net hashrate is less than specified value\n\
|
--max-rate=N[KMG] Only mine if net hashrate is less than specified value\n\
|
||||||
--max-diff=N Only mine if net difficulty is less than specified value\n\
|
--max-diff=N Only mine if net difficulty is less than specified value\n\
|
||||||
Can be tuned with --resume-diff=N to set a resume value\n"
|
Can be tuned with --resume-diff=N to set a resume value\n"
|
||||||
#if defined(USE_WRAPNVML) && (defined(__linux) || defined(_WIN64)) /* via nvml */
|
#if defined(__linux) || defined(_WIN64) /* via nvml */
|
||||||
"\
|
"\
|
||||||
--mem-clock=3505 Set the gpu memory max clock (346.72+ driver)\n\
|
--mem-clock=3505 Set the gpu memory max clock (346.72+ driver)\n\
|
||||||
--gpu-clock=1150 Set the gpu engine max clock (346.72+ driver)\n\
|
--gpu-clock=1150 Set the gpu engine max clock (346.72+ driver)\n\
|
||||||
--pstate=0[,2] Set the gpu power state (352.21+ driver)\n\
|
--pstate=0[,2] Set the gpu power state (352.21+ driver)\n\
|
||||||
--plimit=100W Set the gpu power limit (352.21+ driver)\n"
|
--plimit=100W Set the gpu power limit (352.21+ driver)\n"
|
||||||
|
#else /* via nvapi.dll */
|
||||||
|
"\
|
||||||
|
--plimit=100 Set the gpu power limit in percentage\n"
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYSLOG_H
|
#ifdef HAVE_SYSLOG_H
|
||||||
"\
|
"\
|
||||||
|
@ -230,6 +230,7 @@
|
|||||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||||
<Optimization Condition="'$(Configuration)'=='Release'">Full</Optimization>
|
<Optimization Condition="'$(Configuration)'=='Release'">Full</Optimization>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="nvapi.cpp" />
|
||||||
<ClCompile Include="pools.cpp" />
|
<ClCompile Include="pools.cpp" />
|
||||||
<ClCompile Include="util.cpp" />
|
<ClCompile Include="util.cpp" />
|
||||||
<ClCompile Include="bench.cpp" />
|
<ClCompile Include="bench.cpp" />
|
||||||
@ -539,4 +540,4 @@
|
|||||||
<Target Name="AfterClean">
|
<Target Name="AfterClean">
|
||||||
<Delete Files="@(FilesToCopy->'$(OutDir)%(Filename)%(Extension)')" TreatErrorsAsWarnings="true" />
|
<Delete Files="@(FilesToCopy->'$(OutDir)%(Filename)%(Extension)')" TreatErrorsAsWarnings="true" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
@ -264,6 +264,9 @@
|
|||||||
<ClCompile Include="sph\blake2s.c">
|
<ClCompile Include="sph\blake2s.c">
|
||||||
<Filter>Source Files\sph</Filter>
|
<Filter>Source Files\sph</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="nvapi.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="algos.h">
|
<ClInclude Include="algos.h">
|
||||||
@ -734,4 +737,4 @@
|
|||||||
<Filter>Ressources</Filter>
|
<Filter>Ressources</Filter>
|
||||||
</Text>
|
</Text>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -1,2 +1,44 @@
|
|||||||
/* todo: stripped version... or not */
|
#pragma once
|
||||||
#include "nvapi.h"
|
|
||||||
|
#include "nvapi.h"
|
||||||
|
|
||||||
|
NvAPI_Status nvapi_dll_init();
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
NvU32 version;
|
||||||
|
NvU32 flags;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
NvU32 pstate; // Assumption
|
||||||
|
NvU32 unknown1[2];
|
||||||
|
NvU32 min_power;
|
||||||
|
NvU32 unknown2[2];
|
||||||
|
NvU32 def_power;
|
||||||
|
NvU32 unknown3[2];
|
||||||
|
NvU32 max_power;
|
||||||
|
NvU32 unknown4; // 0
|
||||||
|
} entries[4];
|
||||||
|
} NVAPI_GPU_POWER_INFO;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
NvU32 version;
|
||||||
|
NvU32 flags;
|
||||||
|
struct {
|
||||||
|
NvU32 unknown1;
|
||||||
|
NvU32 unknown2;
|
||||||
|
NvU32 power; // percent * 1000
|
||||||
|
NvU32 unknown4;
|
||||||
|
} entries[4];
|
||||||
|
} NVAPI_GPU_POWER_STATUS;
|
||||||
|
|
||||||
|
#define NVAPI_GPU_POWER_STATUS_VER MAKE_NVAPI_VERSION(NVAPI_GPU_POWER_STATUS, 1)
|
||||||
|
#define NVAPI_GPU_POWER_INFO_VER MAKE_NVAPI_VERSION(NVAPI_GPU_POWER_INFO, 1)
|
||||||
|
|
||||||
|
NvAPI_Status NvAPI_DLL_GetInterfaceVersionString(NvAPI_ShortString string);
|
||||||
|
NvAPI_Status NvAPI_DLL_ClientPowerPoliciesGetInfo(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_GPU_POWER_INFO* pInfo);
|
||||||
|
NvAPI_Status NvAPI_DLL_ClientPowerPoliciesGetStatus(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_GPU_POWER_STATUS* pPolicies);
|
||||||
|
NvAPI_Status NvAPI_DLL_ClientPowerPoliciesSetStatus(NvPhysicalGpuHandle hPhysicalGpu, NVAPI_GPU_POWER_STATUS* pPolicies);
|
||||||
|
|
||||||
|
NvAPI_Status NvAPI_DLL_Unload();
|
||||||
|
|
||||||
|
#define NV_ASSERT(x) { NvAPI_Status ret = x; if(ret != NVAPI_OK) return ret; }
|
||||||
|
128
nvapi.cpp
Normal file
128
nvapi.cpp
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
/**
|
||||||
|
* Wrapper to nvapi.dll to query informations missing for x86 binaries (there is no nvml x86)
|
||||||
|
* based on the work of https://github.com/ircubic/lib_gpu
|
||||||
|
*
|
||||||
|
* tpruvot@ccminer.org 06-2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "compat/nvapi/nvapi_ccminer.h"
|
||||||
|
|
||||||
|
class NvAPILibraryHandle
|
||||||
|
{
|
||||||
|
typedef void *(*QueryPtr)(uint32_t);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HMODULE library;
|
||||||
|
QueryPtr nvidia_query;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NvAPILibraryHandle()
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
library = LoadLibrary("nvapi.dll");
|
||||||
|
if (library != NULL) {
|
||||||
|
nvidia_query = reinterpret_cast<QueryPtr>(GetProcAddress(library, "nvapi_QueryInterface"));
|
||||||
|
if (nvidia_query != NULL) {
|
||||||
|
const uint32_t NVAPI_ID_INIT = 0x0150E828;
|
||||||
|
auto init = static_cast<NvAPI_Status(*)()>(nvidia_query(NVAPI_ID_INIT));
|
||||||
|
NvAPI_Status ret = init();
|
||||||
|
success = (ret == NVAPI_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
throw std::runtime_error("Unable to locate NVAPI library!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~NvAPILibraryHandle()
|
||||||
|
{
|
||||||
|
NvAPI_DLL_Unload();
|
||||||
|
FreeLibrary(library);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *query(uint32_t ID)
|
||||||
|
{
|
||||||
|
return nvidia_query(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::unique_ptr<NvAPILibraryHandle> nvidia_handle;
|
||||||
|
bool nvapi_dll_loaded = false;
|
||||||
|
|
||||||
|
NvAPI_Status nvapi_dll_init()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if (!nvapi_dll_loaded) {
|
||||||
|
nvidia_handle = std::make_unique<NvAPILibraryHandle>();
|
||||||
|
nvapi_dll_loaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::runtime_error) {
|
||||||
|
nvapi_dll_loaded = false;
|
||||||
|
return NVAPI_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NVAPI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hidden nvapi.dll functions
|
||||||
|
|
||||||
|
#define NVAPI_ID_IFVERSION 0x01053FA5
|
||||||
|
NvAPI_Status NvAPI_DLL_GetInterfaceVersionString(NvAPI_ShortString string) {
|
||||||
|
static NvAPI_Status (*pointer)(NvAPI_ShortString string) = NULL;
|
||||||
|
if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED;
|
||||||
|
if(!pointer) {
|
||||||
|
pointer = (NvAPI_Status (*)(NvAPI_ShortString))nvidia_handle->query(NVAPI_ID_IFVERSION);
|
||||||
|
}
|
||||||
|
return (*pointer)(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NVAPI_ID_POWER_INFO 0x34206D86
|
||||||
|
NvAPI_Status NvAPI_DLL_ClientPowerPoliciesGetInfo(NvPhysicalGpuHandle handle, NVAPI_GPU_POWER_INFO* pInfo) {
|
||||||
|
static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_GPU_POWER_INFO*) = NULL;
|
||||||
|
if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED;
|
||||||
|
if(!pointer) {
|
||||||
|
pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_GPU_POWER_INFO*))nvidia_handle->query(NVAPI_ID_POWER_INFO);
|
||||||
|
}
|
||||||
|
return (*pointer)(handle, pInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NVAPI_ID_POWERPOL_GET 0x70916171
|
||||||
|
NvAPI_Status NvAPI_DLL_ClientPowerPoliciesGetStatus(NvPhysicalGpuHandle handle, NVAPI_GPU_POWER_STATUS* pPolicies) {
|
||||||
|
static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_GPU_POWER_STATUS*) = NULL;
|
||||||
|
if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED;
|
||||||
|
if(!pointer) {
|
||||||
|
pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_GPU_POWER_STATUS*))nvidia_handle->query(NVAPI_ID_POWERPOL_GET);
|
||||||
|
}
|
||||||
|
return (*pointer)(handle, pPolicies);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NVAPI_ID_POWERPOL_SET 0x0AD95F5ED
|
||||||
|
NvAPI_Status NvAPI_DLL_ClientPowerPoliciesSetStatus(NvPhysicalGpuHandle handle, NVAPI_GPU_POWER_STATUS* pPolicies) {
|
||||||
|
static NvAPI_Status (*pointer)(NvPhysicalGpuHandle, NVAPI_GPU_POWER_STATUS*) = NULL;
|
||||||
|
if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED;
|
||||||
|
if(!pointer) {
|
||||||
|
pointer = (NvAPI_Status (*)(NvPhysicalGpuHandle, NVAPI_GPU_POWER_STATUS*))nvidia_handle->query(NVAPI_ID_POWERPOL_SET);
|
||||||
|
}
|
||||||
|
return (*pointer)(handle, pPolicies);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NVAPI_ID_UNLOAD 0xD22BDD7E
|
||||||
|
NvAPI_Status NvAPI_DLL_Unload() {
|
||||||
|
static NvAPI_Status (*pointer)() = NULL;
|
||||||
|
if(!nvapi_dll_loaded) return NVAPI_API_NOT_INITIALIZED;
|
||||||
|
if(!pointer) {
|
||||||
|
pointer = (NvAPI_Status (*)())nvidia_handle->query(NVAPI_ID_UNLOAD);
|
||||||
|
}
|
||||||
|
return (*pointer)();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
73
nvml.cpp
73
nvml.cpp
@ -460,7 +460,7 @@ int nvml_set_pstate(nvml_handle *nvmlh, int dev_id)
|
|||||||
nclocks = min(nclocks, 32);
|
nclocks = min(nclocks, 32);
|
||||||
if (nclocks)
|
if (nclocks)
|
||||||
nvmlh->nvmlDeviceGetSupportedMemoryClocks(nvmlh->devs[n], &nclocks, mem_clocks);
|
nvmlh->nvmlDeviceGetSupportedMemoryClocks(nvmlh->devs[n], &nclocks, mem_clocks);
|
||||||
if (wanted_pstate+1 > nclocks) {
|
if ((uint32_t) wanted_pstate+1 > nclocks) {
|
||||||
applog(LOG_WARNING, "GPU #%d: only %u mem clocks available (p-states)", dev_id, nclocks);
|
applog(LOG_WARNING, "GPU #%d: only %u mem clocks available (p-states)", dev_id, nclocks);
|
||||||
}
|
}
|
||||||
for (uint8_t u=0; u < nclocks; u++) {
|
for (uint8_t u=0; u < nclocks; u++) {
|
||||||
@ -789,6 +789,8 @@ int nvml_destroy(nvml_handle *nvmlh)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nvapi alternative for windows x86 binaries
|
* nvapi alternative for windows x86 binaries
|
||||||
* nvml api doesn't exists as 32bit dll :///
|
* nvml api doesn't exists as 32bit dll :///
|
||||||
@ -800,6 +802,7 @@ static int nvapi_dev_map[MAX_GPUS] = { 0 };
|
|||||||
static NvDisplayHandle hDisplay_a[NVAPI_MAX_PHYSICAL_GPUS * 2] = { 0 };
|
static NvDisplayHandle hDisplay_a[NVAPI_MAX_PHYSICAL_GPUS * 2] = { 0 };
|
||||||
static NvPhysicalGpuHandle phys[NVAPI_MAX_PHYSICAL_GPUS] = { 0 };
|
static NvPhysicalGpuHandle phys[NVAPI_MAX_PHYSICAL_GPUS] = { 0 };
|
||||||
static NvU32 nvapi_dev_cnt = 0;
|
static NvU32 nvapi_dev_cnt = 0;
|
||||||
|
extern bool nvapi_dll_loaded;
|
||||||
|
|
||||||
int nvapi_temperature(unsigned int devNum, unsigned int *temperature)
|
int nvapi_temperature(unsigned int devNum, unsigned int *temperature)
|
||||||
{
|
{
|
||||||
@ -967,6 +970,52 @@ int nvapi_getbios(unsigned int devNum, char *desc, unsigned int maxlen)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t nvapi_getplimit(unsigned int devNum)
|
||||||
|
{
|
||||||
|
NvAPI_Status ret = NVAPI_OK;
|
||||||
|
NVAPI_GPU_POWER_STATUS pol = { 0 };
|
||||||
|
pol.version = NVAPI_GPU_POWER_STATUS_VER;
|
||||||
|
if ((ret = NvAPI_DLL_ClientPowerPoliciesGetStatus(phys[devNum], &pol)) != NVAPI_OK) {
|
||||||
|
NvAPI_ShortString string;
|
||||||
|
NvAPI_GetErrorMessage(ret, string);
|
||||||
|
if (opt_debug)
|
||||||
|
applog(LOG_DEBUG, "NVAPI GetPowerPoliciesStatus: %s", string);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (uint8_t) (pol.entries[0].power / 1000); // in percent
|
||||||
|
}
|
||||||
|
|
||||||
|
int nvapi_setplimit(unsigned int devNum, uint16_t percent)
|
||||||
|
{
|
||||||
|
NvAPI_Status ret = NVAPI_OK;
|
||||||
|
uint32_t val = percent * 1000;
|
||||||
|
|
||||||
|
NVAPI_GPU_POWER_INFO nfo = { 0 };
|
||||||
|
nfo.version = NVAPI_GPU_POWER_INFO_VER;
|
||||||
|
ret = NvAPI_DLL_ClientPowerPoliciesGetInfo(phys[devNum], &nfo);
|
||||||
|
if (ret == NVAPI_OK) {
|
||||||
|
if (val == 0)
|
||||||
|
val = nfo.entries[0].def_power;
|
||||||
|
else if (val < nfo.entries[0].min_power)
|
||||||
|
val = nfo.entries[0].min_power;
|
||||||
|
else if (val > nfo.entries[0].max_power)
|
||||||
|
val = nfo.entries[0].max_power;
|
||||||
|
}
|
||||||
|
|
||||||
|
NVAPI_GPU_POWER_STATUS pol = { 0 };
|
||||||
|
pol.version = NVAPI_GPU_POWER_STATUS_VER;
|
||||||
|
pol.flags = 1;
|
||||||
|
pol.entries[0].power = val;
|
||||||
|
if ((ret = NvAPI_DLL_ClientPowerPoliciesSetStatus(phys[devNum], &pol)) != NVAPI_OK) {
|
||||||
|
NvAPI_ShortString string;
|
||||||
|
NvAPI_GetErrorMessage(ret, string);
|
||||||
|
if (opt_debug)
|
||||||
|
applog(LOG_DEBUG, "NVAPI SetPowerPoliciesStatus: %s", string);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int nvapi_init()
|
int nvapi_init()
|
||||||
{
|
{
|
||||||
int num_gpus = cuda_num_devices();
|
int num_gpus = cuda_num_devices();
|
||||||
@ -1017,11 +1066,12 @@ int nvapi_init()
|
|||||||
applog(LOG_DEBUG, "NVAPI NvAPI_GPU_GetFullName: %s", string);
|
applog(LOG_DEBUG, "NVAPI NvAPI_GPU_GetFullName: %s", string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
NvAPI_ShortString ver;
|
if (opt_debug) {
|
||||||
NvAPI_GetInterfaceVersionString(ver);
|
NvAPI_ShortString ver;
|
||||||
applog(LOG_DEBUG, "NVAPI Version: %s", ver);
|
NvAPI_GetInterfaceVersionString(ver);
|
||||||
|
applog(LOG_DEBUG, "%s", ver);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NvU32 udv;
|
NvU32 udv;
|
||||||
@ -1031,6 +1081,19 @@ int nvapi_init()
|
|||||||
sprintf(driver_version,"%d.%02d", udv / 100, udv % 100);
|
sprintf(driver_version,"%d.%02d", udv / 100, udv % 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nvapi.dll
|
||||||
|
ret = nvapi_dll_init();
|
||||||
|
if (ret == NVAPI_OK) {
|
||||||
|
for (int n=0; n < opt_n_threads; n++) {
|
||||||
|
int dev_id = device_map[n % MAX_GPUS];
|
||||||
|
if (device_plimit[dev_id]) {
|
||||||
|
nvapi_setplimit(nvapi_dev_map[dev_id], device_plimit[dev_id]); // 0=default
|
||||||
|
uint32_t res = nvapi_getplimit(nvapi_dev_map[dev_id]);
|
||||||
|
gpulog(LOG_INFO, n, "NVAPI power limit is set to %u%%", res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user