【问题标题】:segfault using numpy's lapack_lite with multiprocessing on osx, not linuxsegfault 使用 numpy 的 lapack_lite 在 osx 上进行多处理,而不是 linux
【发布时间】:2012-04-10 09:13:20
【问题描述】:

以下测试代码在 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) 也是段错误。

f 中所有被注释掉的 np.linalg 东西都会导致崩溃; 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 版本。所有这些 numpy 都链接到系统 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 与 Python 3.2.2、numpy 1.6.1 和 scipy 0.10.1 链接到系统 ATLAS
  • Ubuntu 11.04 与 Python 2.7.1、numpy 1.5.1 和 scipy 0.8.0 链接到系统 ATLAS

我在这里做错了吗?这可能是什么原因造成的?我不明白如何在一个被腌制和解封的 numpy 数组上运行一个函数可能会导致它稍后在不同的进程中出现段错误。


更新:当我进行核心转储时,回溯位于 dispatch_group_async_f 内部,即 Grand Central Dispatch 接口。大概这是 numpy/GCD 和多处理之间的交互中的一个错误。我已将此报告为a numpy bug,但如果有人对解决方法有任何想法,或者就此而言,如何解决该错误,将不胜感激。 :)

【问题讨论】:

  • 作为一个成熟的库,numpy 应该永远不会导致分段错误或以其他方式中止当前进程。您是否在projects.scipy.org/numpy 提交了错误报告?
  • 是的,我举报了:projects.scipy.org/numpy/ticket/2091。不过,该票的响应绝对为零,我刚刚停止在 OSX 上运行该代码。我将在 10.8 上使用 numpy master 重新测试,并在下周发布更新。

标签: python numpy segmentation-fault multiprocessing


【解决方案1】:

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

【讨论】:

  • 在 Python 3.4 中将有 forkserver 模式用于多处理,应该可以使用 Accelerate 或 OpenBLAS 进行多处理。
  • @ogrisel 的评论应该是答案。对我来说就像一个魅力!
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2020-05-10
    相关资源
    最近更新 更多