mpi4py 中的栅障同步操作

在上一篇中我们介绍了 mpi4py 中的扫描操作方法,下面我们将介绍栅障同步操作。

此为实施在通信子上的同步操作,会阻塞所有的进程直到所有的进程都调用此操作。如果是组间通信子,则会在组间通信子上的所有进程之间执行,但也允许当所有远程组中的进程进入 barrier 之后,所有本地组中的进程已经离开。

方法接口

mpi4py 中的栅障同步操作的方法(MPI.Comm 类的方法)接口为:

barrier(self)
Barrier(self)

barrier 和 Barrier 实施的操作相同,可以任意使用其中的一个。

注意:前面介绍的很多阻塞式的集合通信(如 Bcast,Scatter,Gather,Allgather 等)都隐式地包含着同步操作,因此并不需要显式地调用 Barrier 进行同步。但是在某些情况下,显式的同步操作对应保证程序的顺利执行却是必须的,如我们前面介绍的点到点就绪通信模式,要求仅当对方的接收操作启动并准备就绪时才可发送数据,否则可能导致错误或无法预知的结果,一种保证发送操作晚于对方的接收操作的方式就是使用这里的栅障同步,让接收操作在 Barrier 之前,而让就绪的发送操作在 Barrier 之后。另一个常见的例子是,由一个进程创建一个目录或者文件,然后其它的进程向其中写入数据,此时必须保证创建目录/文件的操作在所有其它进程的写入之前,这可以由它们之间的 Barrier 来实现。

例程

下面给出栅障同步操作的使用例程。

# barrier.py

"""
Demonstrates the usage of barrier, Barrier.

Run this with 2 processes like:
$ mpiexec -n 2 python barrier.py
"""

import os
import shutil
import numpy as np
from mpi4py import MPI


comm = MPI.COMM_WORLD
rank = comm.Get_rank()

# ---------------------------------------------------------------------
# example 1
count = 10
send_buf = np.arange(count, dtype='i')
recv_buf = np.empty(count, dtype='i')

if rank == 0:
    comm.Rsend(send_buf, dest=1, tag=11)
    comm.Barrier() # synchronization here
    print 'process %d sends %s' % (rank, send_buf)
elif rank == 1:
    comm.Barrier() # synchronization here
    comm.Recv(recv_buf, source=0, tag=11)
    print 'process %d receives %s' % (rank, recv_buf)


# ---------------------------------------------------------------------
# example 2
temp_dir = './temp_dir'
temp_file = 'temp_file%d.txt' % rank
# rank 0 crates the directory first if necessary
if not os.path.isdir(temp_dir):
    if rank == 0:
        os.mkdir(temp_dir)
        print 'rank %d creates dir: %s' % (rank, temp_dir)

# synchronization before writing to temp_dir
comm.Barrier()

# each process creates its own file
open(temp_dir + '/' + temp_file, 'w').close()
print 'rank %d creates file: %s' % (rank, temp_dir + '/' + temp_file)

# synchronization before remove temp_dir
comm.Barrier()

# now remove temp_dir by rank 0
if rank == 0:
    shutil.rmtree(temp_dir)
    print 'rank %d removes dir: %s' % (rank, temp_dir)

运行结果如下:

$ mpiexec -n 2 python barrier.py
process 0 sends [0 1 2 3 4 5 6 7 8 9]
process 1 receives [0 1 2 3 4 5 6 7 8 9]
rank 0 creates dir: ./temp_dir
rank 1 creates file: ./temp_dir/temp_file1.txt
rank 0 creates file: ./temp_dir/temp_file0.txt
rank 0 removes dir: ./temp_dir

以上我们介绍了 mpi4py 中的栅障同步操作方法,至此我们介绍了 mpi4py 中的各种集合通信,下面我们将进入到对数据类型的介绍,在下一篇中我们首先介绍数据类型图的概念。

你可能感兴趣的:(mpi4py 中的栅障同步操作)