1 1 Передача сообщений

Посылка сообщений в PVM предназначена для передачи данных между различными процессам и состоит из трех шагов. Во-первых, буфер данных перед посылкой должен быть проинициализирован с использованием функций pvm_initsend() или pvm_mkbuf(). Во-вторых, пересылаемые данные должны быть "упакованы" в этот буфер. Для упаковки используется некоторе количество комбинаций вызовов функции pvm_pk*(). В FORTRANе упаковка данных производится подпрограмой pvmfpack(). Третий шаг заключается в пересылке данных адресатам. Для этой цели в зависимости от списка адресатов используется вызов функции pvm_send(), в параметрах которой указывается конкретный процесс-приемник, или функции pvm_mcast(), используемой для всенаправленной передачи (то есть всем процессам сразу).

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

  • для приема любых сообщений
  • для приема любых сообщений от определенного источника
  • для приема любых сообщений с определенным message tag
  • для приема любых сообщений с определенным message tag от определенного источника

Кроме того, существует функция для проверки факта доставки сообщения адресату.

Буфер сообщения

call pvmfinitsend( encoding, bufid )

Если пользователь использует только один буфер сообщения (обычно так и делается), то единственная необходимая для работы с буфером функция - это pvm_initsend(). Эта функция вызывается непосредственно перед упаковкой новой порции пересылаемых данных в буфер сообщения. Функция pvm_initsend освобождает буфер и создает новый для упаковки в него даных. Схема кодировки упаковываемых в буфер данных указывается заданием переменной encoding. Возвращаемое в переменную bufid значение является идентификатором буфера.

Переменная encoding может принимать следующие значения:

PvmDataDefault - XDR кодировка, используемая в PVM по умолчанию. Эта кодировка используется обычно в гетерогенных кластерах, когда PVM не может знать понимает ли принимающая сторона передаваемый формат данных. Например, когда данные передаются с Linux-машины на Windows-машину. В случае, когда в кластере используется только один тип операционной машины или когда пользователь уверен, что принимающая сторона поймет все правильно, следует использовать тип кодировки PvmDataRaw.

PvmDataRaw - без кодировки. Даные передаются без каких либо изменений. Если принимающая сторона не сможет правильно прочитать этот формат, это вызовет возврат кода ошибки в процессе распаковки.

PvmDataInPlace - данные остаются на месте, не перемещаясь в буфер посылки. Этот тип кодировки можно использовать для снижения накладных расходов, связанных с перемещением данных в буфер. В этом случае буфер содержит только длины и указатели на передаваемые данные. Когда вызвана pvm_send(), данные копируются непосредственно с того места, где они асположены. Использование этой кодировки накладывает одно ограничение. Передаваемые данные не должны быть изменены между моментом, когда началась их упаковка и моментом окончания передачи буфера сообщения адресату. Однако, при использовании данного типа упаковки, имеется одно заметное преимущество. Функция упаковки pvm_initsend может быть вызвана только один раз в начале прогарммы. Например в начале работы программы мы можем упаковать данные из области перекрытия (см. главу "Декомпозиция данных") и передавать их множество раз по мере необходимости.

Упаковка данных

Для FORTRANа существует только одна функция, которая управялет упаковкой данных всех типов.

call pvmfpack( what, xp, nitem, stride, info )

В пареметре what указывается тип упаковываемых данных. Параметр xp является первым элементом массива данных. Пареметры nitem и stride описаны выше. Параметр info - возвращаемое значение. Значения параметра what представлены в следующей таблице:

STRING          0       REAL4           4
BYTE1           1       COMPLEX8        5
INTEGER2        2       REAL8           6
INTEGER4        3       COMPLEX16       7

Константы, соответствующие значениям параметра what определены в файле pvm3/include/fpvm3.h. Некоторые производители могут расширять этот список дополнительными данными, например INTEGER8, REAL16 и др.

Приведем пример использования всех этих функций:

CALL PVMFINITSEND(PVMRAW, INFO)
CALL PVMFPACK( INTEGER4, NSIZE, 1, 1, INFO )
CALL PVMFPACK( STRING, `row 5 of NXN matrix', 19, 1, INFO )
CALL PVMFPACK( REAL8, A(5,1), NSIZE, NSIZE , INFO )
CALL PVMFSEND( TID, MSGTAG, INFO )

Прием и посылка данных

call pvmfsend( tid, msgtag, info )
call pvmfmcast( ntask, tids, msgtag, info )

Функция pvm_send() помечает сообщение тагом msgtag и выполняет немедленную пересылку данных процессу с соответствющим идентификатором tid.

Функция pvm_mcast() помечает сообщение тагом msgtag и выполняет немедленную пересылку данных все процессам, имеющим идентификаторы, совпадающими со значениями, хранящимися в массиве tids. Длина массива tids равна ntask.

Следующие функции предназначены для совмещения работы по упаковке данных и их пересылке:

call pvmfpsend( tid, msgtag, xp, cnt, type, info )

Эти функции упаковывают массив определенного параметром type типа в буфер и передают его процессу, идентифицированному параметром tid. В FORTRANе типы данных определены так же, как и для процедуры pvmfpack().

Система PVM содержит несколько методов для организации приема сообщений. Причем отсутствует соотыктствие функций. То есть нет такого ограничения, когда сообщение, посланное процедурой pvm_psend должно быть обязательно принято процедурой с именем тип pvm_precv. Вне зависимости от того, как было послано сообщение, принято оно может быть либым из возможных вариантов. То же замечание касается адресной и мультикастной (multicast) передачи.

Следующие процедуры осуществляют блокирующий прием сообщений:

call pvmfrecv( tid, msgtag, bufid )

Эти процедуры инициируют процесс ожидания поступления сообщения, помеченного тагом msgtag от процеса с идентификатором tid (если сообщение еще не пришло). В случае, когда значения параметров tid и/или msgtag равны -1, осуществляется ожидание сообщения от любого процесса и/или сообщения с любым тагом.

После того, как сообщение получено, эти процедуры возвращают управление вызвавшей их программе, передав в bufid идентификатор буфера, в который помещено полученное сообщение. Значение bufid<0 сигнализирует о возникшей ошибке.

Аналогом блокирующей функции являются функция

call pvmfnrecv( tid, msgtag, bufid )

Параметры и возвращаемое значение этой функции аналогичны используемым в блокирующей функции. Отличие заключается в том, что вызов pvm_nrecv не инициирует процесс ожидания сообщения. В случае, если ожидаемое сообщение еще не поступило, в bufid возвращается 0. Функция pvm_nrecv может быть вызвана в процессе счета неоднократно.

В случае, когда ожидание сообщения не должно прерывать выполнение программы, для проверки факта получения сообщения можно использовать слудующую функцию:

call pvmfprobe( tid, msgtag, bufid )

Если ожидаемое сообщение еще не пришло, эта функция возвращает bufid=0. По пришествии сообщения в bufid возвращается значение отличное от нуля. Функцию можно вызывать неоднократно, заполняя время между вызовами какой-либо другой продуктивной работой. Функция pvm_probe не получает сообщение, для его получение необходимо воспользоваться одной из соответствующих функций.

Вместо последовательного вызова процедур блокирующего приема сообщения и распаковки буфера с извлечением данных в локальные переменные можно использовать функцию

call pvmfprecv( tid, msgtag, xp, cnt, type, rtid, rtag, rcnt, info )

Эту функцию можно использовать для приема сообщений, в которых содержатся однотипные данные. Вызов этой функции инициирует процесс ожидания сообщения, помеченного тагом msgtag от процесса с идентификатором tid. По поступлении сообщения pvm_precv распаковывает данные общим объемом len * (size of data type) в буфер buf.

Типы данных в FORTRAN-программах такие же, как это дано в описании функции pvmfpack.

Описание параметров функций:

tidID процесса откуда мы ждем сообщение. "-1" означает "любой процесс".
msgtagОжидаемый таг сообщения. "-1" означает "любое сообщение".
vpУказатель на массив (переменную) куда будут помещены полученные данные.
xpМассив (переменная) куда будут помещены полученные данные. (FORTRAN)
cntКоличество ожидаемых элементов указанного типа.
typeТип получаемых данных (см. выше).
rtidВозвращаемый параметр. ID процесса, откуда пришло сообщение.
rtagВозвращаемый параметр. Таг (метка) полученного сообщения.
rcntВозвращаемый параметр. Длина полученного сообщения (кол-во элементов).
infoСодержит на выходе PvmOk если все нормально и отрицательное значение в случае ошибки.

Распаковка полученных данных

Функции распаковки данных, записанных в приемном буфере, применяются в той же последовательности, в какой применялись функции упаковки данных в посылаемое сообщение.

call pvmfunpack( what, xp, nitem, stride, info )

Параметр xp - массив, куда будут помещены распакованные данные.
Параметры nitem и stride имеют тот же смысл, что и в соответствующих функциях упаковки (см. выше).
Параметр what был так же описан выше.


Copyleft © 1998-2009 Юрий Сбитнев