在上一篇中我們介紹了 mpi4py 中可重復非阻塞同步通信模式舶赔,下面我們將介紹組合發(fā)送接收操作宰闰。
組合發(fā)送接收操作比較適合接力通信的場合栓拜。在使用組合發(fā)送接收的時候要注意合理安排相關(guān)進程之間發(fā)送/接收操作的順序,以避免死鎖羹呵。
組合通信的發(fā)送操作壁晒,可被任何接收操作匹配瓷们,反之,組合通信的接收操作也可匹配任何其它類型的發(fā)送動作。
組合發(fā)送接收通信方法(MPI.Comm 類的方法)接口如下:
sendrecv(self, sendobj, int dest, int sendtag=0, recvbuf=None, int source=ANY_SOURCE, int recvtag=ANY_TAG, Status status=None)
Sendrecv(self, sendbuf, int dest, int sendtag=0, recvbuf=None, int source=ANY_SOURCE, int recvtag=ANY_TAG, Status status=None)
這些方法調(diào)用中的參數(shù)是與阻塞標準通信模式的方法調(diào)用參數(shù)一樣的谬晕。
下面給出組合發(fā)送接收通信的使用例程:
# sendrecv.py
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
tag = 123
left = rank - 1 if rank >=1 else size - 1
right = rank + 1 if rank < size - 1 else 0
send_obj = {'obj': rank}
recv_obj = comm.sendrecv(send_obj, dest=right, sendtag=tag, source=left, recvtag=tag)
print 'process %d sends %s' % (rank, send_obj)
print 'process %d receives %s' % (rank, recv_obj)
運行結(jié)果如下:
$ mpiexec -n 4 python sendrecv.py
process 0 sends {'obj': 0}
process 0 receives {'obj': 3}
process 1 sends {'obj': 1}
process 1 receives {'obj': 0}
process 2 sends {'obj': 2}
process 2 receives {'obj': 1}
process 3 sends {'obj': 3}
process 3 receives {'obj': 2}
# Sendrecv.py
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
tag = 123
left = rank - 1 if rank >=1 else size - 1
right = rank + 1 if rank < size - 1 else 0
count = 10
send_buf = np.arange(count, dtype='i') + 10 * rank
recv_buf = np.empty(count, dtype='i')
comm.Sendrecv(send_buf, dest=right, sendtag=tag, recvbuf=recv_buf, source=left, recvtag=tag)
print 'process %d sends %s' % (rank, send_buf)
print 'process %d receives %s' % (rank, recv_buf)
運行結(jié)果如下:
$ mpiexec -n 4 python Sendrecv.py
process 0 sends [0 1 2 3 4 5 6 7 8 9]
process 0 receives [30 31 32 33 34 35 36 37 38 39]
process 2 sends [20 21 22 23 24 25 26 27 28 29]
process 2 receives [10 11 12 13 14 15 16 17 18 19]
process 3 sends [30 31 32 33 34 35 36 37 38 39]
process 3 receives [20 21 22 23 24 25 26 27 28 29]
process 1 sends [10 11 12 13 14 15 16 17 18 19]
process 1 receives [0 1 2 3 4 5 6 7 8 9]
上面的例程通過組合發(fā)送接收操作實現(xiàn)了多個進程間的循環(huán)收發(fā)通信卢未。
組合發(fā)送操作方法 Sendrecv 還有一個變化的形式 Sendrecv_replace豺型,它會復用發(fā)送緩沖區(qū)势腮,即發(fā)送消息緩沖區(qū)同時也作為接收消息緩沖區(qū)拳话,原有的發(fā)送消息緩沖區(qū)將被覆蓋,其方法(MPI.Comm 類的方法)接口如下:
Sendrecv_replace(self, buf, int dest, int sendtag=0, int source=ANY_SOURCE, int recvtag=ANY_TAG, Status status=None)
下面給出其使用例程:
# Sendrecv_replace.py
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
tag = 123
left = rank - 1 if rank >=1 else size - 1
right = rank + 1 if rank < size - 1 else 0
count = 10
send_buf = np.arange(count, dtype='i') + 10 * rank
print 'process %d sends %s' % (rank, send_buf)
comm.Sendrecv_replace(send_buf, dest=right, sendtag=tag, source=left, recvtag=tag)
print 'process %d receives %s' % (rank, send_buf)
運行結(jié)果如下:
$ mpiexec -n 4 python Sendrecv_replace.py
process 3 sends [30 31 32 33 34 35 36 37 38 39]
process 1 sends [10 11 12 13 14 15 16 17 18 19]
process 1 receives [0 1 2 3 4 5 6 7 8 9]
process 0 sends [0 1 2 3 4 5 6 7 8 9]
process 0 receives [30 31 32 33 34 35 36 37 38 39]
process 3 receives [20 21 22 23 24 25 26 27 28 29]
process 2 sends [20 21 22 23 24 25 26 27 28 29]
process 2 receives [10 11 12 13 14 15 16 17 18 19]
上面我們介紹了 mpi4py 中組合發(fā)送接收通信方法夕玩,至此我們就對 mpi4py 中提供的各種點到點通信方法都做了一個簡略的介紹你弦,并給出了簡短的使用例程。在下一篇中我們將對點到點通信做一個小結(jié)燎孟。