Невозможно запустить код CUDA, который запрашивает NVML — ошибка относительно libnvidia-ml.so

Недавно коллеге понадобилось использовать NVML для запроса информации об устройстве, поэтому я скачал комплект разработки Tesla 3.304.5 и скопировал файл nvml.h в /usr/include. Для проверки я скомпилировал код примера в tdk_3.304.5/nvml/example, и он отлично работал.

За выходные что-то изменилось в системе (я не могу определить, что именно изменилось, и я не единственный, кто имеет доступ к машине) и теперь любой код, использующий nvml.h, например код примера, завершается с ошибкой :

Failed to initialize NVML:
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
WARNING:

You should always run with libnvidia-ml.so that is installed with your NVIDIA Display Driver. By default it's installed in /usr/lib and /usr/lib64. libnvidia-ml.so in TDK package is a stub library that is attached only for build purposes (e.g. machine that you build your application doesn't have to have Display Driver installed).
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Тем не менее, я все еще могу запустить nvidia-smi и прочитать информацию о состоянии моего K20m, и, насколько мне известно, nvidia-smi — это просто набор вызовов nvml.h. Сообщение об ошибке, которое я получаю, несколько загадочно, но я считаю, что оно говорит мне, что файл nvidia-ml.so должен соответствовать драйверу Tesla, установленному в моей системе. Чтобы убедиться, что все в порядке, я повторно загрузил CUDA 5.0 и установил драйвер, среду выполнения CUDA и тестовые файлы. Я уверен, что файл nvidia-ml.so соответствует драйверу (оба 304.54), поэтому я совершенно не понимаю, что может пойти не так. Я могу скомпилировать и запустить тестовый код с помощью nvcc, а также запустить свой собственный код CUDA, если он не включает nvml.h.

Кто-нибудь сталкивался с этой ошибкой или есть мысли по устранению проблемы?

$ ls -la /usr/lib/libnvidia-ml*
lrwxrwxrwx. 1 root root     17 Jul 19 10:08 /usr/lib/libnvidia-ml.so -> libnvidia-ml.so.1
lrwxrwxrwx. 1 root root     22 Jul 19 10:08 /usr/lib/libnvidia-ml.so.1 -> libnvidia-ml.so.304.54
-rwxr-xr-x. 1 root root 391872 Jul 19 10:08 /usr/lib/libnvidia-ml.so.304.54

$ ls -la /usr/lib64/libnvidia-ml*
lrwxrwxrwx. 1 root root     17 Jul 19 10:08 /usr/lib64/libnvidia-ml.so -> libnvidia-ml.so.1
lrwxrwxrwx. 1 root root     22 Jul 19 10:08 /usr/lib64/libnvidia-ml.so.1 -> libnvidia-ml.so.304.54
-rwxr-xr-x. 1 root root 394792 Jul 19 10:08 /usr/lib64/libnvidia-ml.so.304.54

$ cat /proc/driver/nvidia/version 
NVRM version: NVIDIA UNIX x86_64 Kernel Module  304.54  Sat Sep 29 00:05:49 PDT 2012
GCC version:  gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) 

$ nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2012 NVIDIA Corporation
Built on Fri_Sep_21_17:28:58_PDT_2012
Cuda compilation tools, release 5.0, V0.2.1221

$ whereis nvml.h
nvml: /usr/include/nvml.h

$ ldd example
        linux-vdso.so.1 =>  (0x00007fff2da66000)
        libnvidia-ml.so.1 => /usr/lib64/libnvidia-ml.so.1 (0x00007f33ff6db000)
        libc.so.6 => /lib64/libc.so.6 (0x000000300e400000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x000000300ec00000)
        libdl.so.2 => /lib64/libdl.so.2 (0x000000300e800000)
        /lib64/ld-linux-x86-64.so.2 (0x000000300e000000)

РЕДАКТИРОВАТЬ: решение состояло в том, чтобы удалить все дополнительные экземпляры libnvidia-ml.so. Их почему-то было ОЧЕНЬ много.

$ sudo find / -name 'libnvidia-ml*'
/usr/lib/libnvidia-ml.so.304.54
/usr/lib/libnvidia-ml.so
/usr/lib/libnvidia-ml.so.1
/usr/opt/lib/libnvidia-ml.so
/usr/opt/lib/libnvidia-ml.so.1
/usr/opt/lib64/libnvidia-ml.so
/usr/opt/lib64/libnvidia-ml.so.1
/usr/opt/nvml/lib/libnvidia-ml.so
/usr/opt/nvml/lib/libnvidia-ml.so.1
/usr/opt/nvml/lib64/libnvidia-ml.so
/usr/opt/nvml/lib64/libnvidia-ml.so.1
/usr/lib64/libnvidia-ml.so.304.54
/usr/lib64/libnvidia-ml.so
/usr/lib64/libnvidia-ml.so.1
/lib/libnvidia-ml.so.old
/lib/libnvidia-ml.so.1

person Brian R    schedule 22.07.2013    source источник


Ответы (4)


Вы получаете эту ошибку, потому что приложение, которое пытается использовать nvml, загружает библиотеку-заглушку, расположенную в:

...tdk_install_path/lib64/libnvidia-ml.so

вместо того, что в:

/usr/lib64/libnvidia-ml.so

Я смог воспроизвести вашу ошибку, когда добавил путь к библиотеке-заглушке в свою переменную среды LD_LIBRARY_PATH. Так что это один из возможных источников ошибки, если кто-то добавил путь к библиотеке-заглушке, которая поставляется с дистрибутивом tdk, в вашу переменную среды LD_LIBRARY_PATH, но, вероятно, это не единственный способ, которым это может произойти. Если кто-то необычным образом скопировал библиотеку-заглушку по какому-то системному пути, это также может быть проблемой.

Вам нужно попытаться выяснить, почему ваша система загружает эту библиотеку-заглушку вместо правильной в /usr/lib64. В качестве альтернативы, в целях обнаружения, вы можете попробовать удалить все экземпляры библиотеки-заглушки в любом месте вашей системы (оставьте только правильные библиотеки в /usr/lib и /usr/lib64), и вы сможете наблюдать правильное поведение.

person Robert Crovella    schedule 22.07.2013
comment
Спасибо за ответ. Я просмотрел свой LD_LIBRARY_PATH и не нашел никакой ссылки на каталог tdk. Выполнение whereis на libnvidia-ml.so дает мне только каталоги /usr/lib и /usr/lib64, поэтому я предполагаю, что там нет конфликта, но я ни в коем случае не эксперт по Linux, поэтому я могу быть упущенным что-то. Есть ли другой путь, который был бы определен, кроме LD_LIBRARY_PATH, который может иметь ошибочную ссылку? Возможно, есть хороший способ проверить, не используется ли вместо этого заглушка .so? Я также rm каталоги lib и lib64 из каталога tdk. - person Brian R; 22.07.2013
comment
Какая у вас операционная система? Если у вас есть приложение, созданное для использования nvml, но работающее неправильно, что произойдет, если вы выполните следующую команду: ldd myapp ? (замените myapp на любое имя вашего скомпилированного исполняемого файла) То есть, пожалуйста, отредактируйте свой вопрос с выводом этой команды ldd. - person Robert Crovella; 22.07.2013
comment
Я использую Centos 6.0. Не догадался проверить ldd, но сейчас выложу результаты. К счастью, ваш совет помог мне решить проблему. По какой-то причине выполнение whereis дало мне только два каталога /usr/lib*, но выполнение find /libnvidia-ml* обнаружило кучу записей, разбросанных по всей файловой системе. Удаление их всех решило проблему. Слава тебе! - person Brian R; 22.07.2013

Я решил проблему таким образом на GTX 1070 с использованием Windows 10: зайдите в диспетчер устройств, выберите проблемный графический процессор, отключите графический процессор и снова включите его.

person Pro7ech    schedule 11.07.2017
comment
Это работало и для меня на win10. По крайней мере, мне не нужно выходить из системы и снова заходить. У кого-нибудь есть решение, которое является постоянным? - person Soenhay; 22.03.2018

У меня была такая же или похожая проблема с EWBF Cuda Miner для zCash.

Вот способ автоматически реализовать ответ Pro7ech (который сработал для меня) для WIN10:

Установите WDK для Windows 10, если у вас его еще нет: это даст вам возможность использовать devcon.exe, который позволяет манипулировать устройствами с помощью пакетных сценариев: https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk

Вам также может понадобиться Windows SDK, если у вас нет Visual Studio с настольной разработкой с рабочей нагрузкой C++: https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk

Чтобы упростить задачу, вы можете добавить путь установки в переменную среды PATH: https://www.howtogeek.com/118594/how-to-edit-your-system-path-for-легкийдоступккоманднойстроке/

Devcon.exe был установлен для меня здесь:

C:\Program Files (x86)\Windows Kits\10\Tools\x64

Итак, теперь запустите это или подобное в командной строке cmd.exe, чтобы получить идентификатор устройства:

devcon findall * | find /i "nvidia"

Вот как выглядит мой:

C:\Users\Soenhay>devcon findall * | find /i "nvidia"
HDAUDIO\FUNC_01&VEN_10DE&DEV_0083&SUBSYS_38426674&REV_1001\5&1C277AD4&0&0001: NVIDIA High Definition Audio
SWD\MMDEVAPI\{0.0.0.00000000}.{574980C3-9747-42EF-A78C-4C304E070B81}: SAMSUNG (NVIDIA High Definition Audio)
ROOT\UNNAMED_DEVICE\0000                                    : NVIDIA Virtual Audio Device (Wave Extensible) (WDM)
PCI\VEN_10DE&DEV_1B81&SUBSYS_66743842&REV_A1\4&1F1337ch33s3&0&0000: NVIDIA GeForce GTX 1070

Из этого я вижу, что идентификатор моего графического устройства:

PCI\VEN_10DE&DEV_1B81&SUBSYS_66743842&REV_A1\4&1F1337ch33s3&0&0000

Поэтому я создаю пакетный файл со следующим, чтобы отключить и снова включить драйвер:

devcon disable "@PCI\VEN_10DE&DEV_1B81&SUBSYS_66743842&REV_A1\4&1F1337ch33s3&0&0000"
devcon enable "@PCI\VEN_10DE&DEV_1B81&SUBSYS_66743842&REV_A1\4&1F1337ch33s3&0&0000"

Теперь, когда я получаю ошибку NVML при запуске майнера, я просто запускаю этот командный файл, и он исправляет ее. Вы также можете просто добавить эти 2 строки в начало вашего файла start.bat, чтобы делать это каждый раз, но я обнаружил, что ошибка не всегда возникает каждый раз, когда я перезапускаю майнер.


Использованная литература:

запись суперпользователя

команды devcon

примеры devcon

Подходящие устройства не найдены.

ПРИМЕЧАНИЕ. Команда должна иметь символ @ в начале идентификатора устройства. Пакетный скрипт должен запускаться от имени администратора.

person Soenhay    schedule 22.03.2018

Я столкнулся с той же ошибкой.

Найденные решения - запустить команду:

nvidia-uninstall
person Thuận Đặng Quang    schedule 13.10.2018