在mpi4py中使用运算符归约列表并求和每个元素
我正在写一个mpi的Python代码。例如,四个进程有以下数据:
data on procs0: [1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0]
data on procs1: [0, 0, 0, 4, 5, 6, 0, 0, 0, 0, 0, 0]
data on procs2: [0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0]
data on procs3: [0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12]
我想使用mpi4py库中的reduce函数,把数据汇总到procs0上,得到的结果是:
result on procs0: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
我该如何使用mpi4py库的函数来实现呢?
编辑:上面是一个简单的特殊情况,不能使用集合,下面是另一个案例:
data on procs0: [1,0,0,0,0,0]
data on procs1: [0,2,0,0,0,0]
data on procs2: [0,0,0,3,0,0]
data on procs3: [0,0,0,0,4,5]
理想的结果必须是:
result on procs0: [1,2,0,3,4,5]
2 个回答
0
使用列表推导式和zip函数,来存储每一列的最大值。
In [1]: procs0=[1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0]
In [2]: procs1=[0, 0, 0, 4, 5, 6, 0, 0, 0, 0, 0, 0]
In [3]: procs2=[0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0]
In [4]: procs3=[0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12]
In [5]: [max(i) for i in zip(procs0, procs1, procs2, procs3)]
Out[5]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
9
我不太确定你问的问题是想要数据的总和,还是想要最大值。我写了一个简单的例子,使用了mpi的Reduce
函数,这个函数可以计算总和。
#!/usr/bin/env python
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
comm.Barrier()
t_start = MPI.Wtime()
# this array lives on each processor
data = np.zeros(5)
for i in xrange(comm.rank, len(data), comm.size):
# set data in each array that is different for each processor
data[i] = i
# print out the data arrays for each processor
print '[%i]'%comm.rank, data
comm.Barrier()
# the 'totals' array will hold the sum of each 'data' array
if comm.rank==0:
# only processor 0 will actually get the data
totals = np.zeros_like(data)
else:
totals = None
# use MPI to get the totals
comm.Reduce(
[data, MPI.DOUBLE],
[totals, MPI.DOUBLE],
op = MPI.SUM,
root = 0
)
# print out the 'totals'
# only processor 0 actually has the data
print '[%i]'%comm.rank, totals
comm.Barrier()
t_diff = MPI.Wtime() - t_start
if comm.rank==0: print t_diff
把这个代码保存到一个叫reduce_test.py
的文件里,然后用命令mpirun -np 3 ./reduce_test.py
运行,结果在我的机器上是这样的:
[0] [ 0. 0. 0. 3. 0.]
[1] [ 0. 1. 0. 0. 4.]
[2] [ 0. 0. 2. 0. 0.]
[1] None
[2] None
[0] [ 0. 1. 2. 3. 4.]
0.00260496139526
注意,如果你把调用comm.Reduce
时的参数op = MPI.SUM
改成op = MPI.MAX
,那么就会计算最大值,而不是总和。