How to Send/Receive in MPI using all processors

前端 未结 2 653
予麋鹿
予麋鹿 2021-02-06 00:34

This program written using C Lagrange and MPI. I am new to MPI and want to use all processors to do some calculations, including process 0. To learn this concept, I have written

相关标签:
2条回答
  • 2021-02-06 00:55

    Actually, processes 1-3 are indeed sending the result back to processor 0. However, processor 0 is stuck in the first iteration of this loop:

    for(i=0; i<4; i++)
    {      
        MPI_Recv(&number, 1, MPI_INT, i, 99, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        printf("Process 0 received number %d from i:%d\n", number, i);
    }
    

    In the first MPI_Recv call, processor 0 will block waiting to receive a message from itself with tag 99, a message that 0 did not send yet.

    Generally, it is a bad idea for a processor to send/receive messages to itself, especially using blocking calls. 0 already have the value in memory. It does not need to send it to itself.

    However, a workaround is to start the receive loop from i=1

    for(i=1; i<4; i++)
    {           
        MPI_Recv(&number, 1, MPI_INT, i, 99, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        printf("Process 0 received number %d from i:%d\n", number, i);
    }
    

    Running the code now will give you:

    Process 1 received number -2 from process 0
    Process 2 received number -2 from process 0
    Process 3 received number -2 from process 0
    Process 0 received number 2 from i:1
    Process 0 received number 3 from i:2
    Process 0 received number 4 from i:3
    Process 0 received number -2 from process 0
    

    Note that using MPI_Bcast and MPI_Gather as mentioned by Gilles is a much more efficient and standard way for data distribution/collection.

    0 讨论(0)
  • 2021-02-06 01:12

    I don't really get what would be wrong with using 2 if statements, surrounding the working domain. But anyway, here is an example of what could be done.

    I modified your code to use collective communications as they make much more sense than the series of send/receive you used. Since the initial communications are with a uniform value, I use a MPI_Bcast() which does the same in one single call.
    Conversely, since the result values are all different, a call to MPI_Gather() is perfectly appropriate.
    I also introduce a call to sleep() just to simulate that the processes are working for a while, prior to sending back their results.

    The code now looks like this:

    #include <mpi.h>
    #include <stdlib.h>   // for malloc and free
    #include <stdio.h>    // for printf
    #include <unistd.h>   // for sleep
    
    int main( int argc, char *argv[] ) {
    
        MPI_Init( &argc, &argv );
        int world_rank;
        MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );
        int world_size;
        MPI_Comm_size( MPI_COMM_WORLD, &world_size );
    
        // sending the same number to all processes via broadcast from process 0
        int number = world_rank == 0 ? -2 : 0;
        MPI_Bcast( &number, 1, MPI_INT, 0, MPI_COMM_WORLD );
        printf( "Process %d received %d from process 0\n", world_rank, number );
    
        // Do something usefull here
        sleep( 1 );
        int my_result = world_rank + 1;
    
        // Now collecting individual results on process 0
        int *results = world_rank == 0 ? malloc( world_size * sizeof( int ) ) : NULL;
        MPI_Gather( &my_result, 1, MPI_INT, results, 1, MPI_INT, 0, MPI_COMM_WORLD );
    
        // Process 0 prints what it collected
        if ( world_rank == 0 ) {
            for ( int i = 0; i < world_size; i++ ) {
                printf( "Process 0 received result %d from process %d\n", results[i], i );
            }
            free( results );
        }
    
        MPI_Finalize();
    
        return 0;
    }
    

    After compiling it as follows:

    $ mpicc -std=c99 simple_mpi.c -o simple_mpi
    

    It runs and gives this:

    $ mpiexec -n 4 ./simple_mpi
    Process 0 received -2 from process 0
    Process 1 received -2 from process 0
    Process 3 received -2 from process 0
    Process 2 received -2 from process 0
    Process 0 received result 1 from process 0
    Process 0 received result 2 from process 1
    Process 0 received result 3 from process 2
    Process 0 received result 4 from process 3
    
    0 讨论(0)
提交回复
热议问题