Леция- 14(Т3)н.ppt
- Количество слайдов: 20
В модели программирования MPI параллельная программа при запуске порождает несколько процессов, взаимодействующих между собой с помощью сообщений. Совокупность всех процессов, составляющих параллельное приложение, или их части, описывается специальной структурой, которая называется коммуникатором (областью взаимодействия). Сообщение содержит пересылаемые данные и служебную информацию. Для того, чтобы передать сообщение, необходимо указать: • ранг процесса-отправителя сообщения; • адрес, по которому размещаются пересылаемые данные процессаотправителя; • тип пересылаемых данных; • количество данных; • ранг процесса, который должен получить сообщение; • адрес, по которому должны быть размещены данные процессомполучателем; тег сообщения; • идентификатор коммуникатора, описывающего область взаимодействия, внутри которой происходит обмен. Тег — это задаваемое пользователем целое число от 0 до 32767, которое играет роль идентификатора сообщения и позволяет различать сообщения, приходящие от одного процесса. Прием сообщения начинается с подготовки буфера достаточного размера. В этот буфер записываются принимаемые данные. Операция отправки или приема сообщения считается завершенной, если
Разновидности обменов сообщениями В MPI реализованы разные виды обменов. Прежде всего, это двухточечные (задействованы только два процесса) и коллективные (задействованы более двух процессов). Двухточечные обмены используются для организации локальных и неструктурированных коммуникаций. При выполнении глобальных операций используются коллективные обмены. Асинхронные коммуникации реализуются с помощью запросов о получении сообщений. Имеется несколько разновидностей двухточечного обмена. Блокирующие прием/передача — приостанавливают выполнение процесса на время приема сообщения. Неблокирующие прием/передача — выполнение процесса продолжается в фоновом режиме, а программа в нужный момент может запросить подтверждение завершения приема сообщения. Синхронный обмен — сопровождается уведомлением об окончании приема сообщения. Асинхронный обмен — уведомлением не сопровождается.
В начале программы, сразу после ее заголовка, необходимо подключить соответствующий заголовочный файл. В программе на языке С это mpi. h: #include “mpi. h” В программе на языке FORTRAN это mpif. h: #include “mpif. h” В этих файлах содержатся описания констант и переменных библиотеки MPI. Первым вызовом библиотечной процедуры MPI в программе должен быть вызов подпрограммы инициализации MPI_Init, перед ним может располагаться только вызов MPI_Initialized, с помощью которого определяют, инициализирована ли система MPI.
Подключение к MPI int MPI_Init(int *argc, char **argv) MPI_INIT(IERR) Аргументы argc и argv требуются только в программах на C, где они задают количество аргументов командной строки запуска программы и вектор этих аргументов. Данный вызов предшествует всем прочим вызовам подпрограмм MPI. Завершение работы с MPI int MPI_Finalize() MPI_FINALIZE(IERR) После вызова данной подпрограммы нельзя вызывать подпрограммы MPI_FINALIZE должны вызывать все процессы перед завершением своей работы.
Определение размера области взаимодействия int MPI_Comm_size(MPI_Comm comm, int *size) MPI_COMM_SIZE(COMM. , SIZE, IERR) Входные параметры: comm — коммуникатор. Выходные параметры: size — количество процессов в области взаимодействия. Определение ранга процесса int MPI_Comm_rank(MPI_Comm comm, int *rank) MPI_COMM_RANK(COMM, RANK, IERR) Входные параметры: comm — коммуникатор. Выходные параметры: rank — ранг процесса в области взаимодействия.
Определение имени узла, на котором выполняется данный процесс MPI_Get_processor_name(char *name, int *resultlen) MPI_GET_PROCESSOR_NAME(NAME, RESULTLEN, IERR) Выходные параметры: name — идентификатор вычислительного узла. Массив не менее чем из MPI_MAX_PROCESSOR_NAME элементов; resultlen — длина имени. Время, прошедшее с произвольного момента в прошлом double MPI_Wtime() MPI_WTIME(TIME, IERR)
Простейшая MPI-программа на языке С #include “mpi. h” #include
Двухточечный обмен Участниками двухточечного обмена являются два процесса: процессотправитель и процесс- получатель коммуникационная
Описание интерфейса подпрограмм, реализующих разные виды двухточечного обмена. Стандартная блокирующая передача int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) MPI_SEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERR) Входные параметры: buf — адрес первого элемента в буфере передачи; count — количество элементов в буфере передачи; datatype — тип MPI каждого пересылаемого элемента; dest — ранг процесса-получателя сообщения (целое число от 0 до n - 1, где n — число процессов в области взаимодействия); tag — тег сообщения; comm — коммуникатор; ierr — код завершения.
Стандартный блокирующий прием int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status) MPI_RECV(BUF, COUNT, DATATYPE, SOURCE, TAG, COMM, STATUS, IERR) Входные параметры: count — максимальное количество элементов в буфере приема. Фактическое их количество можно определить с помощью подпрограммы MPI_Get_count; datatype — тип принимаемых данных. Необходимо соблюдать соответствие типов аргументов подпрограмм приема и передачи; source — ранг источника. Можно использовать специальное значение MPI_ANY_SOURCE, соответствующее произвольному значению ранга. Идентификатор, отвечающий произвольному значению параметра, часто называют "джокером"; tag — тег сообщения или "джокер" MPI_ANY_TAG, соответствующий произвольному значению тега; comm — коммуникатор. При указании коммуникатора "джокеры" использовать нельзя. Выходные параметры: buf — начальный адрес буфера приема. Его размер должен быть достаточным, чтобы разместить принимаемое сообщение, иначе при выполнении приема произойдет сбой — возникнет ошибка переполнения; status — статус обмена. Если сообщение меньше, чем буфер приема, изменяется содержимое лишь тех ячеек памяти буфера, которые относятся к сообщению.
Определение размера полученного сообщения (count) int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count) MPI_GET_COUNT(STATUS, DATATYPE, COUNT, IERR) Аргумент datatype должен соответствовать типу данных, указанному в операции передачи сообщения. Синхронная передача int MPI_Ssend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) MP I_S SEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERR) Параметры этой подпрограммы совпадают с параметрами подпрограммы MPI_Send. Буферизованный обмен int MPI_Bsend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) MPI_BSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERR) Параметры совпадают с параметрами подпрограммы MPI_Send.
Создание буфера int MPI_Buffer_attach(void *buf, size) MPI_BUFFER_ATTACH(BUF, SIZE, IERR) Выходной параметр: buf — буфер размером size байтов. В программах на языке Fortran роль буфера может играть массив. Этот массив должен быть описан в программе, его не следует использовать для других целей (например, в качестве первого аргумента подпрограммы MPI_Bsend). За один раз к процессу может быть подключен только один буфер. Отключение буфера int MPI_Buffer_detach(void *buf, int *size) MPI_BUFFER_DETACH(BUF, SIZE, IERR) Выходные параметры: buf — адрес; size — размер отключаемого буфера. Вызов данной подпрограммы блокирует работу процесса до тех пор, пока все сообщения, находящиеся в буфере, не будут обработаны. В языке C данный вызов не освобождает автоматически память, отведенную для буфера.
Передача по готовности int MPI_Rsend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm) MPI_RSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERR) Параметры совпадают с параметрами подпрограммы MPI_Send. Блокирующая проверка доставки сообщения int MPI_Probe(int source, int tag, MPI_Comm comm, MPI_Status *status) MPI_PROBE(SOURCE, TAG, COMM, STATUS, IERR) Входные параметры: source — ранг источника или "джокер"; tag — значение тега или "джокер"; comm — коммуникатор. Выходной параметр: status — статус.
Неблокирующая проверка сообщения int MPI_Iprobe(int source, int tag, MPI_Comm comm, int *flag, MPI_Status *status) MPI_IPROBE(SOURCE, TAG, COMM, FLAG, STATUS, IERR) Входные параметры этой подпрограммы те же, что и у подпрограммы MPI_Probe. Выходные параметры: flag — флаг; status — статус. Если сообщение уже поступило и может быть принято, возвращается значение флага "истина".
Прием и передача данных с блокировкой int MPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dest, int sendtag, void *recvbuf, int recvcount, MPI_Datatype recvtype, int source, int recvtag, MPI_Comm comm, MPI_Status *status) MPI_SENDRECV(SENDBUF, SENDCOUNT, SENDTYPE, DEST, SENDTAG, RECVBUF, RECVCOUNT, RECVTYPE, SOURCE, RECVTAG, COMM, STATUS, IERR) Входные параметры: sendbuf — начальный адрес буфера передачи; sendcount — количество передаваемых элементов; sendtype — тип передаваемых элементов; dest — ранг адресата; sendtag — тег передаваемого сообщения; recvbuf — начальный адрес буфера приема; recvcount — количество элементов в буфере приема; recvtype — тип элементов в буфере приема; source — ранг источника; recvtag — тег принимаемого сообщения; comm — коммуникатор. Выходные параметры: recvbuf — начальный адрес буфера приема; status — статус операции приема. Прием, и передача используют один и тот же коммуникатор. Буферы передачи и приема не должны пересекаться, у них может быть разный размер, типы пересылаемых и принимаемых данных
Отправка и прием сообщения в блокирующем режиме с общим буфером для передачи и для приема int MPI_Sendrecv_replace(void *buf, int count, MPI_Datatype datatype, int dest, int sendtag, int source, int recvtag, MPI_Comm comm, MPI_Status *status) MPI_SENDRECV_REPLACE(BUF, COUNT, DATATYPE, DEST, SENDTAG, SOURCE, RECVTAG, COMM, STATUS, IERR) Входные параметры: count — количество отправляемых данных и емкость буфера приема; datatype — тип данных в буфере приема и передачи; dest — ранг адресата; sendtag — тег передаваемого сообщения; source — ранг источника; recvtag — тег принимаемого сообщения; comm — коммуникатор. Выходные параметры: buf — начальный адрес буфера приема и передачи; status — статус. Принимаемое сообщение не должно превышать по размеру отправляемое сообщение, а передаваемые и принимаемые данные должны быть одного типа. Последовательность приема и передачи выбирается системой автоматически.
Инициализация неблокирующей стандартной передачи int MPI_Isend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) MPI_ISEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERR) Входные параметры этой подпрограммы аналогичны аргументам подпрограммы MPI_Send. Выходной параметр: request — идентификатор операции. Инициализация неблокирующей синхронной передачи данных int MPI_Issend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) MPI_ISSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERR) Параметры этой подпрограммы совпадают с параметрами подпрограммы MPI_Send.
Неблокирующая буферизованная передача сообщения int MPI_Ibsend(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request) MPI_IBSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERR) Неблокирующая передача "по готовности" int MPI_Irsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_request *request) MPI_IRSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERR) Параметры всех подпрограмм неблокирующей передачи совпадают.
Блокировка работы процесса до завершения приема или передачи сообщения int MPI_Wait(MPI_Request *request, MPI_Status *status) MPI_WAIT(REQUEST, STATUS, IERR) Входной параметр: request — идентификатор операции обмена. Выходной параметр: status — статус выполненной операции. Значение статуса для операции передачи сообщения можно получить вызовом подпрограммы MPI_Test_cancelled. Можно вызвать MPI_Wait с пустым или неактивным аргументом request. В этом случае операция завершается сразу же с пустым статусом. Успешное выполнение подпрограммы MPI_Wait после вызова MPI_Ibsend подразумевает, что буфер передачи можно использовать вновь, то есть пересылаемые данные отправлены или скопированы в буфер, выделенный при вызове подпрограммы MPI_Buffer_attach. В этот момент уже нельзя отменить передачу. Если не будет зарегистрирован соответствующий прием, буфер нельзя будет освободить. В этом случае можно применить подпрограмму MPI_Cancel, которая освобождает память, выделенную подсистеме коммуникаций.


