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

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


Скачать 1.61 Mb.
НазваниеОрганизация вычислений в многопроцессорных системах
АнкорПрограммирование для многопроцессорных систем в стандарте MPI - Шпаковский Г.И., Серикова Н.В..pdf
Дата15.03.2018
Размер1.61 Mb.
Формат файлаpdf
Имя файлаПрограммирование для многопроцессорных систем в стандарте MPI - .pdf
ТипКонтрольные вопросы
#16702
КатегорияИнформатика. Вычислительная техника
страница12 из 26
1   ...   8   9   10   11   12   13   14   15   ...   26
Глава 5. ГРУППЫ И КОММУНИКАТОРЫ
5.1. ВВЕДЕНИЕ
В этом разделе рассматриваются средства MPI для поддержки раз- работки параллельных библиотек. Для создания устойчивых парал- лельных библиотек интерфейс MPI должен обеспечить:
• Возможность создавать безопасное коммуникационное простран- ство, которое гарантировало бы, что библиотеки могут выполнять обмен, когда им нужно, без конфликтов с обменами, внешними по отношению к данной библиотеке.
• Возможность определять границы области действия коллективных операций, которые позволяли бы библиотекам избегать ненужного запуска невовлеченных процессов.
• Возможность абстрактного обозначения процессов, чтобы библио- теки могли описывать свои обмены в терминах, удобных для их собственных структур данных и алгоритмов.
• Возможность создавать новые пользовательские средства, такие как дополнительные операции для коллективного обмена. Этот механизм должен обеспечить пользователя или создателя библио- теки средствами эффективного расширения состава операций для передачи сообщений.
Для поддержки библиотек MPI обеспечивает группы процессов
(groups), виртуальные топологии (virtual topologies), коммуникаторы
(communicators).
Коммуникаторы
создают область для всех операций обмена в
MPI. Коммуникаторы разделяются на два вида: интра-коммуникаторы
(внутригрупповые коммуникаторы), предназначенные для операций в пределах отдельной группы процессов, и интер-коммуникаторы (меж- групповые коммуникаторы), предназначенные для обменов между двумя группами процессов.
Группы.
Группы определяют упорядоченную выборку процессов по именам. Таким образом, группы определяют область для парных и коллективных обменов. В MPI группы могут управляться отдельно от коммуникаторов, но в операциях обмена могут использоваться только коммуникаторы.
Виртуальная топология
определяет специальное отображение номеров процессов в группе на определенную топологию, и наоборот.

144
Чтобы обеспечить эту возможность, в главе 6 для коммуникаторов определены специальные конструкторы.
5.2. БАЗОВЫЕ КОНЦЕПЦИИ
Группа
есть упорядоченный набор идентификаторов процессов;
процессы
есть зависящие от реализации объекты. Каждый процесс в группе связан с целочисленным номером. Нумерация является непре- рывной и начинается с нуля. Группы представлены скрытыми объек- тами группы и, следовательно, не могут быть непосредственно пере- даны от одного процесса к другому. Группа используется в пределах коммуникатора для описания участников коммуникационной области и ранжирования этих участников путем предоставления им уникаль- ных имен.
Имеется предопределенная группа:
MPI_GROUP_EMPTY
, кото- рая является группой без членов. Предопределенная константа
MPI_GROUP_NULL
является значением, используемым для оши- бочных дескрипторов группы.
Контекст
есть свойство коммуникаторов, которое позволяет раз- делять пространство обмена. Сообщение, посланное в одном контек- сте, не может быть получено в другом контексте. Более того, где это разрешено, коллективные операции независимы от ждущих операций парного обмена. Контексты не являются явными объектами MPI; они проявляются только как часть реализации коммуникаторов.
Интра-коммуникаторы
объединяют концепции группы и контек- ста для поддержки реализационно-зависимых оптимизаций и при- кладных топологий (глава 6). Операции обмена в MPI используют коммуникаторы для определения области, в которой должны выпол- няться парная или коллективная операции.
Каждый коммуникатор содержит группу участников; эта группа всегда участвует в локальном процессе. Источник и адресат сообще- ния определяются номером процесса в пределах этой группы.
Для коллективной связи интра-коммуникатор определяет набор процессов, которые участвуют в коллективной операции (и их поря- док, когда это существенно). Таким образом, коммуникатор ограни- чивает "пространственную" область коммуникации и обеспечивает машинно-независимую адресацию процессов их номерами.
Начальный для всех возможных процессов интра-коммуникатор
MPI_COMM_WORLD
создается сразу при обращении к функции
MPI_INIT
. Кроме того, существует коммуникатор, который cодержит

145
только себя как процесс –
MPI_COMM_SELF
. Предопределенная константа
MPI_COMM_NULL
есть значение, используемое для не- верных дескрипторов коммуникатора.
В реализации MPI со статической моделью обработки коммуника- тор
MPI_COMM_WORLD
имеет одинаковое значение во всех про- цессах. В реализации
MPI, где процессы могут порождаться динами- чески, возможен случай, когда процесс начинает вычисления, не имея доступа ко всем другим процессам. В таких ситуациях,
коммуникатор
MPI_COMM_WORLD
является коммуникатором, включающим все процессы, с которыми подключающийся процесс может немедленно связаться. Поэтому
MPI_COMM_WORLD
может одновременно иметь различные значения в различных процессах.
Все реализации
MPI должны обеспечить наличие коммуникатора
MPI_COMM_WORLD
. Он не может быть удален в течение времени существования процесса. Группа, соответствующая этому коммуника- тору, не появляется как предопределенная константа, но к ней можно обращаться, используя
MPI_COMM_GROUP
MPI не определяет со- ответствия между номером процесса в
MPI_COMM_WORLD
и его абсолютным адресом.
5.3. УПРАВЛЕНИЕ ГРУППОЙ
Операции управления являются локальными, и их выполнение не требует межпроцессного обмена.
5.3.1. Средства доступа в группу
MPI_GROUP_SIZE (group, size)
IN group группа (дескриптор)
OUT size количество процессов в группе (целое) int MPI_Group_size(MPI_Group group, int *size)
MPI_GROUP_SIZE(GROUP, SIZE, IERROR)
INTEGER GROUP, SIZE, IERROR int MPI::Group::Get_size() const
Функция
MPI_GROUP_SIZE
позволяет определить размер группы.
MPI_GROUP_RANK (group, rank)
IN group группа (дескриптор)
OUT rank номер процесса в группе или MPI_UNDEFINED, если процесс не является членом группы (целое)

146
int MPI_Group_rank(MPI_Group group, int *rank)
MPI_GROUP_RANK(GROUP, RANK, IERROR)
INTEGER GROUP, RANK, IERROR int MPI::Group::Get_rank() const
Функция
MPI_GROUP_RANK
служит для определения номера процесса в группе.
MPI_GROUP_TRANSLATE_RANKS(group1, n, ranks1, group2, ranks2)
IN group1 Группа1 (дескриптор)
IN n число номеров в массивах ranks1 и ranks2 (целое)
IN ranks1 массив из нуля или более правильных номеров в группе1
IN group2 группа2 (дескриптор)
OUT ranks2 массив соответствующих номеров в группе2,
MPI_UNDEFINED, если соответствие отсутствует. int MPI_Group_translate_ranks (MPI_Group group1, int n, int *ranks1,
MPI_Group group2, int *ranks2)
MPI_GROUP_TRANSLATE_RANKS(GROUP1, N, RANKS1, GROUP2, RANKS2,
IERROR)
INTEGER GROUP1, N, RANKS1(*), GROUP2, RANKS2(*), IERROR static void MPI::Group::Translate_ranks(const MPI::Group& group1, int n, const int ranks[], const MPI::Group& group2, int ranks2[])
Эта функция важна для определения относительной нумерации одинаковых процессов в двух различных группах. Например, если из- вестны номера некоторых процессов в
MPI_COMM_WORLD
, то можно узнать их номера в подмножестве этой группы.
MPI_GROUP_COMPARE(group1, group2, result)
IN group1 первая группа (дескриптор)
IN group2 вторая группа (дескриптор)
OUT result результат (целое) int MPI_Group_compare(MPI_Group group1,MPI_Group group2, int *result)
MPI_GROUP_COMPARE(GROUP1, GROUP2, RESULT, IERROR)
INTEGER GROUP1, GROUP2, RESULT, IERROR static int MPI::Group::Compare(const MPI::Group& group1, const MPI::Group& group2)
Если члены группы и их порядок в обеих группах совершенно одинаковы, вырабатывается результат
MPI_IDENT
. Это происходит,

147
например, если
group1
и
group2
имеют тот же самый дескриптор. Ес- ли члены группы одинаковы, но порядок различен, то вырабатывается результат
MPI_SIMILAR
. В остальных случаях получается значение
MPI_UNEQUAL
5.3.2. Конструкторы групп
Конструкторы групп применяются для подмножества и расши- ренного множества существующих групп. Эти конструкторы создают новые группы на основе существующих групп. Данные операции яв- ляются локальными, и различные группы могут быть определены на различных процессах; процесс может также определять группу, кото- рая не включает себя.
MPI не имеет механизма для формирования группы с нуля – груп- па может формироваться только на основе другой, предварительно определенной группы. Базовая группа, на основе которой определены все другие группы, является группой, связанной с коммуникатором
MPI_COMM_WORLD
(через функцию
MPI_COMM_GROUP
).
MPI_COMM_GROUP(comm, group)
IN comm коммуникатор (дескриптор)
OUT group группа, соответствующая comm (дескриптор) int MPI_Comm_group(MPI_Comm comm, MPI_Group *group)
MPI_COMM_GROUP(COMM, GROUP, IERROR)
INTEGER COMM, GROUP, IERROR
MPI::Group MPI::Comm::Get_group() const
Функция
MPI_COMM_GROUP
возвращает в
group
дескриптор группы из
comm.
MPI_GROUP_UNION(group1, group2, newgroup)
IN group1 первая группа (дескриптор)
IN group2 вторая группа (дескриптор)
OUT newgroup объединенная группа (дескриптор) int MPI_Group_union(MPI_Group group1, MPI_Group group2,
MPI_Group *newgroup)
MPI_GROUP_UNION(GROUP1, GROUP2, NEWGROUP, IERROR) INTEGER
GROUP1, GROUP2, NEWGROUP, IERROR static MPI::Group MPI::Group::Union(const MPI::Group& group1, const MPI::Group& group2)

148
Операции над множествами определяются следующим образом:

Объединение
(
union
)

содержит все элементы первой группы
(
group1
) и следующие за ними элементы второй группы (
group2
), не входящие в первую группу.

Пересечение
(
intersect
)

содержит все элементы первой группы, которые также находятся во второй группе, упорядоченные, как в первой группе.

Разность
(
difference
)

содержит все элементы первой группы, ко- торые не находятся во второй группе.
MPI_GROUP_INTERSECTION(group1, group2, newgroup)
IN group1 первая группа (дескриптор)
IN group2 вторая группа (дескриптор)
OUT newgroup группа, образованная пересечением (дескриптор) int MPI_Group_intersection(MPI_Group group1, MPI_Group group2,
MPI_Group *newgroup)
MPI_GROUP_INTERSECTION(GROUP1, GROUP2, NEWGROUP, IERROR)
INTEGER GROUP1, GROUP2, NEWGROUP, IERROR static MPI::Group MPI::Group::Intersect(const MPI::Group& group1, const MPI::Group& group2)
MPI_GROUP_DIFFERENCE(group1, group2, newgroup)
IN group1 первая группа(дескриптор)
IN group2 вторая группа (дескриптор)
OUT newgroup исключенная группа (дескриптор) int MPI_Group_difference(MPI_Group group1, MPI_Group group2,
MPI_Group *newgroup)
MPI_GROUP_DIFFERENCE(GROUP1, GROUP2, NEWGROUP, IERROR)
INTEGER GROUP1, GROUP2, NEWGROUP, IERROR static MPI::Group MPI::Group::Difference(const MPI::Group& group1, const MPI::Group& group2)
Для этих операций порядок процессов в результирующей группе определен, прежде всего, в соответствии с порядком в первой группе и затем, в случае необходимости, в соответствии с порядком во вто- рой группе. Ни объединение, ни пересечение не коммутативны, но обе ассоциативны. Новая группа может быть пуста (эквивалентна
MPI_GROUP_EMPTY)

149
MPI_GROUP_INCL(group, n, ranks, newgroup)
IN group группа (дескриптор)
IN n количество элементов в массиве номеров (и размер newgroup, целое)
IN ranks номера процессов в group, перешедших в новую группу
(массив целых)
OUT newgroup новая группа, полученная из прежней, упорядоченная согласно ranks (дескриптор) int MPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group *newgroup)
MPI_GROUP_INCL(GROUP, N, RANKS, NEWGROUP, IERROR)
INTEGER GROUP, N, RANKS(*), NEWGROUP, IERROR
MPI::Group MPI::Group::Incl(int n, const int ranks[]) const
Функция
MPI_GROUP_INCL
создает группу
newgroup
, которая состоит из
n
процессов из
group
с номерами
rank[0],..., rank[n-1];
процесс с номером
i
в
newgroup
есть процесс с номером
ranks[i]
в
group
. Каждый из
n
элементов
ranks
должен быть правильным номе- ром в
group
, и все элементы должны быть различными, иначе про- грамма будет неверна. Если
n = 0
, то
newgroup
имеет значение
MPI_GROUP_EMPTY
. Эта функция может, например, использо- ваться, чтобы переупорядочить элементы группы.
MPI_GROUP_EXCL(group, n, ranks, newgroup)
IN group группа (дескриптор)
IN n количество элементов в массиве номеров (целое)
IN ranks массив целочисленных номеров в group, не входящих в newgroup
OUT newgroup новая группа, полученная из прежней, сохраняющая порядок, определенный group (дескриптор) int MPI_Group_excl(MPI_Group group, int n, int *ranks, MPI_Group *newgroup)
MPI_GROUP_EXCL(GROUP, N, RANKS, NEWGROUP, IERROR)
INTEGER GROUP, N, RANKS(*), NEWGROUP, IERROR
MPI::Group MPI::Group::Excl(int n, const int ranks[]) const
Функция
MPI_GROUP_EXCL
создает группу
newgroup
, которая получена путем удаления из
group
процессов с номерами
ranks[0] ,...
ranks[n-1].
Упорядочивание процессов в
newgroup
идентично упоря- дочиванию в
group
. Каждый из
n
элементов
ranks
должен быть пра- вильным номером в
group
, и все элементы должны быть различными;

150
в противном случае программа неверна. Если
n = 0
, то
newgroup
идентична
group
5.3.3. Деструкторы групп
MPI_GROUP_FREE(group)
INOUT group идентификатор группы (дескриптор) int MPI_Group_free(MPI_Group *group)
MPI_GROUP_FREE(GROUP, IERROR)
INTEGER GROUP, IERROR void MPI::Group::Free()
Эта операция маркирует объект группы для удаления. Дескриптор
group
устанавливается вызовом в состояние
MPI_GROUP_NULL
Любая выполняющаяся операция, использующая эту группу, завер- шитcя нормально.
5.4. УПРАВЛЕНИЕ КОММУНИКАТОРАМИ
Этот параграф описывает управление коммуникаторами в
MPI
Операции обращения к коммуникаторам являются локальными, их выполнение не требует обмена между процессами. Операции, которые создают коммуникаторы, являются коллективными и могут потребо- вать обмена между процессами.
5.4.1. Доступ к коммуникаторам
Все следующие операции являются локальными.
MPI_COMM_SIZE(comm, size)
IN comm коммуникатор (дескриптор)
OUT size количество процессов в группе comm (целое) int MPI_Comm_size(MPI_Comm comm, int *size)
MPI_COMM_SIZE(COMM, SIZE, IERROR)
INTEGER COMM, SIZE, IERROR int MPI::Comm::Get_size() const
Эта функция указывает число процессов в коммуникаторе. Для
MPI_COMM_WORLD
она указывает общее количество доступных процессов.

151
MPI_COMM_RANK(comm, rank)
IN comm коммуникатор (дескриптор)
OUT rank номер вызывающего процесса в группе comm (целое) int MPI_Comm_rank(MPI_Comm comm, int *rank)
MPI_COMM_RANK(COMM, RANK, IERROR)
INTEGER COMM, RANK, IERROR int MPI::Comm::Get_rank() const
Функция
MPI_COMM_RANK
возвращает номер процесса в част- ной группе коммуникатора. Ее удобно использовать cовместно с
MPI_COMM_SIZE
MPI_COMM_COMPARE(comm1, comm2, result)
IN comm1 первый коммуникатор (дескриптор)
IN comm2 второй коммуникатор (дескриптор)
OUT result результат (целое) int MPI_Comm_compare(MPI_Comm comm1,MPI_Comm comm2, int *result)
MPI_COMM_COMPARE(COMM1, COMM2, RESULT, IERROR)
INTEGER COMM1, COMM2, RESULT, IERROR static inc MPI::Comm::Compare(const MPI::Comm& comm1, const MPI::Comm& comm2)
Результат
MPI_IDENT
появляется тогда и только тогда, когда
comm1
и
comm2
являются дескрипторами для одного и того же объ- екта. Результат
MPI_CONGRUENT
появляется, если исходные груп- пы идентичны по компонентам и нумерации; эти коммуникаторы от- личаются только контекстом. Результат
MPI_SIMILAR
имеет место, если члены группы обоих коммуникаторов являются одинаковыми, но порядок их нумерации различен. В противном случае выдается ре- зультат
MPI_UNEQUAL
5.4.2. Конструкторы коммуникаторов
Нижеперечисленные функции являются коллективными и вызы- ваются всеми процессами в группе, связанной с
comm
. В MPI для соз- дания нового коммуникатора необходим исходный коммуникатор.
Основным коммуникатором для всех MPI коммуникаторов является коммуникатор
MPI_COMM_WORLD.

152
Функция MPI_COMM_DUP
дублирует существующий комму- никатор
comm,
возвращает в аргументе
newcomm
новый коммуника- тор с той же группой.
MPI_COMM_DUP(comm, newcomm)
IN comm коммуникатор (дескриптор)
OUT newcomm копия comm (дескриптор) int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *newcomm)
MPI_COMM_DUP(COMM, NEWCOMM, IERROR)
INTEGER COMM, NEWCOMM, IERROR
MPI::Intracomm MPI::Intracomm::Dup() const
MPI_COMM_CREATE(comm, group, newcomm)
IN comm коммуникатор (дескриптор)
IN group группа, являющаяся подмножеством группы comm (де- скриптор)
OUT newcomm новый коммуникатор (дескриптор) int MPI_Comm_create(MPI_Comm comm, MPI_Group group,
MPI_Comm *newcomm)
MPI_COMM_CREATE(COMM, GROUP, NEWCOMM, IERROR)
INTEGER COMM, GROUP, NEWCOMM, IERROR
MPI::Intracomm MPI::Intracomm::Create(const MPI::Group& croup) const
Эта функция создает новый коммуникатор
newcomm
с коммуни- кационной группой, определенной аргументом
group
и новым кон- текстом. Из
comm
в
newcomm
не передается никакой кэшированной информации. Функция возвращает
MPI_COMM_NULL
для процес- сов, не входящих в
group
. Запрос неверен, если не все аргументы в
group
имеют одинаковое значение или если
group
не является под- множеством группы, связанной с
comm
. Заметим, что запрос должен быть выполнен всеми процессами в
comm
, даже если они не принад- лежат новой группе.
MPI_COMM_SPLIT(comm, color, key, newcomm)
IN comm коммуникатор (дескриптор)
IN color управление созданием подмножества (целое)
IN key управление назначением номеров целое)
OUT newcomm новый коммуникатор (дескриптор) int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)

153
MPI_COMM_SPLIT(COMM, COLOR, KEY, NEWCOMM, IERROR)
INTEGER COMM, COLOR, KEY, NEWCOMM, IERROR
MPI::Intracomm MPI::Intracomm::Split(int color, int key) const
Эта функция делит группу, связанную с
comm,
на непересекаю- щиеся подгруппы по одной для каждого значения
color
. Каждая под- группа содержит все процессы одного цвета. В пределах каждой под- группы процессы пронумерованы в порядке, определенном значением аргумента
key
, со связями, разделенными согласно их номеру в старой группе.
Для каждой подгруппы создается новый коммуникатор и возвра- щается в аргументе
newcomm
. Процесс может иметь значение цвета
MPI_UNDEFINED
, тогда переменная
newcomm
возвращает значение
MPI_COMM_NULL
. Это коллективная операция, но каждому про- цессу разрешается иметь различные значения для
color
и
key
Обращение к
MPI_COMM_CREATE (сomm, group, newcomm)
эквивалентно обращению к
MPI_COMM_SPLIT (comm, color, key,
newcomm),
где все члены
group
имеют
color =0
и
key =
номеру в
group
, и все процессы, которые не являются членами
group
, имеют
color
=
MPI_UNDEFINED
Функция
MPI_COMM_SPLIT
допускает более общее разделение группы на одну или несколько подгрупп с необязательным переупо- рядочением. Этот запрос используют только интра-коммуникаторы.
Значение
color
должно быть неотрицательно.
5.4.3. Деструкторы коммуникаторов
MPI_COMM_FREE(comm)
INOUT comm удаляемый коммуникатор (handle) int MPI_Comm_free(MPI_Comm *comm)
MPI_COMM_FREE(COMM, IERROR)
INTEGER COMM, IERROR void MPI::Comm:Free()
Эта коллективная операция маркирует коммуникационный объект для удаления. Дескриптор устанавливается в
MPI_COMM_NULL
Любые ждущие операции, которые используют этот коммуникатор, будут завершаться нормально; объект фактически удаляется только в том случае, если не имеется никаких других активных ссылок на него.

154
5.5
. ПРИМЕРЫ
Пример 5.1.
main(int argc, char **argv)
{ int me, count, count2; void *send_buf, *recv_buf, *send_buf2, *recv_buf2;
MPI_Group MPI_GROUP_WORLD, grprem;
MPI_Comm commslave; static int ranks[ ] = {0};
MPI_Init(&argc, &argv);
MPI_Comm_group(MPI_COMM_WORLD,&MPI_GROUP_WORLD);
MPI_Comm_rank(MPI_COMM_WORLD, &me);
/* локально */
MPI_Group_excl(MPI_GROUP_WORLD, 1, ranks, &grprem);
/* локально */
MPI_Comm_create(MPI_COMM_WORLD, grprem, &commslave); if(me != 0)
{ …
/* вычисления на подчиненном процессе */
MPI_Reduce(send_buf,recv_buff,count, MPI_INT,
MPI_SUM, 1, commslave);
}
/* процесс 0 останавливается немедленно после выполнения этого reduce, другие процессы – позже... */
MPI_Reduce(send_buf2, recv_buff2, count2, MPI_INT, MPI_SUM, 0,
MPI_COMM_WORLD);
MPI_Comm_free(&commslave);
MPI_Group_free(&MPI_GROUP_WORLD);
MPI_Group_free(&grprem);
MPI_Finalize();
}
Этот пример иллюстрирует, как из исходной группы создается группа, содержащая все процессы, кроме процесса 0, затем, как фор- мируется коммуникатор (
commslave
) для новой группы. Новый ком- муникатор используется в коллективном обмене, и все процессы вы- полняются в контексте
MPI_COMM_WORLD
. Пример иллюстриру- ет, как два коммуникатора (которые обязательно имеют различные контексты) защищают обмен. Это означает, что обмен в
commslave
изолирован от обмена в
MPI_COMM_WORLD,
и наоборот.

155
Пример 5.2.
Следующий пример иллюстрирует "безопасное" выпол- нение парного и коллективного обменов в одном коммуникаторе.
#define TAG_ARBITRARY 12345
#define SOME_COUNT 50 main(int argc, char **argv)
{ int me;
MPI_Request request[2];
MPI_Status status[2];
MPI_Group MPI_GROUP_WORLD, subgroup; int ranks[] = {2, 4, 6, 8};
MPI_Comm the_comm;
MPI_Init(&argc, &argv);
MPI_Comm_group(MPI_COMM_WORLD,&MPI_GROUP_WORLD);
MPI_Group_incl(MPI_GROUP_WORLD,4,ranks, &subgroup);
/*локально */
MPI_Group_rank(subgroup, &me); /* локально */
MPI_Comm_create(MPI_COMM_WORLD, subgroup, &the_comm);
/* парный обмен */ if(me != MPI_UNDEFINED) {
MPI_Irecv(buff1, count, MPI_DOUBLE, MPI_ANY_SOURCE,
TAG_ARBITRARY, the_comm, request);
MPI_Isend(buff2, count, MPI_DOUBLE, (me+1)%4,
TAG_ARBITRARY, the_comm, request+1);
} /* коллективная операция */ for(i = 0; i < SOME_COUNT, i++)
MPI_Reduce(..., the_comm);
MPI_Waitall(2, request, status);
MPI_Comm_free(t&he_comm);
MPI_Group_free(&MPI_GROUP_WORLD);
MPI_Group_free(&subgroup);
MPI_Finalize();
}
КОНТРОЛЬНЫЕ ВОПРОСЫ И ЗАДАНИЯ К ГЛАВЕ 5
Контрольные вопросы к 5.1
1. Какие преимущества получает пользователь, использующий параллельные библиотеки?
2. Перечислите проблемы при написании параллельных библиотек.
3. Какие специфические структуры введены в MPI, необходимые для создания и использования параллельных библиотек?
4. В чем различие между группой процессов и коммуникатором?
5. Могут ли общаться процессы, принадлежащие разным коммуникаторам?
6. Что такое виртуальная топология?

156
Контрольные вопросы к 5.2
1. Можно ли ввести собственную нумерацию процессов в группе, например:
2,4,6,8,…?
2. Какая предопределенная константа является группой без членов?
3. В какой момент выполнения приложения определяется начальный коммуни- катор MPI_COMM_WORLD?
4. MPI_COMM_WORLD является интер или интра-коммуникатором?
5. Можно ли удалить коммуникатор MPI_COMM_WORLD в течение времени существования процесса?
Контрольные вопросы к 5.3
1. Функции управления группой являются локальными или коллективными?
2. Что возвращает функция MPI_Group_rank, если процесс, в котором произво- дится вызов этой функции, не является членом этой группы?
3. Как определить номер процесса в группе, зная его номер в группе, соответст- вующей коммуникатору MPI_COMM_WORLD?
4. Перечислите три возможных варианта результата, которые можно получить после вызова функции MPI_Group_compare.
5. Функции-конструкторы групп являются локальными?
6. Что такое базовая группа? Приведите пример базовой группы.
7. Можно ли определить в каждом процессе приложения собственную группу процессов?
8. Какая функция позволяет определить группу какого-либо коммуникатора?
9. Можно ли определить группу, которая не включает в себя процесс, ее соз- дающий?
10. Перечислите операции над группами процессов, определенные для создания новой группы.
Контрольные вопросы к 5.4
1. Можно ли изменить число процессов приложения после инициализации
MPI?
2. Могут ли быть строго вложенными множества процессов, определяющие раз- личные коммуникаторы?
3. Должны ли быть непересекающимися множества процессов, определяющие различные коммуникаторы?
4. Должны ли множества процессов, определяющие различные коммуникаторы, состоять более чем из одного процесса?
5. Определены ли в каждой программе множества процессов, задающие различ- ные коммуникаторы в количестве большем, чем 2?
6. Функции доступа к коммуникаторам локальные или коллективные?
7. В чем сходство и различие использования функций MPI_Group_size и
MPI_Comm_size, MPI_Group_rank и MPI_Com_rank, MPI_Group_compare и
MPI_Com_compare?
8. Функции создания коммуникаторов локальные или коллективные?
9. Какой коммуникатор создает MPI_Comm_dup?

157 10. Какой коммуникатор создает функция MPI_Comm_create, если она вызывает- ся в процессе, не входящем в коммуникационную группу?
11. Сколько коммуникаторов создает MPI_Comm_split?
Контрольные вопросы к 5.5
1. В каком процессе находится результат коллективной операции MPI_Reduce в примере 5.1, которая выполняется в новом коммуникаторе commslave?
2. Объясните необходимость использования проверки me!=MPI_UNDEFINED в примере 5.2. В каком случае процесс получает номер MPI_UNDEFINED?
3. Сколько процессов и какие входят в коммуникатор the_comm в примере 5.2?
4. Для какой цели в примере 5.2 приведен цикл, в котором MPI_Reduce повторя- ется много раз?
5. По какой схеме осуществляется обмен данными в примере 5.2?
Задания для самостоятельной работы
5.1
. Организуйте передачу данных внутри коммуникатора, который создан на основании группы, созданной из произвольного числа процессов, заданных пользователем. Например, если 10 процессов в MPI_COMM_WORLD, то создайте группу из 2,3,6,8,9 процессов.
5.2.
Постройте ввод-вывод по принципу master/slave. Главный процесс дол- жен принимать сообщения от подчиненных и печатать их в порядке нумерации
(сначала 0, затем 1 и так далее). Подчиненные должны посылать каждый по 2 со- общения мастеру. Например, сообщения:
Hello from slave 3
Goodbye from slave 3
(с соответствующими сообщениями для каждого подчиненного процесса). Для решения разделите процессы из MPI_COMM_WORLD на два коммуникатора: один процесс в качестве главного и остальные процессы – подчиненные. Исполь- зуйте новый коммуникатор для подчиненных процессов для того, чтобы полу- чить номер подчиненного процесса в его коммуникаторе. Подчиненные процессы могут также выполнять любые вычисления.
5.3.
Выполните задание 5.2, изменив код мастера, чтобы он позволял прини- мать три типа сообщений от подчиненных процессов: упорядоченный вывод (та- кой же, как и в примере 1); неупорядоченный вывод (как если бы каждый подчи- ненный процесс печатал непосредственно); сообщение о выходе. Мастер продол- жает получать сообщения до тех пор, пока он не получит сообщения о выходе от всех подчиненных процессов. Для простоты программирования пусть каждый подчиненный процесс посылает сообщения:
Hello from slave 3
Goodbye from slave 3 в упорядоченном выходном режиме и
I'm exiting (3) в неупорядоченном режиме.
5.4.
Напишите программу вычисления числа
π методом Монте-Карло. Суть метода в следующем. Если радиус круга равен 1, тогда площадь круга равна
π, а площадь квадрата вокруг круга равна 4. Следовательно, отношение площади кру-

158
га к площади квадрата равно
π/4. Если теперь случайным образом генерировать точки в пределах контура квадрата, то отношение числа точек, попавших в круг, к общему количеству сгенерированных точек даст величину
π/4. Сгенерированная точка находится в круге, если ее координаты соответствуют выражению x
2
+ y
2
<1.
Для генерации случайных чисел создайте отдельный процесс, который будет рас- сылать эти числа другим процессам. Поскольку другие процессы должны будут выполнить коллективные операции, в которых не участвует этот процесс, необхо- димо определить коммуникатор, чья группа не включает генерацию случайных чисел.
5.5.
Пусть имеем n процессов, где n – произвольно. Создайте два коммуника- тора: отдельно из процессов с четными и нечетными номерами. Осуществите пе- редачу данных по кольцу внутри каждого коммуникатора.
5.6.
Пусть количество процессов n=l*m. Тогда процессы можно представить решеткой: l – строк и m столбцов. Создайте коммуникаторы для каждой строки и каждого столбца решетки. Осуществите передачу данных по кольцу внутри каж- дого коммуникатора.
1   ...   8   9   10   11   12   13   14   15   ...   26


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