При использовании односторонней связи в MPI, нормально ли вызывать Get()
и Put()
на местном уровне? Это кажется мне естественным.
Однако следующий код (использующий mpi4py
) не работает должным образом. Существует два случая, в зависимости от значения флага WILL_IT_FAIL
:
WILL_IT_FAIL = 0
В этом случае ранг 0 записывает [1. 2. ... 9.]
в свое собственное окно (т.е. вызывает Put
с target_rank=0
). Ранг 1 ждет секунду, затем вызывает Get
с target_rank=0
, который читает массив [1. 2. ... 9.]
с ранга 0. Это отлично работает.
WILL_IT_FAIL = 1
В этом случаеранг 0 записывает [1. 2. ... 9.]
в ранг 1 (т. е. вызывает Put
с target_rank=1
). Ранг 1 ждет секунду, затем вызывает Get
с target_rank=1
. Я ожидал бы, что это даст [1. 2. ... 9.]
, но вместо этого он выдаст [0. 0. ... 0.]
.
import mpi4py.MPI as mpi
import numpy as np
import time
comm = mpi.COMM_WORLD
rank = comm.Get_rank()
WILL_IT_FAIL = 0 # Fails if WILL_IT_FAIL = 1
def main():
assert(comm.Get_size() == 2)
buff = np.zeros(10, dtype='d')
win = mpi.Win.Create(buff, comm=mpi.COMM_WORLD)
if (rank == 0):
buff[:10] = np.arange(10)
win.Lock(WILL_IT_FAIL)
win.Put([buff, mpi.DOUBLE], target_rank=WILL_IT_FAIL)
win.Unlock(WILL_IT_FAIL)
else:
time.sleep(1)
print('buff (rank1) before:', buff)
win.Lock(WILL_IT_FAIL)
win.Get([buff, mpi.DOUBLE], target_rank=WILL_IT_FAIL)
win.Unlock(WILL_IT_FAIL)
print('buff (rank1) after: ', buff)
win.Free()
if __name__=='__main__':
main()
Почему это происходит? Разве я не должен звонить Put()
или Get()
с local_rank = mpi.COMM_WORLD.Get_rank()
?