在mpi組通訊中,散發操作有兩個函式,分別是mpi_scatter與mpi_scatterv。分別與之前所說的mpi_gather,mpi_gatherv為互逆操作。
使用mpi_scatter函式可以將root程序的傳送緩衝區中的資料順序地分發給各個程序(自己的接收緩衝區也會接收到)。呼叫方式為:mpi_scatter(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm);
需要注意的是在mpi_scatter中向每個程序傳送的資料數目是相同的,sendcount是固定值且必須和recvcount相同。
與mpi_gatherv類似,mpi_scatterv也是更加複雜更加靈活同時更加有逼格的組通訊散發操作。它同樣也將root程序的傳送緩衝區的資料散發給各個程序,區別在於傳送給每個程序的資料數目以及在傳送緩衝區的起始位置都可以指定。
呼叫方式為:mpi_scatterv(sendbuf,sendcounts,displs,sendtype,recvbuf,recvcount,recvtype,root,comm);
注意sendcounts代表該引數是乙個陣列,指明向每乙個程序傳送資料的數量,而displs是另乙個陣列,指明向每乙個程序傳送資料的起始位置。此外,若向不同程序傳送資料數目不同,recvcount並不是乙個固定值,但也需要與對應程序傳送的資料數目相同。
在下面的例子中,root程序的第乙個傳送緩衝區的大小為向每乙個程序傳送資料的數目scatter_size乘程序數目proc_nums,第i位資料為整數i。將傳送緩衝區分為proc_nums塊,依次散發給各個程序。實現了組通訊中的普通散發操作。
第二個傳送緩衝區的大小為向每乙個程序傳送資料的數目的累加和,第i位資料為整數i。向第j個程序散發從傳送緩衝區的第j個資料開始的共j+1個數,即sendbuf[j-1]到sendbuf[2*j]。
#include
#include
"mpi.h"
#include
"stdlib.h"
#include
#define scatter_size 10
#define dummy 1
intmain
(int argc,
char
**argv)
//scatterv
int send_size=proc_size;
for(
int m=
0;m) displs=
(int*)
malloc
(proc_size*
sizeof
(int))
; scatterv_count=
(int*)
malloc
(proc_size*
sizeof
(int))
; v_send_buff=
(int*)
malloc
(send_size*
sizeof
(int))
;int location=0;
for(
int j=
0;j)for
(int k=
0;kv_recv_buff=
(int*)
malloc
((rank+1)
*sizeof
(int))
;mpi_barrier
(mpi_comm_world)
;mpi_scatter
(send_buffer,scatter_size,mpi_int,recv_buffer,scatter_size,mpi_int,root,mpi_comm_world)
;mpi_scatterv
(v_send_buff,scatterv_count,displs,mpi_int,v_recv_buff,rank+
1,mpi_int,root,mpi_comm_world)
;mpi_barrier
(mpi_comm_world)
;for
(int hwf=
0;hwf)printf
("\n");
printf
("processor %d has been scattervd:\n"
,rank)
;for
(int p=
0;p1;p++
)printf
("\n");
}}//mpi_abort(mpi_comm_world,99);
mpi_finalize()
;return0;
}
組收集是對mpi組通訊中收集操作的擴充套件,相當於通訊域中的每乙個程序都作為root程序對全體程序進行了收集操作。在之前的mpi_gather與mpi_gatherv操作中,只有root程序的接收緩衝區有意義。而在組收集中,所有程序的接收緩衝區都有意義,且接收結果都相同。
每乙個程序都收集全體程序傳送緩衝區中的資料,並依次存放在自己的接收緩衝區中。從每個程序收集到的資料數目相同。
mpi_allgather(sendbuf, sendcount, sendtype, recvbuf, recvcount,recvtype,comm);
注意sendcount是固定值且必須與recvcount相同。
每乙個程序都收集全體程序傳送緩衝區中的資料,並按照偏移陣列指定的位置存放在接收緩衝區中,從每個程序收集到的資料數目可以使用數目陣列指定。
mpi_allgatherv(sendbuf, sendcount, sendtype, recvbuf,recvcounts,displs,recvtype,comm);
recvcounts為指定從各程序收集資料數目的陣列,displs為指定接收緩衝區中存放位置的偏移陣列。此時sendcount不一定是固定值,但需要與對應接收緩衝區的接收資料數目相同。
#include
#include
"mpi.h"
#include
"stdlib.h"
#include
#define gather_size 10
#define dummy 1
intmain
(int argc,
char
**argv)
malloc_size=location+proc_nums;
//printf("processor %d malloc_size is %d,first count is %d,first loc %d,second loc %d ",rank,malloc_size,sendcounts[0],displs[0],displs[1]);
//每個程序都申請接收陣列空間
recv_buff=
(int*)
malloc
(proc_nums*gather_size*
sizeof
(int))
; v_recv_buff=
(int*)
malloc
(malloc_size*
sizeof
(int))
;//定義allgather與allgahterv過程中,每個程序傳送緩衝區的內容
for(
int p=
0;p)for
(int q=
0;q1;q++
)//全收集
mpi_allgather
(send_buff,gather_size,mpi_int,recv_buff,gather_size,mpi_int,mpi_comm_world)
;mpi_allgatherv
(v_send_buff,sendcounts[rank]
,mpi_int,v_recv_buff,sendcounts,displs,mpi_int,mpi_comm_world)
;//每個程序都向其餘程序收集對方程序號+1個資料
//測試
for(
int h=
0;h)printf
("\n");
for(
int f=
0;f)printf
("\n");
}}mpi_finalize()
;return0;
}
MPI筆記(五)組和通訊因子
mpi筆記 一 環境 mpi筆記 二 點對點通訊 mpi筆記 三 集合通訊 mpi筆記 四 資料型別和派生資料型別 mpi筆記 五 組和通訊因子 mpi筆記 六 虛擬拓撲 mpi筆記 七 計算圓周率 組和通訊因子 mpi comm world 是全域性的通訊因子 mpi comm group com...
組通訊與點對點通訊
通訊子 communicator 是指一組可以相互傳送訊息的程序集合。集合通訊 collective communication 也叫組通訊,是指設計通訊子中所有程序的通訊函式。點對點通訊 point to point communication 函式對 兩個函式 之間的通訊。集合通訊和點對點通訊的...
zigbee學習筆記十二 組播通訊
1 協調器建立網路,並加入乙個組,向組內成員組播資料 i am coordinator device n 2 終端1加入網路,並加入與協調器相同的組,收到協調器傳送而來的資料 2 終端2加入網路,並加入另外乙個組,不能收到協調器發來的資料 1 複製工程模板,並重命名 2 加入串列埠通訊 3 配置組播...