当尝试将块写入文件时,我的块在我的进程中分布不均匀,可以使用具有良好偏移量的MPI_File_write_at
。由于此功能不是集体操作,因此效果很好。
例如:
#include <cstdio>
#include <cstdlib>
#include <string>
#include <mpi.h>
int main(int argc, char* argv[])
{
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int global = 7; // prime helps have unbalanced procs
int local = (global/size) + (global%size>rank?1:0);
int strsize = 5;
MPI_File fh;
MPI_File_open(MPI_COMM_WORLD, "output.txt", MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
for (int i=0; i<local; ++i)
{
size_t idx = i * size + rank;
std::string buffer = std::string(strsize, 'a' + idx);
size_t offset = buffer.size() * idx;
MPI_File_write_at(fh, offset, buffer.c_str(), buffer.size(), MPI_CHAR, MPI_STATUS_IGNORE);
}
MPI_File_close(&fh);
MPI_Finalize();
return 0;
}
然而,对于更复杂的写入,特别是在写入原始图像等多维数据时,可能需要使用MPI_Type_create_subarray
在文件上创建视图。但是,当使用简单MPI_File_write
的这个方法(假设是非集体的)时,我会遇到死锁。例如:
#include <cstdio>
#include <cstdlib>
#include <string>
#include <mpi.h>
int main(int argc, char* argv[])
{
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int global = 7; // prime helps have unbalanced procs
int local = (global/size) + (global%size>rank?1:0);
int strsize = 5;
MPI_File fh;
MPI_File_open(MPI_COMM_WORLD, "output.txt", MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &fh);
for (int i=0; i<local; ++i)
{
size_t idx = i * size + rank;
std::string buffer = std::string(strsize, 'a' + idx);
int dim = 2;
int gsizes[2] = { buffer.size(), global };
int lsizes[2] = { buffer.size(), 1 };
int offset[2] = { 0, idx };
MPI_Datatype filetype;
MPI_Type_create_subarray(dim, gsizes, lsizes, offset, MPI_ORDER_C, MPI_CHAR, &filetype);
MPI_Type_commit(&filetype);
MPI_File_set_view(fh, 0, MPI_CHAR, filetype, "native", MPI_INFO_NULL);
MPI_File_write(fh, buffer.c_str(), buffer.size(), MPI_CHAR, MPI_STATUS_IGNORE);
}
MPI_File_close(&fh);
MPI_Finalize();
return 0;
}
如何避免这样的代码锁定?请注意,真正的代码将真正使用MPI_Type_create_subarray
的多维功能,而不能只使用MPI_File_write_at
另外,我很难知道进程中的最大块数,因此我想避免执行reduce_all
然后在{{{{}}时循环使用空写入的最大块数。 1}}
答案 0 :(得分:0)
如果每个节点具有可变数量的块,则不使用MPI_REDUCE。您使用MPI_SCAN或MPI_EXSCAN:MPI IO Writing a file when offset is not known
MPI_File_set_view是集体的,所以如果每个处理器上的“本地”不同,你会发现自己从少于通信器中的所有处理器调用集体例程。如果您确实需要这样做,请使用MPI_COMM_SELF打开该文件。
MPI_SCAN方法意味着每个进程可以根据需要设置文件视图,然后blammo你可以调用集体MPI_File_write_at_all(即使某些进程没有工作 - 他们仍然需要参与)并利用任何聪明的优化你的MPI-IO实现提供。