2016-08-11 10 views
1

mpi4pyの新機能です。私は多数のプロセッサーによって大きいnumpyの配列dataを処理するためにコードを書いた。私が入力ファイルを提供できないので、私はdataの形を言及しています。 dataの形状は[3000000,15]であり、文字列タイプのデータを含んでいます。mpi4py Gatherv向きKeyError: '0'

from mpi4py import MPI 
import numpy as np 
import datetime as dt 
import math as math 


comm = MPI.COMM_WORLD 
numprocs = comm.size 
rank = comm.Get_rank() 
fname = "6.binetflow" 
data = np.loadtxt(open(fname,"rb"), dtype=object, delimiter=",", skiprows=1) 
X = data[:,[0,1,3,14,6,6,6,6,6,6,6,6]] 
num_rows = math.ceil(len(X)/float(numprocs)) 
X = X.flatten() 
sendCounts = list() 
displacements = list() 
for p in range(numprocs): 
    if p == (numprocs-1): #for last processor 
     sendCounts.append(int(len(X) - (p*num_rows*12))) 
     displacements.append(int(p*num_rows*12)) 
     break 
    sendCounts.append(int(num_rows*12)) 
    displacements.append(int(p*sendCounts[p])) 
sendbuf = np.array(X[displacements[rank]: (displacements[rank]+sendCounts[rank])]) 

## Each processor will do some task on sendbuf 

if rank == 0: 
    recvbuf = np.empty(sum(sendCounts), dtype=object) 
else: 
    recvbuf = None 

print("sendbuf: ",sendbuf) 
comm.Gatherv(sendbuf=sendbuf, recvbuf=(recvbuf, sendCounts), root=0) 
if rank == 0: 
    print("Gathered array: {}".format(recvbuf)) 

しかし、私はエラーの下に直面しています:

Traceback (most recent call last): 
    File "hello.py", line 36, in <module> 
    comm.Gatherv(sendbuf=sendbuf, recvbuf=(recvbuf, sendCounts), root=0) 
    File "MPI/Comm.pyx", line 602, in mpi4py.MPI.Comm.Gatherv (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:97993) 
    File "MPI/msgbuffer.pxi", line 525, in mpi4py.MPI._p_msg_cco.for_gather (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:34678) 
    File "MPI/msgbuffer.pxi", line 446, in mpi4py.MPI._p_msg_cco.for_cco_send (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:33938) 
    File "MPI/msgbuffer.pxi", line 148, in mpi4py.MPI.message_simple (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:30349) 
    File "MPI/msgbuffer.pxi", line 93, in mpi4py.MPI.message_basic (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:29448) 
KeyError: 'O' 
Traceback (most recent call last): 
    File "hello.py", line 36, in <module> 
    comm.Gatherv(sendbuf=sendbuf, recvbuf=(recvbuf, sendCounts), root=0) 
    File "MPI/Comm.pyx", line 602, in mpi4py.MPI.Comm.Gatherv (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:97993) 
    File "MPI/msgbuffer.pxi", line 525, in mpi4py.MPI._p_msg_cco.for_gather (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:34678) 
    File "MPI/msgbuffer.pxi", line 446, in mpi4py.MPI._p_msg_cco.for_cco_send (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:33938) 
    File "MPI/msgbuffer.pxi", line 148, in mpi4py.MPI.message_simple (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:30349) 
    File "MPI/msgbuffer.pxi", line 93, in mpi4py.MPI.message_basic (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:29448) 
KeyError: 'O' 
Traceback (most recent call last): 
    File "hello.py", line 36, in <module> 
    comm.Gatherv(sendbuf=sendbuf, recvbuf=(recvbuf, sendCounts), root=0) 
    File "MPI/Comm.pyx", line 602, in mpi4py.MPI.Comm.Gatherv (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:97993) 
    File "MPI/msgbuffer.pxi", line 525, in mpi4py.MPI._p_msg_cco.for_gather (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:34678) 
    File "MPI/msgbuffer.pxi", line 446, in mpi4py.MPI._p_msg_cco.for_cco_send (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:33938) 
    File "MPI/msgbuffer.pxi", line 148, in mpi4py.MPI.message_simple (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:30349) 
    File "MPI/msgbuffer.pxi", line 93, in mpi4py.MPI.message_basic (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:29448) 
KeyError: 'O' 
Traceback (most recent call last): 
    File "hello.py", line 36, in <module> 
    comm.Gatherv(sendbuf=sendbuf, recvbuf=(recvbuf, sendCounts), root=0) 
    File "MPI/Comm.pyx", line 602, in mpi4py.MPI.Comm.Gatherv (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:97993) 
    File "MPI/msgbuffer.pxi", line 516, in mpi4py.MPI._p_msg_cco.for_gather (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:34587) 
    File "MPI/msgbuffer.pxi", line 466, in mpi4py.MPI._p_msg_cco.for_cco_recv (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:34097) 
    File "MPI/msgbuffer.pxi", line 261, in mpi4py.MPI.message_vector (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:31977) 
    File "MPI/msgbuffer.pxi", line 93, in mpi4py.MPI.message_basic (d:\build\mpi4py\mpi4py-2.0.0\src\mpi4py.MPI.c:29448) 
KeyError: 'O' 

すべてのヘルプははるかに高く評価されます。私は長い間この問題に悩まされています。

おかげ

答えて

0

問題がdtype=objectです。

Mpi4pyは2種類の通信機能を提供します。名前の名前は大文字で始まります。 Scatter、および名前が小文字で始まるもの(例: scatter。このことから明らかではないが、何From the Mpi4py documentation:

In MPI for Python, the Bcast(), Scatter(), Gather(), Allgather() and Alltoall() methods of Comm instances provide support for collective communications of memory buffers. The variants bcast(), scatter(), gather(), allgather() and alltoall() can communicate generic Python objects.

はnumpyの配列はおそらくメモリバッファを公開していても、バッファが明らかにプリミティブデータ型の小さなセットのいずれかにする必要があり、確かにジェネリックでは動作しないことですオブジェクト。次の2つのコード部分を比較します

from mpi4py import MPI 
import numpy 

Comm = MPI.COMM_WORLD 
Size = Comm.Get_size() 
Rank = Comm.Get_rank() 

if Rank == 0: 
    Data = numpy.empty(Size, dtype=object) 
else: 
    Data = None 

Data = Comm.scatter(Data, 0) # I work fine! 

print("Data on rank %d: " % Rank, Data) 

from mpi4py import MPI 
import numpy 

Comm = MPI.COMM_WORLD 
Size = Comm.Get_size() 
Rank = Comm.Get_rank() 

if Rank == 0: 
    Data = numpy.empty(Size, dtype=object) 
else: 
    Data = None 

Datb = numpy.empty(1, dtype=object) 

Comm.Scatter(Data, Datb, 0) # I throw KeyError! 

print("Datb on rank %d: " % Rank, Datb) 

残念ながら、Mpi4pyは何 scatterv提供していません。ドキュメント内の同じ場所から:

​​

これらはどちらか、dtypesための大文字小文字VSルールの例外ではありません。

from mpi4py import MPI 
import numpy 

Comm = MPI.COMM_WORLD 
Size = Comm.Get_size() 
Rank = Comm.Get_rank() 

if Rank == 0: 
    Data = numpy.empty(2*Size+1, dtype=object) 
else: 
    Data = None 

if Rank == 0: 
    Datb = numpy.empty(3, dtype=object) 
else: 
    Datb = numpy.empty(2, dtype=object) 

Comm.Scatterv(Data, Datb, 0) # I throw KeyError! 

print("Datb on rank %d: " % Rank, Datb) 

from mpi4py import MPI 
import numpy 

Comm = MPI.COMM_WORLD 
Size = Comm.Get_size() 
Rank = Comm.Get_rank() 

if Rank == 0: 
    Data = numpy.empty(2*Size+1, dtype=numpy.dtype('float64')) 
else: 
    Data = None 

if Rank == 0: 
    Datb = numpy.empty(3, dtype=numpy.dtype('float64')) 
else: 
    Datb = numpy.empty(2, dtype=numpy.dtype('float64')) 

Comm.Scatterv(Data, Datb, 0) # I work fine! 

print("Datb on rank %d: " % Rank, Datb) 

あなたは」残念ながら、scatterを使用できるようにコードを記述する必要があり、各プロセスに同じSendCountを必要とするか、より原始的なポイントツーポイント通信機能を使用するか、またはいくつかのPAを使用しますMpi4py以外の並列機能

Mpi4py 2.0.0を使用して、この執筆時点では現在の安定版です。

関連する問題