Следующий тестовый код segfaults для меня на 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)
Пример вывода для одного из segfaulty:
$ python2.7 test.py
about to call
result: -4.96797718087
calling with multiprocessing
about to call
calling with multiprocessing
about to call
с сообщением о проблеме с OSX ", выскакивающим жалобы на segfault вроде KERN_INVALID_ADDRESS at 0x0000000000000108
; здесь полный.
Если я запускаю его с помощью 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)
также segfaults.
Все прокомментированные 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 framework:
$ 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, который становится маринованным и незакрашенным, может привести к его последующему segfault в другом процессе.
Обновление:, когда я делаю основной дамп, backtrace находится внутри dispatch_group_async_f
, интерфейса Grand Central Dispatch. Предположительно, это ошибка во взаимодействии между numpy/GCD и многопроцессорностью. Я сообщил об этом как numpy bug, но если у кого-нибудь есть идеи об обходных решениях или, если на то пошло, как решить ошибку, было бы весьма полезно,:)