Hi,
I tried to do the following:
make a ring where there is a communicator between every two nodes
(processes) of the ring.
The code I made is added below. Every MPI_Comm_create returns allways
MPI_SUCCESS,
but I skipped all the error checking to make the code more readable.
The "problem"-part is for if you have a unpair number of nodes.
0 -com1- 1 -com2- 3 -com1- 4 -com2- 5 -COM3- 0
(otherwise 0 has two com1's, but it will be clair in the code...)
I know that I could allso use the following technique to set up the
communicators:
* comm 0-1
* 1 sends msg to 2
* comm 1-2
* 2 sends msg to 3
* ...
But I prefer to use my method.
Now the problem is:
There's allways one link which doesn't works (though MPI_Comm_create didn't
gave an error).
It's allways either the link 0-n (n is highest MPI-rank in MPI_COMM_WORLD),
0-1 or n-(n-1).
Which link it is depends of the order of the three "blocks" ( FIRST - SECOND
-PROBLEM),
which can be swapped; strange enough it's the block in the middle which
determines the bad link.
My question:
Does anyone knows what is wrong with the code below?
Are there other methods to attain the same (not the msg-technique I
described above) ?
Thanks in advance for any ideas and suggestions.
Jim.
#include <iostream>
#include <windows.h>
#include "mpi.h"
#pragma comment(lib,"mpi.lib")
static MPI_Comm* pCommL=NULL;
static MPI_Comm* pCommR=NULL;
int* pIntL=(int*)malloc(sizeof(int));
int* pIntR=(int*)malloc(sizeof(int));
void SendLeft(void *buf, int count, MPI_Datatype datatype,int tag);
int main( int argc, char **argv)
{
int size, rank,newrank;
MPI_Init(&argc,&argv);
MPI_Comm_size( MPI_COMM_WORLD, &size);
MPI_Comm_rank( MPI_COMM_WORLD, &rank);
MPI_Comm c_buur1, c_buur2, c_buur3;
MPI_Group g_buren, world;
int tempgroup[2];
bool problem=(rank==size-1 && rank%2==0);
bool problem2=(rank==0 && size%2==1);
/***************FIRST***************/
if(!problem){
if(rank%2==0){
tempgroup[0]=(rank+1+size)%size;
tempgroup[1]=rank;}
else{
tempgroup[0]=rank;
tempgroup[1]=(rank-1+size)%size;
}
MPI_Comm_group(MPI_COMM_WORLD, &world);
MPI_Group_incl(world, 2, tempgroup, &g_buren);
MPI_Comm_create(MPI_COMM_WORLD, g_buren, &c_buur1);
MPI_Group_free(&g_buren);
if(rank%2==0){
pCommL=&c_buur1;
*pIntL=0;
}
else{
pCommR=&c_buur1;
*pIntR=1;
}
}
/***************SECOND***************/
if(!problem2){
if(rank%2==0){
tempgroup[0]=(rank-1+size)%size;
tempgroup[1]=rank;
}
else{
tempgroup[0]=rank;
tempgroup[1]=(rank+1+size)%size;
}
MPI_Comm_group(MPI_COMM_WORLD, &world);
MPI_Group_incl(world, 2, tempgroup, &g_buren);
MPI_Comm_create(MPI_COMM_WORLD, g_buren, &c_buur2);
MPI_Group_free(&g_buren);
if(rank%2==0){
pCommR=&c_buur2;
*pIntR=0;
}
else{
pCommL=&c_buur2;
*pIntL=1;
}
}
/***************PROBLEMS...***************/
if(problem || problem2){
tempgroup[0]=0;
tempgroup[1]=size-1;
MPI_Comm_group(MPI_COMM_WORLD, &world);
MPI_Group_incl(world, 2, tempgroup, &g_buren);
MPI_Comm_create(MPI_COMM_WORLD, g_buren, &c_buur3);
MPI_Group_free(&g_buren);
if(rank==0){
pCommR=&c_buur3;
*pIntR=1;
}
else{
pCommL=&c_buur3;
*pIntL=0;
}
}
/***********************************************************************/
int aa=1;
MPI_Request request;
MPI_Irecv(&aa, 1, MPI_INT, MPI_ANY_SOURCE,22, *pCommR, &request);
if(rank==0) SendLeft(&aa, 1, MPI_INT,22);
int ontvangen=0;
while(!ontvangen){
MPI_Status status;
MPI_Test(&request, &ontvangen, &status);
if(ontvangen) SendLeft(&aa, 1, MPI_INT,22);
}
printf("\n%d RECEIVED",rank);fflush(stdout);
MPI_Finalize();
return 0;
}
void SendLeft(void *buf, int count, MPI_Datatype datatype,int tag){
MPI_Send(buf, count, datatype, *pIntL, tag,*pCommL);
}
|