在上一篇中我们介绍了 mpi4py 中的并行文件相关操作方法,下面我们将介绍并行文件视图。
方法接口
文件视图操作的相关方法(MPI.File 类方法)接口如下:
Set_view(self, Offset disp=0, Datatype etype=None, Datatype filetype=None, datarep=None, Info info=INFO_NULL)
设置文件视图。该方法执行集合操作,修改进程能够看到的文件数据视图,将文件视图修改为以 disp
起始,基本数据类型设置为 etype
,数据在进程间分布设置为 filetype
,文件中数据表示设置为 datarep
,同时也把本地文件指针和共享文件指针均设置为 0。要求所有的进程使用相同的 datarep
和 etype
,但允许指定不同的 disp
,filetype
和 info
参数。在 etype
和 filetype
中使用的派生数据类型在使用之前必须先注册(通过 MPI.Datatype.Commit 提交注册)。disp
需以字节为单位计算。对一些串行文件而言,绝对偏移值没有意义,为了使该操作对串行文件兼容,如果打开文件时指定了 MPI.MODE_SEQUENTIAL,则 disp
必须传递一个特殊的绝对偏移值——MPI.DISPLACEMENT_CURRENT,该参数将导致 MPI 把绝对偏移设置为共享文件指针当前指向的位置。
可使用 disp
参数使某些进程跳过文件中不感兴趣的数据段,此时,不同进程分别使用不同的 disp
和 filetype
参数,能以不同模式访问文件中不同的数据段。
作为文件访问和定位的基本单元,etype
可以是任意的 MPI 内置定义数据类型或派生数据类型。相对偏移(offset)以 etype
为单位计算,文件指针总是指向某个 etype
的起始位置。文件类型 filetype
可以由一个单独的 etype
构成,也可以是在相同 etype
的多个实例基础上利用 MPI 类型构造函数创建的任何派生数据类型,但要求文件类型中的所有空洞的跨度必须是相应 etype
跨度的整数倍。如果以写方式打开一个文件,则相应的 etype
和文件类型定义中都不允许有重叠区域(与点到点通信的接收操作中不允许接收数据类型中存在重叠区域定义的约束一致),但不同进程中定义的文件类型中允许出现重叠区域设置。
如果一个文件类型(filetype)中存在空洞,则以此定义执行文件操作的进程无法访问到空洞区域。此时可通过 Set_view 操作修改 disp
,etype
,filetype
等参数来访问文件的不同区域。
info
参数用于提供与文件系统和文件访问模式相关的信息,MPI 可利用这些信息对操作进行优化。
datarep
参数用于指定数据在文件中的表示方式,默认值 None 会使用 “native”。MPI 可支持以下 3 种数据表示方式:
- native:数据在文件中采取与其在内存中相同的表示方式。这种表示方式的好处是不需要进行类型转换,因此可避免数据精度损失以及减少转换所耗的时间,缺点是只能在同构的环境中使用,无法实现异构环境下的跨平台。这种表示方式的数据,MPI 环境在底层通信中通常要直接使用 MPI.BYTE 数据类型,以免数据类型间转换导致精度变化。
- internal:可用于同构和异构环境中,MPI 环境负责相应的数据类型转换。只要使用数据文件的各进程保持有一致的数据类型定义即可。
- external32:这种方式作为 internal 方式的一个超集。MPI 文件读写函数、通信函数都首先把所操作的数据统一转换成 external32 方式后再进行后续操作。如果是文件,则其在硬盘上采取 external32 表示方式,各运行时环境中的 MPI 进程调用的读写文件操作自动完成 native 和 external32 之间的相互转换。这种表示方式的优点是:首先,异构环境中的进程在外部一致地看到 external32,但在进程内部则可分别使用自己所处平台的本地数据表示;其次,可在不同 MPI 环境之间进行文件导出导入。缺点是:由于有数据格式转换可能会导致精度丢失并增加操作时间开销。具体实现时,可让访问数据一侧的进程具体实施数据转换,而发送数据一侧的进程仍使用 MPI.BYTE 类型提供数据,从而避免两次数据转换的开销和精度损失。
应用程序应设法保证对所指定文件的所有非阻塞操作和分步集合操作均结束之后才可调用 Set_view,否则将导致错误。
Get_view(self)
获取调用进程所看到的文件数据视图。
例程
下面给出文件视图操作方法的使用例程。
# file_view.py
"""
Demonstrates the usage of Open, Set_view, Get_view, Close.
Run this with 2 processes like:
$ mpiexec -n 2 python file_view.py
"""
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
filename = 'temp.txt'
# open the file, create it if it does not exist
fh = MPI.File.Open(comm, filename, amode= MPI.MODE_CREATE | MPI.MODE_RDWR | MPI.MODE_DELETE_ON_CLOSE)
disp = 5 * 4
etype = MPI.INT
# construct filetype
INT2 = MPI.INT.Create_contiguous(2)
filetype = INT2.Create_contiguous(6)
filetype.Commit()
# set the file view
fh.Set_view(disp, etype, filetype)
print 'file view: ', fh.Get_view()
# close the file
fh.Close()
运行结果如下:
$ mpiexec -n 2 python file_view.py
file view: (20, <mpi4py.MPI.Datatype object at 0x141d350>, <mpi4py.MPI.Datatype object at 0x141d370>, 'native')
file view: (20, <mpi4py.MPI.Datatype object at 0x1b13350>, <mpi4py.MPI.Datatype object at 0x1b13370>, 'native')
以上我们介绍了 mpi4py 中的并行文件视图操作方法,在下一篇中我们将介绍访问文件数据的相关方法。