Операция MPI RMA: порядок между MPI_Win_free и локальной загрузкой

Я пытаюсь сделать простой тест на работу RMA MPI с помощью MPI_Win_lock а также MPI_Win_unlock, Программа просто позволила процессу 0 обновить целочисленное значение в процессе 1 и отобразить его.

Приведенная ниже программа работает правильно (по крайней мере, результат мне кажется правильным):

#include "mpi.h"
#include "stdio.h"
#define root 0

int main(int argc, char *argv[])
{
  int myrank, nprocs;
  int send, recv, err;
  MPI_Win nwin;
  int *st;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
  MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

  MPI_Alloc_mem(1*sizeof(int), MPI_INFO_NULL, &st);

  st[0] = 0;
  if (myrank != root) {
    MPI_Win_create(st, 1*sizeof(int), sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &nwin);
  }
  else {
    MPI_Win_create(NULL, 0, sizeof(int), MPI_INFO_NULL, MPI_COMM_WORLD, &nwin);
  }

  if (myrank == root) {
    st[0] = 1;
    MPI_Win_lock(MPI_LOCK_EXCLUSIVE, 1, 0, nwin);
    MPI_Put(st, 1, MPI_INT, 1, 0, 1, MPI_INT, nwin);
    MPI_Win_unlock(1, nwin);
    MPI_Win_free(&nwin);
  }
  else { // rank 1
    MPI_Win_free(&nwin);
    printf("Rank %d, st = %d\n", myrank, st[0]);
  }

  MPI_Free_mem(st);
  MPI_Finalize();
  return 0;
}

Вывод, который я получил Rank 1, st = 1, Но любопытно, если я переключу строки в блоке else для ранга 1 на

  else { // rank 1
    printf("Rank %d, st = %d\n", myrank, st[0]);
    MPI_Win_free(&nwin);
  }

Выход Rank 1, st = 0,

Я не могу выяснить причину этого и почему мне нужно поставить MPI_Win_free после загрузки данных изначально мне нужно поместить все вещи в цикл while и присвоить рангу 0, чтобы определить, когда остановить цикл. Когда условие выполнено, я пытаюсь дать рангу 0 обновить флаг (st) в ранге 1. Я пытаюсь поместить MPI_Win_free вне цикла while, чтобы окно было освобождено только после цикла. Теперь кажется, что я не могу этого сделать и мне нужно создавать и освобождать окно каждый раз в цикле?

1 ответ

Решение

Честно говоря, MPI RMA - не моя специальность, но я попробую:

Проблема в том, что вы попали в состояние гонки. Когда вы делаете MPI_PUT Во время этой операции данные от ранга 0 до ранга 1 отправляются в буфер в какой-то момент в будущем. Вы не имеете никакого контроля над этим с точки зрения ранга 0.

Одна сторона ранга 1, вы ничего не делаете для завершения операции. Я знаю, что RMA (или односторонние операции) звучат так, как будто они не требуют какого-либо вмешательства на целевой стороне, но они требуют немного. Когда вы используете односторонние операции, на принимающей стороне должно быть что-то, что также синхронизирует данные. В этом случае вы пытаетесь использовать операции ввода / вывода MPI в сочетании с операциями сохранения нагрузки без MPI. Это ошибочно и приводит к состоянию гонки, которое вы видите. Когда вы переключаете MPI_WIN_FREE чтобы быть первым, вы выполняете все незавершенные операции, чтобы ваши данные были правильными.

Вы можете узнать больше о пассивной синхронизации целей (что вы здесь делаете) с этим вопросом: MPI с C: пассивной синхронизацией RMA.

Другие вопросы по тегам