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 в коде не изменяет значение.

Другие вопросы по тегам