【问题标题】:Reduce a list with operator as summing each element in mpi4py使用运算符减少列表作为对 mpi4py 中的每个元素求和
【发布时间】:2013-02-22 16:12:43
【问题描述】:

我正在编写一个 mpi python 代码。例如,四个 proc 的数据如下:

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 库函数来实现?

编辑: 上面是一个简单的特殊情况,set不能用,下面看另一种情况:

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]

【问题讨论】:

  • 我不确定 mpi4py,但我认为您应该使用 MPI_Reduce 和 MPI_MAX 作为操作。

标签: python python-2.7 parallel-processing mpi reduce


【解决方案1】:

从你的问题中我不确定你是想要数据的总和还是最大值。我使用 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 将计算最大值而不是总和。

【讨论】:

    【解决方案2】:

    将列表推导与 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]
    

    【讨论】:

    • 我认为 OP 想要添加所有列表的第一个元素,第二个元素等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    • 2017-09-07
    • 2019-11-09
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多