1

I need to implement a simple code in MPI with use of MPI_Bcast(). I wanted to make it more useful with use of MPI_Probe(), so I wouldn't have to write message size into MPI_Recv() manually every time.

I'm used to do this with MPI_Send(), but with MPI_Bcast() the program hangs on MPI_Probe(). Do you have any idea why?


My code

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

#define ARR_LEN 1

int main() {
    MPI_Init(NULL, NULL);

    typedef struct Values {
        int id;
        char * c;
    } Values;

    Values val1;
    val1.id = 5;
    val1.c = "Ahoj";

    MPI_Datatype valuesDatatypeTmp;

    int blockLengths[2] = {1, 3};

    MPI_Aint indices[2];

    MPI_Address( &val1.id, &indices[0] );
    MPI_Address( &val1.c, &indices[1] );
    
    indices[1] -= indices[0];
    indices[0] = 0;

    MPI_Datatype types[2] = {MPI_INT, MPI_CHAR};

    MPI_Type_create_struct( 2, blockLengths, indices, types, &valuesDatatypeTmp );

    MPI_Datatype valuesDatatype;
    MPI_Type_create_resized( valuesDatatypeTmp,
                                indices[0],
                                (MPI_Aint)sizeof(struct Values),
                                &valuesDatatype );

    MPI_Type_free( &valuesDatatypeTmp );
    MPI_Type_commit( &valuesDatatype );

    //-----------------------//
    //--- Message passing ---//
    //-----------------------//

    int world_size;
    MPI_Comm_size( MPI_COMM_WORLD, &world_size );

    int world_rank;
    MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );

    MPI_Status status;
    Values * buf;

    Values val[ARR_LEN] = {val1};

    switch( world_rank ) {
    case 0:
        printf("Toto je proces cislo %d - root.\n", world_rank);
        MPI_Bcast( val, ARR_LEN, valuesDatatype, 0, MPI_COMM_WORLD );
        break;
    default:

        MPI_Probe( 0, 0, MPI_COMM_WORLD, &status );

        int status_size;
        MPI_Get_count( &status, valuesDatatype, &status_size );


        buf = (Values *) malloc( sizeof(struct Values) * status_size );

        MPI_Recv( buf, status_size, valuesDatatype, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE );

        printf( "Toto je proces cislo %d.\n", world_rank );
        
        for( int i = 0; i < ARR_LEN; i++ ) {
            printf("Prijata zprava je %d %s\n"\
                    "Delka zpravy byla %d\n",
                    buf[i].id,
                    buf[i].c,
                    status_size);
        }

        break;
    }

    MPI_Type_free( &valuesDatatype );
    MPI_Finalize();
    return 0;
}
Community
  • 1
  • 1
Eenoku
  • 2,741
  • 4
  • 32
  • 64
  • possible duplicate of [Using MPI\_Bcast for MPI communication](http://stackoverflow.com/questions/7864075/using-mpi-bcast-for-mpi-communication) – Wesley Bland Feb 03 '15 at 21:36

1 Answers1

0

I've found out, that the code is not working properly, because I'm using MPI_Bcast() incorrectly. No MPI_Recv() is used when using MPI_Bcast(). Every process is using just MPI_Bcast(), so the root is "sharing" the buffer with everybody.

I've also found answers explaining this better than me - I somehow missed them before:


Correct code

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

#define ARR_LEN 1

int main() {
    MPI_Init(NULL, NULL);

    typedef struct Values {
        int id;
        char * c;
    } Values;

    Values val1;
    val1.id = 5;
    val1.c = "Ahoj";

    MPI_Datatype valuesDatatypeTmp;

    int blockLengths[2] = {1, 3};

    MPI_Aint indices[2];

    MPI_Address( &val1.id, &indices[0] );
    MPI_Address( &val1.c, &indices[1] );
    indices[1] -= indices[0];
    indices[0] = 0;

    MPI_Datatype types[2] = {MPI_INT, MPI_CHAR};

    MPI_Type_create_struct( 2, blockLengths, indices, types, &valuesDatatypeTmp );

    MPI_Datatype valuesDatatype;
    MPI_Type_create_resized( valuesDatatypeTmp,
                                indices[0],
                                (MPI_Aint)sizeof(struct Values),
                                &valuesDatatype );

    MPI_Type_free( &valuesDatatypeTmp );
    MPI_Type_commit( &valuesDatatype );

    int world_size;
    MPI_Comm_size( MPI_COMM_WORLD, &world_size );

    int world_rank;
    MPI_Comm_rank( MPI_COMM_WORLD, &world_rank );

    MPI_Status status;
    Values * buf;

    Values val[ARR_LEN] = {val1};

    MPI_Bcast( val, ARR_LEN, valuesDatatype, 0, MPI_COMM_WORLD );

    printf( "This is the processnumber %d.\n", world_rank );
    
    for( int i = 0; i < ARR_LEN; i++ ) {
        printf("Message received: %d %s\n",
                val[i].id,
                val[i].c
                );
    }

    MPI_Type_free( &valuesDatatype );
    MPI_Finalize();
    return 0;
}
Community
  • 1
  • 1
Eenoku
  • 2,741
  • 4
  • 32
  • 64