在osx上使用numpy的lapack_lite和多处理的段错误,而不是linux

时间:2012-03-26 20:33:04

标签: python numpy segmentation-fault multiprocessing

以下测试代码在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)

其中一个段错误的示例输出:

$ python2.7 test.py
about to call
result: -4.96797718087

calling with multiprocessing
about to call

calling with multiprocessing
about to call

出现OSX“问题报告”,抱怨像KERN_INVALID_ADDRESS at 0x0000000000000108这样的段错误; here's a full one

如果我用n <= 32运行它,它运行正常;对于任何n >= 33,它都会崩溃。

如果我在原始流程中注释了f(a)来电,那么对call_proc的两次调用都没问题。如果我在另一个大型数组上调用f,它仍然会出现段错误;如果我在一个不同的小数组上调用它,或者我调用f(large_array)然后将f(small_array)传递给另一个进程,它就可以正常工作。它们实际上不需要是相同的功能; np.inv(large_array)然后又传递给np.linalg.slogdet(different_large_array)段错误。

np.linalg中所有已注释掉的f内容都会导致崩溃; np.dot(self.a, self.a.T).sum()scipy.linalg.exp3m工作正常。据我所知,区别在于前者使用numpy的lapack_lite而后者不使用。


这种情况发生在我的桌面上

  • python 2.6.7,numpy 1.5.1
  • python 2.7.1,numpy 1.5.1,scipy 0.10.0
  • python 3.2.2,numpy 1.6.1,scipy 0.10.1

2.6和2.7是我认为默认系统安装;我从源代码压缩包中手动安装了3.2版本。所有这些numpys都链接到系统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的所有选项都适用于运行

的其他计算机
  • OSX 10.6.8与Python 2.6.1和numpy 1.2.1链接到Accelerate 4和vecLib 268(除了它没有scipy或slogdet
  • Debian 6 with Python 3.2.2,numpy 1.6.1,scipy 0.10.1链接到系统ATLAS
  • Ubuntu 11.04 with Python 2.7.1,numpy 1.5.1和scipy 0.8.0链接到系统ATLAS

我在这里做错了吗?什么可能导致这个?我没有看到如何在一个numpy数组上运行一个被pickle和unpickled运行的函数可能会导致它在以后的不同进程中出现段错误。


更新:当我进行核心转储时,回溯位于dispatch_group_async_f内部,即Grand Central Dispatch界面。据推测,这是numpy / GCD与多处理之间相互作用的一个错误。我已将此报告为a numpy bug,但如果有人对变通办法有任何想法,或者就此而言,如何解决这个问题,我们将不胜感激。 :)

2 个答案:

答案 0 :(得分:5)

事实证明,OSX just doesn't support using BLAS calls on both sides of a fork上默认使用的加速框架。除了链接到不同的BLAS之外,没有真正的方法来解决这个问题,而且它似乎并不像他们有兴趣修复它。

答案 1 :(得分:0)

根据@ogrisel的评论,我尝试在使用multiprocessing.set_start_method('forkserver')之前先呼叫multiprocessing.Pool,它就像一个魅力!