在上一篇中我们介绍了 mpi4py 中的全发散操作方法,下面我们将介绍扫描操作。
注意:只有组内通信子支持扫描操作。
方法接口
mpi4py 中的扫描操作的方法(MPI.Intracomm 类的方法)接口为:
scan(self, sendobj, op=SUM)
exscan(self, sendobj, op=SUM)
Scan(self, sendbuf, recvbuf, Op op=SUM)
Exscan(self, sendbuf, recvbuf, Op op=SUM)
这些方法的参数与规约操作相应的参数一致,参数 op
指明用什么算符进行规约,其默认值是 MPI.SUM,即求和算符,其它内置的规约算符可见规约操作。
scan/Scan (也称作 inclusive scan),实际上是逐级执行规约操作,即进程 i 对进程 0, 1, … , i 执行规约。
exscan/Exscan (也称作 exclusive scan),定义了一种“前缀扫描”操作,具体为:对进程 0,其接收缓冲区未定义;对进程 1,其接收缓冲区数据为进程 0 的发送缓冲区数据;对进程 i > 1,其接收缓冲区数据为进程 0, 1, … , i - 1 发送缓冲区数据的规约。
对 Scan/Exscan,可将其 sendbuf
参数设置成 MPI.IN_PLACE,此时从 recvbuf
中提取数据进行逐级规约,然后将结果替换 recvbuf
的数据缓冲区。
例程
下面给出扫描操作的使用例程。
# scan.py
"""
Demonstrates the usage of scan, exscan, Scan, Exscan.
Run this with 4 processes like:
$ mpiexec -n 4 python scan.py
"""
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()