MPI_File_write_at() 是否用零初始化文件?

Does MPI_File_write_at() initialize the file with zeros?

考虑以下简单程序,它将所有排名大于零的进程的排名写入文件:

#include <mpi.h>

int main() {
    MPI_Init(NULL, NULL);

    int world_rank, world_size;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    MPI_Offset offset;
    MPI_Status status;
    MPI_File fh;

    MPI_File_open(MPI_COMM_WORLD, "myfile", MPI_MODE_CREATE | MPI_MODE_WRONLY,
            MPI_INFO_NULL, &fh);
    
    offset = world_rank * sizeof(int);

    if (world_rank > 0) {
        MPI_File_write_at(fh, offset, &world_rank, 1, MPI_INT, &status);
    }

    MPI_File_close(&fh);

    MPI_Finalize();

    return 0;
}

我们在 4 个进程上编译并运行它

mpic++ main.cpp
mpirun --oversubscribe -n 4 a.out 

我们用hexdump -C myfile

检查写入的文件
00000000  00 00 00 00 01 00 00 00  02 00 00 00 03 00 00 00  |................|
00000010

现在,我从未对第一个整数(即前 4 个字节)进行写调用,但它们为零。

我可以确定那些总是零吗?

MPI_File_write_at 将数据写入文件为 binary data。然后,当您 运行 命令 hexdump -C myfile 时,该命令将相应地显示数据,第一个 4 bytes 偏移量 。那些第一个字节不是二进制数据 per si 的一部分,而是由 hexdump -C myfile 出于可读性目的添加的。

十六进制00000010表示二进制10000,十进制表示16。如果您查看第一行,忽略前 4 个字节,则:

  4 bytes   4 bytes      4 bytes      4 bytes       4 bytes 
00000000 | 00 00 00 00  01 00 00 00  02 00 00 00   03 00 00 00
00000010 |

您有 16 (4x4) 个字节,因此为什么下一行以 00000010.

开头

Can I be sure that those are always zero?

就标准而言,我没有在那里找到明确说明如果跳过文件开头 offset > 0,MPI 实现将填补 空白 带零。例如,对于我正在使用的 MPI 版本(Open MPI 1.8.8),如果我将您的代码修改为:

 if (world_rank == 3) {
    MPI_File_write_at(fh, offset, &world_rank, 1, MPI_INT, &status);
}

我从 hexdump -C myfile 得到以下输出:

00000000  00 00 00 00 00 00 00 00  00 00 00 00 03 00 00 00  |................|
00000010

所以对于我正在使用的 MPI 版本,显然对于你的版本,它初始化为零。

尽管如此,除非可以找到可靠的来源(我没有设法找到)明确说明在您的情况下前 4 个字节将始终为零,否则我建议不要对此做出任何假设看待。尽管如此,无论如何,不​​应该关心文件内容部分不是由进程写入的。

编辑: 来自“Open MPI 邮件列表”的说明:

In general, the contents of a file written by the MPI IO interface are going to be implementation-specific.