/* * A trivial little dlopen()-based wrapper library for the * NVIDIA NVML library, to allow runtime discovery of NVML on an * arbitrary system. This is all very hackish and simple-minded, but * it serves my immediate needs in the short term until NVIDIA provides * a static NVML wrapper library themselves, hopefully in * CUDA 6.5 or maybe sometime shortly after. * * This trivial code is made available under the "new" 3-clause BSD license, * and/or any of the GPL licenses you prefer. * Feel free to use the code and modify as you see fit. * * John E. Stone - john.stone@gmail.com * */ /* * Ugly hacks to avoid dependencies on the real nvml.h until it starts * getting included with the CUDA toolkit or a GDK that's got a known * install location, etc. */ typedef enum wrap_nvmlReturn_enum { WRAPNVML_SUCCESS = 0 } wrap_nvmlReturn_t; typedef void * wrap_nvmlDevice_t; /* our own version of the PCI info struct */ typedef struct { char bus_id_str[16]; /* string form of bus info */ unsigned int domain; unsigned int bus; unsigned int device; unsigned int pci_device_id; /* combined device and vendor id */ unsigned int pci_subsystem_id; unsigned int res0; /* NVML internal use only */ unsigned int res1; unsigned int res2; unsigned int res3; } wrap_nvmlPciInfo_t; typedef enum nvmlClockType_t { NVML_CLOCK_GRAPHICS = 0, NVML_CLOCK_SM = 1, NVML_CLOCK_MEM = 2 } wrap_nvmlClockType_t; /* * Handle to hold the function pointers for the entry points we need, * and the shared library itself. */ typedef struct { void *nvml_dll; int nvml_gpucount; int cuda_gpucount; 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; wrap_nvmlReturn_t (*nvmlInit)(void); wrap_nvmlReturn_t (*nvmlDeviceGetCount)(int *); wrap_nvmlReturn_t (*nvmlDeviceGetHandleByIndex)(int, wrap_nvmlDevice_t *); wrap_nvmlReturn_t (*nvmlDeviceGetClockInfo)(wrap_nvmlDevice_t, wrap_nvmlClockType_t, unsigned int *); wrap_nvmlReturn_t (*nvmlDeviceGetApplicationsClock)(wrap_nvmlDevice_t, wrap_nvmlClockType_t, unsigned int *); wrap_nvmlReturn_t (*nvmlDeviceGetPciInfo)(wrap_nvmlDevice_t, wrap_nvmlPciInfo_t *); wrap_nvmlReturn_t (*nvmlDeviceGetName)(wrap_nvmlDevice_t, char *, int); wrap_nvmlReturn_t (*nvmlDeviceGetTemperature)(wrap_nvmlDevice_t, int, unsigned int *); wrap_nvmlReturn_t (*nvmlDeviceGetFanSpeed)(wrap_nvmlDevice_t, unsigned int *); wrap_nvmlReturn_t (*nvmlDeviceGetPerformanceState)(wrap_nvmlDevice_t, int *); /* enum */ wrap_nvmlReturn_t (*nvmlDeviceGetPowerUsage)(wrap_nvmlDevice_t, unsigned int *); wrap_nvmlReturn_t (*nvmlDeviceGetUUID)(wrap_nvmlDevice_t, char *uuid, unsigned int len); wrap_nvmlReturn_t (*nvmlDeviceGetVbiosVersion)(wrap_nvmlDevice_t, char *version, unsigned int len); wrap_nvmlReturn_t (*nvmlSystemGetDriverVersion)(char *version, unsigned int len); char* (*nvmlErrorString)(wrap_nvmlReturn_t); wrap_nvmlReturn_t (*nvmlShutdown)(void); } wrap_nvml_handle; wrap_nvml_handle * wrap_nvml_create(); int wrap_nvml_destroy(wrap_nvml_handle *nvmlh); /* * Query the number of GPUs seen by NVML */ int wrap_nvml_get_gpucount(wrap_nvml_handle *nvmlh, int *gpucount); /* * Query the number of GPUs seen by CUDA */ int wrap_cuda_get_gpucount(wrap_nvml_handle *nvmlh, int *gpucount); /* * query the name of the GPU model from the CUDA device ID * */ int wrap_nvml_get_gpu_name(wrap_nvml_handle *nvmlh, int gpuindex, char *namebuf, int bufsize); /* * Query the current GPU temperature (Celsius), from the CUDA device ID */ int wrap_nvml_get_tempC(wrap_nvml_handle *nvmlh, int gpuindex, unsigned int *tempC); /* * Query the current GPU fan speed (percent) from the CUDA device ID */ int wrap_nvml_get_fanpcnt(wrap_nvml_handle *nvmlh, int gpuindex, unsigned int *fanpcnt); /* * Query the current GPU power usage in millwatts from the CUDA device ID * * This feature is only available on recent GPU generations and may be * limited in some cases only to Tesla series GPUs. * If the query is run on an unsupported GPU, this routine will return -1. */ int wrap_nvml_get_power_usage(wrap_nvml_handle *nvmlh, int gpuindex, unsigned int *milliwatts); /* nvapi functions */ #ifdef WIN32 int wrap_nvapi_init(); #endif /* api functions */ #include "miner.h" #ifdef USE_WRAPNVML int gpu_fanpercent(struct cgpu_info *gpu); float gpu_temp(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_nvids(struct cgpu_info *gpu); int gpu_info(struct cgpu_info *gpu); #endif // cuda api based int gpu_clocks(struct cgpu_info *gpu);