Поиск…


замечания

MPI является стандартом для общения между группой распределенных (или локальных) процессов. Он включает в себя процедуры для отправки и получения данных, совместного общения и других более сложных задач.

Стандарт предоставляет API для C и Fortran, но также существуют привязки к различным другим языкам.

Версии

Версия стандарт Дата выхода
1 МПИ-отчет-1.3-2008-05-30.pdf 1994-05-05
2,0 MPI2-report.pdf 2003-09-15
2,2 mpi22-report.pdf 2009-09-04
3.0 mpi30-report.pdf 2012-09-21
3,1 mpi31-report.pdf 2015-06-04

Ранг и размер

Чтобы получить размер коммуникатора (например, MPI_COMM_WORLD ) и уровень локального процесса внутри него:

int rank, size;
int res;
MPI_Comm communicator = MPI_COMM_WORLD;

res = MPI_Comm_rank (communicator, &rank);
if (res != MPI_SUCCESS)
{
  fprintf (stderr, "MPI_Comm_rank failed\n");
  exit (0);
}
res = MPI_Comm_size (communicator, &size);
if (res != MPI_SUCCESS)
{
  fprintf (stderr, "MPI_Comm_size failed\n");
  exit (0);
}

Init / Доработка

Перед выполнением любых команд MPI среда должна быть инициализирована и завершена в конце:

int main(int argc, char** argv)
{
    int res;
    res = MPI_Init(&argc,&argv);
    if (res != MPI_SUCCESS)
    {
      fprintf (stderr, "MPI_Init failed\n");
      exit (0);
    }
    ...
    res = MPI_Finalize();
    if (res != MPI_SUCCESS)
    {
      fprintf (stderr, "MPI_Finalize failed\n");
      exit (0);
    }
}

Привет, мир!

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

#include <mpi.h>
#include <stdio.h>

int main(int argc, char **argv) {
    int size, rank;
    int res;

    res = MPI_Init(&argc, &argv);
    if (res != MPI_SUCCESS)
    {
        fprintf (stderr, "MPI_Init failed\n");
        exit (0);
    }

    res = MPI_Comm_size(MPI_COMM_WORLD, &size);
    if (res != MPI_SUCCESS)
    {
        fprintf (stderr, "MPI_Comm_size failed\n");
        exit (0);
    }
    res = MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    if (res != MPI_SUCCESS)
    {
        fprintf (stderr, "MPI_Comm_rank failed\n");
        exit (0);
    }

    fprintf(stdout, "Hello World from rank %d of %d~\n", rank, size);

    res = MPI_Finalize();
    if (res != MPI_SUCCESS)
    {
        fprintf (stderr, "MPI_Finalize failed\n");
        exit (0);
    }
}

Если вы запустите эту программу следующим образом:

mpiexec -n 2 ./hello

Вы ожидаете получить результат следующим образом:

Hello World from rank 0 of 2!
Hello World from rank 1 of 2!

Вы также можете получить этот вывод назад (см. Http://stackoverflow.com/a/17571699/491687 ) для более подробного обсуждения этого:

Hello World from rank 1 of 2!
Hello World from rank 0 of 2!

Возвращаемые значения вызовов MPI

Почти любой вызов MPI возвращает целочисленный код ошибки, что означает успешность операции. Если ошибка не возникает, код возврата - MPI_SUCCESS :

if (MPI_Some_op(...) != MPI_SUCCESS)
{
   // Process error
}

Если возникает ошибка, MPI вызывает обработчик ошибок, связанный с коммуникатором, окном или файлом, перед тем как вернуться к пользовательскому коду. Существует два предопределенных обработчика ошибок (пользователь может определить дополнительные обработчики ошибок):

  • MPI_ERRORS_ARE_FATAL - ошибки приводят к прекращению программы MPI
  • MPI_ERRORS_RETURN - ошибки приводят к тому, что код ошибки передается пользователю

По умолчанию обработчик ошибок для коммуникаторов и окон - MPI_ERRORS_ARE_FATAL ; для файловых объектов это MPI_ERRORS_RETURN . Обработчик ошибок для MPI_COMM_WORLD также применяется ко всем операциям, которые не связаны конкретно с объектом (например, MPI_Get_count ). Таким образом, проверка возвращаемого значения операций без ввода-вывода без установки обработчика ошибок в MPI_ERRORS_RETURN является избыточной, поскольку ошибочные вызовы MPI не возвращаются.

// The execution will not reach past the following line in case of error
int res = MPI_Comm_size(MPI_COMM_WORLD, &size);
if (res != MPI_SUCCESS)
{
    // The following code will never get executed
    fprintf(stderr, "MPI_Comm_size failed: %d\n", res);
    exit(EXIT_FAILURE);
}

Чтобы включить обработку ошибок пользователя, необходимо сначала изменить обработчик ошибок MPI_COMM_WORLD :

MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN);

int res = MPI_Comm_size(MPI_COMM_WORLD, &size);
if (res != MPI_SUCCESS)
{
    fprintf(stderr, "MPI_Comm_size failed: %d\n", res);
    exit(EXIT_FAILURE);
}

Стандарт MPI не требует, чтобы реализации MPI могли восстанавливаться после ошибок и продолжать выполнение программы.



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow