MPI除了有一個默認的通信域MPI_COMM_WORLD包含所有結點之外,還可以將其分解爲多個子通信域進行組內通訊。主要使用MPI_Comm_split(myComm,color,key,splitComm)這個API實現。其主要說明如下:
參數myComm是待分裂的通信域,而splitComm是分裂後的通信域。color是子域的標誌,而key是結點在組內的標誌。
比如如果有9個結點其rank分別爲0-8;
那麼用一下規則分組:
color = rank % 3
key = rank / 3
那麼結點5(rank=5)就在子通信域的第3個組內(組id爲2,從0開始算),在組內的標誌爲1。
這時如果再次調用廣播MPI_Bcast函數,如果其第5個參數是SplitComm通信域的話,每個組都會由指定的root進行一次廣播通訊。而這個root不在是總通訊域的id,而是在自己組內的id。如果每個組都有id爲root的結點,那麼每個組都要在組內進行一次廣播。
下面有一段代碼可以說明:
/********************************
*author : ysc
*email : [email protected]
**************************&****/
#include <mpi.h>
#include <stdio.h>
void main(int argc,char *argv[])
{
MPI_Comm MyWorld, SplitWorld;
int my_rank,group_size, Color, Key;
char message[80] = "this is no.x node";
MPI_Init(&argc, &argv);
MPI_Comm_dup(MPI_COMM_WORLD,&MyWorld);
MPI_Comm_rank(MyWorld,&my_rank);
MPI_Comm_size(MyWorld,&group_size);
Color=my_rank%3;
Key=my_rank/3;
if(my_rank/3 == 0)
message[11] = my_rank + '0';
MPI_Comm_split(MyWorld,Color,Key,&SplitWorld);
MPI_Bcast(message,80,MPI_CHAR,0,SplitWorld);
printf("node: %d message: %s\n",my_rank,message);
MPI_Finalize();
}
只有每個組內id爲0的結點對message進行一次賦值,否則都是x。這個id爲0的結點在自己的組內進行一次廣播,同組的結點都收到了這個信息。運行結果如下:
ysc@ysc-K42JP:~$ mpicc 1.c -o 1
ysc@ysc-K42JP:~$ mpirun -np 9 ./1
node: 0 message: this is no.0 node
node: 6 message: this is no.0 node
node: 1 message: this is no.1 node
node: 2 message: this is no.2 node
node: 8 message: this is no.2 node
node: 5 message: this is no.2 node
node: 7 message: this is no.1 node
node: 4 message: this is no.1 node
node: 3 message: this is no.0 node