【发布时间】:2020-02-22 18:46:33
【问题描述】:
我正在学习如何在 mpi4py 中使用单向通信。为了测试我的理解,我想出了这个人为的例子:
import mpi4py.MPI as mpi
import numpy as np
import time
def main():
rank = mpi.COMM_WORLD.Get_rank()
n_proc = mpi.COMM_WORLD.Get_size()
assert(n_proc == 2)
buff = np.zeros(10, dtype='d')
win = mpi.Win.Create(buff, 1, mpi.INFO_NULL, mpi.COMM_WORLD)
if (rank == 0):
win.Lock(1)
win.Put([buff, mpi.DOUBLE], 1)
win.Unlock(1)
buff[-1] = 9
time.sleep(30)
win.Lock(1)
win.Put([buff, mpi.DOUBLE], 1)
win.Unlock(1)
else:
holder = np.zeros(10)
failures = 0
while (holder[-1] != 9):
failures += 1
win.Lock(0)
win.Get([holder, mpi.DOUBLE], 0)
win.Unlock(0)
print('Took', failures, 'dials')
if __name__=='__main__':
main()
我希望它按如下方式工作:rank 0 将等待 30 秒,然后将包含 [0, 0, ..., 0, 9] 的 ndarray 放入共享内存中。同时,rank 1 将不断检查 rank 0 是否更新了它的共享内存——一旦更新,它将打印出它看到的内容。具体来说,我希望 rank 1 会在 30 秒等待期间多次执行其 while 循环,而 rank 0 空闲。但是,当我使用 mpirun -n 2 python mwe.py 运行此代码时,我始终得到以下输出:
Took 2 dials
表示对Get的调用只发生了两次。
具体问题:为什么排名 1 的 Get 只有两次调用?
更模糊的问题:我在这个 MWE 中是否犯了明显的错误?一般来说,我对 mpi4py/MPI 还是很陌生。
【问题讨论】:
标签: python-3.x parallel-processing mpi mpi4py