mpi4py 中的访问文件数据方法

上一篇中我们介绍了 mpi4py 中的并行文件视图操作方法,下面我们将介绍访问文件数据的相关方法。

文件访问方法

MPI 环境下应用程序对文件的访问主要有 3 种特征:定位(positioning),包括显式偏移和隐式文件指针;同步性(synchronism),主要包括阻塞、非阻塞和分步集合操作;集合性(coordination),主要包括非集合操作和集合操作。下表列出的相应的访问方法(MPI.File 类方法)反应了这些操作特征的组合,其中结合了两种类型的文件指针——独立文件指针和共享文件指针。

文件访问方法

上表中访问文件数据的方法很多,不能在此一一详细介绍,但是它们根据访问文件的特征却有其规律性,下面我们介绍 3 种访问特征的具体含义和数据访问的基本规范:

定位(positioning)

MPI 中的文件定位有 3 种:显式偏移(explicit offset)、独立文件指针(individual file pointers)和共享文件指针(shared file pointers),相同进程中可混合使用这 3 种操作方式,彼此无影响。

所有使用显式指针的方法,其命名中都包含 “_at“ 字符,使用显式指针访问数据时,其参数为直接指定的文件偏移位置,而不必再通过任何文件指针,也与文件视图中的相对偏移位置无关。注意:这里使用偏移不需要执行 seek 操作。

所有使用独立文件指针的数据访问方法,其命名中不包含与定位有关的字符串。

所有使用共享文件指针访问数据的方法,其命名中均包含 “_shard“ 或 “_ordered“ 字符串。

对使用指针访问文件的方法而言,MPI 负责维护其文件指针,使用时要注意的关键问题是界定相应 I/O 动作何时以及如何更新文件指针。通常情况下,I/O 操作结束时会控制文件指针指向其最后一个访问过的数据项之后第一个数据项的起始位置,而非阻塞或分步集合操作的启动方法就能修改文件指针,因此有可能在实际数据访问结束之前,文件指针就已经被修改指向新的位置。

同步性(synchronism)

MPI 支持 3 种同步类型:阻塞、非阻塞以及专门用于集合数据访问函数的带约束非阻塞操作——分步集合操作。

与非阻塞点到点通信类似,非阻塞的 I/O 操作会发起一个 I/O 操作让 MPI 在后台实现数据访问,把其它计算与数据访问重叠起来,然后再在必要位置设置测试结束函数(如 Wait, Test 等)确认数据访问操作是否真正完成。所有非阻塞 I/O 操作方法都以 I 开头命名。在发起非阻塞操作到测试结束函数返回正确执行结果之前,数据访问操作所使用的缓冲区不应再作为其它通信操作的缓冲区复用。

集合性(coordination)

所有非集合操作方法都有对应的集合操作版本,其对应关系为: xxx 对应于 xxx_all 或一对 xxx_begin/xxx_end;xxx_shared 对应的集合操作方法为 xxx_ordered。一般来说,全局数据访问具有更大的优化潜力,因此集合操作通常比相应的非集合操作方法性能更好。

数据访问基本规范(data access conventions)

读序列方法从文件读数据到进程空间,写序列方法负责把进程内存空间的数据写入文件,所有文件操作都通过文件句柄进行,通过相对于当前视图的偏移(offset)定位数据在文件中的位置,内存中的数据由三元组(buf, count, datatype)描述,操作结束时通过状态变量返回操作所涉及的数据数量。

偏移量(offset)指定访问文件的起始位置,以 etype 为单位,取相对于当前视图的计数。如果方法使用显式偏移量(explicit offset),则在其参数中指定偏移参数。操作文件指针的方法则使用隐式偏移量(implicit offset)。

通常访问文件数据的方法都在用户缓冲区 buf 和文件 file 之间传递类型为 datatype 的数据项 count 个。要求 datatype 的类型定义必是当前视图 etype 类型的若干个连续复制。与点到点通信的接收操作类似,不能使用内部定义了重叠区域的类型进行文件读写操作。

对非阻塞操作,与点到点通信类似,MPI 启动异步操作的同时注册一个 MPI.Request 对象,然后通过其 Test,Wait 等方法测试 I/O 操作是否完成。

对阻塞操作,操作完成即可得到纪录操作过程的状态对象;而对非阻塞操作和分步集合操作,经测试操作完成后才能返回正确的状态对象。一次操作所涉及的 datatype 数据个数以及其它一些通信信息都可通过 MPI.Status.Get_count,MPI.Status.Get_elements 等状态对象的方法提取出来。另外也可通过状态对象的 MPI.Status.Is_cancelled 方法获得操作是否被取消。

对读取操作,测试文件末尾的方法是判断读到的数据项个数少于参数预先指定的个数。对写操作,超过文件末尾会自动导致扩大文件大小。

文件指针及其定位操作

以上介绍的部分文件数据访问方法需要辅助以文件指针及其定位操作才能完成,下面给出相关方法(MPI.File 类方法)接口:

独立文件指针

Seek(self, Offset offset, int whence=SEEK_SET)

根据 whence 参数指定的方式更新进程各自的文件指针到指定偏移位置 offsetwhence 可能的取值如下:

  • MPI.SEEK_SET:将文件指针设置为 offset 参数给出的值;
  • MPI.SEEK_CUR:将文件指针设置为相对于当前位置的 offset 偏移处,即当前位置加上 offset 参数;
  • MPI.SEEK_END:将文件指针设置为指向文件末尾再加上 offset 参数的值。

offset 的值可为负,但要注意在文件视图中指定相对于视图起始位置负数的偏移会导致错误。

Get_position(self)

返回独立文件指针在当前文件视图中的相对偏移位置,以当前视图的 etype 为计量单位。

Get_byte_offset(self, Offset offset)

将相对视图的偏移量 offset 转换为以字节为单位的绝对偏移位置(相对于文件物理起始位置的字节偏移量)并返回。

共享文件指针

Seek_shared(self, Offset offset, int whence=SEEK_SET)

执行集合操作,根据 whence 参数移动共享文件指针到指定偏移位置 offsetwhence 可能的取值同 Seek 方法。

Get_position_shared(self)

返回共享文件指针相对当前文件视图的位置,以 etype 为单位。

文件一致性

文件一致性是指解决多个操作访问同一个文件时的一致性。MPI 程序访问文件都通过一个集合操作 Open 打开的文件句柄来执行,应提供以下 3 个级别的一致性。

  • 使用相同文件句柄访问文件的串行一致性;
  • 使用同一个集合操作(Open)以原子模式(atomic mode)打开的若干文件句柄访问文件的串行一致性;
  • 其它应用程序根据需要自定义的访问一致性。

所谓串行一致性是指要求一组访问文件的操作按照一定顺序依次实施,每个访问都应是原子操作,但允许具体执行时的顺序有所不同。应用程序自定义的一致性可通过程序语句顺序加之以 Sync 实现。

文件一致性的相关方法(MPI.File 类方法)接口如下:

Set_atomicity(self, bool flag)

设置当前打开文件的原子模式,如果 flag 为 True,则设置为原子模式,否则设置为非原子模式。该方法执行一个集合操作,参与该操作的进程组必须传递相同的 flag 参数值。

Get_atomicity(self)

返回当前一致性约束的状态。如果是原子模式则返回 True,否则返回 False。

Sync(self)

该方法是一个集合操作,如果某个进程调用该方法,则到此为止该进程已经写入文件的数据全部刷新到磁盘上。如果其它进程也更新过文件,则此方法之后所有更新的结果都会对组内进程可见。在调用此方法之前,应用程序应确保文件句柄上的所有非阻塞操作、分步集合操作以及其它操作都已经完成,否则可能导致一些随机错误。

例程

下面给出部分文件访问操作方法的使用例程。

# file_io.py

"""
Demonstrates the usage of Open, Set_atomicity, Set_view, Seek,
Read, Write, Get_position, Close.

Run this with 4 processes like:
$ mpiexec -n 4 python file_io.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)

# set to be atomicity mode to avoid read/write conflict
fh.Set_atomicity(True)

# set file view, use MPI.INT as etype and filetype
fh.Set_view(0, MPI.INT, MPI.INT)

num_ints = 10 # number of int types
buf1 = np.arange(num_ints, dtype='i')
buf2 = np.zeros(num_ints, dtype='i') # initialize to all zeros

# set individual file pointer of each process
fh.Seek(rank*num_ints, whence=MPI.SEEK_SET)

# each process writes buf1 to file
fh.Write(buf1)

# reset individual file pointer of each process
fh.Seek(rank*num_ints, whence=MPI.SEEK_SET)

# each process reads data to buf2 from file
fh.Read(buf2)

print 'process %d has buf2 = %s' % (rank, buf2)

# check position of individual file pointer
print 'process %d has file pointer position %d after read' % (rank, fh.Get_position())

# close the file
fh.Close()

运行结果如下:

$ mpiexec -n 4 python file_io.py
process 0 has buf2 = [0 1 2 3 4 5 6 7 8 9]
process 0 has file pointer position 10 after read
process 1 has buf2 = [0 1 2 3 4 5 6 7 8 9]
process 1 has file pointer position 20 after read
process 2 has buf2 = [0 1 2 3 4 5 6 7 8 9]
process 2 has file pointer position 30 after read
process 3 has buf2 = [0 1 2 3 4 5 6 7 8 9]
process 3 has file pointer position 40 after read

以上我们介绍了 mpi4py 中的访问文件数据操作方法,在下一篇中我们将介绍 mpi4py 的一些使用技巧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,409评论 25 707
  • 丢丢的外婆因为家里人多,外公做为村支书,常年在外,丢丢妈妈做为老二,就必须承担家里的家务活,丢丢外婆在为她女儿选择...
    小蓝儿阅读 323评论 1 0
  • 1. 你把生活搞砸了,你很伤心。 那又怎样? 要知道,你从没辉煌过。 所以谁管...
    兆西阅读 210评论 0 0
  • 上世纪六七十年代,乡下小镇是很少有浴室的,像我们渭塘那时就没有浴室,记忆里太平老街有家浴室,因为每年过春节的时候,...
    蒋坤元阅读 4,493评论 21 123
  • 聊了四天的爱心早餐,今天重点聊一聊爱这个字,怎么才会让早餐变的更有爱,你最难忘的满满的都是爱的早餐是哪一次? 我吃...
    M豆小姐阅读 303评论 0 0