如何用 MPI_File_open 替换 MPI 中的现有文件

Posted

技术标签:

【中文标题】如何用 MPI_File_open 替换 MPI 中的现有文件【英文标题】:How to replace an existing file in MPI with MPI_File_open 【发布时间】:2014-10-18 08:27:59 【问题描述】:

我正在阅读“使用 MPI-2”并尝试自己执行代码。我为 MPI_File_open 指定了 MPI_MODE_CREATE,但它实际上并没有创建新文件,而是覆盖了以前的同名文件。我碰巧在第一次运行更多进程,然后运行更少进程时发现了这一点。我的 MPI 版本是 openmpi 1.8.1。

这里是代码

#include <stdio.h>
#include <mpi.h>
#define BUFSIZE 4
int main(int argc, char **argv)

    int map[BUFSIZE], i, rank , size;
    char buf[BUFSIZE];
    MPI_File fh;
    MPI_Datatype filetype;
    MPI_Status status;
    MPI_Offset disp=0;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    for(i=0;i<BUFSIZE;i++)
    
//      buf[i]=size*i+rank+'0';
        buf[i]=size*i+rank+'A';
        map[i]=size*i+rank;
    
    MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
    MPI_Type_create_indexed_block(BUFSIZE, 1, map, MPI_CHAR, &filetype);
    MPI_Type_commit(&filetype);
    MPI_File_set_view(fh, disp, MPI_CHAR, filetype, "native", MPI_INFO_NULL);
    MPI_File_write_all(fh, buf, BUFSIZE, MPI_CHAR, &status);
    MPI_File_close(&fh);
    MPI_Type_free(&filetype);
    MPI_Finalize();
    return 0;

这是我运行 6 个进程时的文件内容

ABCDEFGHIJKLMNOPQRSTUVWX

然后我稍微修改了一下。替代

buf[i]=size*i+rank+'A';

buf[i]=size*i+rank+'0';

运行2个进程,文件如下

01234567IJKLMNOPQRSTUVWX

【问题讨论】:

【参考方案1】:

这是正确的行为 - MPI_MODE_CREATE "creates the file if it does not exist",如果这样做没有效果;正如文档所说,与相应的 POSIX O_CREAT 完全相同。

无论出于何种原因,没有一个 MPI_MODE_* 等效于 O_TRUNC 如果文件已经存在,它会破坏文件;为此,您必须使用MPI_MODE_CREATE|MPI_MODE_EXCL 打开,检查是否打开失败,如果是,请删除文件并重复(或者可能使用 MPI_MODE_DELETE_ON_CLOSE 打开它,关闭它,然后重新打开它)

双向编码:

#include <stdio.h>
#include <mpi.h>
#define BUFSIZE 4
int main(int argc, char **argv)

    int map[BUFSIZE], i, rank , size;
    char buf[BUFSIZE];
    MPI_File fh;
    MPI_Datatype filetype;
    MPI_Status status;
    MPI_Offset disp=0;

    if (argc != 3) 
        fprintf(stderr,"Usage: %s letters|numbers test|delete|none\n", argv[0]);
        exit(-1);
    

    int letters=0;
    if (!strcasecmp(argv[1],"letters"))
        letters = 1;

    int test=0;
    if (!strcasecmp(argv[2],"test"))
        test = 1;
    int delete = 0;
    if (!strcasecmp(argv[2],"delete"))
        delete = 1;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    for(i=0;i<BUFSIZE;i++)
    
        if (letters)
            buf[i]=size*i+rank+'A';
        else
            buf[i]=size*i+rank+'0';

        map[i]=size*i+rank;
    

    if (test) 
        int err = MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_EXCL|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
        if (err != MPI_SUCCESS)  
            if (rank == 0)
                MPI_File_delete("datafile4",MPI_INFO_NULL);
            MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_EXCL|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
        
     else if (delete) 
        MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_DELETE_ON_CLOSE|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
        MPI_File_close(&fh);
        MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_EXCL|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
     else 
        MPI_File_open(MPI_COMM_WORLD, "datafile4", MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
    

    MPI_Type_create_indexed_block(BUFSIZE, 1, map, MPI_CHAR, &filetype);
    MPI_Type_commit(&filetype);
    MPI_File_set_view(fh, disp, MPI_CHAR, filetype, "native", MPI_INFO_NULL);
    MPI_File_write_all(fh, buf, BUFSIZE, MPI_CHAR, &status);
    MPI_File_close(&fh);
    MPI_Type_free(&filetype);
    MPI_Finalize();
    return 0;

运行给出:

# just open CREATE|WRONLY, reproduce result above
$ mpirun -np 6 ./clobber letters none
$ cat datafile4
ABCDEFGHIJKLMNOPQRSTUVWX$
$ mpirun -np 2 ./clobber numbers none
$ cat datafile4
01234567IJKLMNOPQRSTUVWX$ 

# test for failed EXCL open, and if so, remove file:
$ mpirun -np 6 ./clobber letters test
$ cat datafile4
ABCDEFGHIJKLMNOPQRSTUVWX$
$ mpirun -np 2 ./clobber numbers test
$ cat datafile4
01234567$

# or always open delete-on-close, close, then re-open              
$ mpirun -np 6 ./clobber letters delete
$ cat datafile4
ABCDEFGHIJKLMNOPQRSTUVWX$
$ mpirun -np 2 ./clobber numbers delete
$ cat datafile4
01234567$

【讨论】:

感谢您的回答!顺便说一句,为什么输出文件中的字符串后面有一个 $ 符号? 是提示符;数据末尾没有换行符(这在 MPI-IO 的通常用例中很好)。我只是在这些行之后按 Enter 键,否则阅读它会很混乱。

以上是关于如何用 MPI_File_open 替换 MPI 中的现有文件的主要内容,如果未能解决你的问题,请参考以下文章

如何用加号“+”号替换空格

如何用 setKeepAliveTimeout 方法替换 UIRemoteNotificationTypeVoip 方法?

如何用 HttpClient 替换 WebClient?

如何用一个字符替换两个字符?

如何用 UISearchBar 替换导航栏?

如何用 CADisplayLink 替换 NSTimer?