MPI_Scatter用法

时间:2016-05-13 16:15:27

标签: c mpi

我正在尝试修改我的程序,以便代码看起来更好。现在我正在使用MPI_Send和MPI_Recv,但我试图让它与MPI_Scatter一起使用。我有一个名为All_vals的数组,我试图将Sub_arr_len相等的部分发送给每个奴隶。 因此,在我第一次找到我应发送给每个奴隶的值的数量后,我必须发送并接收值的数量,然后发送并接收值。我试图将那些send / recv更改为MPI_Scatter,并考虑这样的情况:值的数量不能被分成相等的部分,就像我有20个数字,但我有3个进程。所以奴隶应该有20/3 = 6的值,但是主人应该剩下20-2 * 6 = 8 这是我要编辑的部分:

int master(int argc, char **argv){
...
for (i=0; i<ntasks; i++)
    {
    Sub_arr_len[i]=Num_vals/ntasks;      //Finding the number of values I should send to every process             
    printf("\n\nIn range %d there are %d\n\n",i,Sub_arr_len[i]);
    }

    for(i=1;i<ntasks;i++) {
        Sub_len = Sub_arr_len[i];
        MPI_Isend(&Sub_len,1, MPI_INTEGER, i, i, MPI_COMM_WORLD, &request);
        MPI_Wait(&request, &status);
        Sub_arr_start += Sub_arr_len[i-1];
        printf("\r\nSub_arr_start = %d ",Sub_arr_start);
        MPI_Isend(&All_vals[Sub_arr_start],Sub_len, MPI_INTEGER, i, i, MPI_COMM_WORLD, &request);
        MPI_Wait(&request, &status);
    }
...
}  


int slave(){
MPI_Irecv(&Sub_arr_len, 1, MPI_INTEGER, 0, myrank, MPI_COMM_WORLD, &request);
    MPI_Wait(&request,&status);
    printf("\r\nSLAVE:Sub_arr_len = %d\n\n",Sub_arr_len);
    All_vals = (int*) malloc(Sub_arr_len * sizeof(MPI_INTEGER));

    MPI_Irecv(&All_vals[0], Sub_arr_len, MPI_INTEGER, 0, myrank, MPI_COMM_WORLD, &request);
    MPI_Wait(&request,&status);
}

我正在尝试制作分散的东西,但是我做错了什么,所以如果有人帮我构建它,我会很高兴。

1 个答案:

答案 0 :(得分:0)

对于MPI_Scatter,所涉及的每个等级必须接收相同数量的元素,包括根。通常,根进程是分散操作中的正常参与者并且“接收”他自己的块。这意味着您还需要为根进程指定接收缓冲区。您基本上有以下选项:

  1. 在根目录上使用MPI_IN_PLACE作为recvbuf,通过这样做,root将不会向自身发送任何内容。将其与从根分散原始sendbuffer的尾部相结合,使得该“尾部”具有可被进程数量整除的多个元素。例如。对于20个元素散布&All_vals[2],它有18个元素,每个元素6个(包括root)。然后根可以使用All_vals [0-7]。
  2. 使用一些不执行任何操作的元素填充sendbuffer,使其可以被进程数整除。
  3. 使用MPI_Scatterv向每个等级发送不等数量的元素。 Here is a good example如何正确设置发送计数和置换
  4. 最后一个选项有一些明显的优势。它在进程之间创建了最小的负载不平衡,并允许所有进程使用相同的代码。如果适用,第二个选项非常简单,并且仍然具有良好的负载平衡。