ajc*_*ajc 5 c++ linux rpath dlopen python-bindings
onnxruntime
我正在构建一个在底层使用的库(Ubuntu 22) 。反过来,onnxruntime
使用 CUDA,动态加载一些专用的“后端”。我构建了除 CUDA 库之外的整个代码堆栈,并且没有一个库具有其RPATH
或RUNPATH
设置(使用 进行双重检查readelf -d
)。
我构建了两个应用程序,一个是 C++,并直接链接到我的库。该应用程序有其RPATH
设置,一切正常。如果我运行它,LD_DEBUG=libs
我会看到类似这样的内容(请注意,路径已被编辑,并且我仅显示调试输出的一小部分):
158834: calling init: .../install/bin/../lib/libonnxruntime_providers_cuda.so
158834:
158834: find library=libcudnn_ops_infer.so.8 [0]; searching
158834: search path=.../install/bin/../lib (RPATH from file .../install/bin/test)
158834: trying file=.../install/bin/../lib/libcudnn_ops_infer.so.8
158834:
158834:
158834: calling init: .../install/bin/../lib/libcudnn_ops_infer.so.8
158834:
Run Code Online (Sandbox Code Playgroud)
这就是我所期待的,我很高兴。
但是,我还需要通过一些链接到它的 python 绑定来使用相同的库。为了让它工作,我需要在这种情况下设置RPATH
python 绑定(至少在我看来,它只是一个在运行时加载的共享库)。请注意,Python 可执行文件既没有RPATH
也没有RUNPATH
设置。这仅部分有效。也就是说,RPATH
传播似乎在沿着依赖关系树向下移动时起作用,直到开始搜索 CUDA 库,此时它不再起作用。这是以相同的方式、相同的构建运行完全相同的 onnxruntime API,并在与上面相同的文件夹中使用相同的文件。唯一的区别是 python 扩展层。输出LD_DEBUG
如下所示:
159602: find library=libonnxruntime.so.1.15.1 [0]; searching
159602: search path=.../install/lib/../lib (RPATH from file .../install/lib/pyext.cpython-310-x86_64-linux-gnu.so)
159602: trying file=.../install/lib/../lib/libonnxruntime.so.1.15.1
[...]
159602: calling init: .../install/lib/pyext.cpython-310-x86_64-linux-gnu.so
159602:
159602: find library=libonnxruntime_providers_shared.so [0]; searching
159602: search path=.../install/lib/../lib (RPATH from file .../install/lib/pyext.cpython-310-x86_64-linux-gnu.so)
159602: trying file=.../install/lib/../lib/libonnxruntime_providers_shared.so
159602:
159602:
159602: calling init: .../install/lib/../lib/libonnxruntime_providers_shared.so
159602:
159602: find library=libonnxruntime_providers_cuda.so [0]; searching
159602: search path=.../install/lib/../lib (RPATH from file .../install/lib/pyext.cpython-310-x86_64-linux-gnu.so)
159602: trying file=.../install/lib/../lib/libonnxruntime_providers_cuda.so
159602:
159602: find library=libcublas.so.11 [0]; searching
159602: search cache=/etc/ld.so.cache
159602: search path=/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3:/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2:/lib/x86_64-linux-gnu/tls/haswell/x86_64:/lib/x
86_64-linux-gnu/tls/haswell:/lib/x86_64-linux-gnu/tls/x86_64:/lib/x86_64-linux-gnu/tls:/lib/x86_64-linux-gnu/haswell/x86_64:/lib/x86_64-linux-gnu/haswell:/lib/x86_64-
linux-gnu/x86_64:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3:/usr/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2:/usr/lib/x86_64-linux-gnu/tls
/haswell/x86_64:/usr/lib/x86_64-linux-gnu/tls/haswell:/usr/lib/x86_64-linux-gnu/tls/x86_64:/usr/lib/x86_64-linux-gnu/tls:/usr/lib/x86_64-linux-gnu/haswell/x86_64:/usr
/lib/x86_64-linux-gnu/haswell:/usr/lib/x86_64-linux-gnu/x86_64:/usr/lib/x86_64-linux-gnu:/lib/glibc-hwcaps/x86-64-v3:/lib/glibc-hwcaps/x86-64-v2:/lib/tls/haswell/x86_
64:/lib/tls/haswell:/lib/tls/x86_64:/lib/tls:/lib/haswell/x86_64:/lib/haswell:/lib/x86_64:/lib:/usr/lib/glibc-hwcaps/x86-64-v3:/usr/lib/glibc-hwcaps/x86-64-v2:/usr/li
b/tls/haswell/x86_64:/usr/lib/tls/haswell:/usr/lib/tls/x86_64:/usr/lib/tls:/usr/lib/haswell/x86_64:/usr/lib/haswell:/usr/lib/x86_64:/usr/lib (system search
path)
159602: trying file=/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v3/libcublas.so.11
159602: trying file=/lib/x86_64-linux-gnu/glibc-hwcaps/x86-64-v2/libcublas.so.11
159602: trying file=/lib/x86_64-linux-gnu/tls/haswell/x86_64/libcublas.so.11
[...]
159602: calling fini: .../install/lib/../lib/libonnxruntime_providers_shared.so [0]
Run Code Online (Sandbox Code Playgroud)
所以基本上libcublas
找不到(也没有找到任何其他 CUDA 库),从而触发onnxruntime
避免使用 CUDA 的回退机制。
为什么RPATH
传播适用于 C++ 应用程序但不适用于 Python 扩展?我是否遗漏了一些愚蠢的东西,或者它与如何在 python 会话上下文中加载库密切相关?这可能是 bug 的奇怪表现onnxruntime
,也许是做错了什么dlopen
?
请注意,Python 版本本身似乎也存在同样的问题onnxruntime
:它们setup.py
确保所有依赖项都已预先加载,使用ctypes.CDLL
with RTLD_GLOBAL
。
点击此链接: https: //wiki.debian.org/RpathIssue。动态链接器ld
将在以下位置寻找匹配的库:
所以在你的情况下:
因此,要使 libonnxruntime 加载 libcublas,您也必须在 libonnxruntime 上设置 RPATH(以便规则 1 适用)。
为了帮助调试,可以使用lddtree
工具 ( apt install pax-utils
) 来获取 lib 依赖项的分层视图。
归档时间: |
|
查看次数: |
291 次 |
最近记录: |