簡體   English   中英

mpi4py 散布和收集大型 numpy 數組

[英]mpi4py scatter and gather with large numpy arrays

我正在嘗試使用 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數組引起的; 由於 scatter 和 gather 將數組作為數組列表發送,因此很容易超過列表大小。 我遇到的一個建議是使用 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的輸出,因此我不能指定recvbufcomm.Scatter

解決方案是使用comm.Scattervcomm.Gatherv ,它們將數據作為內存塊而不是 numpy 數組列表發送和接收,從而解決數據大小問題。 comm.Scattervcomm.Gatherv假設內存中的數據塊為 C 序(行主),並且需要指定兩個向量, sendcountsdisplacements Sendcounts給出分割輸入數據的位置的整數值(索引)(即發送到給定核心的每個向量的起點),而displacements給出該向量的長度。 因此,可以改變發送到每個內核的數據量。 更多細節可以在這里找到: http : //materials.jeremybejarano.com/MPIwithPython/collectiveCom.html

此處給出了使用comm.Scattervcomm.Gatherv用於 2D 矩陣的示例: mpi4py Scatterv 函數沿哪個軸拆分 numpy 數組?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM