mpi учебник
Начало работы с mpi
Поиск…
замечания
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 могли восстанавливаться после ошибок и продолжать выполнение программы.