nvmlDeviceGetPowerManagementMode() всегда возвращает NVML_ERROR_INVALID_ARGUMENT?
Я пишу код для периодического измерения энергопотребления графического процессора NVIDIA Tesla K20 (архитектура Kepler) с использованием API-интерфейса NVML.
Переменные:
nvmlReturn_t result;
nvmlEnableState_t pmmode;
nvmlDevice_t nvmlDeviceID;
unsigned int powerInt;
Основной код:
result = nvmlDeviceGetPowerManagementMode(nvmlDeviceID, &pmmode);
if (pmmode == NVML_FEATURE_ENABLED) {
result = nvmlDeviceGetPowerUsage(nvmlDeviceID, &powerInt);
}
Моя проблема в том, что nvmlDeviceGetPowerManagementMode
всегда возвращается NVML_ERROR_INVALID_ARGUMENT
, Я проверил это.
Документация по API NVML гласит, что NVML_ERROR_INVALID_ARGUMENT
возвращается, когда либо nvmlDeviceID
является недействительным или pmmode
является NULL
,
nvmlDeviceID
определенно действителен, потому что я могу запросить его свойства, которые соответствуют моему GPU. Но я не понимаю, почему я должен установить значение pmmode
ни к чему, потому что в документации сказано, что это Reference in which to return the current power management mode
, Для записи я попытался присвоить ему значение разрешения, но результат был все тот же.
Я явно делаю что-то не так, потому что другие пользователи системы написали свои собственные библиотеки, используя эту функцию, и у них нет проблем. Я не могу связаться с ними. Что я должен исправить, чтобы эта функция работала правильно?
1 ответ
Проблема здесь была не в вызове API, а в остальной части кода, но ответ мог бы быть полезен для других. Прежде чем пытаться использовать это решение, необходимо убедиться, что включен режим управления питанием (проверьте с помощью nvidia-smi -q -d POWER
).
В случае ошибки неверного аргумента весьма вероятно, что проблема заключается в nvmlDeviceID
, Я сказал, что могу запрашивать свойства устройства, и в то время я был уверен, что это правильно, но помните о любых вызовах API, которые изменяют nvmlDeviceID
ценность позже.
Например, в этом случае следующий вызов API some_variable
как неверный индекс, так nvmlDeviceID
стал недействительным.
nvmlDeviceGetHandleByIndex(some_variable, &nvmlDeviceID);
Это должно было быть изменено на:
nvmlDeviceGetHandleByIndex(0, &nvmlDeviceID);
Таким образом, решение состоит в том, чтобы либо удалить все вызовы API, которые изменяют, либо сделать недействительным значение nvmlDeviceID
или, по крайней мере, чтобы гарантировать, что любой существующий вызов API в коде не изменяет значение.