2012-03-26 9 views
11

Los siguientes violaciones de segmento de código de prueba para mí en OSX 10.7.3, pero no a otras máquinas:violación de segmento usando lapack_lite de numpy con multiprocesamiento en OSX, Linux no

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) 

ejemplo de salida para uno de los segfaulty:

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

calling with multiprocessing 
about to call 

calling with multiprocessing 
about to call 

con un "informe de problema" de OSX apareciendo quejándose de un segfault como KERN_INVALID_ADDRESS at 0x0000000000000108; here's a full one.

Si lo ejecuto con n <= 32, funciona bien; para cualquier n >= 33, se bloquea.

Si comento la llamada f(a) que se hace en el proceso original, ambas llamadas a call_proc están bien. Todavía falla si llamo al f en una matriz grande diferente; si lo llamo en una matriz pequeña diferente, o si llamo al f(large_array) y luego paso f(small_array) a un proceso diferente, funciona bien. En realidad, no necesitan ser la misma función; np.inv(large_array) seguido de pasar a np.linalg.slogdet(different_large_array) también segfaults.

Todos los comentarios out-out np.linalg cosas en f causan cuelgues; np.dot(self.a, self.a.T).sum() y scipy.linalg.exp3m funcionan bien. Por lo que puedo decir, la diferencia es que los primeros usan lapack_lite de numpy y los segundos no.


Esto sucede para mí en mi escritorio con

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

el 2.6 y 2.7 son Creo que el sistema se instala por defecto; Instalé las versiones 3.2 manualmente desde los archivos tar de origen. Todas esas numpys están vinculados al sistema Acelerar marco:

$ 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) 

consigo el mismo comportamiento en otro Mac con una configuración similar.

Pero todas las opciones para f trabajo en otras máquinas corriendo

  • OSX 10.6.8 con Python 2.6.1 y 1.2.1 numpy vinculado a Acelerar 4 y vecLib 268 (excepto que no lo hace tener scipy o slogdet)
  • Debian 6 con Python 3.2.2, 1.6.1 numpy, y scipy 0.10.1 vinculado al sistema ATLAS
  • Ubuntu 11.04 con Python 2.7.1, 1.5.1 numpy y scipy 0.8. 0 vinculado al sistema ATLAS

¿Estoy haciendo algo mal aquí? ¿Qué podría estar causando esto? No veo cómo ejecutar una función en una matriz numpy que se está reduciendo a salmuera y desatornillando puede causar que falle posteriormente en un proceso diferente.


Actualización: cuando lo haga un volcado de memoria, la traza se encuentra dentro dispatch_group_async_f, la interfaz de Grand Central Dispatch. Presumiblemente, esto es un error en las interacciones entre numpy/GCD y multiprocesamiento. Lo he informado como a numpy bug, pero si alguien tiene alguna idea sobre soluciones temporales o, para el caso, cómo resolver el error, sería muy apreciado. :)

+0

Como una biblioteca madura, numpy * should * nunca causa un error de segmentación o cancela el proceso actual. ¿Ha enviado un informe de error en http://projects.scipy.org/numpy? – Collin

+0

Sí, lo informé: http://projects.scipy.org/numpy/ticket/2091. Sin embargo, el ticket ha tenido una respuesta absolutamente nula y dejé de ejecutar ese código en OSX. Voy a volver a probar en 10.8 con Numpy Master y publicar una actualización la próxima semana. – Dougal

Respuesta

5

Resulta que el marco de Accelerate utilizado por defecto en OSX just doesn't support using BLAS calls on both sides of a fork. No hay otra forma de lidiar con esto que no sea vincular a un BLAS diferente, y no parece que sea algo que estén interesados ​​en solucionar.

+2

En Python 3.4, habrá un modo 'forkserver' para multiprocesamiento que debería permitir el uso de Accelerate o OpenBLAS con multiprocesamiento. – ogrisel

Cuestiones relacionadas