- Added option --veracrypt-keyfile to set Keyfiles used, can be multiple
- Added option --veracrypt-pim to set the VeraCrypt personal iterations multiplier
- Added option --machine-readable for easier parsing of output
+- Added option --powertune-enable to work with NVidia devices as well, not just AMD
##
## Algorithms
- Dropped special 64-bit rotate() handling for NV, it seems that they've added it to their OpenCL runtime
- Disabled retain support by default, you can reactive it using --gpu-temp-retain
- Completely get rid of HAVE_ADL, HAVE_NVML and HAVE_NVAPI in sources
+- Replaced NVAPI with NVML on windows
typedef nvmlReturn_t (*NVML_DEVICE_SET_OPERATIONMODE) (nvmlDevice_t, nvmlGpuOperationMode_t);
typedef nvmlReturn_t (*NVML_DEVICE_GET_POWERMANAGEMENTLIMITCONSTRAINTS) (nvmlDevice_t, unsigned int *, unsigned int *);
typedef nvmlReturn_t (*NVML_DEVICE_SET_POWERMANAGEMENTLIMIT) (nvmlDevice_t, unsigned int);
+typedef nvmlReturn_t (*NVML_DEVICE_GET_POWERMANAGEMENTLIMIT) (nvmlDevice_t, unsigned int *);
typedef struct
{
NVML_DEVICE_SET_OPERATIONMODE nvmlDeviceSetGpuOperationMode;
NVML_DEVICE_GET_POWERMANAGEMENTLIMITCONSTRAINTS nvmlDeviceGetPowerManagementLimitConstraints;
NVML_DEVICE_SET_POWERMANAGEMENTLIMIT nvmlDeviceSetPowerManagementLimit;
+ NVML_DEVICE_GET_POWERMANAGEMENTLIMIT nvmlDeviceGetPowerManagementLimit;
} hm_nvml_lib_t;
const char * hm_NVML_nvmlErrorString (NVML_PTR *nvml, nvmlReturn_t nvml_rc);
nvmlReturn_t hm_NVML_nvmlInit (NVML_PTR *nvml);
nvmlReturn_t hm_NVML_nvmlShutdown (NVML_PTR *nvml);
-nvmlReturn_t hm_NVML_nvmlDeviceGetName (NVML_PTR *nvml, nvmlDevice_t device, char *name, unsigned int length);
+nvmlReturn_t hm_NVML_nvmlDeviceGetName (NVML_PTR *nvml, int, nvmlDevice_t device, char *name, unsigned int length);
nvmlReturn_t hm_NVML_nvmlDeviceGetHandleByIndex (NVML_PTR *nvml, int, unsigned int index, nvmlDevice_t *device);
-nvmlReturn_t hm_NVML_nvmlDeviceGetTemperature (NVML_PTR *nvml, nvmlDevice_t device, nvmlTemperatureSensors_t sensorType, unsigned int *temp);
+nvmlReturn_t hm_NVML_nvmlDeviceGetTemperature (NVML_PTR *nvml, int, nvmlDevice_t device, nvmlTemperatureSensors_t sensorType, unsigned int *temp);
nvmlReturn_t hm_NVML_nvmlDeviceGetFanSpeed (NVML_PTR *nvml, int, nvmlDevice_t device, unsigned int *speed);
-nvmlReturn_t hm_NVML_nvmlDeviceGetPowerUsage (NVML_PTR *nvml, nvmlDevice_t device, unsigned int *power);
-nvmlReturn_t hm_NVML_nvmlDeviceGetUtilizationRates (NVML_PTR *nvml, nvmlDevice_t device, nvmlUtilization_t *utilization);
-nvmlReturn_t hm_NVML_nvmlDeviceGetClockInfo (NVML_PTR *nvml, nvmlDevice_t device, nvmlClockType_t type, unsigned int *clock);
-nvmlReturn_t hm_NVML_nvmlDeviceGetTemperatureThreshold (NVML_PTR *nvml, nvmlDevice_t device, nvmlTemperatureThresholds_t thresholdType, unsigned int *temp);
-nvmlReturn_t hm_NVML_nvmlDeviceGetCurrPcieLinkGeneration (NVML_PTR *nvml, nvmlDevice_t device, unsigned int *currLinkGen);
-nvmlReturn_t hm_NVML_nvmlDeviceGetCurrPcieLinkWidth (NVML_PTR *nvml, nvmlDevice_t device, unsigned int *currLinkWidth);
-nvmlReturn_t hm_NVML_nvmlDeviceGetCurrentClocksThrottleReasons (NVML_PTR *nvml, nvmlDevice_t device, unsigned long long *clocksThrottleReasons);
-nvmlReturn_t hm_NVML_nvmlDeviceGetSupportedClocksThrottleReasons (NVML_PTR *nvml, nvmlDevice_t device, unsigned long long *supportedClocksThrottleReasons);
+nvmlReturn_t hm_NVML_nvmlDeviceGetPowerUsage (NVML_PTR *nvml, int, nvmlDevice_t device, unsigned int *power);
+nvmlReturn_t hm_NVML_nvmlDeviceGetUtilizationRates (NVML_PTR *nvml, int, nvmlDevice_t device, nvmlUtilization_t *utilization);
+nvmlReturn_t hm_NVML_nvmlDeviceGetClockInfo (NVML_PTR *nvml, int, nvmlDevice_t device, nvmlClockType_t type, unsigned int *clock);
+nvmlReturn_t hm_NVML_nvmlDeviceGetTemperatureThreshold (NVML_PTR *nvml, int, nvmlDevice_t device, nvmlTemperatureThresholds_t thresholdType, unsigned int *temp);
+nvmlReturn_t hm_NVML_nvmlDeviceGetCurrPcieLinkGeneration (NVML_PTR *nvml, int, nvmlDevice_t device, unsigned int *currLinkGen);
+nvmlReturn_t hm_NVML_nvmlDeviceGetCurrPcieLinkWidth (NVML_PTR *nvml, int, nvmlDevice_t device, unsigned int *currLinkWidth);
+nvmlReturn_t hm_NVML_nvmlDeviceGetCurrentClocksThrottleReasons (NVML_PTR *nvml, int, nvmlDevice_t device, unsigned long long *clocksThrottleReasons);
+nvmlReturn_t hm_NVML_nvmlDeviceGetSupportedClocksThrottleReasons (NVML_PTR *nvml, int, nvmlDevice_t device, unsigned long long *supportedClocksThrottleReasons);
nvmlReturn_t hm_NVML_nvmlDeviceSetComputeMode (NVML_PTR *nvml, int, nvmlDevice_t device, nvmlComputeMode_t mode);
nvmlReturn_t hm_NVML_nvmlDeviceSetGpuOperationMode (NVML_PTR *nvml, int, nvmlDevice_t device, nvmlGpuOperationMode_t mode);
nvmlReturn_t hm_NVML_nvmlDeviceGetPowerManagementLimitConstraints (NVML_PTR *nvml, int, nvmlDevice_t device, unsigned int *minLimit, unsigned int *maxLimit);
nvmlReturn_t hm_NVML_nvmlDeviceSetPowerManagementLimit (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, unsigned int limit);
+nvmlReturn_t hm_NVML_nvmlDeviceGetPowerManagementLimit (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, unsigned int *limit);
#endif // HAVE_HWMON
int hm_get_memoryspeed_with_device_id (const uint device_id);
int hm_get_corespeed_with_device_id (const uint device_id);
int hm_get_throttle_with_device_id (const uint device_id);
-
-int hm_set_fanspeed_with_device_id_amd (const uint device_id, const int fanspeed, const int fanpolicy);
-int hm_set_fanspeed_with_device_id_nvml (const uint device_id, const int fanspeed, const int fanpolicy);
+int hm_set_fanspeed_with_device_id_amd (const uint device_id, const int fanspeed, const int fanpolicy);
void hm_device_val_to_str (char *target_buf, int max_buf_size, char *suffix, int value);
#endif // HAVE_HWMON
HC_LOAD_FUNC(nvml, nvmlDeviceSetGpuOperationMode, NVML_DEVICE_SET_OPERATIONMODE, NVML, 0)
HC_LOAD_FUNC(nvml, nvmlDeviceGetPowerManagementLimitConstraints, NVML_DEVICE_GET_POWERMANAGEMENTLIMITCONSTRAINTS, NVML, 0)
HC_LOAD_FUNC(nvml, nvmlDeviceSetPowerManagementLimit, NVML_DEVICE_SET_POWERMANAGEMENTLIMIT, NVML, 0)
+ HC_LOAD_FUNC(nvml, nvmlDeviceGetPowerManagementLimit, NVML_DEVICE_GET_POWERMANAGEMENTLIMIT, NVML, 0)
return 0;
}
return nvml_rc;
}
-nvmlReturn_t hm_NVML_nvmlDeviceGetName (NVML_PTR *nvml, nvmlDevice_t device, char *name, unsigned int length)
+nvmlReturn_t hm_NVML_nvmlDeviceGetName (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, char *name, unsigned int length)
{
if (!nvml) return -1;
if (nvml_rc != NVML_SUCCESS)
{
- const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
+ if (skip_warnings == 0)
+ {
+ const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
- log_info ("WARN: %s %d %s\n", "nvmlDeviceGetName()", nvml_rc, string);
+ log_info ("WARN: %s %d %s\n", "nvmlDeviceGetName()", nvml_rc, string);
+ }
}
return nvml_rc;
return nvml_rc;
}
-nvmlReturn_t hm_NVML_nvmlDeviceGetTemperature (NVML_PTR *nvml, nvmlDevice_t device, nvmlTemperatureSensors_t sensorType, unsigned int *temp)
+nvmlReturn_t hm_NVML_nvmlDeviceGetTemperature (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, nvmlTemperatureSensors_t sensorType, unsigned int *temp)
{
if (!nvml) return -1;
if (nvml_rc != NVML_SUCCESS)
{
- const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
+ if (skip_warnings == 0)
+ {
+ const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
- log_info ("WARN: %s %d %s\n", "nvmlDeviceGetTemperature()", nvml_rc, string);
+ log_info ("WARN: %s %d %s\n", "nvmlDeviceGetTemperature()", nvml_rc, string);
+ }
}
return nvml_rc;
return nvml_rc;
}
-nvmlReturn_t hm_NVML_nvmlDeviceGetPowerUsage (NVML_PTR *nvml, nvmlDevice_t device, unsigned int *power)
+nvmlReturn_t hm_NVML_nvmlDeviceGetPowerUsage (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, unsigned int *power)
{
if (!nvml) return -1;
if (nvml_rc != NVML_SUCCESS)
{
- const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
+ if (skip_warnings == 0)
+ {
+ const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
- log_info ("WARN: %s %d %s\n", "nvmlDeviceGetPowerUsage()", nvml_rc, string);
+ log_info ("WARN: %s %d %s\n", "nvmlDeviceGetPowerUsage()", nvml_rc, string);
+ }
}
return nvml_rc;
}
-nvmlReturn_t hm_NVML_nvmlDeviceGetUtilizationRates (NVML_PTR *nvml, nvmlDevice_t device, nvmlUtilization_t *utilization)
+nvmlReturn_t hm_NVML_nvmlDeviceGetUtilizationRates (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, nvmlUtilization_t *utilization)
{
if (!nvml) return -1;
if (nvml_rc != NVML_SUCCESS)
{
- const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
+ if (skip_warnings == 0)
+ {
+ const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
- log_info ("WARN: %s %d %s\n", "nvmlDeviceGetUtilizationRates()", nvml_rc, string);
+ log_info ("WARN: %s %d %s\n", "nvmlDeviceGetUtilizationRates()", nvml_rc, string);
+ }
}
return nvml_rc;
}
-nvmlReturn_t hm_NVML_nvmlDeviceGetClockInfo (NVML_PTR *nvml, nvmlDevice_t device, nvmlClockType_t type, unsigned int *clock)
+nvmlReturn_t hm_NVML_nvmlDeviceGetClockInfo (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, nvmlClockType_t type, unsigned int *clock)
{
if (!nvml) return -1;
if (nvml_rc != NVML_SUCCESS)
{
- const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
+ if (skip_warnings == 0)
+ {
+ const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
- log_info ("WARN: %s %d %s\n", "nvmlDeviceGetUtilizationRates()", nvml_rc, string);
+ log_info ("WARN: %s %d %s\n", "nvmlDeviceGetClockInfo()", nvml_rc, string);
+ }
}
return nvml_rc;
}
-nvmlReturn_t hm_NVML_nvmlDeviceGetTemperatureThreshold (NVML_PTR *nvml, nvmlDevice_t device, nvmlTemperatureThresholds_t thresholdType, unsigned int *temp)
+nvmlReturn_t hm_NVML_nvmlDeviceGetTemperatureThreshold (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, nvmlTemperatureThresholds_t thresholdType, unsigned int *temp)
{
if (!nvml) return -1;
if (nvml_rc != NVML_SUCCESS)
{
- const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
+ if (skip_warnings == 0)
+ {
+ const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
- log_info ("WARN: %s %d %s\n", "nvmlDeviceGetTemperatureThreshold()", nvml_rc, string);
+ log_info ("WARN: %s %d %s\n", "nvmlDeviceGetTemperatureThreshold()", nvml_rc, string);
+ }
}
return nvml_rc;
}
-nvmlReturn_t hm_NVML_nvmlDeviceGetCurrPcieLinkGeneration (NVML_PTR *nvml, nvmlDevice_t device, unsigned int *currLinkGen)
+nvmlReturn_t hm_NVML_nvmlDeviceGetCurrPcieLinkGeneration (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, unsigned int *currLinkGen)
{
if (!nvml) return -1;
if (nvml_rc != NVML_SUCCESS)
{
- const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
+ if (skip_warnings == 0)
+ {
+ const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
- log_info ("WARN: %s %d %s\n", "nvmlDeviceGetUtilizationRates()", nvml_rc, string);
+ log_info ("WARN: %s %d %s\n", "nvmlDeviceGetCurrPcieLinkGeneration()", nvml_rc, string);
+ }
}
return nvml_rc;
}
-nvmlReturn_t hm_NVML_nvmlDeviceGetCurrPcieLinkWidth (NVML_PTR *nvml, nvmlDevice_t device, unsigned int *currLinkWidth)
+nvmlReturn_t hm_NVML_nvmlDeviceGetCurrPcieLinkWidth (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, unsigned int *currLinkWidth)
{
if (!nvml) return -1;
if (nvml_rc != NVML_SUCCESS)
{
- const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
+ if (skip_warnings == 0)
+ {
+ const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
- log_info ("WARN: %s %d %s\n", "nvmlDeviceGetUtilizationRates()", nvml_rc, string);
+ log_info ("WARN: %s %d %s\n", "nvmlDeviceGetCurrPcieLinkWidth()", nvml_rc, string);
+ }
}
return nvml_rc;
}
-nvmlReturn_t hm_NVML_nvmlDeviceGetCurrentClocksThrottleReasons (NVML_PTR *nvml, nvmlDevice_t device, unsigned long long *clocksThrottleReasons)
+nvmlReturn_t hm_NVML_nvmlDeviceGetCurrentClocksThrottleReasons (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, unsigned long long *clocksThrottleReasons)
{
if (!nvml) return -1;
if (nvml_rc != NVML_SUCCESS)
{
- const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
+ if (skip_warnings == 0)
+ {
+ const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
- log_info ("WARN: %s %d %s\n", "nvmlDeviceGetUtilizationRates()", nvml_rc, string);
+ log_info ("WARN: %s %d %s\n", "nvmlDeviceGetCurrentClocksThrottleReasons()", nvml_rc, string);
+ }
}
return nvml_rc;
}
-nvmlReturn_t hm_NVML_nvmlDeviceGetSupportedClocksThrottleReasons (NVML_PTR *nvml, nvmlDevice_t device, unsigned long long *supportedClocksThrottleReasons)
+nvmlReturn_t hm_NVML_nvmlDeviceGetSupportedClocksThrottleReasons (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, unsigned long long *supportedClocksThrottleReasons)
{
if (!nvml) return -1;
if (nvml_rc != NVML_SUCCESS)
{
- const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
+ if (skip_warnings == 0)
+ {
+ const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
- log_info ("WARN: %s %d %s\n", "nvmlDeviceGetSupportedClocksThrottleReasons()", nvml_rc, string);
+ log_info ("WARN: %s %d %s\n", "nvmlDeviceGetSupportedClocksThrottleReasons()", nvml_rc, string);
+ }
}
return nvml_rc;
return nvml_rc;
}
+
+nvmlReturn_t hm_NVML_nvmlDeviceGetPowerManagementLimit (NVML_PTR *nvml, int skip_warnings, nvmlDevice_t device, unsigned int *limit)
+{
+ if (!nvml) return -1;
+
+ nvmlReturn_t nvml_rc = nvml->nvmlDeviceGetPowerManagementLimit (device, limit);
+
+ if (nvml_rc != NVML_SUCCESS)
+ {
+ if (skip_warnings == 0)
+ {
+ const char *string = hm_NVML_nvmlErrorString (nvml, nvml_rc);
+
+ log_info ("WARN: %s %d %s\n", "nvmlDeviceGetPowerManagementLimit()", nvml_rc, string);
+ }
+ }
+
+ return nvml_rc;
+}
#ifdef HAVE_HWMON
" --gpu-temp-abort | Num | Abort if GPU temperature reaches X degrees celsius | --gpu-temp-abort=100",
" --gpu-temp-retain | Num | Try to retain GPU temperature at X degrees celsius | --gpu-temp-retain=95",
- " --powertune-enable | | Enable automatic power tuning (AMD OverDrive 6 only) |",
+ " --powertune-enable | | Enable power tuning, restores settings when finished |",
#endif
" --scrypt-tmto | Num | Manually override TMTO value for scrypt to X | --scrypt-tmto=3",
" -s, --skip | Num | Skip X words from the start | -s 1000000",
{
unsigned int speed;
- if (hm_NVML_nvmlDeviceGetFanSpeed (data.hm_nv, 1, hm_adapters_nv[i].adapter_index.nv, &speed) != NVML_ERROR_NOT_SUPPORTED) hm_adapters_nv[i].fan_get_supported = 1;
+ if (hm_NVML_nvmlDeviceGetFanSpeed (data.hm_nv, 0, hm_adapters_nv[i].adapter_index.nv, &speed) == NVML_SUCCESS) hm_adapters_nv[i].fan_get_supported = 1;
hm_NVML_nvmlDeviceSetComputeMode (data.hm_nv, 1, hm_adapters_nv[i].adapter_index.nv, NVML_COMPUTEMODE_EXCLUSIVE_PROCESS);
hm_NVML_nvmlDeviceSetGpuOperationMode (data.hm_nv, 1, hm_adapters_nv[i].adapter_index.nv, NVML_GOM_ALL_ON);
-
- unsigned int minLimit;
- unsigned int maxLimit;
-
- if (hm_NVML_nvmlDeviceGetPowerManagementLimitConstraints (data.hm_nv, 1, hm_adapters_nv[i].adapter_index.nv, &minLimit, &maxLimit) == NVML_SUCCESS)
- {
- if (maxLimit > 0)
- {
- hm_NVML_nvmlDeviceSetPowerManagementLimit (data.hm_nv, 1, hm_adapters_nv[i].adapter_index.nv, maxLimit);
- }
- }
}
}
}
int *od_power_control_status = (int *) mycalloc (data.devices_cnt, sizeof (int));
+ unsigned int *nvml_power_limit = (unsigned int *) mycalloc (data.devices_cnt, sizeof (unsigned int));
+
/**
* User-defined GPU temp handling
*/
}
/**
- * Temporary fix:
- * with AMD r9 295x cards it seems that we need to set the powertune value just AFTER the ocl init stuff
- * otherwise after hc_clCreateContext () etc, powertune value was set back to "normal" and cards unfortunately
- * were not working @ full speed (setting hm_ADL_Overdrive_PowerControl_Set () here seems to fix the problem)
- * Driver / ADL bug?
+ * powertune on user request
*/
if (powertune_enable == 1)
if (device_param->skipped) continue;
- if (data.hm_device[device_id].od_version == 6)
+ if (data.devices_param[device_id].device_vendor_id == VENDOR_ID_AMD)
{
- // set powertune value only
-
- int powertune_supported = 0;
-
- int ADL_rc = 0;
+ /**
+ * Temporary fix:
+ * with AMD r9 295x cards it seems that we need to set the powertune value just AFTER the ocl init stuff
+ * otherwise after hc_clCreateContext () etc, powertune value was set back to "normal" and cards unfortunately
+ * were not working @ full speed (setting hm_ADL_Overdrive_PowerControl_Set () here seems to fix the problem)
+ * Driver / ADL bug?
+ */
- if ((ADL_rc = hm_ADL_Overdrive6_PowerControl_Caps (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &powertune_supported)) != ADL_OK)
+ if (data.hm_device[device_id].od_version == 6)
{
- log_error ("ERROR: Failed to get ADL PowerControl Capabilities");
+ int ADL_rc;
- return (-1);
- }
+ // check powertune capabilities first, if not available then skip device
- if (powertune_supported != 0)
- {
- // powertune set
- ADLOD6PowerControlInfo powertune = {0, 0, 0, 0, 0};
+ int powertune_supported = 0;
- if ((ADL_rc = hm_ADL_Overdrive_PowerControlInfo_Get (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &powertune)) != ADL_OK)
+ if ((ADL_rc = hm_ADL_Overdrive6_PowerControl_Caps (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &powertune_supported)) != ADL_OK)
{
- log_error ("ERROR: Failed to get current ADL PowerControl settings");
+ log_error ("ERROR: Failed to get ADL PowerControl Capabilities");
return (-1);
}
- if ((ADL_rc = hm_ADL_Overdrive_PowerControl_Set (data.hm_amd, data.hm_device[device_id].adapter_index.amd, powertune.iMaxValue)) != ADL_OK)
+ // first backup current value, we will restore it later
+
+ if (powertune_supported != 0)
{
- log_error ("ERROR: Failed to set new ADL PowerControl values");
+ // powercontrol settings
- return (-1);
+ ADLOD6PowerControlInfo powertune = {0, 0, 0, 0, 0};
+
+ if ((ADL_rc = hm_ADL_Overdrive_PowerControlInfo_Get (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &powertune)) == ADL_OK)
+ {
+ ADL_rc = hm_ADL_Overdrive_PowerControl_Get (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &od_power_control_status[device_id]);
+ }
+
+ if (ADL_rc != ADL_OK)
+ {
+ log_error ("ERROR: Failed to get current ADL PowerControl settings");
+
+ return (-1);
+ }
+
+ if ((ADL_rc = hm_ADL_Overdrive_PowerControl_Set (data.hm_amd, data.hm_device[device_id].adapter_index.amd, powertune.iMaxValue)) != ADL_OK)
+ {
+ log_error ("ERROR: Failed to set new ADL PowerControl values");
+
+ return (-1);
+ }
+
+ // clocks
+
+ memset (&od_clock_mem_status[device_id], 0, sizeof (ADLOD6MemClockState));
+
+ od_clock_mem_status[device_id].state.iNumberOfPerformanceLevels = 2;
+
+ if ((ADL_rc = hm_ADL_Overdrive_StateInfo_Get (data.hm_amd, data.hm_device[device_id].adapter_index.amd, ADL_OD6_GETSTATEINFO_CUSTOM_PERFORMANCE, &od_clock_mem_status[device_id])) != ADL_OK)
+ {
+ log_error ("ERROR: Failed to get ADL memory and engine clock frequency");
+
+ return (-1);
+ }
+
+ // Query capabilities only to see if profiles were not "damaged", if so output a warning but do accept the users profile settings
+
+ ADLOD6Capabilities caps = {0, 0, 0, {0, 0, 0}, {0, 0, 0}, 0, 0};
+
+ if ((ADL_rc = hm_ADL_Overdrive_Capabilities_Get (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &caps)) != ADL_OK)
+ {
+ log_error ("ERROR: Failed to get ADL device capabilities");
+
+ return (-1);
+ }
+
+ int engine_clock_max = caps.sEngineClockRange.iMax * 0.6666;
+ int memory_clock_max = caps.sMemoryClockRange.iMax * 0.6250;
+
+ int warning_trigger_engine = (int) (0.25 * (float) engine_clock_max);
+ int warning_trigger_memory = (int) (0.25 * (float) memory_clock_max);
+
+ int engine_clock_profile_max = od_clock_mem_status[device_id].state.aLevels[1].iEngineClock;
+ int memory_clock_profile_max = od_clock_mem_status[device_id].state.aLevels[1].iMemoryClock;
+
+ // warning if profile has too low max values
+
+ if ((engine_clock_max - engine_clock_profile_max) > warning_trigger_engine)
+ {
+ log_info ("WARN: the custom profile seems to have too low maximum engine clock values. You therefore may not reach full performance");
+ }
+
+ if ((memory_clock_max - memory_clock_profile_max) > warning_trigger_memory)
+ {
+ log_info ("WARN: the custom profile seems to have too low maximum memory clock values. You therefore may not reach full performance");
+ }
+
+ ADLOD6StateInfo *performance_state = (ADLOD6StateInfo*) mycalloc (1, sizeof (ADLOD6StateInfo) + sizeof (ADLOD6PerformanceLevel));
+
+ performance_state->iNumberOfPerformanceLevels = 2;
+
+ performance_state->aLevels[0].iEngineClock = engine_clock_profile_max;
+ performance_state->aLevels[1].iEngineClock = engine_clock_profile_max;
+ performance_state->aLevels[0].iMemoryClock = memory_clock_profile_max;
+ performance_state->aLevels[1].iMemoryClock = memory_clock_profile_max;
+
+ if ((ADL_rc = hm_ADL_Overdrive_State_Set (data.hm_amd, data.hm_device[device_id].adapter_index.amd, ADL_OD6_SETSTATE_PERFORMANCE, performance_state)) != ADL_OK)
+ {
+ log_info ("ERROR: Failed to set ADL performance state");
+
+ return (-1);
+ }
+
+ local_free (performance_state);
+ }
+
+ // set powertune value only
+
+ if (powertune_supported != 0)
+ {
+ // powertune set
+ ADLOD6PowerControlInfo powertune = {0, 0, 0, 0, 0};
+
+ if ((ADL_rc = hm_ADL_Overdrive_PowerControlInfo_Get (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &powertune)) != ADL_OK)
+ {
+ log_error ("ERROR: Failed to get current ADL PowerControl settings");
+
+ return (-1);
+ }
+
+ if ((ADL_rc = hm_ADL_Overdrive_PowerControl_Set (data.hm_amd, data.hm_device[device_id].adapter_index.amd, powertune.iMaxValue)) != ADL_OK)
+ {
+ log_error ("ERROR: Failed to set new ADL PowerControl values");
+
+ return (-1);
+ }
+ }
+ }
+ }
+
+ if (data.devices_param[device_id].device_vendor_id == VENDOR_ID_NV)
+ {
+ // first backup current value, we will restore it later
+
+ unsigned int limit;
+
+ int powertune_supported = 0;
+
+ if (hm_NVML_nvmlDeviceGetPowerManagementLimit (data.hm_nv, 0, data.hm_device[device_id].adapter_index.nv, &limit) == NVML_SUCCESS)
+ {
+ powertune_supported = 1;
+ }
+
+ // if backup worked, activate the maximum allowed
+
+ if (powertune_supported != 0)
+ {
+ unsigned int minLimit;
+ unsigned int maxLimit;
+
+ if (hm_NVML_nvmlDeviceGetPowerManagementLimitConstraints (data.hm_nv, 0, data.hm_device[device_id].adapter_index.nv, &minLimit, &maxLimit) == NVML_SUCCESS)
+ {
+ if (maxLimit > 0)
+ {
+ if (hm_NVML_nvmlDeviceSetPowerManagementLimit (data.hm_nv, 0, data.hm_device[device_id].adapter_index.nv, maxLimit) == NVML_SUCCESS)
+ {
+ // now we can be sure we need to reset later
+
+ nvml_power_limit[device_id] = limit;
+ }
+ }
}
}
}
}
}
- /**
- * Store original powercontrol/clocks settings, set overdrive 6 performance tuning settings
- */
-
- if (powertune_enable == 1) // VENDOR_ID_AMD implied
- {
- hc_thread_mutex_lock (mux_adl);
-
- if (data.hm_device[device_id].od_version == 6)
- {
- int ADL_rc;
-
- // check powertune capabilities first, if not available then skip device
-
- int powertune_supported = 0;
-
- if ((ADL_rc = hm_ADL_Overdrive6_PowerControl_Caps (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &powertune_supported)) != ADL_OK)
- {
- log_error ("ERROR: Failed to get ADL PowerControl Capabilities");
-
- return (-1);
- }
-
- if (powertune_supported != 0)
- {
- // powercontrol settings
-
- ADLOD6PowerControlInfo powertune = {0, 0, 0, 0, 0};
-
- if ((ADL_rc = hm_ADL_Overdrive_PowerControlInfo_Get (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &powertune)) == ADL_OK)
- {
- ADL_rc = hm_ADL_Overdrive_PowerControl_Get (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &od_power_control_status[device_id]);
- }
-
- if (ADL_rc != ADL_OK)
- {
- log_error ("ERROR: Failed to get current ADL PowerControl settings");
-
- return (-1);
- }
-
- if ((ADL_rc = hm_ADL_Overdrive_PowerControl_Set (data.hm_amd, data.hm_device[device_id].adapter_index.amd, powertune.iMaxValue)) != ADL_OK)
- {
- log_error ("ERROR: Failed to set new ADL PowerControl values");
-
- return (-1);
- }
-
- // clocks
-
- memset (&od_clock_mem_status[device_id], 0, sizeof (ADLOD6MemClockState));
-
- od_clock_mem_status[device_id].state.iNumberOfPerformanceLevels = 2;
-
- if ((ADL_rc = hm_ADL_Overdrive_StateInfo_Get (data.hm_amd, data.hm_device[device_id].adapter_index.amd, ADL_OD6_GETSTATEINFO_CUSTOM_PERFORMANCE, &od_clock_mem_status[device_id])) != ADL_OK)
- {
- log_error ("ERROR: Failed to get ADL memory and engine clock frequency");
-
- return (-1);
- }
-
- // Query capabilities only to see if profiles were not "damaged", if so output a warning but do accept the users profile settings
-
- ADLOD6Capabilities caps = {0, 0, 0, {0, 0, 0}, {0, 0, 0}, 0, 0};
-
- if ((ADL_rc = hm_ADL_Overdrive_Capabilities_Get (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &caps)) != ADL_OK)
- {
- log_error ("ERROR: Failed to get ADL device capabilities");
-
- return (-1);
- }
-
- int engine_clock_max = caps.sEngineClockRange.iMax * 0.6666;
- int memory_clock_max = caps.sMemoryClockRange.iMax * 0.6250;
-
- int warning_trigger_engine = (int) (0.25 * (float) engine_clock_max);
- int warning_trigger_memory = (int) (0.25 * (float) memory_clock_max);
-
- int engine_clock_profile_max = od_clock_mem_status[device_id].state.aLevels[1].iEngineClock;
- int memory_clock_profile_max = od_clock_mem_status[device_id].state.aLevels[1].iMemoryClock;
-
- // warning if profile has too low max values
-
- if ((engine_clock_max - engine_clock_profile_max) > warning_trigger_engine)
- {
- log_info ("WARN: the custom profile seems to have too low maximum engine clock values. You therefore may not reach full performance");
- }
-
- if ((memory_clock_max - memory_clock_profile_max) > warning_trigger_memory)
- {
- log_info ("WARN: the custom profile seems to have too low maximum memory clock values. You therefore may not reach full performance");
- }
-
- ADLOD6StateInfo *performance_state = (ADLOD6StateInfo*) mycalloc (1, sizeof (ADLOD6StateInfo) + sizeof (ADLOD6PerformanceLevel));
-
- performance_state->iNumberOfPerformanceLevels = 2;
-
- performance_state->aLevels[0].iEngineClock = engine_clock_profile_max;
- performance_state->aLevels[1].iEngineClock = engine_clock_profile_max;
- performance_state->aLevels[0].iMemoryClock = memory_clock_profile_max;
- performance_state->aLevels[1].iMemoryClock = memory_clock_profile_max;
-
- if ((ADL_rc = hm_ADL_Overdrive_State_Set (data.hm_amd, data.hm_device[device_id].adapter_index.amd, ADL_OD6_SETSTATE_PERFORMANCE, performance_state)) != ADL_OK)
- {
- log_info ("ERROR: Failed to set ADL performance state");
-
- return (-1);
- }
-
- local_free (performance_state);
- }
- }
-
- hc_thread_mutex_unlock (mux_adl);
- }
-
#endif // HAVE_HWMON
}
if (device_param->skipped) continue;
- if (data.hm_device[device_id].od_version == 6)
+ if (data.devices_param[device_id].device_vendor_id == VENDOR_ID_AMD)
{
- // check powertune capabilities first, if not available then skip device
-
- int powertune_supported = 0;
-
- if ((hm_ADL_Overdrive6_PowerControl_Caps (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &powertune_supported)) != ADL_OK)
+ if (data.hm_device[device_id].od_version == 6)
{
- log_error ("ERROR: Failed to get ADL PowerControl Capabilities");
+ // check powertune capabilities first, if not available then skip device
- return (-1);
- }
-
- if (powertune_supported != 0)
- {
- // powercontrol settings
+ int powertune_supported = 0;
- if ((hm_ADL_Overdrive_PowerControl_Set (data.hm_amd, data.hm_device[device_id].adapter_index.amd, od_power_control_status[device_id])) != ADL_OK)
+ if ((hm_ADL_Overdrive6_PowerControl_Caps (data.hm_amd, data.hm_device[device_id].adapter_index.amd, &powertune_supported)) != ADL_OK)
{
- log_info ("ERROR: Failed to restore the ADL PowerControl values");
+ log_error ("ERROR: Failed to get ADL PowerControl Capabilities");
return (-1);
}
- // clocks
+ if (powertune_supported != 0)
+ {
+ // powercontrol settings
- ADLOD6StateInfo *performance_state = (ADLOD6StateInfo*) mycalloc (1, sizeof (ADLOD6StateInfo) + sizeof (ADLOD6PerformanceLevel));
+ if ((hm_ADL_Overdrive_PowerControl_Set (data.hm_amd, data.hm_device[device_id].adapter_index.amd, od_power_control_status[device_id])) != ADL_OK)
+ {
+ log_info ("ERROR: Failed to restore the ADL PowerControl values");
- performance_state->iNumberOfPerformanceLevels = 2;
+ return (-1);
+ }
- performance_state->aLevels[0].iEngineClock = od_clock_mem_status[device_id].state.aLevels[0].iEngineClock;
- performance_state->aLevels[1].iEngineClock = od_clock_mem_status[device_id].state.aLevels[1].iEngineClock;
- performance_state->aLevels[0].iMemoryClock = od_clock_mem_status[device_id].state.aLevels[0].iMemoryClock;
- performance_state->aLevels[1].iMemoryClock = od_clock_mem_status[device_id].state.aLevels[1].iMemoryClock;
+ // clocks
- if ((hm_ADL_Overdrive_State_Set (data.hm_amd, data.hm_device[device_id].adapter_index.amd, ADL_OD6_SETSTATE_PERFORMANCE, performance_state)) != ADL_OK)
- {
- log_info ("ERROR: Failed to restore ADL performance state");
+ ADLOD6StateInfo *performance_state = (ADLOD6StateInfo*) mycalloc (1, sizeof (ADLOD6StateInfo) + sizeof (ADLOD6PerformanceLevel));
- return (-1);
+ performance_state->iNumberOfPerformanceLevels = 2;
+
+ performance_state->aLevels[0].iEngineClock = od_clock_mem_status[device_id].state.aLevels[0].iEngineClock;
+ performance_state->aLevels[1].iEngineClock = od_clock_mem_status[device_id].state.aLevels[1].iEngineClock;
+ performance_state->aLevels[0].iMemoryClock = od_clock_mem_status[device_id].state.aLevels[0].iMemoryClock;
+ performance_state->aLevels[1].iMemoryClock = od_clock_mem_status[device_id].state.aLevels[1].iMemoryClock;
+
+ if ((hm_ADL_Overdrive_State_Set (data.hm_amd, data.hm_device[device_id].adapter_index.amd, ADL_OD6_SETSTATE_PERFORMANCE, performance_state)) != ADL_OK)
+ {
+ log_info ("ERROR: Failed to restore ADL performance state");
+
+ return (-1);
+ }
+
+ local_free (performance_state);
}
+ }
+ }
- local_free (performance_state);
+ if (data.devices_param[device_id].device_vendor_id == VENDOR_ID_NV)
+ {
+ unsigned int limit = nvml_power_limit[device_id];
+
+ if (limit > 0)
+ {
+ hm_NVML_nvmlDeviceSetPowerManagementLimit (data.hm_nv, 0, data.hm_device[device_id].adapter_index.nv, limit);
}
}
}
local_free (temp_retain_fanspeed_value);
local_free (od_clock_mem_status);
local_free (od_power_control_status);
+ local_free (nvml_power_limit);
#endif
global_free (devices_param);
{
int target = 0;
- hm_NVML_nvmlDeviceGetTemperatureThreshold (data.hm_nv, data.hm_device[device_id].adapter_index.nv, NVML_TEMPERATURE_THRESHOLD_SLOWDOWN, (unsigned int *) &target);
+ if (hm_NVML_nvmlDeviceGetTemperatureThreshold (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, NVML_TEMPERATURE_THRESHOLD_SLOWDOWN, (unsigned int *) &target) != NVML_SUCCESS) return -1;
return target;
}
{
int target = 0;
- hm_NVML_nvmlDeviceGetTemperatureThreshold (data.hm_nv, data.hm_device[device_id].adapter_index.nv, NVML_TEMPERATURE_THRESHOLD_SHUTDOWN, (unsigned int *) &target);
+ if (hm_NVML_nvmlDeviceGetTemperatureThreshold (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, NVML_TEMPERATURE_THRESHOLD_SHUTDOWN, (unsigned int *) &target) != NVML_SUCCESS) return -1;
return target;
}
{
int temperature = 0;
- hm_NVML_nvmlDeviceGetTemperature (data.hm_nv, data.hm_device[device_id].adapter_index.nv, NVML_TEMPERATURE_GPU, (uint *) &temperature);
+ if (hm_NVML_nvmlDeviceGetTemperature (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, NVML_TEMPERATURE_GPU, (uint *) &temperature) != NVML_SUCCESS) return -1;
return temperature;
}
{
int speed = 0;
- hm_NVML_nvmlDeviceGetFanSpeed (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, (uint *) &speed);
+ if (hm_NVML_nvmlDeviceGetFanSpeed (data.hm_nv, 0, data.hm_device[device_id].adapter_index.nv, (uint *) &speed) != NVML_SUCCESS) return -1;
return speed;
}
{
unsigned int currLinkWidth;
- hm_NVML_nvmlDeviceGetCurrPcieLinkWidth (data.hm_nv, data.hm_device[device_id].adapter_index.nv, &currLinkWidth);
+ if (hm_NVML_nvmlDeviceGetCurrPcieLinkWidth (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, &currLinkWidth) != NVML_SUCCESS) return -1;
return currLinkWidth;
}
{
nvmlUtilization_t utilization;
- hm_NVML_nvmlDeviceGetUtilizationRates (data.hm_nv, data.hm_device[device_id].adapter_index.nv, &utilization);
+ if (hm_NVML_nvmlDeviceGetUtilizationRates (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, &utilization) != NVML_SUCCESS) return -1;
return utilization.gpu;
}
{
unsigned int clock;
- hm_NVML_nvmlDeviceGetClockInfo (data.hm_nv, data.hm_device[device_id].adapter_index.nv, NVML_CLOCK_MEM, &clock);
+ if (hm_NVML_nvmlDeviceGetClockInfo (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, NVML_CLOCK_MEM, &clock) != NVML_SUCCESS) return -1;
return clock;
}
{
unsigned int clock;
- hm_NVML_nvmlDeviceGetClockInfo (data.hm_nv, data.hm_device[device_id].adapter_index.nv, NVML_CLOCK_SM, &clock);
+ if (hm_NVML_nvmlDeviceGetClockInfo (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, NVML_CLOCK_SM, &clock) != NVML_SUCCESS) return -1;
return clock;
}
unsigned long long clocksThrottleReasons = 0;
unsigned long long supportedThrottleReasons = 0;
- hm_NVML_nvmlDeviceGetCurrentClocksThrottleReasons (data.hm_nv, data.hm_device[device_id].adapter_index.nv, &clocksThrottleReasons);
-
- hm_NVML_nvmlDeviceGetSupportedClocksThrottleReasons (data.hm_nv, data.hm_device[device_id].adapter_index.nv, &supportedThrottleReasons);
+ if (hm_NVML_nvmlDeviceGetCurrentClocksThrottleReasons (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, &clocksThrottleReasons) != NVML_SUCCESS) return -1;
+ if (hm_NVML_nvmlDeviceGetSupportedClocksThrottleReasons (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, &supportedThrottleReasons) != NVML_SUCCESS) return -1;
clocksThrottleReasons &= supportedThrottleReasons;
return -1;
}
-int hm_set_fanspeed_with_device_id_nvml (const uint device_id, const int fanspeed, const int fanpolicy)
-{
- if (data.hm_device[device_id].fan_set_supported == 1)
- {
- if (data.hm_nv)
- {
- // NVML does not support setting the fan speed... :((
-
- if (fanspeed == fanpolicy) return -1; // makes the compiler happy
- }
- }
-
- return -1;
-}
-
#endif // HAVE_HWMON
/**