mpi4py 中的单边通信相关操作

原创 2018年04月14日 22:35:57

本文从本人简书博客同步过来

上一篇中我们简要地介绍了 mpi4py 中的单边通信概念,下面我们将介绍单边通信的相关操作。

创建/释放窗口对象

注意:在使用单边通信操作之前,所有进程都须通过共同参与的创建窗口操作公开声明自己可供访问的内存空间。

创建和释放窗口对象的方法(MPI.Win 类方法)接口如下:

Create(type cls, memory, int disp_unit=1, Info info=INFO_NULL, Intracomm comm=COMM_SELF)

创建并返回用于单边通信的窗口对象。在组内通信子 comm 所指定的通信子范围内所有进程上执行集合操作,每个进程通过一块内存缓冲区 memory 指定要创建的窗口,可以为 None(或 MPI.BOTTOM),此时不提供可供其它进程访问的窗口。disp_unit 指定在远端内存访问操作中的地址单位,即 origin 所指定的位置在 target 一侧要以 target 进程所指定的 diap_unit 为单位计算。通常如果采用相同类型创建窗口,则统一将 disp_unit 设置成 1 即可。如果有的进程需要以组合数据类型(type)给出缓冲区,则可能需要指定 disp_unit 为 sizeof(type)。info 对象用于为 MPI 环境提供优化所需的辅助信息,目前可用的 key 为 no_lock,如果该值设置为 True,则指示 MPI 环境不对进程的本地窗口加锁,也就是说此时表示应用程序可以确信相应窗口不会作为第三方参与通信,这样就可减少相应进程异步代理机制上的一些额外操作。参与创建窗口的进程可分别指定不同的 memorydisp_unitinfo 参数,内存中的同一块区域也可同时存在于多个窗口中,只要应用程序能确保并发访问这块区域所需的安全语义。

Free(self)

释放当前窗口对象。会在所有进程间实施 barrier 同步操作,直至所有进程都执行完毕才返回。所有进程都必须在其远端内存访问结束后才可调用此操作。

通信操作

单边通信的 3 种操作方法(MPI.Win 类方法)接口如下:

Put(self, origin, int target_rank, target=None)

该操作把当前进程 origin 中的数据传输到进程 target_ranktarget 位置。参数 origin 应该是一个长度为2或3的 list 或 tuple,类似于 [data, MPI.DOUBLE],或者 [data, count, MPI.DOUBLE],以指明发送数据缓冲区,数据计数以及数据类型。当 count 省略时会利用 data 的字节长度和数据类型计算出对应的 count。对 numpy 数组,其计数和数据类型可以自动推断出来,因此可以直接以 data 作为第一个参数传给 origintarget 可以是 None,一个整数或是一个长度为3的 list 或 tuple,类似于 [target_disp, target_count, target_datatype],分别指定接收到的数据写入 target_rank 进程相对于窗口内存缓冲区的起始位置的偏移,数据量和数据类型,当为 None 或一个整数时,会设置 target_disp 为 0 或该整数,而 target_counttarget_datatype 会设置成目标窗口缓冲区的大小和数据类型。与点到点通信类似,target 进程缓冲区的大小也需要有足够的空间以容纳要传输的数据。如果 target_datatype 是自定义数据类型,则必须仅包含相对偏移,而不能使用绝对地址,这一限制对后面的 Get 和 Accumulate 方法同样适用。

此操作的实际效果相当于执行一次点到点通信,在源进程执行 Send(origin, dest=target_rank, tag=tag),在目标进程执行 Recv(buf, source=source, tag=tag),不同的是,Put 操作的源进程指定所有通信参数,而不需要在目标进程里启动与之匹配的接收操作。

Get(self, origin, int target_rank, target=None)

该操作从 target_rank 的窗口缓冲区读取数据,各参数的含义及限制与 Put 基本相同,只是数据传输的方向改为由目标流向源。

Accumulate(self, origin, int target_rank, target=None, Op op=SUM)

该操作将 origin 中的数据用 Reduce 中所定义的操作 op 更新 target_rank 的窗口缓冲区中由 target 所指定位置处的数据。各参数的含义及限制与 Put 基本相同, op 指定操作的规约算符。该操作只能使用 Reduce 内置定义的操作和 Accumulate 增加的一个操作——MPI.REPLACE。Put 是 Accumulate 执行 MPI.REPLACE 的特殊情形。可以使用预定义数据类型和用户自定义数据类型,但 target_datatype 不能指定重叠的区域,且目标进程中缓冲区不能超过目标进程所声明窗口的范围。

以上介绍的 Put,Get,Accumulate 均为非阻塞操作,仅当操作发起者对相同的窗口对象调用同步函数(在下一篇中将会介绍)后才能确保实际数据传输完毕。从启动远端内存访问操作起,到通过同步函数确认操作完成之间,不能更新本地进程为实现该次通信所使用的数据缓冲区,即使是 Get 操作,在此期间也不能更新其所使用的本地通信缓冲区。

例程

下面给出单边通信操作相关方法的使用例程。

# win.py

"""
Demonstrates the usage of Create, Free, Put, Get, Accumulate.

Run this with 4 processes like:
$ mpiexec -n 4 python win.py
"""

import numpy as np
from mpi4py import MPI


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

# Create and Put
if rank == 0:
    mem = np.array([1, 2], dtype='i')
    # create a window object with no accessable memory, used to communicate with other only
    win =  MPI.Win.Create(None, comm=comm)
    # synchronize
    win.Fence()
    # put data into a memory window of rank 1
    print 'rank 0 puts %s to rank 1' % mem
    win.Put(mem, target_rank=1)
    # synchronize
    win.Fence()
else:
    # initialize a memory of [0, 0]
    mem = np.array([0, 0], dtype='i')
    # use mem to create a window for receiving data
    win =  MPI.Win.Create(mem, comm=comm)
    # synchronize
    win.Fence()
    # synchronize
    win.Fence()
    print 'rank %d has %s after put' % (rank, mem)


# Get and Accumulate
if rank == 0:
    a = np.array(0.5, dtype='d')
    # initialize acc with 0.0
    acc = np.array(0.0, dtype='d')
    # create window objects
    win_a =  MPI.Win.Create(a, comm=comm)
    win_acc =  MPI.Win.Create(acc, comm=comm)
    # synchronize for win_a
    win_a.Fence()
    # synchronize for win_a
    win_a.Fence()
    # synchronize for win_acc
    win_acc.Fence()
    # synchronize for win_acc
    win_acc.Fence()
    # after accumulate, print the value of acc = 0.5 + 0.5 + 0.5
    print 'rank 0 has acc = %s' % acc
else:
    # initialize a with 0.0
    a = np.array(0.0, dtype='d')
    win_a =  MPI.Win.Create(None, comm=comm)
    win_acc =  MPI.Win.Create(None, comm=comm)
    # synchronize for win_a
    win_a.Fence()
    # get data from a memory window of rank 0
    win_a.Get(a, target_rank=0)
    # synchronize for win_a
    win_a.Fence()
    print 'rank %d has a = %s' % (rank, a)
    # synchronize for win_acc
    win_acc.Fence()
    # each rank except 0 accumulates a to the memory window of rank 0
    win_acc.Accumulate(a, target_rank=0, op=MPI.SUM)
    # synchronize for win_acc
    win_acc.Fence()

# free the window object
win.Free()
win_a.Free()
win_acc.Free()

运行结果如下:

$ mpiexec -n 4 python win.py 
rank 0 puts [1 2] to rank 1
rank 3 has [0 0] after put
rank 2 has [0 0] after put
rank 1 has [1 2] after put
rank 1 has a = 0.5
rank 3 has a = 0.5
rank 2 has a = 0.5
rank 0 has acc = 1.5

以上我们介绍了 mpi4py 中的单边通信相关操作,在下一篇中我们将介绍单边通信的同步操作。

版权声明: https://blog.csdn.net/ZuoShifan/article/details/79945199

mpi4py 中的单边通信

本文从本人简书博客同步过来 在上一篇中我们介绍了 mpi4py 中的动态进程管理,下面我们将介绍单边通信。 简介 单边通信又称作远端内存访问(Remote Memory Access,RMA...
  • ZuoShifan
  • ZuoShifan
  • 2018-04-12 16:30:37
  • 1

mpi4py 中的单边通信同步操作

本文从本人简书博客同步过来 在上一篇中我们介绍了 mpi4py 中的单边通信相关操作,下面我们将介绍单边通信的同步操作。 单边通信(远端内存访问)操作包括以下两个范畴: 主动目标通信。与点到点...
  • ZuoShifan
  • ZuoShifan
  • 2018-04-14 22:37:30
  • 2

mpi学习日志(5):mpi4py与多点通信续

在多点通信里我们已经学习了广播bcast,散播scatter,收集gather,规约reduce. 今天我们再来简略看一些可能更为少用的多点通信. 1.allgather 简单来说就是收集+广播....
  • ljhandlwt
  • ljhandlwt
  • 2016-07-19 10:22:44
  • 844

mpi4py 点到点通信之标准阻塞通信模式

本文从本人简书博客同步过来 在上一篇中概要地介绍了 mpi4py 中的点到点通信方法及其消息传递的流程,下面我们介绍 mpi4py 中标准的阻塞通信模式。 阻塞通信是指消息发送方的 send 调用...
  • ZuoShifan
  • ZuoShifan
  • 2018-03-25 11:55:20
  • 14

mpi学习日志(7):mpi4py与通信子,通信组

从第一篇笔记开始,我们就使用了comm这个对象. 而且,几乎每次新学习的函数,都是这个comm的一个方法. 今天,我们就来重新认识comm,它到底是什么? 1.通信子 comm是一个通...
  • ljhandlwt
  • ljhandlwt
  • 2016-07-19 20:11:08
  • 1081

mpi4py 快速上手

本文从本人简书博客同步过来 在上一篇中我们介绍了如何安装和使用 mpi4py,下面我们以几个简单的例子来展示怎么使用 mpi4py 来进行并行编程,以使读者能够快速地上手使用 mpi4py。这些例子...
  • ZuoShifan
  • ZuoShifan
  • 2018-03-25 11:44:40
  • 39

mpi4py 中的发散操作

在上一篇中我们介绍了 mpi4py 中的广播操作方法,下面将介绍发散操作。 对组内通信子对象,发散操作从组内的根进程分别向组内进程散发不同的消息。 对组间通信子对象,发散操作的函数调用应该包含组间...
  • ZuoShifan
  • ZuoShifan
  • 2018-03-30 20:46:19
  • 22

mpi学习日志(3):mpi4py与广播

前面我们学习了点对点通信,那是关于两个点的通信.今天,我们学习多个点之间的通信.首先,我们学习广播. 所谓广播,就是说某个进程要向其他所有进程发送数据,而不是单独某个进程. 显然,一次的广...
  • ljhandlwt
  • ljhandlwt
  • 2016-07-18 18:34:01
  • 850

mpi4py安装包及依赖包

  • 2016年04月17日 00:27
  • 32.1MB
  • 下载

Python多核编程mpi4py实践

Python多核编程mpi4py实践zouxy09@qq.comhttp://blog.csdn.net/zouxy09 一、概述       CPU从三十多年前的8086,到十年前的奔腾,再到当下的...
  • zouxy09
  • zouxy09
  • 2015-10-10 22:58:38
  • 20655
收藏助手
不良信息举报
您举报文章:mpi4py 中的单边通信相关操作
举报原因:
原因补充:

(最多只允许输入30个字)