MPI_Alltoall是否正确使用?

时间:2013-12-15 18:58:39

标签: mpi mpich

我打算使用MPI集体通信来完成一项简单的任务,但对MPI来说是新手,我发现集体例程有些不直观。我有4个从站,每个从站必须读取一个唯一的字符串并将字符串发送给所有其他从站。

我查看了MPI_Bcast,MPI_Scatter和MPI_Alltoall。我选择了MPI_Alltoall,但程序结束时终止不良。

该计划是:

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);
 }

1 个答案:

答案 0 :(得分:1)

MPI_AlltoAll()将每个人的消息发送给每个人。如果每个进程发送20个char,则输入和输出缓冲区应远大于20。从您的代码开始,以下是MPI_AlltoAll()的工作原理:

#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;
}

看看你的问题,似乎MPI_AllGather()就是可以解决问题的函数......

“每个进程都会收到第j个进程发送的数据块,并将其放在缓冲区recvbuf的第j个块中。”

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

再见,

弗朗西斯