在文件视图中使用非集体写入

时间:2015-03-16 00:05:33

标签: io mpi

当尝试将块写入文件时,我的块在我的进程中分布不均匀,可以使用具有良好偏移量的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}}

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实现提供。