nvmlDeviceGetPowerManagementMode() всегда возвращает NVML_ERROR_INVALID_ARGUMENT?

Я пишу код для периодического измерения энергопотребления графического процессора NVIDIA Tesla K20 (архитектура Kepler) с использованием NVML API.

Переменные:

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. Я проверил это.

В документации NVML API сказано, что NVML_ERROR_INVALID_ARGUMENT возвращается, когда либо nvmlDeviceID недопустимо, либо pmmode равно NULL.

nvmlDeviceID определенно действителен, потому что я могу запросить его свойства, которые соответствуют моему графическому процессору. Но я не понимаю, почему я должен устанавливать значение pmmode на что-либо, потому что в документации сказано, что это Reference in which to return the current power management mode. Для записи я попытался присвоить ему значение включения, но результат был тот же.

Я явно делаю что-то не так, потому что другие пользователи системы написали свои собственные библиотеки, используя эту функцию, и у них не возникает проблем. Я не могу связаться с ними. Что нужно исправить, чтобы эта функция работала корректно?


person Kajal    schedule 18.05.2016    source источник


Ответы (1)


Проблема здесь была не непосредственно в вызове API — она была в остальной части кода — но ответ может быть полезен другим. Перед попыткой этого решения необходимо точно знать, что режим управления питанием включен (проверьте с помощью nvidia-smi -q -d POWER).

В случае ошибки неверного аргумента, очень вероятно, что проблема связана с nvmlDeviceID. Я сказал, что могу запросить свойства устройства, и в то время я был уверен, что это правильно, но помните о любых вызовах API, которые позже изменяют значение nvmlDeviceID.

Например, в этом случае следующий вызов API имел some_variable как недопустимый индекс, поэтому nvmlDeviceID стал недействительным.

nvmlDeviceGetHandleByIndex(some_variable, &nvmlDeviceID);

Пришлось изменить на:

nvmlDeviceGetHandleByIndex(0, &nvmlDeviceID);

Таким образом, решение состоит в том, чтобы либо удалить все вызовы API, которые изменяют или делают недействительным значение nvmlDeviceID, либо, по крайней мере, гарантировать, что любой существующий вызов API в коде не изменяет значение.

person Kajal    schedule 19.05.2016