【问题标题】:Copy large data file using parallel I/O使用并行 I/O 复制大型数据文件
【发布时间】:2015-10-20 18:06:21
【问题描述】:

我有一个相当大的数据集,大约 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。

【问题讨论】:

    标签: c++ parallel-processing mpi openmpi


    【解决方案1】:

    您现在担心光泽条纹还为时过早,除了光泽条纹默认情况下对于“并行文件系统”来说非常小。使用lfs setstripe增加您将在其中写入和读取这些文件的目录的条带大小

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

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

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

    (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 以及其他功能将保留我为您提到的索引,因此您可以设置 hyperslab 并进行并行读写。

    【讨论】:

    • +1;您可以以这种方式处理文本文件(例如,this answer here),但正如 Rob Latham 所指出的,文本是处理大量数字数据的糟糕方式;它也慢得多。 CSV 文件很好地映射到HDF5 tables,或者如果所有列都属于同一类型,您可以只使用二维数组作为 HDF5 数据集。如果没有做太多的计算并且你知道一些 python,h5py 比 HDF5 C 接口好得多。
    • 谢谢罗伯和乔纳森!我想给你们一个大拇指,但我没有足够的声誉。任意行包含 5 个值,但可以是负数或正数,因此不能选择除以大小。我会尝试 hdf5,这似乎是一个有前途的解决方案。再次感谢
    猜你喜欢
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    • 2016-01-26
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多