Использование барьера MPI приводит к фатальной ошибке - PullRequest
0 голосов
/ 02 июня 2018

Я получаю странное поведение моей простой программы MPI.Я потратил время, чтобы найти ответ сам, но не могу.Здесь я отвечаю на некоторые вопросы, например OpenMPI MPI_Barrier проблемы , MPI_SEND перестает работать после MPI_BARRIER , Использование MPI_Bcast для связи MPI .Я красный MPI учебник по mpitutorial .Моя программа просто изменяет массив, который транслируется из корневого процесса, а затем собирает измененные массивы в один массив и печатает их.Итак, проблема в том, что, когда я использую код, указанный ниже, с некомментированным MPI_Barrier (MPI_COMM_WORLD), я получаю ошибку.

#include "mpi/mpi.h"
#define N 4

void transform_row(int* row, const int k) {
  for (int i = 0; i < N; ++i) {
    row[i] *= k;
  }
}
const int root = 0;


int main(int argc, char** argv) {
  MPI_Init(&argc, &argv);
  int rank, ranksize;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Comm_size(MPI_COMM_WORLD, &ranksize);
  if (rank == root) {
    int* arr = new int[N];
    for (int i = 0; i < N; ++i) {
      arr[i] = i * i + 1;
    }
    MPI_Bcast(arr, N, MPI_INT, root, MPI_COMM_WORLD);
  }
  int* arr = new int[N];
  MPI_Bcast(arr, N, MPI_INT, root, MPI_COMM_WORLD);
  //MPI_Barrier(MPI_COMM_WORLD);
  transform_row(arr, rank * 100);
  int* transformed = new int[N * ranksize];
  MPI_Gather(arr, N, MPI_INT, transformed, N, MPI_INT, root, MPI_COMM_WORLD);
  if (rank == root) {
    for (int i = 0; i < ranksize; ++i) {
      for (int j = 0; j < N ; j++) {
        printf("%i ", transformed[i * N + j]);
      }
      printf("\n");
    }
  }
  MPI_Finalize();
  return 0;
}

Ошибка происходит с номером потока> 1. Ошибка:

Неустранимая ошибка в PMPI_Barrier: сообщение обрезано, стек ошибок: PMPI_Barrier (425) ...................: сбой MPI_Barrier (MPI_COMM_WORLD)

MPIR_Barrier_impl (332) ..............: сбой во время коллективного

MPIR_Barrier_impl (327) ..............:

MPIR_Barrier (292) ...................:

MPIR_Barrier_intra (150) .............:

барьер_smp_intra (111) ..............:

MPIR_Bcast_impl (1452) ...............:

MPIR_Bcast (1476) ....................:

MPIR_Bcast_intra (1287) ..............:

MPIR_Bcast_binomial (239) ............:

MPIC_Recv (353) ......................:

MPIDI_CH3U_Request_unpack_uebuf (568): сообщение обрезано;Получено 16 байт, но размер буфера равен 1

Я понимаю, что существует некоторая проблема с буфером, но когда я использую MPI_buffer_attach для подключения большого буфера к MPI, это не помогает.

Кажется, мне нужноувеличить этот буфер, но я не знаю, как это сделать.

XXXXXX @ XXXXXXXXX: ~ / test_mpi $ mpirun --version

Детали сборки HYDRA:

Version:                                 3.2

Release Date:                            Wed Nov 11 22:06:48 CST 2015

Так помогите мне, пожалуйста.

1 Ответ

0 голосов
/ 03 июня 2018

Одна проблема MPI_Bcast() вызывается дважды рангом root, но только один раз остальными рангами.И тогда root rank использует неинициализированный arr.

MPI_Barrier() может только скрыть проблему, но не может ее исправить.

Также обратите внимание, что если N is "достаточно большой ", тогда второй MPI_Bcast(), вызванный root рангом, скорее всего зависнет.

Вот как вы можете обновить фазу инициализации / трансляции, чтобы исправить эти проблемы.

int* arr = new int[N];
if (rank == root) {
    for (int i = 0; i < N; ++i) {
        arr[i] = i * i + 1;
    }
MPI_Bcast(arr, N, MPI_INT, root, MPI_COMM_WORLD);

Обратите внимание, что в этом случае вы можете просто инициализировать arr во всех рангах, так что вам даже не нужно транслировать массив.

В качестве примечания, MPI-программа обычно

#include <mpi.h>

и затем используйте mpicc для компиляции / компоновки (это оболочка, которая вызывает реальный компилятор после установки путей include / library и использования библиотек MPI)

...