mpi4py を使用して、大きな numpy 配列でいくつかの操作を並列化しようとしています。私は現在numpy.array_split
、配列をチャンクに分割し、続いcom.scatter
て配列を異なるコアに送信しcomm.gather
、結果の配列を収集するために使用しています。最小限の(そうではない)動作例を以下に示します。
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()
if rank == 0:
test = np.random.rand(411,48,52,40)
test_chunks = np.array_split(test,size,axis=0)
else:
test_chunks = None
test_chunk = comm.scatter(test_chunks,root=0)
output_chunk = np.zeros([np.shape(test_chunk)[0],128,128,128])
for i in range(0,np.shape(test_chunk)[0],1):
print(i)
output_chunk[i,0:48,0:52,0:40] = test_chunk[i]
outputData = comm.gather(output_chunk,root=0)
if rank == 0:
outputData = np.concatenate(outputData,axis = 0)
これを実行すると、次のエラーが表示されます。
File "test_4d.py", line 23, in <module>
outputData = comm.gather(output_chunk,root=0)
File "Comm.pyx", line 869, in mpi4py.MPI.Comm.gather (src/mpi4py.MPI.c:73266)
File "pickled.pxi", line 614, in mpi4py.MPI.PyMPI_gather (src/mpi4py.MPI.c:33592)
File "pickled.pxi", line 146, in mpi4py.MPI._p_Pickle.allocv (src/mpi4py.MPI.c:28517)
File "pickled.pxi", line 95, in mpi4py.MPI._p_Pickle.alloc (src/mpi4py.MPI.c:27832)
SystemError: Negative size passed to PyString_FromStringAndSize
このエラーは、gather によって収集される numpy 配列のサイズが大きいことが原因のようです。スキャッターとギャザーは配列を配列のリストとして送信するため、リストのサイズを簡単に超えるように見えます。私が遭遇した 1 つの提案は、comm.Scatter と comm.Gather を使用することです。ただし、これらの関数の明確なドキュメントを見つけるのに苦労しており、これまでのところそれらを正常に実装できていません。例えば:
交換する
outputData = comm.gather(output_chunk,root=0)
線で
outputData=comm.Gather(sendbuf[test_chunks,MPI.DOUBLE],recvbuf=output_chunk,MPI.DOUBLE],root=0)
エラーが発生します:
File "Comm.pyx", line 415, in mpi4py.MPI.Comm.Gather (src/mpi4py.MPI.c:66916)
File "message.pxi", line 426, in mpi4py.MPI._p_msg_cco.for_gather (src/mpi4py.MPI.c:23559)
File "message.pxi", line 355, in mpi4py.MPI._p_msg_cco.for_cco_send (src/mpi4py.MPI.c:22959)
File "message.pxi", line 111, in mpi4py.MPI.message_simple (src/mpi4py.MPI.c:20516)
File "message.pxi", line 51, in mpi4py.MPI.message_basic (src/mpi4py.MPI.c:19644)
File "asbuffer.pxi", line 108, in mpi4py.MPI.getbuffer (src/mpi4py.MPI.c:6757)
File "asbuffer.pxi", line 50, in mpi4py.MPI.PyObject_GetBufferEx (src/mpi4py.MPI.c:6093)
TypeError: expected a readable buffer object
または次の行で:
outputData = comm.Gather(sendbuf=test_chunks, recvbuf=output_chunk,root=0)
エラーが発生します:
File "test_4d_2.py", line 24, in <module>
outputData = comm.Gather(sendbuf=test_chunks, recvbuf=output_chunk,root=0)
File "Comm.pyx", line 415, in mpi4py.MPI.Comm.Gather (src/mpi4py.MPI.c:66916)
File "message.pxi", line 426, in mpi4py.MPI._p_msg_cco.for_gather (src/mpi4py.MPI.c:23559)
File "message.pxi", line 355, in mpi4py.MPI._p_msg_cco.for_cco_send (src/mpi4py.MPI.c:22959)
File "message.pxi", line 111, in mpi4py.MPI.message_simple (src/mpi4py.MPI.c:20516)
File "message.pxi", line 60, in mpi4py.MPI.message_basic (src/mpi4py.MPI.c:19747)
TypeError: unhashable type: 'numpy.ndarray'
さらに、入力行列test
もサイズが大きくなり、 に対して同様の問題が発生する可能性がありますcomm.scatter
。は、 の出力であるのサイズに基づいて定義されているため、のcomm.Gather
設定方法がわかりません。そのため、内で指定することはできません。comm.Scatter
recvbuf
test_chunk
comm.scatter
recvbuf
comm.Scatter