Основные функции MPI, с помощью которых можно организовать параллельное вычисление
1 | MPI_Init | подключение к MPI |
2 | MPI_Finalize | завершение работы с MPI |
3 | MPI_Comm_size | определение размера области взаимодействия |
4 | MPI_Comm_rank | определение номера процесса |
5 | MPI_Send | стандартная блокирующая передача |
6 | MPI_Recv | блокирующий прием |
Утверждается, что этого хватит. Причем первые четыре функции должны вызываться только один раз, а собственно взаимодействие процессов — это последние два пункта.
Описание функций, осуществляющих передачу, оставим на потом, а сейчас рассмотрим описание функций инициализации/завершения function MPI_Init( var argc : longint; var argv : ppchar) : longint;
Инициализация MPI. Аргументы argc и argv — переменные модуля system, определяющие число параметров командной строки и сами эти параметры, соответственно.
При успешном вызове функции MPI_Init создается коммуникатор ( область взаимодействия процессов), под именем MPI_COMM_WORLD. function MPI_Comm_size( comm : MPI_Comm; var nump : longint) : longint;
Определяет число процессов, входящих в коммуникатор comm. function MPI_Comm_rank( comm : MPI_Comm; var proc_id : longint) : longint;
Определяется ранг процесса внутри коммуникатора. После вызова этой функции все процессы, запущенные загрузчиком MPI-приложения, получают свой уникальный номер (значение возвращаемой переменной proc_id у всех разное). После вызова функции MPI_Comm_rank можно, таким образом, назначать различным процессам различные вычисления. functionnn MPI_Finalize : longint;
Завершает работу с MPI.
Порядок вызова таков:
1. MPI_Init — подключение к MPI
2. MPI_Comm_size — определение размера области взаимодействия
3. MPI_Comm_rank — определение номера процесса
4. Далее идет любая совокупность команд обмена (передача, прием, и тп.)
5. MPI_Finalize — завершение работы с MPI
Простейшая MPI программа такова.
test.pas uses mpi; var namelen, numprocs, myid : longint; processor_name : pchar; begin MPI_Init( argc, argv); MPI_Comm_size( MPI_COMM_WORLD, numprocs); MPI_Comm_rank( MPI_COMM_WORLD, myid); GetMem( processor_name, MPI_MAX_PROCESSOR_NAME+1); // константа MPI_MAX_PROCESSOR_NAME равна 256 namelen := MPI_MAX_PROCESSOR_NAME; MPI_Get_processor_name( processor_name, namelen); Writeln('Hello from ',myid,' on ', processor_name); FreeMem(processor_name); MPI_Finalize; end.
Здесь, как видно, никакого обмена нет, каждый процесс только "докладывает" свой ранг.
Для наглядности выводится также имя компьютера, где запущен каждый процесс. Для его определения используется функция MPI_Get_processor_name. function MPI_Get_processor_name( proc_name : Pchar; var name_len : longint) : longint;
При успешном вызове этой функции переменная proc_name содержит строку с именем компьютера, а name_len — длину этой строки.
После компиляции (с соответствующими опциями) >fpc -dRELEASE [-Fu<каталог, где размещен файл mpi.pp>] test.pas
должен появиться исполняемый файл test.exe, однако рано радоваться. Запуск этого exe-файла не есть запуск параллельной программы.