MPI二进制文件I / O基本功能和性能问题

时间:2017-06-23 01:30:21

标签: c++ for-loop mpi

TLDR

当我并行创建文件时,循环挂起。为什么? (参见下面的代码)另外,写入多个二进制文件(由迭代变量确定的指针和偏移量)的安全/有效方法是什么?

背景和问题

我希望我的代码可以执行以下操作:

(1)所有进程读取包含双精度矩阵的单个二进制文件 - >已经使用MPI_File_read_at()

实现了这一点

(2)对于输入数据的每个“列”,使用每个“行”中的数字执行计算,并将每列的数据保存到其自己的二进制输出文件中(“File0.bin” - >第0列)

(3)为了使用户能够指定任意数量的进程,我使用简单的索引将矩阵视为一个长(行)X(cols)向量,并按进程数分割该向量。每个进程获取(行)X(cols)/ tot_proc条目来处理......使用这种方法,列不会被每个进程整齐划分,因此,每个进程都需要访问与其对应的任何文件和,使用适当的偏移量,写入正确文件的正确部分。目前,生成的文件将被分段并不重要。

当我朝着这个目标努力时,我编写了一个简短的程序来在循环中创建二进制文件,但循环在最后一次迭代时挂起(13个文件分为4个进程)。要创建的文件数=(行)。

问题1 为什么这段代码会在循环结束时挂起?在我的4个进程的玩具示例中,id_proc 1-3有3个要创建的文件,而id_proc 0(根进程)有4个要创建的文件。当根进程尝试使其成为第4个文件时,循环挂起。注意:我正在使用mpic ++在运行Ubuntu的笔记本电脑上编译它。

问题2 最后我会添加第二个for循环,就像你在下面看到的一样,除了在这个循环中,进程必须写入已经创建的二进制文件的相应部分。我计划使用MPI_File_write_at()来执行此操作,但我还读过使用MPI_File_set_size()来静态调整文件大小,然后,每个进程都应该使用MPI_File_set_view()来拥有自己的文件视图。所以,我的问题是,为了实现这一点,我应该做以下几点吗?

(循环1)MPI_File_open(...,MPI_WRONLY | MPI_CREATE,...),MPI_File_set_size(),MPI_File_close()

(循环2)MPI_File_open(...,MPI_WRONLY,...),MPI_File_set_view(),MPI_File_write_at(),MPI_File_close()

....循环2似乎会因每次迭代打开和关闭文件而变慢,但我事先并不知道用户将提供多少输入数据,也不知道用户将提供多少进程。例如,进程N可能需要写入文件1的末尾,文件2的中间和文件8的结尾。原则上,所有这些都可以通过偏移来处理。我不知道的是MPI是否允许这种灵活性。

代码尝试并行创建多个文件

#include <iostream>
#include <cstdlib>
#include <stdio.h>
#include <vector>
#include <fstream>
#include <string>
#include <sstream>
#include <cmath>
#include <sys/types.h>
#include <sys/stat.h>
#include <mpi.h>

using namespace std;

int main(int argc, char** argv)
{
    //Variable declarations
    string oname;
    stringstream temp;
    int rows = 13, cols = 7, sz_dbl = sizeof(double);
    //each binary file will eventually have 7*sz_dbl bytes
    int id_proc, tot_proc, loop_min, loop_max;
    vector<double> output(rows*cols,1.0);//data to write

    //MPI routines
    MPI_Init(&argc,&argv);//initialize MPI
    MPI_Comm_rank(MPI_COMM_WORLD,&id_proc);//get "this" node's id#/rank
    MPI_Comm_size(MPI_COMM_WORLD,&tot_proc);//get the number of processors

    //MPI loop variable assignments
    loop_min = id_proc*rows/tot_proc + min(rows % tot_proc, id_proc);
    loop_max = loop_min + rows/tot_proc + (rows % tot_proc > id_proc);

    //File handle
    MPI_File outfile;

    //Create binary files in parallel
    for(int i = loop_min; i < loop_max; i++)
    {
        temp << i;
        oname = "Myout" + temp.str() + ".bin";
        MPI_File_open(MPI_COMM_WORLD, oname.c_str(), MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_INFO_NULL, &outfile);
        temp.clear();
        temp.str(string());
        MPI_File_close(&outfile);
    }
    MPI_Barrier(MPI_COMM_WORLD);//with or without this, same error

    MPI_Finalize();//MPI - end mpi run
    return 0;
}

到目前为止我读过的教程/信息页面

http://beige.ucs.indiana.edu/B673/node180.html

http://beige.ucs.indiana.edu/B673/node181.html

http://mpi-forum.org/docs/mpi-2.2/mpi22-report/node305.htm

https://www.open-mpi.org/doc/v1.4/man3/MPI_File_open.3.php

http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node215.htm

Parallel output using MPI IO to a single file

Is it possible to write with several processors in the same file, at the end of the file, in an ordonated way?

1 个答案:

答案 0 :(得分:1)

MPI_File_open()是一项集体操作,这意味着MPI_COMM_WORLD的所有任务都必须在相同时打开相同的文件。

如果您想为每个任务打开一个进程,请改用MPI_COMM_SELF