Понимание Put / Get в mpi4py - PullRequest
       109

Понимание Put / Get в mpi4py

1 голос
/ 27 октября 2019

Я учусь использовать одностороннее общение в 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()

Я ожидаю, что это будет работать следующим образом: ранг 0 будет ждать 30 секунд, прежде чем поместить ndarray, содержащий [0, 0, ..., 0, 9], в общую память. Между тем, ранг 1 будет постоянно проверять, обновил ли ранг 0 свою совместно используемую память - когда это произойдет, он напечатает то, что видит. В частности, Я бы ожидал, что ранг 1 будет выполнять свой цикл while много раз в течение 30 секунд ожидания, пока ранг 0 не используется. Однако, когда я запускаю этот код с mpirun -n 2 python mwe.py, я последовательно получаю этот вывод:

Took 2 dials

, указывающий, что вызов Get произошел только дважды.

Конкретный вопрос: Почему только два звонка Get с ранга 1?

Более расплывчатый вопрос: Я делаю очевидные ошибки в этом MWE? Я довольно новичок в mpi4py / MPI в целом.

...