以下测试代码在OSX 10.7.3上适用于我,但不适用于其他计算机:
from __future__ import print_function
import numpy as np
import multiprocessing as mp
import scipy.linalg
def f(a):
print("about to call")
### these all cause crashes
sign, x = np.linalg.slogdet(a)
#x = np.linalg.det(a)
#x = np.linalg.inv(a).sum()
### these are all fine
#x = scipy.linalg.expm3(a).sum()
#x = np.dot(a, a.T).sum()
print("result:", x)
return x
def call_proc(a):
print("\ncalling with multiprocessing")
p = mp.Process(target=f, args=(a,))
p.start()
p.join()
if __name__ == '__main__':
import sys
n = int(sys.argv[1]) if len(sys.argv) > 1 else 50
a = np.random.normal(0, 2, (n, n))
f(a)
call_proc(a)
call_proc(a)
其中一个SEG故障的输出示例:
^{pr2}$出现一个OSX“问题报告”,抱怨一个类似KERN_INVALID_ADDRESS at 0x0000000000000108
;here's a full one的segfault。在
如果我用n <= 32
运行它,它运行得很好;对于任何{
如果我注释掉在原始进程中完成的f(a)
调用,那么对call_proc
的两个调用都可以。如果我在一个不同的大数组上调用f
,它仍然会出错;如果我在不同的小数组上调用它,或者如果我调用f(large_array)
,然后将f(small_array)
传递给另一个进程,它仍然可以正常工作。它们实际上不需要是同一个函数;np.inv(large_array)
,然后传递给np.linalg.slogdet(different_large_array)
也可以是segfaults。在
f
中所有被注释掉的np.linalg
都会导致崩溃;np.dot(self.a, self.a.T).sum()
和{
在我的桌面上
我认为2.6和2.7是默认的系统安装;我从源tarballs手动安装了3.2版本。所有这些NUMPY都与system Accelerate框架相关联:
$ otool -L `python3.2 -c 'from numpy.core import _dotblas; print(_dotblas.__file__)'`
/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages/numpy/core/_dotblas.so:
/System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate (compatibility version 1.0.0, current version 4.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.1)
我在另一台设置类似的Mac电脑上也有同样的行为。在
但是f
的所有选项都适用于其他正在运行的计算机
slogdet
)我是不是做错了什么?是什么原因造成的?我看不出在一个正在被pickle和unpickle的numpy数组上运行一个函数如何可能导致它稍后在另一个进程中执行segfault。在
更新:当我执行核心转储时,回溯位于dispatch_group_async_f
,Grand Central Dispatch接口内。这大概是numpy/GCD和多处理之间交互中的一个bug。我已经将此报告为a numpy bug,但是如果有人对解决方法有任何想法,或者,关于如何解决这个bug,我将不胜感激。:)
事实证明,在OSX上默认使用的加速框架just doesn't support using BLAS calls on both sides of a ^{} 。除了链接到一个不同的BLAS之外,没有其他真正的方法来处理这个问题,而且这似乎不是他们感兴趣解决的问题。在
相关问题 更多 >
编程相关推荐