首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >MPI-IO以非连续模式写入文件

MPI-IO以非连续模式写入文件
EN

Stack Overflow用户
提问于 2019-03-19 15:54:03
回答 1查看 338关注 0票数 2

我在编写并行MPI I/O程序时遇到了问题,该程序将以特定的模式写入。我能够让进程0写入整数0-9,进程1写入整数10-19,进程2写入整数20-29,等等。

代码语言:javascript
复制
proc 0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
proc 1: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
proc 2: [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
proc 3: [30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
result: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20

下面是实现这一点的代码:

代码语言:javascript
复制
int main(int argc, char *argv[]) {
    // MPI_Finalize();

    int i, rank, size, offset;
    MPI_File fhw;
    MPI_Status status;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    int N = size * 10;
    int buf[N];
    for ( i = 0; i < N; ++i ) {
        buf[i] = rank * 10 + i;
    }

    offset = rank * (N/size) * sizeof(int);
    MPI_File_open(MPI_COMM_WORLD, "datafile", MPI_MODE_CREATE|MPI_MODE_WRONLY,
                MPI_INFO_NULL, &fhw);
    printf("(%d) Writing to file...\n", rank);
    printf("\nRank: (%d), Offset: %d\n", rank, offset);
    MPI_File_write_at(fhw, offset, buf, (N/size), MPI_INT, &status);
    MPI_File_close(&fhw);

    MPI_Finalize();

    return 0;
}

但是,我对如何产生以下结果感到困惑:

代码语言:javascript
复制
// starting out:
proc 0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
proc 1: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
proc 2: [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
proc 3: [30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
// proc 0 writes first 2 slots, then proc 1 writes next 2, etc.
result: [0, 1, 10, 11, 20, 21, 30, 31, 2, 3, 12, 13, 22, 23, ..., 8, 9, 18, 19, 28, 29, 38, 29]

在过去的几个小时里,我在网上查找示例和文档时尝试使用MPI_File_set_view,但无法正常工作。有人能给我指引正确的方向吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-20 08:12:55

正如您所了解的那样,您需要设置一个视图...

然后是代码中的一些小错误: 1)每个进程真的需要大于10的buf吗? 2) MPI_File_wite_at中的偏移量是以字节为单位的,但以元素的数量为单位(就视图的元素大小而言)。

因此,要设置视图,只需要一行代码:

代码语言:javascript
复制
#include "mpi.h"
#include <cstdio>

int main(int argc, char *argv[]) {
    // MPI_Finalize();                                                                                                      

    int i, rank, size, offset;
    MPI_File fhw;
    MPI_Status status;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    int N = 10; 
    int buf[N];
    for ( i = 0; i < N; ++i ) {
        buf[i] = rank * 10 + i;
    }

    offset = 10*rank;
    MPI_File_open(MPI_COMM_WORLD,"datafile",MPI_MODE_CREATE|MPI_MODE_WRONLY,
                MPI_INFO_NULL, &fhw);
    printf("(%d) Writing to file...\n", rank);
    printf("\nRank: (%d), Offset: %d\n", rank, offset);
    MPI_File_set_view( fhw,0,MPI_INT, MPI_INT, "native", MPI_INFO_NULL ) ;
    MPI_File_write_at(fhw, offset, buf, N, MPI_INT, &status);
    MPI_File_close(&fhw);

    MPI_Finalize();

    return 0;
}

然后,您可以使用MPI_File_write :-)执行完全相同的操作,并为每个进程设置不同的视图,只需替换视图并编写:

代码语言:javascript
复制
MPI_File_set_view(fhw,offset*sizeof(int),MPI_INT,MPI_INT,
                        "native",MPI_INFO_NULL ) ;
MPI_File_write_at(fhw, 0, buf, N, MPI_INT, &status);

或者简单地说:

代码语言:javascript
复制
MPI_File_set_view(fhw,offset*sizeof(int),MPI_INT,MPI_INT,
                        "native",MPI_INFO_NULL ) ;
MPI_File_write(fhw, buf, N, MPI_INT, &status);

注意:在视图中,偏移量是以字节为单位的,而在写入中,它是以视图元素的大小为单位的……可能有点困惑:-)

然后是魔术:

你需要写2个整数大小为2*的块,你有N/2个这样的块,所以你创建一个类型:

代码语言:javascript
复制
MPI_Type_vector(N/2, 2 , size*2,  MPI_INT, &ftype);
MPI_Type_commit(&ftype);

并设置视图:

代码语言:javascript
复制
MPI_File_set_view( fhw, rank*2*sizeof(int), MPI_INT, ftype, "native", MPI_INFO_NULL ) ;

然后你必须认为在内存中你有一个连续的数据存储,为了适合你的视图,它必须是N/2个块的东西,所以你创建了一个数据类型:

代码语言:javascript
复制
MPI_Type_contiguous(2,   MPI_INT, &mtype);
MPI_Type_commit(&mtype);

然后你就可以开始写了:

代码语言:javascript
复制
MPI_File_write(fhw, buf, N/2, mtype, &status);
MPI_File_close(&fhw);

因此,整个代码将变成:

代码语言:javascript
复制
#include "mpi.h"
#include <cstdio>

int main(int argc, char *argv[]) {
    int i, rank, size, offset;
    MPI_File fhw;
    MPI_Status status;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    int N = 10; //need to be even!!!
    int buf[N];
    for ( i = 0; i < N; ++i ) {
        buf[i] = rank * N + i;
    }

    offset = 10*rank;
    MPI_File_open(MPI_COMM_WORLD, "datafile", MPI_MODE_CREATE|MPI_MODE_WRONLY,
                    MPI_INFO_NULL, &fhw);
    printf("(%d) Writing to file...\n", rank);
    printf("\nRank: (%d), Offset: %d\n", rank, offset);

    MPI_Datatype ftype,mtype;
    MPI_Type_vector(N/2, 2 , size*2,  MPI_INT, &ftype);
    MPI_Type_commit(&ftype);

    MPI_File_set_view( fhw, rank*2*sizeof(int), MPI_INT, ftype,
                         "native",MPI_INFO_NULL ) ;

    MPI_Type_contiguous(2,   MPI_INT, &mtype);
    MPI_Type_commit(&mtype);

    MPI_File_write(fhw, buf, N/2, mtype, &status);
    MPI_File_close(&fhw);

    MPI_Finalize();
    return 0;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55235929

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档