无法运行CUDA代码来查询NVML - 关于libnvidia-ml.so的错误

6
最近,我的同事需要使用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),所以我很困惑可能出了什么问题。只要不包括nvml.h,我可以使用nvcc编译和运行测试代码以及运行自己的CUDA代码。

是否有人遇到过这个错误或者对纠正这个问题有任何想法?

$ 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
4个回答

7

您看到这个错误是因为试图使用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中的正确库),然后就应该能够观察到正确的行为。

谢谢您的回复。我已经查看了我的LD_LIBRARY_PATH,没有找到任何关于tdk目录的引用。在libnvidia-ml.so上执行whereis只给出了/usr/lib和/usr/lib64目录,因此我认为那里没有冲突,但我并不是Linux专家,所以可能会漏掉一些东西。除了LD_LIBRARY_PATH之外,是否还有其他定义路径可能存在错误引用?也许有一个好方法可以检查并查看是否正在使用stub .so?我还从tdk目录中删除了lib和lib64目录。 - Brian R
你使用的操作系统是什么?如果你有一个使用nvml构建的应用程序,但它不能正常工作,当你运行以下命令时会发生什么:ldd myapp?(将myapp更改为你编译的可执行文件的名称)也就是说,请编辑你的问题并附上该ldd命令的输出。 - Robert Crovella
我正在运行CentOS 6.0。我没有想到要检查ldd,但现在我会发布结果。幸运的是,你的建议确实帮助我解决了这个问题。出于某种原因,只做whereis只给了我两个/usr/lib目录,但是做一个find / libnvidia-ml发现散布在整个文件系统中的大量条目。删除它们全部解决了问题。向你致敬! - Brian R

1

我在使用Windows 10的GTX 1070上通过以下方式解决了这个问题:打开设备管理器,选择出现问题的GPU,禁用该GPU并重新启用。


这也适用于我在Win10上的情况。至少我不需要退出并重新登录。有人有永久解决方案吗? - Soenhay

0

我在使用EWBF Cuda Miner for zCash时遇到了同样或类似的问题。

以下是一种自动实现Pro7ech答案(对我有效)的方法,适用于WIN10:

如果您还没有安装Windows 10的WDK,请先安装:这将使您能够使用devcon.exe通过批处理脚本操纵设备: https://learn.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk

如果您没有带有C++工作负载的Visual Studio,则可能还需要Windows SDK: https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk

为了使事情更容易,您可能希望将安装路径添加到PATH环境变量中: https://www.howtogeek.com/118594/how-to-edit-your-system-path-for-easy-command-line-access/

Devcon.exe在我的计算机上安装在此位置:

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

现在在 cmd.exe 命令提示符中运行此命令或类似命令,以获取设备 ID:

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

从这里我可以看到我的图形设备ID是:

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错误时,我只需运行此批处理文件即可解决问题。您也可以将这两行代码添加到start.bat文件的开头,以便每次都能自动执行,但我发现该错误并不总是在每次重启矿工时发生。

参考资料:

超级用户帖子

devcon命令

devcon示例

未找到匹配的设备。

注意: 命令应在设备ID开头加上@符号。 批处理脚本应以管理员身份运行。


-4
我遇到了相同的错误。 找到的解决方案是运行以下命令:
nvidia-uninstall

我笑得很厉害。非常感谢,亲爱的先生。 - Faridzs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接