Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
更改导入顺序会导致Python中出现错误_Python_Python 3.x_Scipy_Cython - Fatal编程技术网

更改导入顺序会导致Python中出现错误

更改导入顺序会导致Python中出现错误,python,python-3.x,scipy,cython,Python,Python 3.x,Scipy,Cython,我正在试图了解以下错误的原因。首先,如果我在python中键入以下内容 >>> import scipy.sparse >>> import torch 它运行无误。然而,当我输入 >>> import torch >>> import scipy.sparse 我得到以下错误: 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 文件“/global/software/sl-7.x86_64/modules/lang

我正在试图了解以下错误的原因。首先,如果我在python中键入以下内容

>>> import scipy.sparse
>>> import torch
它运行无误。然而,当我输入

>>> import torch
>>> import scipy.sparse
我得到以下错误:
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/global/software/sl-7.x86_64/modules/langs/python/3.6/lib/python3.6/site packages/scipy/sparse/_uuuuinit_uuu.py”,第229行
从.csr导入*
文件“/global/software/sl-7.x86_64/modules/langs/python/3.6/lib/python3.6/site packages/scipy/sparse/csr.py”,第15行,在
从。sparsetools导入csr\u tocsc、csr\u tobsr、csr\u count\u块\
ImportError:/lib64/libstdc++.so.6:找不到版本“CXXABI_1.3.9”(由/global/software/sl-7.x86_64/modules/langs/python/3.6/lib/python3.6/site packages/scipy/sparse/_sparsetools.cpython-36m-x86_64-linux-gnu.so所需)
我甚至可以进入目录“/global/software/sl-7.x86_64/modules/langs/python/3.6/lib/python3.6/site packages/scipy/sparse/”并导入二进制文件“_sparsetools.cpython-36m-x86_64-linux-gnu.so”,然后导入torch而不出问题。但是如果我换一种方式尝试,我会再次得到上面的错误


有人知道为什么改变这些进口的顺序会产生不同的效果吗

共享对象的简单搜索策略假定存在每个对象的单个版本,或者至少将包含较新版本的目录放在搜索路径的第一位。该路径包括
$LD\u LIBRARY\u path
(应该避免),
DT\u RPATH
及其较新的变体
DT\u RUNPATH
(这主要取决于正在加载的客户机),以及系统目录,如
/lib
。这适用于遵循全局包管理的系统,但安装的包在单个每个包目录中(在Windows和一些“普通用户”包管理器中很常见)复制其依赖项可以轻松地使用同一个对象生成共享对象的多个版本

人们的期望是,共享该名称是无害的,因为一个名称可以用来代替另一个名称(因此可以放在路径的第一位)。事实上,没有一个目录是所有库的最新目录,甚至没有一个路径可以配置
DT\ucode>标记

结果是,无论第一个加载的是哪一个,都会赢:动态加载程序不能同时加载这两个(因为它们提供了许多相同的符号),因此第二个请求只起到检查库版本标记的作用,这里发现这是不充分的。在这种情况下,一个客户端(<代码> Trase<代码>)依赖于系统的C++标准库,而另一个(<代码>它可能需要也可能不需要它的新版本:因为它是根据它构建的,所以默认情况下被保守地标记为需要它


这是一个问题:甚至像虚拟环境这样的工具也不能处理它,因为问题在于现有包的不兼容编译。从源代码(如或)重建所有内容的系统可以,但只能以控制所有相关构建的通常成本为代价。不幸的是,简单地控制导入订单可能是最好的选择。

@DavisHerring的回答向您解释了发生了什么,这里有一个可能的解决方法,以确保加载正确的版本:

1。步骤:

通过控制台查找正确的libc++.so版本:

$ ldd _sparsetools.cpython-36m-x86_64-linux-gnu.so
libstdc++.so.6 => <path to right version>/libstdc++.so.6(...)
$ldd\u sparsetools.cpython-36m-x86\u 64-linux-gnu.so
libstdc++.so.6=>/libstdc++.so.6(…)
2。步骤:

启动python时,预加载正确的版本,以便加载程序选择正确的版本:

$ LD_PRELOAD=<path to right version>/libstdc++.so python
$LD_PRELOAD=/libstdc++.so python


然而,最好的解决方案是使用正确的libc++依赖项重建
pytorch

也许这与torch捆绑其依赖项有关?我知道你可以(可以?)使用CUDA和torch,而不必亲自安装CUDA。不知道思想对我来说很好(Ubuntu18、python-3.6.9、pytorch-0.4.1、scipy-1.1.0、cudnn-7.6.4)。
$ LD_PRELOAD=<path to right version>/libstdc++.so python