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

Copy large data file using parallel I/O

我有一个相当大的数据集,大约 1.41 亿行,格式为 .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。

除了光泽条纹默认情况下对于 "parallel file system" 来说小得离谱的事实之外,您还太早担心光泽条纹。使用 lfs setstripe

增加您将写入和读取这些文件的目录的条带大小

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

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

  1. 一行是 aa,b,c(8 个字节)。
  2. 行是aaaaaaa,bbbbbbb,ccccccc(24字节)。
  3. 第三行是 ,,c(4 个字节)。

(darnit, markdown,如何让这个列表从零开始?)

Rank 0 可以从文件的开头读取,但是Rank 1 和2 从哪里开始呢?如果简单地将总大小(8+24+4=36)除以3,那么分解就是

  1. 0 最终阅读 aa,b,c\naaaaaa
  2. 1 读 a,bbbbbbb,ccc
  3. 阅读cccc\n,,c\n

非结构化文本输入的两种方式如下。一种选择是在事后或在生成文件时索引您的文件。该索引将存储每一行​​的起始偏移量。 Rank 0 读取偏移量然后广播给其他人。

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

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