簡體   English   中英

HPC上的mpi4py:comm.gather

[英]mpi4py on HPC: comm.gather

我的目標是遍歷大型2D數組( data )的每個元素,並對每個元素進行一些繁重的處理。 因此,我想使用多個MPI來占用陣列的一部分進行處理。 我遇到的問題是我不知道如何准確地編寫代碼以最后收集所有數據。 這是一些示例代碼:

import numpy as np
import math
from mpi4py import MPI

M = 400
N = 300
data = np.random.rand(M,N)
result_a = np.zeros((M,N))
result_b = np.zeros((M,N))

def process_function(data):
    a = data**2
    b = data**0.5
    return a,b

comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
minimum = 0
maximum = int(M*N)
perrank = maximum//size

for index in range(minimum + rank*perrank, minimum + (rank+1)*perrank):
    i = int(math.floor(index/N))
    j = int(index % N)

    a,b = process_function(data[i,j])
    result_a[i,j] = a
    result_b[i,j] = b

a_gath = comm.gather(result_a, root=0)
b_gath = comm.gather(result_b, root=0)

print(np.shape(a_gath))
print('---')
print(np.shape(b_gath))

不幸的是,對於我真正的問題,當我將a_gathb_gath都保存到磁盤(作為泡菜)時,當我重新加載它們時,它們僅包含一次出現的() (即,鍵入None )。 comm.gather之前/之后,我還有其他事情comm.gather嗎?

這是我的提交腳本:

#!/bin/bash -l

#$ -S /bin/bash
#$ -l h_rt=00:05:00
#$ -l mem=2G
#$ -l tmpfs=10G
#$ -pe mpi 5
#$ -N stack_test
#$ -notify
#$ -wd /home/user/Scratch/

module load gcc-libs
module load python3/recommended
module unload compilers mpi
module load compilers/gnu/4.9.2
module load mpi/openmpi/3.1.1/gnu-4.9.2
module load mpi4py
module list

python_infile=test.py

echo ""
echo "Running python < $python_infile ..."
echo ""
gerun python $python_infile

我使用qsub js_test.sh提交此腳本

對於該假示例返回的.o文件顯示,在這種情況下4/5 mpis包含類型None信息:在這種情況下,如果我隨后將a_gathb_gath保存到磁盤,它將保存最后的mpi嗎? 哪個是None類型? 我希望在使用comm.gather ,對於變量a_gathb_gath我將有一個大小為MxN數組

()
---
()
()
---
()
()
---
()
(5, 400, 300)
---
(5, 400, 300)
()
---
()

非常感謝。

為了澄清您在注釋中為自己找到的答案: MPI_Gather是一個根操作 :其結果在所有等級上都不相同,特別是在root參數中提供的等級上有所不同。

Gather的情況下,您發現排名0最終以數據結尾的排名與您調用它的方式( root=0 )完全正確。

雖然原則上MPI支持多個程序,多個數據執行,其中不同的等級運行不同的代碼,但實際上,大多數MPI代碼是用單個程序編寫的,具有多種數據樣式,就像您編寫的一樣。 由於所有等級都在運行相同的代碼體,因此由您決定從諸如MPI_Gather之類的根操作返回后,是要檢查您正在運行的等級是否是根,並相應地執行不同的代碼路徑。 如果您不這樣做,那么每個級別都將執行以下行:

print(np.shape(a_gath))
print('---') 
print(np.shape(b_gath))

正如您已經指出的那樣,除了等級0之外,它不會輸出您預期的a_gathb_gath結果。

請嘗試以下操作:

a_gath = comm.gather(result_a, root=0)
b_gath = comm.gather(result_b, root=0)

if rank == 0:
    print(np.shape(a_gath))
    print('---')
    print(np.shape(b_gath))

暫無
暫無

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

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