mpi4py 中的单边通信相关操作

上一篇中我们简要地介绍了 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 中的单边通信相关操作,在下一篇中我们将介绍单边通信的同步操作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容