同 comm.gather 一样, comm.reduce 接收一个数组,每一个元素是一个进程的输入,然后返回一个数组,每一个元素是进程的输出,返回给 root 进程。输出的元素中包含了简化的结果。
comm.gather
comm.reduce
在 mpi4py 中,我们将简化操作定义如下: :
mpi4py
comm.Reduce(sendbuf, recvbuf, rank_of_root_process, op = type_of_reduction_operation)
这里需要注意的是,这里有个参数 op 和 comm.gather 不同,它代表你想应用在数据上的操作, mpi4py 模块代表定义了一系列的简化操作,其中一些如下:
op
MPI.MAX
MPI.MIN
MPI.SUM
MPI.PROD
MPI.LAND
MPI.MAXLOC
MPI.MINLOC
现在,我们用 MPI.SUM 实验一下对结果进行相加的操作。每一个进程维护一个大小为 3 的数组,我们用 numpy 来操作这些数组: :
numpy
import numpy import numpy as np from mpi4py import MPI comm = MPI.COMM_WORLD size = comm.size rank = comm.rank array_size = 3 recvdata = numpy.zeros(array_size, dtype=numpy.int) senddata = (rank+1)*numpy.arange(size,dtype=numpy.int) print("process %s sending %s " % (rank , senddata)) comm.Reduce(senddata, recvdata, root=0, op=MPI.SUM) print('on task', rank, 'after Reduce: data = ', recvdata)
我们用通讯组进程数为 3 来运行,等于维护的数组的大小。输出的结果如下: :
C:\>mpiexec -n 3 python reduction2.py process 2 sending [0 3 6] on task 2 after Reduce: data = [0 0 0] process 1 sending [0 2 4] on task 1 after Reduce: data = [0 0 0] process 0 sending [0 1 2] on task 0 after Reduce: data = [ 0 6 12]
为了演示相加简化操作,我们使用 comm.Reduce 语句,并将含有 recvbuf 的 rank 设置为 0, recvdata 代表了最后的计算结果: :
comm.Reduce
recvbuf
recvdata
comm.Reduce(senddata, recvdata, root=0, op=MPI.SUM)
我们的 op = MPI.SUM 选项,将在所有的列上面应用求和操作。下图表示了这个步骤:
op = MPI.SUM
操作的过程如下:
简化操作将每个 task 的第 i 个元素相加,然后放回到 P0 进程的第 i 个元素中。在接收操作中, P0 收到数据 [0 6 12]。
(译注:"简化"翻译的可能不太合适)
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8