MPI 从文本文件中读取

2024-05-24

我正在学习 MPI 编程,我遇到了这个问题。假设我有一个包含 100,000 行/行的 .txt 文件,如何将它们分块以供 4 个处理器处理?即我想让处理器 0 负责第 0-25000 行的处理,让处理器 1 负责第 25001-50000 行的处理,依此类推。我做了一些搜索,确实遇到了 MPI_File_seek,但我不确定它是否可以在 .txt 上工作并随后支持 fscanf。


文本并不是并行处理的理想格式,因为您事先不知道(例如)第 25001 行从哪里开始。因此,这类问题通常通过一些预处理步骤提前处理,要么构建索引,要么将文件分区为适当数量的块供每个进程读取。

如果您确实想通过 MPI 来完成此操作,我建议使用 MPI-IO 将文本文件的重叠块读取到各个处理器上,其中重叠部分比您预期的最长行长得多,然后每个处理者就从哪里开始达成一致;例如,您可以说进程 N 和 N+1 共享的重叠区域中的第一条(或最后一条)新行是进程 N 离开而 N+1 开始的地方。

为了跟进一些代码,

#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
    
void parprocess(MPI_File *in, MPI_File *out, const int rank, const int size, const int overlap) {
    MPI_Offset globalstart;
    int mysize;
    char *chunk;
    
    /* read in relevant chunk of file into "chunk",
     * which starts at location in the file globalstart
     * and has size mysize 
     */
    {
        MPI_Offset globalend;
        MPI_Offset filesize;
    
        /* figure out who reads what */
        MPI_File_get_size(*in, &filesize);
        filesize--;  /* get rid of text file eof */
        mysize = filesize/size;
        globalstart = rank * mysize;
        globalend   = globalstart + mysize - 1;
        if (rank == size-1) globalend = filesize-1;
    
        /* add overlap to the end of everyone's chunk except last proc... */
        if (rank != size-1)
            globalend += overlap;
    
        mysize =  globalend - globalstart + 1;
    
        /* allocate memory */
        chunk = malloc( (mysize + 1)*sizeof(char));
    
        /* everyone reads in their part */
        MPI_File_read_at_all(*in, globalstart, chunk, mysize, MPI_CHAR, MPI_STATUS_IGNORE);
        chunk[mysize] = '\0';
    }
    
    
    /*
     * everyone calculate what their start and end *really* are by going 
     * from the first newline after start to the first newline after the
     * overlap region starts (eg, after end - overlap + 1)
     */
    
    int locstart=0, locend=mysize-1;
    if (rank != 0) {
        while(chunk[locstart] != '\n') locstart++;
        locstart++;
    }
    if (rank != size-1) {
        locend-=overlap;
        while(chunk[locend] != '\n') locend++;
    }
    mysize = locend-locstart+1;
    
    /* "Process" our chunk by replacing non-space characters with '1' for
     * rank 1, '2' for rank 2, etc... 
     */
    
    for (int i=locstart; i<=locend; i++) {
        char c = chunk[i];
        chunk[i] = ( isspace(c) ? c : '1' + (char)rank );
    }

    
    /* output the processed file */
    
    MPI_File_write_at_all(*out, (MPI_Offset)(globalstart+(MPI_Offset)locstart), &(chunk[locstart]), mysize, MPI_CHAR, MPI_STATUS_IGNORE);
    
    return;
}
    
int main(int argc, char **argv) {
    
    MPI_File in, out;
    int rank, size;
    int ierr;
    const int overlap = 100;
    
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    
    if (argc != 3) {
        if (rank == 0) fprintf(stderr, "Usage: %s infilename outfilename\n", argv[0]);
        MPI_Finalize();
        exit(1);
    }
    
    ierr = MPI_File_open(MPI_COMM_WORLD, argv[1], MPI_MODE_RDONLY, MPI_INFO_NULL, &in);
    if (ierr) {
        if (rank == 0) fprintf(stderr, "%s: Couldn't open file %s\n", argv[0], argv[1]);
        MPI_Finalize();
        exit(2);
    }
    
    ierr = MPI_File_open(MPI_COMM_WORLD, argv[2], MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &out);
    if (ierr) {
        if (rank == 0) fprintf(stderr, "%s: Couldn't open output file %s\n", argv[0], argv[2]);
        MPI_Finalize();
        exit(3);
    }
    
    parprocess(&in, &out, rank, size, overlap);
    
    MPI_File_close(&in);
    MPI_File_close(&out);
    
    MPI_Finalize();
    return 0;
}

在问题文本的缩小版本上运行它,我们得到

$ mpirun -n 3 ./textio foo.in foo.out
$ paste foo.in foo.out
Hi guys I am learning to            11 1111 1 11 11111111 11
program in MPI and I came           1111111 11 111 111 1 1111
across this question. Lets          111111 1111 111111111 1111
say I have a .txt file with         111 1 1111 1 1111 1111 1111
100,000 rows/lines, how do          1111111 11111111111 111 11
I chunk them for processing         1 11111 1111 111 1111111111
by 4 processors? i.e. I want        22 2 22222222222 2222 2 2222
to let processor 0 take care        22 222 222222222 2 2222 2222
of the processing for lines         22 222 2222222222 222 22222
0-25000, processor 1 to take        22222222 222222222 2 22 2222
care of 25001-50000 and so          2222 22 22222222222 222 22
on. I did some searching and        333 3 333 3333 333333333 333
did came across MPI_File_seek       333 3333 333333 3333333333333
but I am not sure can it work       333 3 33 333 3333 333 33 3333
on .txt and supports fscanf         33 3333 333 33333333 333333
afterwards.                         33333333333
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MPI 从文本文件中读取 的相关文章

随机推荐

  • 在 MySQL 连接字符串中指定密码

    我使用 MySQL 作为 DB 和 Yeoman 生成器创建了 ExpressJS MVC 应用程序 并在config js我想更改 MySQL 连接字符串 但我不知道在字符串中指定密码 我的字符串是mysql root localhost
  • 无法加载程序集问题

    我收到以下错误 无法加载程序集 错误详细信息 System BadImageFormatException 无法加载文件或程序集 文件 或其依赖项之一 该程序集是由比当前加载的运行时更新的运行时构建的 无法加载 该程序集是使用 Net Fr
  • Angular2,测试和解析数据:如何测试 ngOnInit?

    我正在通过Angular2 测试指南 https angular io docs ts latest guide testing html并希望编写一个测试ngOnInit 功能 那个来自编程指南的路由部分 https angular io
  • opencv中如何去除二值图像噪声?

    将图像转换为二值图像 黑白 后如果有任何噪音怎么办 我消除了那些不需要的噪音 您可以看到下图的黑色区域内有一些白噪声 我该如何去除噪声 使用opencv http img857 imageshack us img857 999 blackn
  • 在Python中确定句子中2个单词之间的邻近度

    我需要确定 Python 句子中两个单词之间的接近度 例如 在下面的句子中 the foo and the bar is foo bar 我想确定单词之间的距离foo and bar 确定之间出现的单词数foo and bar 请注意 该词
  • Linq 合并列表

    我的课 public class Foo public int A get set public List
  • 在 ElasticSearch 中,我应该对单独但相关的实体使用多个索引吗?

    添加索引的开销有详细记录 但我无法找到有关何时针对要建立索引的各种文档类型使用多个索引的良好信息 这是一个说明问题的通用示例 假设我们有以下实体 产品 名称 产品 ID 产品类别 ID 商店列表 产品类别 名称 ProductCategor
  • 如何将列表中的每个项目转换为字符串,以便连接它们? [复制]

    这个问题在这里已经有答案了 我需要加入一个项目列表 列表中的许多项目都是从函数返回的整数值 IE myList append munfunc 我应该如何将返回的结果转换为字符串以便将其加入列表 我是否需要对每个整数值执行以下操作 myLis
  • T-SQL参数嗅探重新编译计划

    我有 SQL 命令 exec sp executesql N SELECT TOP 10 FROM mytableView WHERE Name LIKE Value0 ORDER BY Id DESC N Value0 varchar 5
  • 为什么 mod 在表达式中给出的结果与在函数调用中给出的结果不同?

    假设有人想要计算函数 f x y x mod 3 y mod 3 mod 2 那么 如果再展开f 1 0 手动 可以得到 1 mod 3 0 mod 3 mod 2 1 然而 如果使用内联函数 结果是 let f x y x mod 3 y
  • 多对多不检索映射数据

    Spring boot 2 5 6 我无法安装版本 概要文件 java Getter Setter NoArgsConstructor AllArgsConstructor EqualsAndHashCode FieldDefaults l
  • Apache-FOP - 减少嵌入到 PDF 中的图像大小

    我有很多 JPG 图像 应该嵌入到生成的 PDF 中 它们的分辨率相当大 每个大约 5 10MB 我想将它们作为预览嵌入到 PDF 中 并且我正在使用适合比例的 XSL FO 属性 图像在正确调整大小的 PDF 中显示 但生成的 PDF 的
  • NSRunAlertPanel 显示在“活动窗口”后面

    我正在尝试整理一个简单的错误报告包 如果我的主程序崩溃 它会保存崩溃日志 然后启动报告程序 报告程序询问用户是否可以将崩溃日志发送给我 然后就这样做了 我正在使用 NSRunAlertPanel 创建一个基本消息框 由于某种原因 该消息框显
  • 将文件从 docker 容器复制到主机

    有没有其他方法可以复制文件或文件夹docker通过在容器中运行命令来将容器连接到主机 我读到的所有其他问题都建议运行docker cp主机上的命令 也可能是重复的将文件从 Docker 容器复制到主机 https stackoverflow
  • 新部署后,React 应用程序必须清除浏览器缓存

    我们正在使用 Jenkins 管道在 apache 服务器上部署 React 应用程序 当我们部署新代码时 大多数新功能都可以正常工作 但并非所有更改都反映浏览器中的最新内容 用户必须打开隐身窗口或清除缓存才能看到新功能 我见过一些相关的解
  • 在Spring-Boot中,我们如何在同一个项目中连接两个数据库(Mysql数据库和MongoDB)?

    我正在尝试创建一个 Spring Boot 项目 其中我有一个要求 我想连接到不同的数据库 MySql 和 MongoDB 我是否需要做一些特殊的事情来连接到这两个数据库 或者 spring boot 会自动计算出自己连接到这两个数据库 我
  • 无法让 TeamCity 使用默认私钥向 GitHub 进行身份验证

    我正在尝试让 TeamCity 构建我的私人 GitHub 存储库 当我显式设置密钥文件的路径时 我能够成功让我的 VCS 根通过连接测试 然而 尽管进行了大量的谷歌搜索 当我使用 默认私钥 选项时 我无法让它工作 我明白了com jcra
  • 如何使用 Soundcloud api 将流传输到 html5 音频播放器中?

    我刚刚开始学习 javascript 作为我的第一次尝试 我想创建自定义音频播放器 它使用 soundcloud 的 api 作为音乐源 到目前为止 这就是我的设置
  • Docker 中的 Electron:SIGTRAP、ELIFECYCLE、errno1

    介绍 我有一个演示电子应用程序 运行时运行良好npm run start从我的Mac 我有兴趣将应用程序移至 Docker 容器中 但是当docker compose达到electron命令步骤 我得到以下信息 gt electron no
  • MPI 从文本文件中读取

    我正在学习 MPI 编程 我遇到了这个问题 假设我有一个包含 100 000 行 行的 txt 文件 如何将它们分块以供 4 个处理器处理 即我想让处理器 0 负责第 0 25000 行的处理 让处理器 1 负责第 25001 50000