【问题标题】:Storing values starting from a particular location in MPI_Recv从 MPI_Recv 中的特定位置开始存储值
【发布时间】:2021-07-05 13:40:48
【问题描述】:

我正在测试一个示例,我尝试将一个包含 4 个元素的数组从进程 0 发送到进程 1,并且我正在使用 MPI_Type_contiguous 这样做

这是相同的代码

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

int main( int argc, char *argv[] )
{
    MPI_Init(&argc, &argv);
    
    int myrank, size; //size will take care of number of processes 
         
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank) ;
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    //declaring the matrix
    double mat[4]={1,   2,  3,  4};
    int r=4;

    double snd_buf[r];
    double recv_buf[r];
    double buf[r];
    
    int position=0;
    
    MPI_Status status[r];
    
    MPI_Datatype type;
    MPI_Type_contiguous( r, MPI_DOUBLE, &type );
    MPI_Type_commit(&type);
             
    
    //sending the data
    if(myrank==0)
    {
       MPI_Send (&mat[0], r , type, 1 /*dest*/ , 100 /*tag*/ , MPI_COMM_WORLD);
    }   
    //receiving the data
    
    if(myrank==1)
    {
       MPI_Recv(recv_buf, r, type, 0 /*src*/ , 100 /*tag*/, MPI_COMM_WORLD,&status[0]);
    }
    //printing
    if(myrank==1)
    {
       for(int i=0;i<r;i++)
       {
           printf("%lf ",recv_buf[i]);
       }
       printf("\n");
    }
    MPI_Finalize();
    return 0;

}

正如我们所见,recv_buf 的大小与数组的大小相同。正在打印的输出是1 2 3 4

现在我要做的是,假设 recv_buf 大小为 10,我想存储从位置 6 到 9 的元素。为此我编写了这段代码,但令我惊讶的是它没有给出输出

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

int main( int argc, char *argv[] )
{
    MPI_Init(&argc, &argv);
    
    int myrank, size; //size will take care of number of processes 
         
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank) ;
    MPI_Comm_size(MPI_COMM_WORLD, &size);


    //declaring the matrix
    double mat[4]={1,   2,  3,  4};
    int r=4;
    double snd_buf[r];
    double recv_buf[10];   //declared it of size 10
    double buf[r];
    int position=0;
    MPI_Status status[r];
    
    MPI_Datatype type;
    MPI_Type_contiguous( r, MPI_DOUBLE, &type );
    MPI_Type_commit(&type);
    //packing and sending the data
    if(myrank==0)
    {
        MPI_Send (&mat[0], r , type, 1 /*dest*/ , 100 /*tag*/ , MPI_COMM_WORLD);
    }   
    //receiving the data
    if(myrank==1)
    {
        MPI_Recv(&recv_buf[6], r, type, 0 /*src*/ , 100 /*tag*/, MPI_COMM_WORLD,&status[0]);
    }
    //printing
    if(myrank==1)
    {
       for(int i=6;i<10;i++)
       {
           printf("%lf ",recv_buf[i]);
       }
       printf("\n");
    }
    MPI_Finalize();
    return 0;

}

我哪里出错了?

【问题讨论】:

    标签: c performance parallel-processing mpi hpc


    【解决方案1】:

    从这个SO Thread可以读到:

    MPI_Type_contiguous 用于创建一个新的数据类型,它是计数副本 现有的。这对于简化流程很有用 一起发送多个数据类型,因为您不需要跟踪 它们的组合大小(MPI_send 中的计数可以替换为 1)

    话虽如此,在您的MPI_Send 电话中:

    MPI_Send (&mat[0], r , type, 1 /*dest*/ , 100 /*tag*/ , MPI_COMM_WORLD);
    

    您不应该发送一个包含 'r' 类型的 'type' 元素的数组,而应该发送 1 个 'type' 类型的元素(等于 4 个双精度数)。 MPI_Type_contiguous 的目标之一是将 count 抽象为 1,而不是跟踪元素的数量。

    这同样适用于您的 recv 调用:

    MPI_Recv(&recv_buf[6], 1, type, 0 /*src*/ , 100 /*tag*/, MPI_COMM_WORLD,&status[0]);
    

    最后,您还应该相应地释放自定义类型:

    MPI_Type_free(&type);
    

    整个代码:

    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include "mpi.h"
    
    int main( int argc, char *argv[] )
    {
        MPI_Init(&argc, &argv);
        int myrank, size;
        MPI_Comm_rank(MPI_COMM_WORLD, &myrank) ;
        MPI_Comm_size(MPI_COMM_WORLD, &size);
        double mat[4]={1, 2, 3, 4};
        int r=4;
        double snd_buf[r];
        double recv_buf[10];
      
        MPI_Status status;
        MPI_Datatype type;
        MPI_Type_contiguous( r, MPI_DOUBLE, &type );
        MPI_Type_commit(&type);
                 
        if(myrank==0)
           MPI_Send (&mat[0], 1 , type, 1, 100, MPI_COMM_WORLD);
        else if(myrank==1)
        {
           MPI_Recv(&recv_buf[6], 1, type, 0, 100, MPI_COMM_WORLD, &status);
           for(int i=6;i<10;i++)
              printf("%lf ",recv_buf[i]);
          printf("\n");
       }
    
       MPI_Type_free(&type);        
       MPI_Finalize();
       return 0;
    }
    

    输出:

    1.000000 2.000000 3.000000 4.000000 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多