В настоящее время интерфейс MPI предоставляет только две процедуры, для конструирования интеркоммуникаторов:
MPI_INTERCOMM_CREATE
, создающую один интеркоммуникатор из двух.
MPI_COMM_DUP
, дублирующую текущий интеркоммуникатор (или
интракоммуникатор).
Другие конструкторы коммуникаторов, MPI_COMM_CREATE
и
MPI_COMM_SPLIT
, в настоящее время применимы только к
интракоммуникаторам. Эти операции фактически имеют хорошо определенную
семантику для интеркоммуникаторов [20].
В следующем обсуждении выделяются две группы интеркоммуникатора, называемые левой и правой группами. Процесс в интеркоммуникаторе является членом либо левой, либо правой группы. С точки зрения этого процесса, группа, членом которой он является, называется локальной группой; другая группа (относительно этого процесса) называется удаленной группой. Метки групп левая и правая дают нам способ описать две группы в интеркоммуникаторе, который не относится ни к одному специфическому процессу (как это имеет место для локальных и удаленных групп).
Кроме того, спецификация коллективных операций (раздел 4.1 MPI-1) требует, чтобы все коллективные процедуры вызывались с соответствующими аргументами. Для расширений интеркоммуникаторов, требование соответствия ослабляется для всех членов одной локальной группы.
------------------------------------------------------------------
MPI_COMM_CREATE(comm_in, group, comm_out)
------------------------------------------------------------------
IN | comm_in |
оригинальный коммуникатор (указатель) | ||||
IN | group |
группа процессов, которая будет в новом коммуникаторе (указатель) | ||||
OUT | comm_out |
новый коммуникатор (указатель) |
MPI::Intercomm MPI::Intercomm::Create(const Group& group) const
MPI::Intracomm MPI::Intracomm::Create(const Group& group) const
Привязка к языкам Си и ФОРТРАН идентична реализации ее в MPI-1 и здесь не показана.
Если comm_in
- интеркоммуникатор, то выходной коммуникатор
comm_out
также является интеркоммуникатором, в котором локальная
группа состоит только из тех процессов, которые содержатся в group
(см. рисунок 7.1). Аргумент group
должен содержать только те
процессы в локальной группе входного интеркоммуникатора, которые должны
стать частью comm_out
. Если group
не задает, по крайней
мере, ни одного процесса в локальной группе интеркоммуникатора или
вызывающий процесс не включен в группу, возвращается MPI_COMM_NULL
.
Объяснение: В случае, когда левая или правая группа пусты, возвращается
нулевой коммуникатор вместо интеркоммуникатора с MPI_GROUP_EMPTY
,
потому что сторона с пустой группой должна вернуть MPI_COMM_NULL
.
[]
MPI_COMM_CREATE
. Входные группы показаны в серых
кругах.
Пример 7.1. Ниже приводится пример, иллюстрирующий, как первый узел левой стороны интеркоммуникатора может быть объединен со всеми членами его правой стороны для формирования нового интеркоммуникатора.
MPI_Comm inter_comm, new_inter_comm;
MPI_Group local_group, group;
int rank = 0; /* ранг на левой стороне для включения в новый inter-comm */
/* конструирование оригинального интеркоммуникатора: ''inter_comm'' */
...
/* конструирование группы процессов для включения в новый
интеркоммуникатор */
if (/* ? есть на левой стороне интеркоммуникатора */) {
MPI_Comm_group ( inter_comm, &local_group );
MPI_Group_incl ( local_group, 1, &rank, &group );
MPI_Group_free ( &local_group );
} else {
MPI_Comm_group ( inter_comm, &group );
}
MPI_Comm_create ( inter_comm, group, &new_inter_comm );
MPI_Group_free( &group );
------------------------------------------------------------------
MPI_COMM_SPLIT(comm_in, color, key, comm_out)
------------------------------------------------------------------
IN | comm_in |
Оригинальный коммуникатор (указатель) | ||||
IN | color |
Контролирует подмножество назначения (целое) | ||||
IN | key |
Контролирует номер назначения (целое) | ||||
OUT | comm_out |
Новый коммуникатор (указатель) |
MPI::Intercomm MPI::Intercomm::Split(int color, int key) const
MPI::Intracomm MPI::Intracomm::Split(int color, int key) const
Привязки к языкам Си и ФОРТРАН идентичны их реализации в MPI-1 и здесь не показаны.
Результатом работы MPI_COMM_SPLIT
для интеркоммуникатора является
то, что те процессы на левой стороне, у которых одинаковый color
,
плюс такие же процессы на правой стороне объединяются для создания нового
интеркоммуникатора. Аргумент key
описывает относительный ранг процессов
на каждой стороне интеркоммуникатора (см. рисунок). При указании тех
colors
, которые определены только на одной стороне интеркоммуникатора,
возвращается MPI_COMM_NULL
. MPI_COMM_NULL
также
возвращается в те процессы, для которых color
указан как
MPI_UNDEFINED
.
MPI_COMM_SPLIT
для интеркоммуникаторов.
Пример 7.2. (Параллельная клиент-серверная модель). Ниже приводится код для клиента, иллюстрирующий как клиенты на левой стороне некого интеркоммуникатора могут ставиться в соответствие выбранному серверу из пула серверов на правой стороне этого интеркоммуникатора.
/* Код клиента */
MPI_Comm multiple_server_comm;
MPI_Comm single_server_comm;
int color, rank, num_servers;
/* Создание интеркоммуникатора с клиентами и серверами:
multiple_server_comm */
...
/* Нахождение количества доступных серверов */
MPI_Comm_remote_size(multiple_server_comm, &num_servers);
/* Определение своего color */
MPI_Comm_rank(multiple_server_comm, &rank);
color = rank % num_servers;
/* Разбиение интеркоммуникатора */
MPI_Comm_split(multiple_server_comm, color, rank,
&single_server_comm);
Соответствующий код для сервера:
/* Код сервера */
MPI_Comm multiple_client_comm;
MPI_Comm single_server_comm;
int rank;
/* Создание интеркоммуникатора с клиентами и серверами:
multiple_client_comm */
...
/* Разбиение интеркоммуникатора так, чтобы получился
один сервер для группы клиентов */
MPI_Comm_rank(multiple_client_comm, &rank);
MPI_Comm_split(multiple_client_comm, rank, 0,
&single_server_comm );