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.
考虑以下简单程序,它将所有排名大于零的进程的排名写入文件:
#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.