Главная страница

Программирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В.. Программирование для многопроцессорных систем в стандарте MPI -. Организация вычислений в многопроцессорных системах


Скачать 1.61 Mb.
НазваниеОрганизация вычислений в многопроцессорных системах
АнкорПрограммирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В..pdf
Дата15.03.2018
Размер1.61 Mb.
Формат файлаpdf
Имя файлаПрограммирование для многопроцессорных систем в стандарте MPI - .pdf
ТипКонтрольные вопросы
#16702
КатегорияИнформатика. Вычислительная техника
страница8 из 26
1   ...   4   5   6   7   8   9   10   11   ...   26
MPI_TEST_CANCELLED (status, flag)
IN status статус (Status)
OUT flag
(логический тип ) int MPI_Test_cancelled(MPI_Status *status, int *flag)
MPI_TEST_CANCELLED(STATUS, FLAG, IERROR)
LOGICAL FLAG
INTEGER STATUS(MPI_STATUS_SIZE), IERROR bool MPI::Status::Is_cancelled () const
Функция
MPI_TEST_CANCELLED
возвращает
flag = true
, если обмен, связанный со статусным объектом, был отменен успешно. В таком случае все другие поля статуса (такие как
count
или
tag
) не оп- ределены. В противном случае возвращается
flag = false
3.9. СОВМЕЩЕННЫЕ ПРИЕМ И ПЕРЕДАЧА СООБЩЕНИЙ
Операция
send–receive
комбинирует в одном обращении посылку сообщения одному получателю и прием сообщения от другого отпра- вителя. Получателем и отправителем может быть тот же самый про- цесс. Эта операция весьма полезна для выполнения сдвига по цепи

82
процессов. Если для такого сдвига были использованы блокирующие приемы и передачи, тогда нужно корректно упорядочить эти приемы и передачи так, чтобы предупредить циклические зависимости, кото- рые могут привести к дедлоку.
MPI_SENDRECV
выполняет операции блокируемой передачи и приема. Передача и прием используют тот же самый коммуникатор, но, возможно, различные тэги. Буфера отправителя и получателя должны быть разделены и могут иметь различную длину и типы дан- ных. Сообщение, посланное операцией
send–receive
, может быть по- лучено обычной операцией приема или опробовано операцией
probe
,
send–receive
может также получать сообщения, посланные обычной операцией передачи.
MPI_SENDRECV(sendbuf, sendcount, sendtype, dest, sendtag,
recvbuf, recvcount, recvtype, source, recvtag, comm, status)
IN sendbuf начальный адрес буфера отправителя (альтернатива)
IN sendcount число элементов в буфере отправителя (целое)
IN sendtype тип элементов в буфере отправителя (дескриптор)
IN dest номер процесса-получателя (целое)
IN sendtag тэг процесса-отправителя (целое)
OUT recvbuf начальный адрес приемного буфера (альтернатива)
IN recvcount число элементов в приемном буфере (целое)
IN recvtype тип элементов в приемном буфере (дескриптор)
IN source номер процесса-отправителя (целое)
IN recvtag тэг процесса-получателя (целое)
IN comm коммуникатор (дескриптор)
OUT status статус (статус) int MPI_Sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype, int dest, int sendtag, void *recvbuf, int recvcount, MPI_Datatype recvtype, int source,
MPI_Datatype recvtag, MPI_Comm comm, MPI_Status *status)
MPI_SENDRECV(SENDBUF, SENDCOUNT, SENDTYPE, DEST, SENDTAG,
RECVBUF, RECVCOUNT, RECVTYPE, SOURCE, RECVTAG,
COMM, STATUS, IERROR)
SENDBUF(*), RECVBUF(*)
INTEGER SENDCOUNT, SENDTYPE, DEST, SENDTAG, RECVCOUNT,
RECVTYPE, SOURCE, RECVTAG, COMM,
STATUS(MPI_STATUS_SIZE), IERROR void MPI::Comm::Sendrecv(const void *sendbuf, int sendcount, const MPI::Datatype& sendtype, int dest, int sendtag, void *recvbuf, int recvcount, const MPI::Datatype& recvtype, int source, int recvtag, MPI::Status& status) const

83
MPI_SENDRECV_REPLACE
выполняет блокируемые передачи и приемы. Тот же самый буфер используется для отправки и получе- ния, так что посланное сообщение замещается полученным.
MPI_SENDRECV_REPLACE (buf, count, datatype, dest,
sendtag, source, recvtag, comm, status)
INOUT buf начальный адрес буфера отправителя и получателя
(альтернатива)
IN count число элементов в буфере отправителя и получателя (целое)
IN datatype тип элементов в буфере отправителя и получателя (дескриптор)
IN dest номер процесса-получателя (целое)
IN sendtag тэг процесса-отправителя (целое)
IN source номер процесса-отправителя (целое)
IN recvtag тэг процесса-получателя (целое)
IN comm коммуникатор (дескриптор)
OUT 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, IERROR)
BUF(*)
INTEGER COUNT, DATATYPE, DEST, SENDTAG, SOURCE, RECVTAG,
COMM, STATUS(MPI_STATUS_SIZE), IERROR void MPI::Comm::Sendrecv_replace (void* buf, int count, const MPI::Datatype& datatype, int dest, int sendtag, int source, int recvtag, MPI::Status& status) const
Семантика операции
send–receive
похожа на запуск двух конкури- рующих потоков, один выполняет передачу, другой – прием, с после- дующим объединением этих потоков. Во многих случаях удобно опи- сать "фиктивный" отправитель или получатель для коммуникаций.
Это упрощает код, который необходим для работы с границами, на- пример, в случае нециклического сдвига, выполненного по вызову
send–receive
. Когда в вызове нужны аргументы отправителя или по- лучателя, вместо номера может быть использовано специальное зна- чение
MPI_PROC_NULL.
Обмен с процессом, который имеет значе- ние
MPI_PROC_NULL,
не дает результата. Передача в процесс с
MPI_PROC_NULL
успешна и заканчивается сразу, как только воз- можно. Прием от процесса с
MPI_PROC_NULL
успешен и заканчи- вается сразу, как только возможно без изменения буфера приема. Ко- гда выполняется прием с
source = MPI_PROC_NULL
, тогда статус возвращает
source = MPI_PROC_NULL, tag = MPI_ANY_TAG
и
count = 0

84
3.10. ПРОИЗВОДНЫЕ ТИПЫ ДАННЫХ
До сих пор все парные обмены использовали только непрерывные буфера, содержащие последовательности элементов одного типа. Час- то необходимо передавать сообщения, которые содержат значения различных типов или посылать несмежные данные. Одно из решений состоит в том, чтобы упаковать несмежные данные в смежный буфер на стороне отправителя и распаковать обратно на приемной стороне.
Это неэффективно, поскольку требуется дополнительная операция копирования память–память на обеих сторонах. MPI обеспечивает ме- ханизм для описания общих буферов для несмежных коммуникаций, в которых используются производные типы данных, образуемые конст- рукторами, описанными в этом разделе.
Универсальный тип данных
есть скрытый объект, который опи- сывается двумя составляющими: последовательностью базисных ти- пов и последовательностью целых (байтовых) смещений.
Не требуется, чтобы смещения были положительными, различны- ми или возрастающего порядка. Порядок объектов не обязан совпа- дать с их порядком в памяти, и объект может появляться более чем один раз.
Последовательность указанных выше пар называется
картой ти-
па
. Последовательность базисных типов данных (смещения игнори- руются) есть
сигнатура типа.
Можно использовать дескриптор обще- го типа данных как аргумент в операциях передачи или приема вместо аргумента базисного типа данных.
Операция
MPI_SEND
(
buf, 1, datatype,...)
будет использовать бу- фер посылки, определенный базовым адресом
buf
и общим типом данных, связанным с
datatype
; она будет генерировать сообщение с сигнатурой типа, определенной аргументом
datatype.
Базисные типы данных, представленные в 3.2.2, – частные случаи универсального типа и являются предопределенными
(например,
MPI_INT
есть предопределенный указатель на тип данных с одним элементом типа
int
и смещением равным нулю).
Экстент
(
extent)
типа данных определяется как пространство, от первого байта до последнего байта, занятое элементами этого типа данных, округленное вверх с учетом требований выравнивания дан- ных.

85
3.10.1. Конструкторы типа данных
Простейшим типом конструктора типа данных является конструк- тор
MPI_TYPE_CONTIGUOUS
, который позволяет копировать тип данных в смежные области.
MPI_TYPE_CONTIGUOUS (count, oldtype, newtype)
IN count число повторений (неотрицательное целое)
IN oldtype старый тип данных (дескриптор)
OUT newtype новый тип данных (дескриптор) int MPI_Type_contiguous(int count, MPI_Datatype oldtype, MPI_Datatype *newtype)
MPI_TYPE_CONTIGUOUS(COUNT, OLDTYPE, NEWTYPE, IERROR)
INTEGER COUNT, OLDTYPE, NEWTYPE, IERROR
MPI::Datatype MPI::Datatype::Create_contiguous (int count) const
Новый тип
newtype
есть тип, полученный конкатенацией (сцепле- нием)
count
копий старого типа
oldtype
Функция
MPI_TYPE_VECTOR
является универсальным конст- руктором, который позволяет реплицировать типы данных в области, которые состоят из блоков равного объема. Каждый блок получается как конкатенация некоторого количества копий старого типа. Про- странство между блоками кратно размеру
old datatype
MPI_TYPE_VECTOR ( count, blocklength, stride, oldtype, newtype)
IN count число блоков (неотрицательное целое)
IN blocklength число элементов в каждом блоке (неотрицательное целое)
IN stride число элементов между началами каждого блока (целое)
IN oldtype старый тип данных (дескриптор)
OUT newtype новый тип данных (дескриптор) int MPI_Type_vector(int count, int blocklength, int stride,MPI_Datatype oldtype,
MPI_Datatype *newtype)
MPI_TYPE_VECTOR(COUNT, BLOCKLENGTH, STRIDE, OLDTYPE,
NEWTYPE, IERROR)
INTEGER COUNT, BLOCKLENGTH, STRIDE, OLDTYPE, NEWTYPE, IERROR
MPI::Datatype MPI::Datatype::Create_vector (int count, int blocklength, int stride) const

86
Функция
MPI_TYPE_HVECTOR
идентична за исключением то- го, что страйд задается в байтах, а не в элементах. (
H
соответствует слову heterogeneous – неоднородный.)
MPI_TYPE_HVECTOR ( count, blocklength, stride, oldtype, newtype)
IN count число блоков (неотрицательное целое)
IN blocklength число элементов в каждом блоке (неотрицательное целое)
IN stride число байтов между началом каждого блока (целое)
IN oldtype старый тип данных (дескриптор)
OUT newtype новый тип данных (дескриптор) int MPI_Type_hvector(int count, int blocklength, MPI_Aint stride,
MPI_Datatype oldtype, MPI_Datatype *newtype)
MPI_TYPE_HVECTOR(COUNT, BLOCKLENGTH, STRIDE, OLDTYPE,
NEWTYPE, IERROR)
INTEGER COUNT, BLOCKLENGTH, STRIDE, OLDTYPE, NEWTYPE, IERROR
MPI::Datatype MPI::Datatype::Create_hvector (int count, int blocklength,
MPI::Aint stride) const
Функция
MPI_TYPE_INDEXED
позволяет реплицировать старый тип
old datatype
в последовательность блоков (каждый блок есть кон- катенация
old datatype
), где каждый блок может содержать различное число копий и иметь различное смещение. Все смещения блоков кратны длине старого блока
oldtype
MPI_TYPE_INDEXED(count, array_of_blocklengths,
array_of_displacements, oldtype, newtype)
IN count число блоков
IN array_of_blocklengths число элементов в каждом блоке (массив неотри- цательных целых)
IN array_of_displacements смещение для каждого блока (массив целых)
IN oldtype старый тип данных (дескриптор)
OUT newtype новый тип данных (дескриптор) int MPI_Type_indexed(int count, int *array_of_blocklengths, int *array_of_displacements, MPI_Datatype oldtype, MPI_Datatype *newtype)
MPI_TYPE_INDEXED(COUNT, ARRAY_OF_BLOCKLENGTHS,
ARRAY_OF_DISPLACEMENTS, OLDTYPE, NEWTYPE, IERROR)
INTEGER COUNT, ARRAY_OF_BLOCKLENGTHS(*),
ARRAY_OF_DISPLACEMENTS(*), OLDTYPE, NEWTYPE, IERROR
MPI::Datatype MPI::Datatype::Create_indexed(int count, const int array_of_blocklengths[], const int array_of_displacements[]) const

87
Функция
MPI_TYPE_HINDEXED
идентична.
MPI_TYPE_HINDEXED (count, array_of_blocklengths,
array_of_displacements, oldtype, newtype)
IN count число блоков (неотрицательное целое)
IN array_of_blocklengths число элементов в каждом блоке (массив неотри- цательных целых)
IN array_of_displacements смещение каждого блока в байтах (массив целых)
IN oldtype старый тип данных (дескриптор)
OUT newtype новый тип данных (дескриптор) int MPI_Type_hindexed(int count, int *array_of_blocklengths,
MPI_Aint *array_of_displacements, MPI_Datatype oldtype, MPI_Datatype *newtype)
MPI_TYPE_HINDEXED(COUNT, ARRAY_OF_BLOCKLENGTHS,
ARRAY_OF_DISPLACEMENTS, OLDTYPE, NEWTYPE, IERROR)
INTEGER COUNT, ARRAY_OF_BLOCKLENGTHS(*),
ARRAY_OF_DISPLACEMENTS(*), OLDTYPE, NEWTYPE, IERROR
Смещения блоков в массиве
array_of_displacements
задаются в байтах, а не в кратностях ширины старого типа
oldtype
MPI_TYPE_STRUCT
является общим типом конструктора. Он отличается от предыдущего тем, что позволяет каждому блоку состо- ять из репликаций различного типа.
MPI_TYPE_STRUCT (count, array_of_blocklengths,
array_of_displacements, array_of_types, newtype)
IN count число блоков (целое)
IN array_of_blocklength число элементов в каждом блоке (массив целых)
IN array_of_displacements смещение каждого блока в байтах (массив целых)
IN array_of_types тип элементов в каждом блоке (массив дескрипто- ров объектов типов данных)
OUT newtype новый тип данных (дескриптор) int MPI_Type_struct(int count, int *array_of_blocklengths, MPI_Aint
*array_of_displacements, MPI_Datatype *array_of_types, MPI_Datatype *newtype)
MPI_TYPE_STRUCT(COUNT, ARRAY_OF_BLOCKLENGTHS,
ARRAY_OF_DISPLACEMENTS, ARRAY_OF_TYPES, NEWTYPE, IERROR)
INTEGER COUNT, ARRAY_OF_BLOCKLENGTHS(*),
ARRAY_OF_DISPLACEMENTS(*), ARRAY_OF_TYPES(*), NEWTYPE, IERROR

88
Обращение к
MPI_TYPE_HINDEXED
(count, B, D, oldtype, new- type) эквивалентно обращению к
MPI_TYPE_STRUCT
(count, B, D, T, newtype), где каждый вход T равен oldtype.
3.10.2. Адресные функции и функции
экстентов
Смещения в универсальном типе данных задаются относительно начального буферного адреса. Этот начальный адрес “нуль” отмечает- ся константой
MPI_BOTTOM
. Поэтому тип данных может описывать абсолютный адрес элементов в коммуникационном буфере, в этом случае аргумент
buf
получает значение
MPI_BOTTOM
Адрес ячейки памяти может быть найден путем использования функции
MPI_ADDRESS
MPI_ADDRESS (location, address)
IN location ячейка в памяти (альтернатива)
OUT address адрес ячейки (целое) int MPI_Address(void* location, MPI_Aint *address)
MPI_ADDRESS(LOCATION, ADDRESS, IERROR)
LOCATION(*)
INTEGER ADDRESS, IERROR
Функция
MPI_ADDRESS
возвращает байтовый адрес ячейки.
Пример 3.17.
Использование
MPI_ADDRESS
для массива.
REAL A(100,100)
INTEGER I1, I2, DIFF
CALL MPI_ADDRESS(A(1,1), I1, IERROR)
CALL MPI_ADDRESS(A(10,10), I2, IERROR)
DIFF = I2 – I1
! значение DIFF есть 909*sizeofreal; значение I1 и I2 зависят от реализации.
Функция
MPI_TYPE_EXTENT
возвращает экстент типа данных.
MPI_TYPE_EXTENT(datatype, extent)
IN datatype тип данных (дескриптор)
OUT extent экстент типа данных (целое) int MPI_Type_extent(MPI_Datatype datatype, MPI_Aint *extent)
MPI_TYPE_EXTENT(DATATYPE, EXTENT, IERROR)
INTEGER DATATYPE, EXTENT, IERROR

89
Функция
MPI_TYPE_SIZE
возвращает общий размер в байтах элементов в сигнатуре типа, связанной с
datatype
, то есть общий раз- мер данных в сообщении, которое было бы создано с этим типом дан- ных. Элементы, которые появляются несколько раз в типе данных, подсчитываются с учетом их кратности.
MPI_TYPE_SIZE (datatype, size)
IN datatype тип данных (дескриптор)
OUT size размер типа данных (целое) int MPI_Type_size (MPI_Datatype datatype, int *size)
MPI_TYPE_SIZE(DATATYPE, SIZE, IERROR)
INTEGER DATATYPE, SIZE, IERROR int MPI::Datatype::Get_size ( ) const
3.10.3. Маркеры нижней и верхней границ
Часто удобно явно указать нижнюю и верхнюю границы карты типа. Это позволяет определить тип данных, который имеет «дыры» в начале или конце, или тип с элементами, которые идут выше верхней или ниже нижней границы. Пользователь может явно описать грани- цы типа данных, которые соответствуют этим структурам. Чтобы дос- тичь этого, вводятся два дополнительных «псевдо-типа данных»:
MPI_LB
и
MPI_UB
, – которые могут быть использованы соответст- венно для маркировки нижней и верхней границ типа данных. Эти псевдотипы не занимают места
(
экстент (
MPI_LB
)
=
экстент
(
MPI_UB
)
=
0). Они не меняют
size
или
count
типа данных и не влия- ют на содержание сообщения, созданного с этим типом данных. Они влияют на определение экстента типа данных и, следовательно, влия- ют на результат репликации этого типа данных конструктором типа данных.
Две функции могут быть использованы для нахождения нижней и верхней границ типа данных.
MPI_TYPE_LB( datatype, displacement)
IN datatype тип данных (дескриптор)
OUT displacement смещение нижней границы от исходной в байтах (целое) int MPI_Type_lb(MPI_Datatype datatype, MPI_Aint* displacement)

90
MPI_TYPE_LB( DATATYPE, DISPLACEMENT, IERROR)
INTEGER DATATYPE, DISPLACEMENT, IERROR
MPI_TYPE_UB( datatype, displacement)
IN datatype тип данных (дескриптор)
OUT displacement смещение верхней границы от исходной в байтах (целое)
int MPI_Type_ub(MPI_Datatype datatype, MPI_Aint* displacement)
MPI_TYPE_UB( DATATYPE, DISPLACEMENT, IERROR)
INTEGER DATATYPE, DISPLACEMENT, IERROR
1   ...   4   5   6   7   8   9   10   11   ...   26


написать администратору сайта