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

Copy large data file using parallel I/O

本文关键字:复制 数据 文件 并行      更新时间:2023-10-16

我有一个相当大的数据集,大约141M行的。csv格式。我想使用MPI命令与c++来复制和操作一些列,但我是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]: %dn", rank, rank*bufsize, buf[0]);
    printf("My rank is: %dn", 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: %dn", rank); */
    MPI_File_close(&fp);
    MPI_File_close(&fpwrite);
    MPI_Finalize();
}

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

现在担心光泽条还为时过早,除了光泽条在默认情况下对于"并行文件系统"来说非常小这个事实。使用lfs setstripe

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

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

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

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

(该死,降价,我怎么让这个列表从0开始?)

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

  1. 0最终读取aa,b,cnaaaaaa
  2. 1读取a,bbbbbbb,ccc
  3. 读取ccccn,,cn

非结构化文本输入的两种方法如下。一种选择是对文件进行索引,可以是事后索引,也可以是在文件生成时索引。该索引将存储每行的开始偏移量。Rank 0读取偏移量,然后广播给其他所有人。

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

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