【发布时间】:2017-12-17 04:06:16
【问题描述】:
我有这个测试代码,它执行以下操作:
将测试消息写入文件 > 屏障 > 读取测试消息 > 断言等于 > 重复。
from __future__ import print_function
import os
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
loop = True
def main():
global loop
txt_write = 'buhahaha'
with open('test', 'w') as f1:
if rank == 0:
f1.write(txt_write)
f1.flush()
os.fsync(f1.fileno())
comm.barrier()
with open('test') as f2:
txt_read = f2.read()
try:
assert txt_read == txt_write
except:
print("Assertion error", txt_read, "!=", txt_write, 'rank=', rank)
loop = False
finally:
comm.barrier()
if rank == 0:
os.remove('test')
if __name__ == '__main__':
i = 0
while loop:
main()
if i % 1000 == 0 and rank == 0:
print("Iterations:", i)
i += 1
它适用于 100 或 1000 次迭代,但随后它会读取一个空文件并且断言失败。其他答案建议使用flush 和os.fsync,但这似乎无济于事——它只会使执行速度变慢。知道如何解决这个问题吗?
【问题讨论】:
-
你使用什么文件系统?这是单个节点还是集群?
-
不以可写方式打开文件通常会将其截断为空吗?那么,您的线程不是在它们中的大多数将其截断为空而一个正在截断它然后向其写入字符串之间竞争吗?
-
@zulan ext4 文件系统在 Linux 上。我在工作站上使用 2 个进程运行此代码。
-
@jschultz410 MPI 屏障一直等到
write、flush、os.fsync,最后是__exit__函数调用,这会关闭文件。问题是文本保留在 I/O 缓冲区中等待写入。大多数情况下,此代码有效。如果没有,所有线程读取一个空文件,而不仅仅是rank > 1线程。 -
@jadelord 也许我在这里遗漏了一些非常基本的东西。我的理解是,您有 N 个进程(或线程)在循环内执行 main(),它们在共享磁盘上每次迭代的写入和读取部分之间(以及每次迭代之间)的屏障上同步。我的评论很简单,打开像
open(fname, 'w')这样的文件通常会将文件截断为空(即写入它),并且不能保证所有修改同一个文件的竞争进程之间的写入顺序。我离这里很远吗?
标签: python io mpi mpi4py barrier