MPI_File_write_at :两次写入相同的结构会导致二进制文件中的数据块略有不同
MPI_File_write_at : Writing the same struct twice results in slightly different data blocks in binary file
我有以下简单的 MPI 代码:
#include <iostream>
#include <mpi.h>
int main() {
struct test {
int rank = 1;
double begin = 0.5;
double end = 0.5;
};
MPI_Init(NULL, NULL);
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_File fh;
MPI_Offset offset;
MPI_Status status;
MPI_Datatype TIMEDATA_DATATYPE;
// Create datatype
int blocklen[3] = {1,1,1};
MPI_Datatype type[3] = { MPI_INT, MPI_DOUBLE, MPI_DOUBLE };
MPI_Aint disp[3] = {0, 4, 12};
MPI_Type_create_struct(3, blocklen, disp, type, &TIMEDATA_DATATYPE);
MPI_Type_commit(&TIMEDATA_DATATYPE);
// Open file
offset = 20*world_rank;
MPI_File_open(MPI_COMM_WORLD, "test.bin", MPI_MODE_CREATE | MPI_MODE_WRONLY,
MPI_INFO_NULL, &fh);
// Write to file
test t1, t2;
MPI_File_write_at(fh, offset, &t1, 1, TIMEDATA_DATATYPE, &status);
MPI_File_write_at(fh, offset, &t2, 1, TIMEDATA_DATATYPE, &status);
// Close file
MPI_File_close(&fh);
MPI_Finalize();
return 0;
}
运行 并用
编译
mpic++ Test.cpp
mpirun -n 2 a.out
所以在上面的代码中,我基本上想写入同一个文件两次。每次来自不同的过程。数据是格式为 int、double、double 的结构,所以 4+8+8=20 字节的数据。我们有两个该结构的对象,但都使用相同的值进行了初始化。所以我们将两个 20 字节的数据块写入文件 test.bin,我希望在二进制表示中看到这种“对称性”,但我得到:(我提供了两个不同的 cli 工具的两个不同的输出。)
$ xxd test.bin
00000000: 0100 0000 fe7f 0000 0000 0000 0000 e03f ...............?
00000010: 0000 e03f 0100 0000 ff7f 0000 0000 0000 ................
00000020: 0000 e03f 0000 0000 ...?....
$ hexdump test.bin
0000000 0001 0000 7ffe 0000 0000 0000 0000 3fe0
0000010 0000 0000 0001 0000 7fff 0000 0000 0000
0000020 0000 3fe0 0000 0000
0000028
现在,如果我们查看 xxd 的输出,我们会看到:
前 20 个字节:
- 整数:0100 0000
- 双:fe7f 0000 0000 0000
- 双:0000 e03f 0000 e03f
后 20 个字节:
- 整数:0100 0000
- 双:ff7f 0000 0000 0000
- 双:0000 e03f 0000 0000
现在基本上,我不完全确定为什么这里的双打不同。
而不是:
MPI_Aint disp[3] = {0, 4, 12};
执行以下操作:
disp[0] = offsetof(test, rank);
disp[1] = offsetof(test, begin);
disp[2] = offsetof(test, end);
不要忘记包含“#include <stddef.h>
”,并调整偏移量(即 offset = sizeof(test) * world_rank;
)
不要尝试手动硬编码偏移量,最好使用 <stddef.h>
中的 offsetof
来为您计算。无法保证结构内部使用的填充将匹配您在数组中为位移硬编码的值(即 disp
)
Structure padding is a concept in C that adds the one or more empty bytes between the memory addresses to align the data in memory. (source). To a better understanding of padding look into this SO thread
我有以下简单的 MPI 代码:
#include <iostream>
#include <mpi.h>
int main() {
struct test {
int rank = 1;
double begin = 0.5;
double end = 0.5;
};
MPI_Init(NULL, NULL);
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_File fh;
MPI_Offset offset;
MPI_Status status;
MPI_Datatype TIMEDATA_DATATYPE;
// Create datatype
int blocklen[3] = {1,1,1};
MPI_Datatype type[3] = { MPI_INT, MPI_DOUBLE, MPI_DOUBLE };
MPI_Aint disp[3] = {0, 4, 12};
MPI_Type_create_struct(3, blocklen, disp, type, &TIMEDATA_DATATYPE);
MPI_Type_commit(&TIMEDATA_DATATYPE);
// Open file
offset = 20*world_rank;
MPI_File_open(MPI_COMM_WORLD, "test.bin", MPI_MODE_CREATE | MPI_MODE_WRONLY,
MPI_INFO_NULL, &fh);
// Write to file
test t1, t2;
MPI_File_write_at(fh, offset, &t1, 1, TIMEDATA_DATATYPE, &status);
MPI_File_write_at(fh, offset, &t2, 1, TIMEDATA_DATATYPE, &status);
// Close file
MPI_File_close(&fh);
MPI_Finalize();
return 0;
}
运行 并用
编译mpic++ Test.cpp
mpirun -n 2 a.out
所以在上面的代码中,我基本上想写入同一个文件两次。每次来自不同的过程。数据是格式为 int、double、double 的结构,所以 4+8+8=20 字节的数据。我们有两个该结构的对象,但都使用相同的值进行了初始化。所以我们将两个 20 字节的数据块写入文件 test.bin,我希望在二进制表示中看到这种“对称性”,但我得到:(我提供了两个不同的 cli 工具的两个不同的输出。)
$ xxd test.bin
00000000: 0100 0000 fe7f 0000 0000 0000 0000 e03f ...............?
00000010: 0000 e03f 0100 0000 ff7f 0000 0000 0000 ................
00000020: 0000 e03f 0000 0000 ...?....
$ hexdump test.bin
0000000 0001 0000 7ffe 0000 0000 0000 0000 3fe0
0000010 0000 0000 0001 0000 7fff 0000 0000 0000
0000020 0000 3fe0 0000 0000
0000028
现在,如果我们查看 xxd 的输出,我们会看到:
前 20 个字节:
- 整数:0100 0000
- 双:fe7f 0000 0000 0000
- 双:0000 e03f 0000 e03f
后 20 个字节:
- 整数:0100 0000
- 双:ff7f 0000 0000 0000
- 双:0000 e03f 0000 0000
现在基本上,我不完全确定为什么这里的双打不同。
而不是:
MPI_Aint disp[3] = {0, 4, 12};
执行以下操作:
disp[0] = offsetof(test, rank);
disp[1] = offsetof(test, begin);
disp[2] = offsetof(test, end);
不要忘记包含“#include <stddef.h>
”,并调整偏移量(即 offset = sizeof(test) * world_rank;
)
不要尝试手动硬编码偏移量,最好使用 <stddef.h>
中的 offsetof
来为您计算。无法保证结构内部使用的填充将匹配您在数组中为位移硬编码的值(即 disp
)
Structure padding is a concept in C that adds the one or more empty bytes between the memory addresses to align the data in memory. (source). To a better understanding of padding look into this SO thread