Параллельное программирование: Учебное пособие, страница 79

В программах на языке FORTRAN объекты MPI_Datatype или MPI_Comm являются объектами целого типа (INTEGER). Библиотечные программы на языках С/С++ и ФОРТРАН называются по-разному — соответственно функции и процедуры, однако в описании MPI их удобнее называть одним словом — подпрограммы.

4.8  Коды завершения

Кодами завершения подпрограмм MPI, в случае функций С/С++, являются возвращаемые значения функций, а в FORTRAN-процедурах код передается последним аргументом. Исключение составляют подпрограммы MPI_Wtime и MPI_Wtick, в которых возвращение кода ошибки не предусмотрено. Успешное завершение представляется константой MPI_SUCCESS, а неудачное — MPI_ERR_OTHER. Последнее обычно происходит при попытке повторного вызова процедуры  MPI_Init.

Системой распознаются и другие ошибки. Вместо числовых кодов в программах обычно используют специальные именованные константы. Среди них:

·  MPI_ERR_BUFFER – неправильный указатель на буфер;

·  MPI_ERR_COMM – неправильный коммуникатор;

·  MPI_ERR_RANK – неправильный ранг;

·  MPI_ERR_OP – неправильная операция;

·  MPI_ERR_ARG – неправильный аргумент;

·  MPI_ERR_UNKNOWN – неизвестная ошибка;

·  MPI_ERR_TRUNCATE – сообщение обрезано при приеме;

·  MPI_ERR_INTERN – внутренняя ошибка. Обычно возникает, если системе не хватает памяти.

4.9  Структура программы в среде МPI

В программе MPI следует соблюдать определенные правила, без которых она окажется неработоспособной. Прежде всего, в начале программы, сразу после ее заголовка, необходимо подключить соответствующий заголовочный файл. В программе на языке  С  это  mpi.h:

#include "mpi.h"

на языке  С ++ это  mpi++.h:

#include "mpi++.h"

а в программе на языке FORTRAN — mpif.h:

include "mpif.h"

В этих файлах содержатся описания констант и переменных библиотеки MPI.

Первым вызовом библиотечной процедуры MPI в программе должен быть вызов подпрограммы инициализации MPI_Init, перед ним может располагаться только вызов MPI_Initialized, с помощью которого определяют, инициализирована ли система MPI. Вызов процедуры инициализации выполняется только один раз.

Параметры функции инициализации получают адреса аргументов главной программы, задаваемых в командной строке при ее запуске:

MPI_Init(&argc, &argv);

При инициализации создается коммуникатор MPI_COMM_WORLD, имя которого  указывается во всех последующих вызовах подпрограмм MPI.

После выполнения всех обменов сообщениями в программе должен располагаться вызов подпрограммы MPI_Finalize(). В результате этого вызова удаляются структуры данных MPI и выполняются другие необходимые действия. Программист должен позаботиться о том, чтобы к моменту вызова подпрограммы MPI_Finalize были завершены все пересылки данных. После выполнения данного вызова другие вызовы процедур MPI, включая MPI_Init, недопустимы. Исключение составляет подпрограмма MPI_Initialized, которая возвращает значение "истина", если процесс вызывал MPI_Init. Данный вызов может находиться в любом месте программы.

В тех частях программы, которые находятся до вызова MPI_Init и после вызова MPI_Finalize, не рекомендуется открывать файлы, выполнять считывание и запись в файлы стандартного ввода и вывода.

Выполнение всех процессов в коммуникаторе может быть прервано процедурой MPI_Abort. Если коммуникатор описывает область связи всех процессов программы, то выполнение программы будет завершено. Данный вызов используется для аварийного останова программы при возникновении серьезных ошибок. Вид простой программы на С представлен текстом 4.3.

Текст 4.3. MPI-программа на языке С

#include "mpi.h"

#include <stdio.h>

int main(int argc, char *argv[])

{

int myid, numprocs;

MPI_Init(&argc, &argv);

MPI_Comm_size(MPI_COMM_WORLD, &numprocs);

MPI_Conm_rank(MPI_COMM_WORLD, &myid);

fprintf(stdout,"Process %d of %d\n", myid, numprocs),

MPI_Finalize(),

return 0;

}