MPI 自定义通用结构和传输

来源:互联网 发布:数据仿真模型 编辑:程序博客网 时间:2024/06/15 11:50

MPI 自定义通用结构和传输  

这些天写了一个MPI程序,却总是出错,在百度和谷歌上也找不到对出错结果的解释,烦恼之极。后来想了一个笨办法,依次在每一个Send()和Recv()语句之后加上MPI_Abort()语句,逐次运行查看,终于发现错误所在。原来是自定义的结构体传输发生错误。找了一份正确的代码,学习之后写了一个试验程序,运行成功。

试验程序张贴如下:

#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
void main(int argc,char *argv[])
{
 int size,rank;
 MPI_Status status;
 struct var {
  int i,n,size,rank;
  float mytmp,ml,mr,mlen,l,len;
 } ;
 struct var b;
 //下面构建一个自定义变量,利用MPI函数构建,若用C语言的结构体
 //则在Send和Recv是不能识别数据类型
 MPI_Datatype myvar;
 MPI_Datatype old_types[2];
 MPI_Aint indices[2]; 
 //指定每个块中的变量个数,这里只有2个块,其中包含4个MPI_INT,6个MPI_FLOAT
 int blocklens[2];
 MPI_Init(&argc,&argv);
 blocklens[0]=4;
 blocklens[1]=6;
 //指定原来旧的数据类型
 old_types[0]=MPI_INT;
 old_types[1]=MPI_FLOAT;  
 //指定每个块中变量的偏移量,需要依靠一个结构体的实例,这里是b。
 MPI_Address(&b,&indices[0]);
 MPI_Address(&b.mytmp,&indices[1]);
 indices[1] -= indices[0];
 indices[0]=0;
 //看来indices[0]也可以一开始就应当赋值为0
 

 //创建新数据于var之中
 MPI_Type_struct(2,blocklens,indices,old_types,&myvar);
 //注册新数据
 MPI_Type_commit(&myvar);

 MPI_Comm_size(MPI_COMM_WORLD,&size);
 MPI_Comm_rank(MPI_COMM_WORLD,&rank);

 if(rank == 0)
 {
  struct var a={0};
  a.i=100;
  fprintf(stdout,"before sending the value i is %d\n",a.i);
  fflush(stdout);
  MPI_Send(&a,1,myvar,1,1,MPI_COMM_WORLD);
  fprintf(stdout,"after sending the value i is %d\n",a.i);
  fflush(stdout);
 }
 else if(rank == 1)
 { struct var t={0};
  fprintf(stdout,"before receiving the value i is %d\n",t.i);
  fflush(stdout);
  MPI_Recv(&t,1,myvar,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
  fprintf(stdout,"after receiving the value i is %d\n",t.i);
  fflush(stdout);
 }

 MPI_Finalize();
}

 

需要加强的还有对于自定义数据的偏移量进行理解。若在程序中适当位置加入如下语句:

printf("the value of indices[1] is %d\n",indices[1]); 则输出结果为16,看来是4个int的长度。


原创粉丝点击