MPI декартова сетка: накопить скалярное значение через проки заданной оси сетки - PullRequest
0 голосов
/ 02 мая 2018

У меня вопрос MPI об использовании декартовой сетки процессоров, которая представляет собой декомпозицию пространственной области (кубическая геометрическая область, разделенная на несколько меньших кубов ...). У меня есть много возможных коммуникаторов для работы с процессами, например, для связи по каждой из трех осей I, J, K или по плоскости IK, JK, IJ и т. Д.). Мне нужно накопить скалярное значение (SCAL) через проки, которые принадлежат данной оси (скажем, ось K, определенная как I = J = 0). Происхождение 0-0-0 имеет заданное значение для SCAL (скажем, SCAL000) Я хочу обновить 'следующий' процесс (0-0-1), выполнив SCAL = SCAL + SCAL000, и я хочу распространить по этой оси. В конце, последний процесс оси должен иметь общую сумму SCAL вдоль оси. Пожалуйста, вы видите способ сделать это с MPI? Я перепробовал много вещей (с MPI_SENDRECV, но безуспешно ...). Спасибо в любом случае.

1 Ответ

0 голосов
/ 04 мая 2018

Я даю некоторую точность в моем вопросе (и ответе): У меня есть 3D-домен, который разделен на декартову сетку поддоменов с MPI. Каждый поддомен знает свой размер (физический размер в метрах), но не знает своего абсолютного положения относительно данного абсолютного источника, и это то, что мне было нужно. Мое решение (возможно, классическое) состоит в циклическом сдвиге в 3 направлениях (здесь показано только направление X) и создании MPI_SENDRECV. В следующем, я полагаю, я знаю: - «Соседи»: массив, который дает номер процесса 6 непосредственных соседей текущего процесса. - ALRNK_I (): ARRAY, в котором хранятся процессы, которые находятся в той же строке (направление X), что и текущий процесс. - I_PROCS: число или процессы в этой строке (размер ALRNK_I) - ДЛИНА (1): физический размер (в метрах) текущего домена в направлении X. Каждый процесс получает Xmax левого соседа (который он хранит в своем буфере Xmin) и отправляет свое значение Xmax своему правому соседу (который делает то же самое). Нам просто нужно позаботиться об ограничениях и сделать условие циклического выполнения ... (в коде значение xmax равно XEND, значение xmin - XORI)

  DO N=1,I_PROCS-1
    DEST=NEIGHBORS(1 , 0, 0)
    SOUR=NEIGHBORS(-1, 0, 0)
    XEND=XORI+LENGTH(1) ! UPDATE ORIGIN

    IF (DEST.EQ.MPI_PROC_NULL) DEST=ALRNK_I(1)

    IF (SOUR.EQ.MPI_PROC_NULL) THEN
      SOUR=ALRNK_I(I_PROCS)
      CALL MPI_SENDRECV(XEND, 1, MPI_REAL8, DEST, TAG,
 &                     DUMMY, 1, MPI_REAL8, SOUR, TAG,
 &                            COMM_IKJ,STATUS, MPIERR)
    ELSE
      CALL MPI_SENDRECV(XEND, 1, MPI_REAL8, DEST, TAG,
 &                      XORI, 1, MPI_REAL8, SOUR, TAG,
 &                            COMM_IKJ,STATUS, MPIERR)
    ENDIF
  ENDDO
...