使用MPI-IO写入多个共享文件

时间:2017-02-24 04:58:08

标签: c mpi hpc mpi-io

我正在使用数千个MPI进程运行模拟,需要将输出数据写入一小组文件。例如,即使我可能有10,000个进程,我只想写出10个文件,每个文件写入1,000个(在某个适当的偏移处)。 AFAIK执行此操作的正确方法是为将要写入相同文件的进程组创建新的通信器,使用MPI_File_open()为该通信器打开共享文件,然后使用{{1 }}。那是对的吗?以下代码是我写的一个玩具示例:

MPI_File_write_at_all()

我可以使用#include <mpi.h> #include <math.h> #include <stdio.h> const int MAX_NUM_FILES = 4; int main(){ MPI_Init(NULL, NULL); int rank; MPI_Comm_rank(MPI_COMM_WORLD, &rank); int numProcs; MPI_Comm_size(MPI_COMM_WORLD, &numProcs); int numProcsPerFile = ceil(((double) numProcs) / MAX_NUM_FILES); int targetFile = rank / numProcsPerFile; MPI_Comm fileComm; MPI_Comm_split(MPI_COMM_WORLD, targetFile, rank, &fileComm); int targetFileRank; MPI_Comm_rank(fileComm, &targetFileRank); char filename[20]; // Sufficient for testing purposes snprintf(filename, 20, "out_%d.dat", targetFile); printf( "Proc %d: writing to file %s with rank %d\n", rank, filename, targetFileRank); MPI_File outFile; MPI_File_open( fileComm, filename, MPI_MODE_CREATE | MPI_MODE_WRONLY, MPI_INFO_NULL, &outFile); char bufToWrite[4]; snprintf(bufToWrite, 4, "%3d", rank); MPI_File_write_at_all( outFile, targetFileRank * 3, bufToWrite, 3, MPI_CHAR, MPI_STATUS_IGNORE); MPI_File_close(&outFile); MPI_Finalize(); } 进行编译,然后使用mpicc file.c -lm运行20个进程,我得到预期的输出(四个文件,每个包含五个条目),但我不确定这是否是技术上正确/最佳的做法。有什么我应该做的不同吗?

3 个答案:

答案 0 :(得分:1)

MPI_File_write_at_all应该是最有效的方法。对于共享文件的大型非连续并行写入,集体IO函数通常最快,而_all变体将搜索和写入组合成一个调用。

答案 1 :(得分:1)

你的方法是正确的。为了澄清,我们需要重新审视标准和定义。来自MPI: A Message-Passing Interface Standard Version 2.2的MPI_File_Open API(第391页)

  

int MPI_File_open(MPI_Comm comm,char * filename,int amode,MPI_Info info,   MPI_File * fh)

说明

  

MPI_FILE_OPEN打开由所有进程中的文件名filename标识的文件   通信传播组。 MPI_FILE_OPEN是一个集体例程:所有进程都必须   为amode提供相同的值,并且所有进程都必须提供引用的文件名   同一个文件。 (信息的值可能会有所不同。)comm必须是 intracommunicator ;它是   错误地将 intercommunicator 传递给MPI_FILE_OPEN。

intraracommunicator vs intercommunicator(第134页):

  

就本章而言,知道有两种类型就足够了   传播者:传播者和传播者。一个内部通信器   可以被认为是与上下文链接的单个进程组的标识符。一个   intercommunicator识别与上下文链接的两个不同的进程组。

将内部通信器传递给MPI_File_open()的目的是指定一组将对该文件执行操作的进程。 MPI运行时需要此信息,因此它可以在发生集合I / O操作时强制执行适当的同步。程序员有责任理解应用程序的逻辑并创建/选择正确的内部通信器。

MPI_Comm_Split()在一个功能强大的API中,允许将通信组拆分为不相交的子组,以用于不同的用例,包括MPI I / O.

答案 2 :(得分:1)

我认为这可能是一个错字,但它是&#34; _all&#34;这意味着集体行动。

然而,我想说的是,集体操作更快的原因是它们使I / O系统能够聚合来自许多进程的数据。您可以从1000个进程发出1000个写入,但是使用集合表单,这可能会聚合成对文件的单个大写(而不是1000个小写入)。这当然是最好的情况,但改进可能是戏剧性的 - 对于共享文件的访问,我看到集体I / O比非集体I / O快1000倍,不可否认的是比这更复杂的IO模式。