Nurul Asyiqin Nurul Asyiqin - 3 years ago 184
C Question

MPI send receive

#include "mpi.h"
#include <stdio.h>

int main(argc,argv)
int argc;
char *argv[]; {
int numtasks, rank, dest, source, rc, count, tag=1;
MPI_Status Stat;

MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if (rank%2 == 1) {
dest = (rank+1)%numtasks;
source = (rank-1+numtasks)%numtasks;
rc = MPI_Send(&outmsg, 1, MPI_CHAR, dest, tag, MPI_COMM_WORLD);
rc = MPI_Recv(&inmsg, 1, MPI_CHAR, source, tag,MPICOMM_WORLD, &Stat);
}

else {
dest = (rank-1+numtasks)%numtasks;
source = (rank+1)%numtasks;
rc = MPI_Recv( &inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat );
rc = MPI_Send( &outmsg, 1, MPI_CHAR, dest, tag, MPI_COMM_WORLD );
}
rc = MPI_Get_count(&Stat, MPI_CHAR, &count);
printf("Task %d: Received %d char(s) from task %d with tag %d\n",
rank, count, Stat.MPI_SOURCE, Stat.MPI_TAG);

MPI_Finalize();
}


Results:

Task 2: Received 1 char(s) from task 3 with a tag 1
Task 0: Received 1 char(s) from task 1 with a tag 1


Why the task can't identify more than 2 processors?

I want run it on more than 2 processors.

I've updated the mpi program with the ring pattern, i think maybe wrong at the line if(rank%2==1)

Answer Source

May try to better investigate the MPI mechanics:

Do not hesitate to experiment with the code, as it will help you grasp the concept of numtasks, rank-ID and associated run-time operations. Compilation errors will report shortcuts in the above posted code. For more MPI-related practices and insights, one ought also assign and evaluate rc return codes, from the respective MPI_<fun>()-calls

Q: Why the task can't identify more than 2 processors?
A: It can, but the if(){..}else if(){..} code-blocks did not allow others to produce any visible output.

Q: I want to change that 4197005 result into 2, 3 - how?
A: One cannot change an MPI-reported number, but you can change the behaviour of your code ( see below ) and make some more outputs, where feasible about who is doing what, when, how and where it is actually going on. This way we learn to understand the MPI-concepts and validate the actual MPI-code execution.

Feel free to ask more.

#include "mpi.h"
#include <stdio.h>

int main( int   argc,
          char *argv[]
          ) {
   int        numtasks, rank, dest, source, rc, count, tag = 1;
   MPI_Status Stat;

   printf( "(INF) will MPI_Init()...\n" );

   MPI_Init( &argc, &argv );
   printf( "(INF)      MPI_Init() done.\n" );

   MPI_Comm_size( MPI_COMM_WORLD, &numtasks );
   MPI_Comm_rank( MPI_COMM_WORLD, &rank );
   printf( "(INF) I am MPI[%d of %d]\n",
            rank,
            numtasks
            );

   if ( rank  == 0 ) {
        dest   = 1;
        source = 1;
        rc     = MPI_Send( &outmsg, 1, MPI_CHAR, dest,   tag, MPI_COMM_WORLD );
        rc     = MPI_Recv(  &inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat );
        printf( "(INF) I am MPI[%d of %d] having just completed an MPI_Send( ->MPI[%d] ) + MPI_Recv( <-MPI[%d] ). Last RetCODE == %d.\n",
                 rank,
                 numtasks,
                 dest,
                 source,
                 rc
                 );
   }
   else
   if ( rank  == 1 ) {
        dest   = 0;
        source = 0;
        rc     = MPI_Recv(  &inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat );
        rc     = MPI_Send( &outmsg, 1, MPI_CHAR, dest,   tag, MPI_COMM_WORLD );
        printf( "(INF) I am MPI[%d of %d] having just completed an MPI_Recv( <-MPI[%d] ) + MPI_Send( ->MPI[%d] ). Last RetCODE == %d\n",
                 rank,
                 numtasks,
                 source,
                 dest,
                 rc
                 );
   }
   else
   if ( rank  == 2 ) {
        dest   = 3;
        source = 3;
        rc     = MPI_Recv(  &inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat );
        rc     = MPI_Send( &outmsg, 1, MPI_CHAR, dest,   tag, MPI_COMM_WORLD );
        printf( "(INF) I am MPI[%d of %d] having just completed an MPI_Recv( <-MPI[%d] ) + MPI_Send( ->MPI[%d] ). Last RetCODE == %d\n",
                 rank,
                 numtasks,
                 source,
                 dest,
                 rc
                 );
   }
   else
   if ( rank  == 3 ) {
        dest   = 2;
        source = 2;
        rc     = MPI_Send( &outmsg, 1, MPI_CHAR, dest,   tag, MPI_COMM_WORLD );
        rc     = MPI_Recv(  &inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat );
        printf( "(INF) I am MPI[%d of %d] having just completed an MPI_Send( ->MPI[%d] ) + MPI_Recv( <-MPI[%d] ). Last RetCODE == %d\n",
                 rank,
                 numtasks,
                 dest,
                 source,
                 rc
                 );
   }
   else {
        printf( "(INF) I am MPI[%d of %d] will NOP...\n",
                 rank,
                 numtasks
                 );

   }
   rc = MPI_Get_count( &Stat, MPI_CHAR, &count );
   /*
            Task  3: Received  1 char(s) from task 4197005 with a tag 0
            Task  2: Received  1 char(s) from task 4197005 with a tag 0
            Task  1: Received  1 char(s) from task 0       with a tag 1
            Task  0: Received  1 char(s) from task 1       with a tag 1                        */
   printf( "Task %d: Received %d char(s) from task %d with tag %d\n",
            rank,
            count,
            Stat.MPI_SOURCE,
            Stat.MPI_TAG
            );

   printf( "(INF) I am MPI[%d of %d]: will MPI_Finalize()...\n",
            rank,
            numtasks
            );
   MPI_Finalize();

   printf( "(INF) I am MPI[%d of %d]:      MPI_Finalize() done, will exit()...\n",
            rank,
            numtasks
            );
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download