如何使用 MPI I/O 将多维结构数组写入磁盘?
How to write a multi-dimensional array of structs to disk using MPI I/O?
我正在尝试使用 MPI I/O 将一组复数写入磁盘。特别是,我正在尝试使用函数 MPI_File_set_view
来实现这一点,以便我可以将我的代码推广到更高的维度。请在下面查看我的尝试。
struct complex
{
float real=0;
float imag=0;
};
int main(int argc, char* argv[])
{
/* Initialise MPI parallel branch */
int id, nprocs;
MPI_Init(&argc, &argv);
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Comm_rank(comm, &id);
MPI_Comm_size(comm, &nprocs);
/* Create a datatype to represent structs of complex numbers */
MPI_Datatype MPI_Complex;
const int lengths[2] = { 1, 1 };
MPI_Datatype types[2] = { MPI_FLOAT, MPI_FLOAT };
MPI_Aint displacements[2], base_address;
complex dummy_complex;
MPI_Get_address(&dummy_complex, &base_address);
MPI_Get_address(&dummy_complex.real, &displacements[0]);
MPI_Get_address(&dummy_complex.imag, &displacements[1]);
displacements[0] = MPI_Aint_diff(displacements[0], base_address);
displacements[1] = MPI_Aint_diff(displacements[1], base_address);
MPI_Type_create_struct(2, lengths, displacements, types, &MPI_Complex);
MPI_Type_commit(&MPI_Complex);
/* Create a datatype to represent local arrays as subarrays of a global array */
MPI_Datatype MPI_Complex_array;
const int global_size[1] = { 100 };
const int local_size[1] = { (id < nprocs-1 ? 100/nprocs : 100/nprocs + 100%nprocs) };
const int glo_coord_start[1] = { id * (100/nprocs) };
MPI_Type_create_subarray(1, global_size, local_size, glo_coord_start, MPI_ORDER_C,
MPI_Complex, &MPI_Complex_array);
MPI_Type_commit(&MPI_Complex_array);
/* Define and populate an array of complex numbers */
complex *z = (complex*) malloc( sizeof(complex) * local_size[0] );
/* ...other stuff here... */
/* Write local data out to disk concurrently */
MPI_Offset offset = 0;
MPI_File file;
MPI_File_open(comm, "complex_nums.dat", MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &file);
MPI_File_set_view(file, offset, MPI_Complex, MPI_Complex_array, "external", MPI_INFO_NULL);
MPI_File_write_all(file, z, local_size[0], MPI_Complex, MPI_STATUS_IGNORE);
MPI_File_close(&file);
/* ...more stuff here... */
}
但是,使用上面的代码,只有来自标记为 id = 0
的进程的本地数据被保存到磁盘。我做错了什么,我该如何解决?谢谢。
N.B. 请注意,对于这个一维示例,我可以通过放弃 MPI_File_set_view
并使用像 MPI_File_write_at_all
。尽管如此,我还没有解决根本问题,因为我仍然不明白为什么上面的代码不起作用,我想要一个可以推广到多维数组的解决方案。在这方面非常感谢您的帮助。谢谢。
当 MPI-IO 子例程失败时,默认行为是 不 中止。
因此,除非您更改此默认行为,否则您应该始终测试 MPI-IO 子例程返回的错误代码。
在您的情况下,MPI_File_set_view()
失败,因为 external
不是有效的数据表示形式。
我想这是一个错字,你的意思是 external32
.
我正在尝试使用 MPI I/O 将一组复数写入磁盘。特别是,我正在尝试使用函数 MPI_File_set_view
来实现这一点,以便我可以将我的代码推广到更高的维度。请在下面查看我的尝试。
struct complex
{
float real=0;
float imag=0;
};
int main(int argc, char* argv[])
{
/* Initialise MPI parallel branch */
int id, nprocs;
MPI_Init(&argc, &argv);
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Comm_rank(comm, &id);
MPI_Comm_size(comm, &nprocs);
/* Create a datatype to represent structs of complex numbers */
MPI_Datatype MPI_Complex;
const int lengths[2] = { 1, 1 };
MPI_Datatype types[2] = { MPI_FLOAT, MPI_FLOAT };
MPI_Aint displacements[2], base_address;
complex dummy_complex;
MPI_Get_address(&dummy_complex, &base_address);
MPI_Get_address(&dummy_complex.real, &displacements[0]);
MPI_Get_address(&dummy_complex.imag, &displacements[1]);
displacements[0] = MPI_Aint_diff(displacements[0], base_address);
displacements[1] = MPI_Aint_diff(displacements[1], base_address);
MPI_Type_create_struct(2, lengths, displacements, types, &MPI_Complex);
MPI_Type_commit(&MPI_Complex);
/* Create a datatype to represent local arrays as subarrays of a global array */
MPI_Datatype MPI_Complex_array;
const int global_size[1] = { 100 };
const int local_size[1] = { (id < nprocs-1 ? 100/nprocs : 100/nprocs + 100%nprocs) };
const int glo_coord_start[1] = { id * (100/nprocs) };
MPI_Type_create_subarray(1, global_size, local_size, glo_coord_start, MPI_ORDER_C,
MPI_Complex, &MPI_Complex_array);
MPI_Type_commit(&MPI_Complex_array);
/* Define and populate an array of complex numbers */
complex *z = (complex*) malloc( sizeof(complex) * local_size[0] );
/* ...other stuff here... */
/* Write local data out to disk concurrently */
MPI_Offset offset = 0;
MPI_File file;
MPI_File_open(comm, "complex_nums.dat", MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &file);
MPI_File_set_view(file, offset, MPI_Complex, MPI_Complex_array, "external", MPI_INFO_NULL);
MPI_File_write_all(file, z, local_size[0], MPI_Complex, MPI_STATUS_IGNORE);
MPI_File_close(&file);
/* ...more stuff here... */
}
但是,使用上面的代码,只有来自标记为 id = 0
的进程的本地数据被保存到磁盘。我做错了什么,我该如何解决?谢谢。
N.B. 请注意,对于这个一维示例,我可以通过放弃 MPI_File_set_view
并使用像 MPI_File_write_at_all
。尽管如此,我还没有解决根本问题,因为我仍然不明白为什么上面的代码不起作用,我想要一个可以推广到多维数组的解决方案。在这方面非常感谢您的帮助。谢谢。
当 MPI-IO 子例程失败时,默认行为是 不 中止。 因此,除非您更改此默认行为,否则您应该始终测试 MPI-IO 子例程返回的错误代码。
在您的情况下,MPI_File_set_view()
失败,因为 external
不是有效的数据表示形式。
我想这是一个错字,你的意思是 external32
.