2012-03-30 41 views
4

我有一个FORTRAN MPI代码来解决流场问题。MPI-FORTRAN的文件IO

在开始时,我想从文件读取数据并将其分发给参与进程。

数据由多个三维数组(空间x,y,z中的速度)组成。

每个进程只存储数组的一部分。

因此,如果每个进程都要读取文件(我认为最简单的方法),它不会起作用,因为它只会存储文件的第一部分,该部分对应于进程可以保存的数组数量。

MPI Bcast可以用于3D数组吗?但事情变得复杂。

还是有更简单的方法吗?

回答

4

从广义上讲,根据您的平台,您有2或3种选择。

  1. 一个进程读取输入数据并将其发送(部分)到其他进程。我通常不会使用广播,因为这是一个集体操作,所有流程都必须参与。我通常只是将必要的信息发送到每个过程。如果方便(而不是内存问题),你当然可以将所有输入数据广播给所有进程,但这不仅仅是我使用或看到的很多操作模式。
  2. 所有进程都会读取它们需要的数据。这可能涉及读取整个输入文件并仅存储它所需的部分的过程。但是如果你有非常大的输入文件,你可以编写例程来只读入每个进程的内存空间中的必要部分。这种方法可能涉及竞争磁盘访问的进程,这在相对意义上只是缓慢的:如果您正在运行大规模并且长时间运行的并行计算,等待几秒钟,而所有进程获取其数据并不是很大的开销。
  3. 如果您有一个并行文件系统,那么您可以使用MPI的并行I/O例程,以便每个进程只读取它需要的那些输入数据部分。
+0

有第二种选择,我可以看任何的例子吗? – 2017-10-09 05:22:39

3

在MPI这样的I/O模式的规范的方法要么是

  • 阅读等级0中的数据,然后使用MPI_Scatter分发它。或者如果内存紧张,请按块进行,或者使用1对1通信而不是MPI_Scatter。

  • 使用MPI-I/O,并让每个等级都读取它自己的数据文件的子集(这很有用,当然这需要一个文件格式,您可以在没有先读取整个文件的情况下找出边界)。

对于极端的可扩展性,可结合这两种方法,也就是处理的子集(比如,SQRT(N)作为一个粗略的规则)使用MPI I/O,并且每个MPI进程发送数据到它自己的IO进程。

3

如果您使用良好的文件系统(例如Lustre)在少于1000个内核上运行代码,那么只需使用Fortran I/O,其中每个等级打开文件并读取所需的数据(跳过其余部分)。是的,这需要几分钟的时间,但您只在开始时阅读文件一次。MPI I/O(仅适用于二进制文件)并不重要,通常情况下,使用HDF5或并行NetCDF等更高级别的库文件通常会更好。性能将取决于数据的读取方式(连续与非连续等)。以下链接可能会有所帮助......

+0

感谢您提供HDF5或Parallel-NetCDF:今天很少有理由让新代码直接使用MPI-IO。 – 2014-08-26 14:07:19