2015-11-16 3 views
1

Я использую mpi4py для распространения задачи обработки по кластеру ядер. Мой код выглядит следующим образом:Ошибка сегментации с использованием mpi4py

comm = MPI.COMM_WORLD 
size = comm.Get_size() 
rank = comm.Get_rank() 

'''Perform processing operations with each processor returning 
    two arrays of equal size, array1 and array2''' 

all_data1 = comm.gather(array1, root = 0) 
all_data2 = comm.gather(array2, root = 0) 

Это возвращает следующее сообщение об ошибке:

SystemError: Negative size passed to PyString_FromStringAndSize 

Я считаю, что эта ошибка означает, что массив данных, хранящихся в all_data1 превышает максимальный размер массива в Python , что вполне возможно.

Я пытался сделать это на более мелкие куски, следующим образом:

comm.isend(array1, dest = 0, tag = rank+1) 
comm.isend(array2, dest = 0, tag = rank+2) 
if rank == 0: 
    for proc in xrange(size): 
     partial_array1 = comm.irecv(source = proc, tag = proc+1) 
     partial_array2 = comm.irecv(source = proc, tag = proc+2) 

, но это возвращает следующее сообщение об ошибке.

[node10:20210] *** Process received signal *** 
[node10:20210] Signal: Segmentation fault (11) 
[node10:20210] Signal code: Address not mapped (1) 
[node10:20210] Failing at address: 0x2319982b 

последовали целой нагрузкой непонятного пути, как информация и окончательным сообщение:

mpirun noticed that process rank 0 with PID 0 on node node10 exited on signal 11 (Segmentation fault). 

Это, кажется, происходит независимо от того, сколько процессоров я использую.

Для подобных вопросов в C решение, похоже, тонко меняет способ анализа аргументов в вызове recv. С Python синтаксис отличается, поэтому я был бы признателен, если бы кто-то мог дать некоторую ясность, почему появляется эта ошибка и как ее исправить.

+0

Не могли бы вы рассолить и gzip ваш массив на одной стороне, и gunzip/unickle его на другой стороне? – Ashalynd

+0

Исправьте меня, если я ошибаюсь, но разве это не так, как работает mpi4py? Как я понимаю, данные, которые будут переданы, рассосаются «под капотом». – berkelem

+0

В теории, он должен ... Можете ли вы отправить что-нибудь вообще с одной стороны на другую? Все ли объекты в кластере похожи друг на друга? – Ashalynd

ответ

0

Мне удалось решить проблему, с которой я столкнулся, выполнив следующее.

if rank != 0: 
    comm.Isend([array1, MPI.FLOAT], dest = 0, tag = 77) 
    # Non-blocking send; allows code to continue before data is received. 

if rank == 0: 
    final_array1 = array1 
    for proc in xrange(1,size): 
     partial_array1 = np.empty(len(array1), dtype = float) 
     comm.Recv([partial_array1, MPI.FLOAT], source = proc, tag = 77) 
     # A blocking receive is necessary here to avoid a Segfault. 

     final_array1 += partial_array1 

if rank != 0: 
    comm.Isend([array2, MPI.FLOAT], dest = 0, tag = 135) 

if rank == 0: 
    final_array2 = array2 
    for proc in xrange(1,size): 
     partial_array2 = np.empty(len(array2), dtype = float) 
     comm.Recv([partial_array2, MPI.FLOAT], source = proc, tag = 135) 

     final_array2 += partial_array2 

comm.barrier() # This barrier call resolves the Segfault. 
if rank == 0: 
    return final_array1, final_array2 
else: 
    return None 
Смежные вопросы