使用并行I / O复制大数据文件

时间:2015-07-29 16:15:02

标签: c++ parallel-processing mpi openmpi

我有一个相当大的数据集,大约有141M行.csv格式化。我想在C ++中使用MPI命令来复制和操作几列,但我是C ++和MPI的新手。

到目前为止,我的代码看起来像这样

#include <stdio.h>
#include "mpi.h"

using namespace std;

int main(int argc, char **argv)
{
    int i, rank, nprocs, size, offset, nints, bufsize, N=4;
    MPI_File fp, fpwrite; // File pointer
    MPI_Status status;
    MPI_Offset filesize;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
    MPI_File_get_size(fp, &filesize);

    int buf[N];
    for (i = 0; i<N; i++)
        buf[i] = i;
    offset = rank * (N/size)*sizeof(int);
    MPI_File_open(MPI_COMM_WORLD, "new.csv", MPI_MODE_RDONLY, MPI_INFO_NULL, &fp);

    MPI_File_open(MPI_COMM_WORLD, "Ntest.csv", MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &fpwrite);

    MPI_File_read(fp, buf, N, MPI_INT, &status);

    // printf("\nrank: %d, buf[%d]: %d\n", rank, rank*bufsize, buf[0]);
    printf("My rank is: %d\n", rank);
    MPI_File_write_at(fpwrite, offset, buf, (N/size), MPI_INT, &status);

    /* // repeat the process again
    MPI_Barrier(MPI_COMM_WORLD);
    printf("2/ My rank is: %d\n", rank); */

    MPI_File_close(&fp);
    MPI_File_close(&fpwrite);
    MPI_Finalize();
}

我不知道从哪里开始,我看过一些带有光泽条纹的例子。如果可能的话,我想走那个方向。其他选项包括HDF5和T3PIO。

1 个答案:

答案 0 :(得分:1)

除了光泽条纹默认为“并行文件系统”小得可笑之外,你还为时过早担心光泽条纹。增加要编写的目录的条带大小,并使用lfs setstripe

读取这些文件

您的第一个挑战将是如何分解此CSV文件。典型的行是什么样的?如果行的长度可变,你会有点头疼。原因如下:

考虑一个包含3行和3个MPI进程的CSV文件。

  1. 一行是aa,b,c(8个字节)。
  2. 行是aaaaaaa,bbbbbbb,ccccccc(24个字节)。
  3. 第三行是,,c(4个字节)。
  4. (darnit,markdown,如何让这个列表从零开始?)

    等级0可以从文件的开头读取,但是排名1和2的起点在哪里?如果你只是将总大小(8 + 24 + 4 = 36)除以3,那么分解就是

    1. 0最终阅读aa,b,c\naaaaaa
    2. 1读取a,bbbbbbb,ccc
    3. 读取cccc\n,,c\n
    4. 非结构化文本输入的两种方法如下。一种选择是在事实之后或在生成文件时索引文件。该索引将存储每行的起始偏移量。等级0读取偏移然后广播给其他人。

      第二个选项是按文件大小进行初始分解,然后修复分割。在上面的简单示例中,排名0将在换行符之后将所有内容发送到排名1.排名1将接收新数据并将其粘贴到其行的开头并将其自己的换行符后的所有内容发送到排名2.这非常繁琐且我不会建议刚刚启动MPI-IO的人。

      HDF5是个不错的选择!不要尝试编写自己的并行CSV解析器,而是让CSV创建者生成HDF5数据集。除了其他功能之外,HDF5将保留我提到的那个索引,因此您可以设置hyperslabs并进行并行读写。