NewToAndroid
NewToAndroid

Reputation: 581

Is MPI_Alltoall used correctly?

I intend to achieve a simple task using MPI collective communication but being new to MPI, I have found the collective routines somewhat non-intuitive. I have 4 slaves, each of which must read a unique string and send the string to all the other slaves.

I looked into MPI_Bcast, MPI_Scatter, and MPI_Alltoall. I settled for MPI_Alltoall but the program ends with bad termination.

The program is:

int main(int argc,char *argv[])
{
    int my_rank, num_workers;
    MPI_Comm SLAVES_WORLD;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &num_workers);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    createSlavesCommunicator(&SLAVES_WORLD);

    char send_msg[20], recv_buf[20];
    sprintf(send_msg, "test string %d", my_rank); 

    MPI_Alltoall(send_buf, strlen(send_buf), MPI_CHAR, recv_buf, 20, MPI_CHAR, MPI_COMM_WORLD);
    printf("slave %d recvd message %s\n", my_rank, recv_buf);

}

 void createSlavesCommunicator(MPI_Comm *SLAVES_WORLD)
 {
    MPI_Group SLAVES_GROUP, MPI_COMM_GROUP;

    int ranks_to_excl[1];
    ranks_to_excl[0] = 0;

    MPI_Comm_group(MPI_COMM_WORLD, &MPI_COMM_GROUP);
    MPI_Group_excl(MPI_COMM_GROUP, 1, ranks_to_excl, &SLAVES_GROUP);

    MPI_Comm_create(MPI_COMM_WORLD, SLAVES_GROUP, SLAVES_WORLD);
 }

Upvotes: 1

Views: 800

Answers (1)

francis
francis

Reputation: 9817

MPI_AlltoAll() sends messages from everyone to everyone. Input and output buffer should be much larger than 20 if each process sends 20 char. Starting from your code, here is how MPI_AlltoAll() works :

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "mpi.h"

int main(int argc,char *argv[])
{
    int my_rank, num_workers;
    MPI_Comm SLAVES_WORLD;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &num_workers);
    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
    //createSlavesCommunicator(&SLAVES_WORLD);

    char send_msg[20*num_workers], recv_buf[20*num_workers];
    int i;
    for(i=0;i<num_workers;i++){
        sprintf(&send_msg[i*20], "test from %d to %d", my_rank,i);
    } 

    MPI_Barrier(MPI_COMM_WORLD);
    //MPI_Alltoall(send_msg, strlen(send_msg), MPI_CHAR, recv_buf, 20, MPI_CHAR, MPI_COMM_WORLD);
    MPI_Alltoall(send_msg, 20, MPI_CHAR, recv_buf, 20, MPI_CHAR, MPI_COMM_WORLD);
    MPI_Barrier(MPI_COMM_WORLD);


    for(i=0;i<num_workers;i++){
        printf("slave %d recvd message %s\n", my_rank, &recv_buf[20*i]);
    }

    MPI_Finalize();
    return 0;
}

Looking at your question, it seems that MPI_AllGather() is the function that would do the trick...

"The block of data sent from the jth process is received by every process and placed in the jth block of the buffer recvbuf. "

http://www.mcs.anl.gov/research/projects/mpi/www/www3/MPI_Allgather.html

Bye,

Francis

Upvotes: 1

Related Questions