nvmlDeviceSetDefaultFanSpeed_v2 doesn’t work as documented. According to the header, it’s supposed to set the fan speed AND resume the auto fan curve!
Reproducing is as easy as setting the fan speed to 100% via nvmlDeviceSetFanSpeed_v2 and then calling nvmlDeviceSetDefaultFanSpeed_v2. The fan speed will both be reported as decreasing until it hits the “default” speed and will audible decrease in noise. Start any graphics-intensive application(in my case, Unigine Superposition) and notice that the only fans to ramp up are the ones controlled by custom AIB fan controllers! The fan speed for the GPU itself(index 0) is still at default speeds!
Nvidia, I REALLY appreciate the new NVML functions and all, but the quality of the last dozen or so functions is absolutely terrible.
Here is just A FEW highlights:
There is a copy/paste error here:
* - \ref NVML_ERROR_NOT_SUPPORTED if this query is not supported by the device
* - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible
*
*/
nvmlReturn_t DECLDIR nvmlDeviceGetPcieLinkMaxSpeed(nvmlDevice_t device, unsigned int *maxSpeed);
/**
* Gets the device's PCIe Link speed in Mbps
*
* @param device The identifier of the target device
* @param pcieSpeed The devices's PCIe Max Link speed in Mbps
*
* @return
* - \ref NVML_SUCCESS if \a pcieSpeed has been retrieved
* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized
* - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pcieSpeed is NULL
* - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support PCIe speed getting
* - \ref NVML_ERROR_UNKNOWN on any unexpected error
*/
nvmlReturn_t DECLDIR nvmlDeviceGetPcieSpeed(nvmlDevice_t device, unsigned int *pcieSpeed);
The nvmlDeviceSetTemperatureThreshold function takes in a pointer for some reason and only accepts one of the many enum types, NVML_TEMPERATURE_THRESHOLD_ACOUSTIC_CURR, it supposedly allows you to set:
* @param thresholdType The type of threshold value queried
* @param temp Reference in which to return the temperature reading
* @return
* - \ref NVML_SUCCESS if \a temp has been set
* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized
* - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid, \a thresholdType is invalid or \a temp is NULL
* - \ref NVML_ERROR_NOT_SUPPORTED if the device does not have a temperature sensor or is unsupported
* - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible
* - \ref NVML_ERROR_UNKNOWN on any unexpected error
*/
nvmlReturn_t DECLDIR nvmlDeviceGetTemperatureThreshold(nvmlDevice_t device, nvmlTemperatureThresholds_t thresholdType, unsigned int *temp);
/**
* Sets the temperature threshold for the GPU with the specified threshold type in degrees C.
*
* For Maxwell &tm; or newer fully supported devices.
*
* See \ref nvmlTemperatureThresholds_t for details on available temperature thresholds.
*
* @param device The identifier of the target device
* @param thresholdType The type of threshold value to be set
Nor is there a way to get default the default value of that one value. How do I reset it to default!?!?
There are references to NVAPI opaque types in NVML when they aren’t even used:
{
unsigned long long referenceTime; //!< referenceTime represents CPU timestamp in microseconds
unsigned long long violationTime; //!< violationTime in Nanoseconds
}nvmlViolationTime_t;
#define NVML_MAX_THERMAL_SENSORS_PER_GPU 3
typedef enum
{
NVML_THERMAL_TARGET_NONE = 0,
NVML_THERMAL_TARGET_GPU = 1, //!< GPU core temperature requires NvPhysicalGpuHandle
NVML_THERMAL_TARGET_MEMORY = 2, //!< GPU memory temperature requires NvPhysicalGpuHandle
NVML_THERMAL_TARGET_POWER_SUPPLY = 4, //!< GPU power supply temperature requires NvPhysicalGpuHandle
NVML_THERMAL_TARGET_BOARD = 8, //!< GPU board ambient temperature requires NvPhysicalGpuHandle
NVML_THERMAL_TARGET_VCD_BOARD = 9, //!< Visual Computing Device Board temperature requires NvVisualComputingDeviceHandle
NVML_THERMAL_TARGET_VCD_INLET = 10, //!< Visual Computing Device Inlet temperature requires NvVisualComputingDeviceHandle
NVML_THERMAL_TARGET_VCD_OUTLET = 11, //!< Visual Computing Device Outlet temperature requires NvVisualComputingDeviceHandle
NVML_THERMAL_TARGET_ALL = 15,
NVML_THERMAL_TARGET_UNKNOWN = -1,
} nvmlThermalTarget_t;
An enum type, nvmlGpuUtilizationDomainId_t, is defined but nothing uses it:
#define NVML_ADAPTIVE_CLOCKING_INFO_STATUS_DISABLED 0x00000000
#define NVML_ADAPTIVE_CLOCKING_INFO_STATUS_ENABLED 0x00000001
#define NVML_MAX_GPU_UTILIZATIONS 8
typedef enum nvmlGpuUtilizationDomainId_t
{
NVML_GPU_UTILIZATION_DOMAIN_GPU = 0, //!< Graphics engine domain
NVML_GPU_UTILIZATION_DOMAIN_FB = 1, //!< Frame buffer domain
NVML_GPU_UTILIZATION_DOMAIN_VID = 2, //!< Video engine domain
NVML_GPU_UTILIZATION_DOMAIN_BUS = 3, //!< Bus interface domain
} nvmlGpuUtilizationDomainId_t;
typedef struct nvmlGpuDynamicPstatesInfo_st
{
unsigned int flags; //!< Reserved for future use
struct
{
unsigned int bIsPresent; //!< Set if this utilization domain is present on this GPU
unsigned int percentage; //!< Percentage of time where the domain is considered busy in the last 1-second interval
unsigned int incThreshold; //!< Utilization threshold that can trigger a perf-increasing P-State change when crossed
unsigned int decThreshold; //!< Utilization threshold that can trigger a perf-decreasing P-State change when crossed
I’m guessing those enum values correspond to the struct array defined after it, but it’s not clear!
How are you supposed to even use nvmlDeviceGetThermalSettings?
* @param pThermalSettings Reference in which to return the thermal sensor information
*
* @return
* - \ref NVML_SUCCESS if \a pThermalSettings has been set
* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized
* - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a pThermalSettings is NULL
* - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature
* - \ref NVML_ERROR_GPU_IS_LOST if the target GPU has fallen off the bus or is otherwise inaccessible
* - \ref NVML_ERROR_UNKNOWN on any unexpected error
*/
nvmlReturn_t DECLDIR nvmlDeviceGetThermalSettings(nvmlDevice_t device, unsigned int sensorIndex, nvmlGpuThermalSettings_t *pThermalSettings);
/**
* Retrieves the current performance state for the device.
*
* For Fermi &tm; or newer fully supported devices.
*
* See \ref nvmlPstates_t for details on allowed performance states.
*
* @param device The identifier of the target device
* @param pState Reference in which to return the performance state reading
What even is GPCCLK VF!?!?
* @param[in] device The identifier of the target device
* @param[out] offset The retrieved GPCCLK VF offset value
*
* @return
* - \ref NVML_SUCCESS if \a offset has been successfully queried
* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized
* - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL
* - \ref NVML_ERROR_NOT_SUPPORTED if the device does not support this feature
* - \ref NVML_ERROR_UNKNOWN on any unexpected error
*/
nvmlReturn_t DECLDIR nvmlDeviceGetGpcClkVfOffset(nvmlDevice_t device, int *offset);
/**
* Set the GPCCLK VF offset value
* @param[in] device The identifier of the target device
* @param[in] offset The GPCCLK VF offset value to set
*
* @return
* - \ref NVML_SUCCESS if \a offset has been set
* - \ref NVML_ERROR_UNINITIALIZED if the library has not been successfully initialized
* - \ref NVML_ERROR_INVALID_ARGUMENT if \a device is invalid or \a offset is NULL
The function docs give zero indication. Calling the get function on my 1080 returns NVML_ERROR_NOT_FOUND!?!? What range of values are acceptable for setting an offset?
New constants were defined for defining when adaptive clock was disabled(0)/enabled(1):
#define NVML_PCIE_LINK_MAX_SPEED_INVALID 0x00000000
#define NVML_PCIE_LINK_MAX_SPEED_2500MBPS 0x00000001
#define NVML_PCIE_LINK_MAX_SPEED_5000MBPS 0x00000002
#define NVML_PCIE_LINK_MAX_SPEED_8000MBPS 0x00000003
#define NVML_PCIE_LINK_MAX_SPEED_16000MBPS 0x00000004
#define NVML_PCIE_LINK_MAX_SPEED_32000MBPS 0x00000005
/*
* Adaptive clocking status
*/
#define NVML_ADAPTIVE_CLOCKING_INFO_STATUS_DISABLED 0x00000000
#define NVML_ADAPTIVE_CLOCKING_INFO_STATUS_ENABLED 0x00000001
#define NVML_MAX_GPU_UTILIZATIONS 8
typedef enum nvmlGpuUtilizationDomainId_t
{
NVML_GPU_UTILIZATION_DOMAIN_GPU = 0, //!< Graphics engine domain
NVML_GPU_UTILIZATION_DOMAIN_FB = 1, //!< Frame buffer domain
NVML_GPU_UTILIZATION_DOMAIN_VID = 2, //!< Video engine domain
NVML_GPU_UTILIZATION_DOMAIN_BUS = 3, //!< Bus interface domain
} nvmlGpuUtilizationDomainId_t;
but NVML already has nvmlEnableState_t:
*/
/***************************************************************************************************/
/**
* Generic enable/disable enum.
*/
typedef enum nvmlEnableState_enum
{
NVML_FEATURE_DISABLED = 0, //!< Feature disabled
NVML_FEATURE_ENABLED = 1 //!< Feature enabled
} nvmlEnableState_t;
//! Generic flag used to specify the default behavior of some functions. See description of particular functions for details.
#define nvmlFlagDefault 0x00
//! Generic flag used to force some behavior. See description of particular functions for details.
#define nvmlFlagForce 0x01
/**
* * The Brand of the GPU
* */
typedef enum nvmlBrandType_enum
Please Nvidia, stop this!
How are you supposed to even use nvmlDeviceGetThermalSettings?
In case anyone is wondering, the entire function seems to be broken. The “count” field is what gives you the amount of populated thermal sensors but you have no way of knowing that beforehand. You can tell because if you invoke the function with a value greater than 2 it’ll throw NVML_ERROR_UNKNOWN. So I guess you just always invoke it with an index of 0?
And I just found out Windows doesn’t have these functions yet. Can someone from Nvidia please explain what is going on?