使用自定义MPI_Datatype作为文件类型

时间:2016-02-22 15:33:53

标签: c++ mpi

我很想知道MPI_File_set_view是如何工作的,特别是第四个参数让我感到困惑。

  

int MPI_File_set_view(MPI_File fh,MPI_Offset disp,MPI_Datatype etype,MPI_Datatype filetype,const char * datarep,MPI_Info info)

假设我有n个线程,每个线程都有一个长度为10的char数组,名为" v",此数组的所有条目都等于线程ID。所以

  

thread0:v = {0,0,0,0,0,0,0,0,0,0}

     

thread1:v = {1,1,1,1,1,1,1,1,1,1}

     

thread2:v = {2,2,2,2,2,2,2,2,2,2}

     

...

现在我想按以下顺序编写一个包含这些数组值的二进制文件:

  

file = thread0.v [0],thread1.v [0],thread2.v [0],...,thread0.v [1],thread1.v [1],thread2.v [1] ,...,thread0.v [2],thread1.v [2],thread2.v [2],...

据我所知,我必须为filetype参数构建一个MPI_Datatype,其大小为[sizeof(char)* n],其中有一个" hole"在MPI_Char数据之前的大小[sizeof(char)* threadID]和另一个" hole"在数据之后的大小[sizeof(char)*(n-threadID-1)]我认为这是我犯错的部分。

我的代码如下所示:

#include<iostream>
#include<mpi.h>

using namespace std;


int main(int argc, char* argv[]){
    int myId;
    int numProcs;
    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&numProcs);
    MPI_Comm_rank(MPI_COMM_WORLD,&myId);

    int size=100;
    char v[size];
    for(int i=0;i<size;i++){
        v[i]=myId;
    }

    int blocklen[numProcs];
    MPI_Aint disp[numProcs];
    MPI_Datatype type[numProcs];
    for(int i=0;i<numProcs;i++){
        blocklen[i]=1;
        disp[i]=sizeof(char)*myId;
        type[i]=MPI_CHAR;
    }

    MPI_Datatype mytype;
    MPI_Type_create_struct(numProcs, blocklen, disp, type, &mytype);
    MPI_Type_commit(&mytype);

    MPI_File fh;
    MPI_File_open(MPI_COMM_WORLD, "binfile", MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &fh);
    MPI_File_set_view(fh, 0, MPI_BYTE, mytype, "native", MPI_INFO_NULL);
    MPI_File_write(fh, v, size, MPI_BYTE, MPI_STATUS_IGNORE);

    MPI_File_close(&fh);
    MPI_Finalize();
    return 0;
}

当我hexdump文件&#34; binfile&#34;我得到了这个(使用4个线程):

  

$ hd binfile

     

00000000 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 | ................ |

     

00000010 01 01 01 01 01 01 01 01 01 01 02 03 | ............ |

     

0000001c

我在哪里犯了错误?

1 个答案:

答案 0 :(得分:0)

感谢Hristo Iliev的评论,我能够解决我的问题。 功能

  

int MPI_Type_create_subarray(int ndims,const int array_of_sizes [],   const int array_of_subsizes [],const int array_of_starts [],int order,   MPI_Datatype oldtype,MPI_Datatype * newtype)

诀窍。 array_of_sizes定义新数据类型的大小。 array_of_subsizes定义零件的大小,它不是“孔”的一部分,array_of_starts定义“非孔”零件的开始位置。

对于任何感兴趣的人,这是工作代码:

#include<iostream>
#include<mpi.h>

using namespace std;


int main(int argc, char* argv[]){
    int myId;
    int numProcs;
    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&numProcs);
    MPI_Comm_rank(MPI_COMM_WORLD,&myId);

    int size=100;
    char v[size];
    for(int i=0;i<size;i++){
        v[i]=myId;
    }

    int array_of_sizes[1];
    array_of_sizes[0]=numProcs;
    int array_of_subsizes[1];
    array_of_subsizes[0]=1;
    int array_of_starts[1];
    array_of_starts[0]=myId;


    MPI_Datatype mytype;
    MPI_Type_create_subarray(1,array_of_sizes, array_of_subsizes, array_of_starts, MPI_ORDER_C, MPI_BYTE, &mytype);
    MPI_Type_commit(&mytype);

    MPI_File fh;
    MPI_File_open(MPI_COMM_WORLD, "binfile", MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &fh);
    MPI_File_set_view(fh, 0, MPI_BYTE, mytype, "native", MPI_INFO_NULL);
    MPI_File_write(fh, v, size, MPI_BYTE, MPI_STATUS_IGNORE);

    MPI_File_close(&fh);
    MPI_Finalize();
    return 0;
}