Группы Контексты, и Коммуникаторы icon

Группы Контексты, и Коммуникаторы




Скачати 208.77 Kb.
НазваГруппы Контексты, и Коммуникаторы
Дата14.07.2012
Розмір208.77 Kb.
ТипРассказ
1. /BOOK/CHAPTER1.DOC
2. /BOOK/CHAPTER2.DOC
3. /BOOK/CHAPTER3.DOC
4. /BOOK/CHAPTER4.DOC
5. /BOOK/CHAPTER5.DOC
6. /BOOK/CHAPTER6.DOC
7. /BOOK/SODERG.DOC
Предисловие к mpi
Mpi договоренности
Сканирующая связь
Коллективная связь
Группы Контексты, и Коммуникаторы
Топологии процессов
Содержаhие



Глава 5


Группы Контексты, и Коммуникаторы


5.1 Введение


Эта глава рассказывает о MPI эллиментах, которые поддерживают разработку параллельных библиотек.


Поддержка MPI библиотек


Hиже приведены некоторые понятия, которые используются в MPI :

  • Контексты связи,

  • Группы процессов,

  • Виртуальные топологии,

  • Атрибут кеширования,

  • Коммуникаторы.


Коммуникаторы преднозначены для изоляции реализованных частей одной задачи и для возможности связи между этими частями. Возможны следующие виды коммуникаторов :


  • коммуникаторы интра - для операций в пределах одной группы процессов,

  • межкоммуникаторы - для сканирующей связи между двумя группами

процессов.


Кэширование.

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


Группы.

Группы определяют упорядоченную совокупность процессов, каждого со своим рангом. Группа определяет имена низкого уровня для межпроцессной связи (ранги используются для передачи и приема). Таким образом, группы определяют область для имен процесса на сканирующей связи. Кроме того, группы определяют область коллективных операций. Группы в MPI могут создаваться отдельно от коммуникаторов , но только коммуникаторы могут использоваться на операциях связи.


Коммуникаторы Интра.

Наиболее часто используются сообщения, передаюиеся в MPI через коммуникаторы интра. Коммуникаторы Интра содержат группы, контексты связи для сканирующей и коллективной связи, и позволяют использовать виртуальные топологии и другие атрибуты.

  • Группы определяют участников на связи коммуникатора.

  • Контекст выступает в роли этикетки данного коммуникатора.


5.2 Основные понятия


В этом разделе мы более подробно знакомимся с понятиями введенными выше.


5.2.1 Группы


Группа - это комплект идентификаторов процесса (в дальнейшем процессы). Каждый процесс в группе связывается с рангом. Ранги непрерывные и начинают с нуля. Группы представляются невидимыми групповыми объектами, и следовательно не могут непосредственно передаваться от одного процесса в другой. Группа используется в пределах одного коммуникатора, который описывает участников связи и ранжируют этих участников (таким образом давая им уникальные имена в пределах "общей" связи). Есть специальная предопределенная группа: MPI_GROUP_EMPTY - группа без участников. Встроенная константа MPI_GROUP_NULL - используется для неправильных групповых указателей.


Совет пользователям.

MPI_GROUP_EMPTY - является правильным указателем на пустую группу. Ее не надо путать с MPI_GROUP_NULL ( неправильным указателем.) (Конец совета пользователям.)


5.2.2 Контексты


Контекст - раздел коммуникаторов (определяемый после коммуникатора), который выступает в роли маркера коммуникатора и производит разметку пространства связи. Сообщение посланное в одном контексте не может получаться в другом контексте. Контексты неявные MPI объекты; они вводятся только как часть реализации коммуникаторов (ниже).


5.2.3 Комуникаторы Интра


Коммуникаторы Интра сводят вместе понятия группы и контекста. MPI операции связи делают ссылку на коммуникаторы, чтобы определить область и "общность связи" (сканирующая или коллективная).

Каждый коммуникатор определяет группу ; эта группа работает в своем локальном процессе. Hа источник и расположение сообщения в пределах этой группы указывает ранг процесса. Для коллективной связи, коммуникатор интра определяет комплект процессов, которые участвуют в коллективном функционировании. Таким образом, коммуникатор ограничивает "пространственную" область связи, и обеспечивает машинно-независимые процессы, которые определяется рангами. Коммуникаторы Интра не могут непосредственно передаваться от одного процесса в другой.


5.2.4 Встроенные коммуникаторы Интра


Коммуникатор интра MPI_COMM_WORLD делает доступным все процессы. Локальный процесс может сообщаться после инициализации с любым другим процессом (включая себя).

Коммуникатор MPI_СОММ_SELF разрешает связь только с самим собой. Встроенная константа MPI_СОММ_NULL - используется для неправильных указателей на коммуникатор.


5.3 Групповое управление


Этот раздел описывает операции с группами процессов в MPI. Эти операции - локальные и их выполнение не требует межпроцесной связи.


5.3.1 Групповые команды


MPI_GROUP_SIZE(group, size)

IN group - номер группы (handle)

OUT size - число процессов в группе (integer)


int MPI_Group_size(MPI Group group, int *size)

MPI_GROUP_SIZE(GROUP, SIZE, IERROR)

INTEGER GROUP, SIZE, IERROR


MPI_GROUP_RANK(group, rank)

IN group - группа (handle)

OUT rank - ранг вызывающегося процесса группы, или MPI_UNDEFINED

если нет вызова (integer)


int MPI_Group_rank(MPI Group group, int *rank)

MPI_GROUP_RANK(GROUP, RANK, IERROR)

INTEGER GROUP, RANK, IERROR


Функция MPI_GROUP_SIZE используется для получения количества процессов в группе. Функция MPI_GROUP_RANK используется для получения ранга вызывающегося процесса в группе.


MPI_GROUP_TRANSLATE_RANKS (group1, n, ranks1, group2, ranks2)

IN group1 - группа 1 (handle)

IN n - число рангов в массивах ranks1 и ranks2 (integer)

IN ranks1 - массив (от 0 и >=числу рангов в group1)

IN group2 - группа 2 (handle)

OUT ranks2 - массив corresponding рангов в group2, MPI UNDEFINED

когда corresponding непроизводится.


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


Эта функция нужна для определения относительной нумерации тех же самых процессов в двух группах.


MPI_GROUP_COMPARE(group1, group2, result)

IN group1 - первая группа (handle)

IN group2 - вторая группа (handle)

OUT result - результат (integer)


int MPI_Group _ompare(MPI Group group1,MPI Group group2, int *result)

MPI_GROUP_COMPARE(GROUP1, GROUP2, RESULT, IERROR)

INTEGER GROUP1, GROUP2, RESULT, IERROR


Производит сравнение двух групп. Результат может принимать следующие значения :


MPI_IDENT - групповые участники и групповой порядок одинаковы в группах.

(например если group1 и group2 - один и тотже указатель.)

MPI_SIMILAR - групповые участники теже но порядок другой.

MPI_UNEQUAL - разные участники.


5.3.2 Групповые конструкторы


Эти конструкторы создают новые группы от уже существующих групп.


MPI_COMM_GROUP(comm, group)

IN comm - коммуникатор (handle)

OUT group - группа дублирующая групп у в коммуникаторе comm (handle)


int MPI_Comm_group(MPI Comm comm, MPI Group *group)

MPI_COMM_GROUP(COMM, GROUP, IERROR)

INTEGER COMM, GROUP, IERROR


MPI_GROUP_UNION(group1, group2, newgroup)

IN group1 - первая группа (handle)

IN group2 - вторая группа (handle)

OUT newgroup - объединеная группа (handle)


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


MPI_GROUP_INTERSECTION(group1, group2, newgroup)

IN group1 - первая группа (handle)

IN group2 - вторая группа (handle)

OUT newgroup - пересечение групп (handle)


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


MPI_GROUP_DIFFERENCE(group1, group2, newgroup)

IN group1 - первая группа (handle)

IN group2 - вторая группа (handle)

OUT newgroup - различия групп (handle)


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


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

зом :

union - все элементы первой группы (group1), соединяются со всеми элимента-

ми второй группы (group2), которых нет в первой.

intersection - все элементы первой группы, которые также существуют и во

второй группе.

difference - все элементы первой и второй группы, без общих элиментов.

Имейте в виду, что новая группа может быть пустой, что соответствует

MPI_GROUP_EMPTY.


MPI_GROUP_INCL(group, n, ranks, newgroup)

IN group - группа (handle)

IN n - число элиментов в массиве рангов (и размер новой группы)

(integer)

IN ranks - ранги процессов в группе, которые появится в newgroup

(array ofinteger)

OUT newgroup - новая группа полученная из первоначальной (handle)


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_INCL создает группу newgroup, которая состоит из n процессов с рангами rank[0],..., rank[n-1]. Если n = 0, то newgroup MPI_GROUP_EMPTY.


MPI_GROUP_EXCL(group, n, ranks, newgroup)

IN group - группа (handle)

IN n - число элиментов в массиве ranks (integer)

IN ranks - массив рангов group, которые не должны войти в

newgroup (array of integer)

OUT newgroup - полученная группа (handle)


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_EXCL создает группу процессов newgroup, которая аналогична group но без процессов с рангами ранг[0],... ранг[n-1]. Если n = 0, то newgroup идентична group.


MPI_GROUP_RANGE_INCL(group, n, ranges, newgroup)

IN group - группа (handle)

IN n - число триплетов в массиве ranks (integer)

IN ranks - массив триплетов формы(начальный ранг, последний ранг, шаг)

включающие ранги процессов в group, которые войдут в

newgroup (array of integer)

OUT newgroup - полученная группа (handle)


int MPI_Group_range_incl(MPI Group group, int n, int ranges[][3],

MPI Group *newgroup)

MPI_GROUP_RANGE_INCL(GROUP, N, RANGES, NEWGROUP, IERROR)

INTEGER GROUP, N, RANGES(3,*), NEWGROUP, IERROR


Если группу представить в виде триплетов


(первый 1; последний 1; шаг 1);...; (первый n; последний n; шаг n )


то newgroup состоит из последовательности процессов group с рангами


первый_1, первый_1 + шаг_1,...,первый_1 + (посл._1-первый_1/шаг_1)* шаг_1,

...

первый_n, первый_n + шаг_n,...,первый_n + (посл._n-первый_n/шаг_n)* шаг_n.


Последний может быть меньше первого, тогда шаг должен быть отрецателен. Однако шаг никогда не должен быть равным нулю.


MPI_GROUP_RANGE_EXCL(group, n, ranges, newgroup)

IN group - группа (handle)

IN n - число элиментов в массиве ranks (integer)

IN ranks - массив триплетов формы(начальный ранг, последний ранг, шаг)

указывающий ранги процессов в group, которые не должны войти

в newgroup (array of integer)

OUT newgroup - полученная группа (handle)


int MPI_Group_range_excl(MPI Group group, int n, int ranges[][3],

MPI Group *newgroup)

MPI_GROUP_RANGE_EXCL(GROUP, N, RANGES, NEWGROUP, IERROR)

INTEGER GROUP, N, RANGES(3,*), NEWGROUP, IERROR


Функция MPI_GROUP_RANGE_INCL аналогична MPI_GROUP_INCL но ранги в ranks заменены на триплеты.

Функция MPI_GROUP_RANGE_EXCL аналогична MPI_GROUP_EXCL но ранги в ranks заменены на триплеты.


5.3.3 Освобождение групп


MPI_GROUP_FREE(group)

INOUT group - группа (handle)


int MPI_Group_free(MPI Group *group)

MPI_GROUP_FREE(GROUP, IERROR)

INTEGER GROUP, IERROR


Это команда выделяет групповой объект для освобождения. Групповой указатель устанавливается в MPI_GROUP_NULL.


5.4 Управление коммуникаторами


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


5.4.1 Команды работающие с коммуникаторами


MPI_COMM_SIZE(comm, size)

IN comm - комуникатор (handle)

OUT size - число процессов в группе с комуникатором comm (integer)


int MPI_Comm_size(MPI Comm comm, int *size)

MPI_COMM_SIZE(COMM, SIZE, IERROR)

INTEGER COMM, SIZE, IERROR


Эта команда указывает количество процессов включенное в коммуникатор. MPI_COMM_WORLD - указывает что все процессы доступны.

Следующий вызов MPI_COMM_RANK указывает ранг процесса, который использует область пользователя.


MPI_COMM_RANK(comm, rank)

IN comm - коммуникатор (handle)

OUT rank - ранг вызывающегося процесс (integer)

int MPI_Comm_rank(MPI Comm comm, int *rank)

MPI_COMM_RANK(COMM, RANK, IERROR)

INTEGER COMM, RANK, IERROR


Эта функция возвращает ранг процесса в конкретной группе. Это полез-

но при написании программ со следующей моделью : один процесс (например нулевой процесс) выполняет контролирующую роль, а другие процессы служат в качестве вычислительного узла. В этой модели две предшествующие команды полезны для определения ролей различных процессов группы.


MPI_COMM_COMPARE(comm1, comm2, result)

IN comm1 - первый коммуникатор (handle)

IN comm2 - второй коммуникатор (handle)

OUT result - результат (integer)


int MPI_Comm_compare(MPI Comm comm1,MPI Comm comm2, int *result)

MPI_COMM_COMPARE(COMM1, COMM2, RESULT, IERROR)

INTEGER COMM1, COMM2, RESULT, IERROR


Функция MPI_COMM_COMPARE производит сравнение коммуникаторов. В результате могут получиться следующие значения result :


MPI_IDENT - когда comm1 и comm2 - указатели на один и тотже объект (идентичные группы).

MPI_CONGRUENT - если коммуникаторы отличаются только контекстом.

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

MPI UNEQUAL - если коммуникаторы различны.


5.4.2 Коммуникаторы от коммуникатора


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


MPI_COMM_DUP(comm, newcomm)

IN comm - коммуникатор (handle)

OUT newcomm - копия коммуникатора (handle)


int MPI_Comm_dup(MPI Comm comm, MPI Comm *newcomm)

MPI_COMM_DUP(COMM, NEWCOMM, IERROR)

INTEGER COMM, NEWCOMM, IERROR


MPI_СОММ_DUP дублирует существующий коммуникатор с той же группой, но с новым контекстом. Это используется для обеспечения параллельных вызовов.


MPI_COMM_CREATE(comm, group, newcomm)

IN comm - коммуникатор (handle)

IN group - группа которая является подмножеством группы comm

(handle)

OUT newcomm - новый коммуникатор (handle)


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


Эта функция создает новый коммуникатор newcomm с группой связи, определяемой группой group. newcomm может использоваться в следующих вызовах MPI_СОММ_CREATЕ. Это необходимо для разделения вычисления на параллельные под-вычисления.


MPI_COMM_SPLIT(comm, color, key, newcomm)

IN comm - коммуникатор (handle)

IN color - ко-во подмножеств (integer)

IN key - управляет ранжированием рангов (integer)

OUT newcomm - новый коммуникатор (handle)


int MPI_Comm_split(MPI Comm comm, int color, int key, MPI Comm *newcomm)

MPI_COMM_SPLIT(COMM, COLOR, KEY, NEWCOMM, IERROR)

INTEGER COMM, COLOR, KEY, NEWCOMM, IERROR


Эта функция разбивает группу связанную с сомм на непересекающиеся подгруппы, по величине цвета. Каждая подгруппа содержит все процессы одного и того же цвета. В пределах каждой подгруппы, процессы ранжируются по порядку, определяемого величиной ключа. Новый коммуникатор создается для каждой подгруппы и возвращается в newcomm.


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


Это команда выделяет объект связи для освобождения. Указатель устанавливается в MPI_СОММ_NULL.


5.5 Примеры


5.5.1 Практика #1


Пример #1a:

main(int argc, char **argv)

{

int me, size;

...

MPI_Init ( &argc, &argv );

MPI_Comm_rank (MPI_COMM_WORLD, &me);

MPI_Comm_size (MPI_COMM_WORLD, &size);

(void)printf (''Process %d size %d``n'', me, size);

...

MPI_Finalize();

}


Пример #1a - программа, которая инициализирует себя, имеет отношение ко всем коммуникаторам, печатает сообщение и завершается.


Пример #1b :


main(int argc, char **argv)

{

int me, size;

int SOME_TAG = 0;

...

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &me); /* локальное */

PI_Comm_size(MPI_COMM_WORLD, &size); /* локальное */

if((me % 2) == 0)

{

/* посылка если процесс четный */

if((me + 1) ! size)

MPI_Send(..., me + 1, SOME_TAG, MPI_COMM_WORLD);

}

else MPI_Recv(..., me - 1, SOME_TAG, MPI_COMM_WORLD);

...

MPI_Finalize();

}


Пример #1b схематически иллюстрирует передачу сообщений между всеми четными и нечетными процессами.


5.5.2 Практика #2


main(int argc, char **argv)

{

int me, count;

void *data;

...

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &me);

if(me == 0)

{

/* cоздает буфер данных для ввода */

...

}

MPI_Bcast(data, count, MPI_BYTE, 0, MPI_COMM_WORLD);

...

MPI_Finalize();

}

Этот пример иллюстрирует использование коллективной связи.


5.5.3 Практика #3


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); /* local */

MPI_Group_excl(MPI_GROUP_WORLD, 1, ranks, &grprem); /* local */

MPI_Comm_create(MPI_COMM_WORLD, grprem, &commslave);

if(me != 0)

{

/* Вычисления не в главном процессе */

...

MPI_Reduce(send_buf,recv_buff,count, MPI_INT, MPI_SUM, 1, commslave);

...

}

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();

}


Этот пример иллюстрирует создание новой группы и коммуникатора (commslave) для этой новой группы. Новый коммуникатор используется в коллективном вызове.

Также пример иллюстрирует защищенность связи двух коммуникаторов. Связь в MPI_COMM_WORLD изолируется от связи в commslave, и наоборот. В результате групповая безопасность достигается через коммуникаторы.


5.5.4 Пример #4


Следующий пример приведен для иллюстрации безопасности между сканирующей и коллективной связи. В MPI один и тотже коммуникатор может использоваться для сканирующей и для коллективнай связи.


#define TAG_ARBITRARY 12345

#define SOME_COUNT 50

main(int argc, char **argv)

{

int me;

MPI_Ruest 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); /* local */

MPI_Group_rank(subgroup, &me); /* local */

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.5 Библиотечный Пример #1


Основная программа:

main(int argc, char **argv)

{

int done = 0;

user_lib_t *libh_a, *libh_b;

void *dataset1, *dataset2;

...

MPI_Init(&argc, &argv);

...

init_user_lib(MPI_COMM_WORLD, &libh_a);

init_user_lib(MPI_COMM_WORLD, &libh_b);

...

user_start_op(libhЧa, dataset1);

user_start_op(libh_b, dataset2);

...

while(!done)

{

/* work */

...

MPI_Reduce(..., MPI_COMM_WORLD);

...

/* see if done */

...

}

user_endЧop(libh_a);

user_endЧop(libh_b);

uninit_user_lib(libh_a);

uninit_user_lib(libh_b);

MPI_Finalize();

}


Код инициализации библиотеки потребителя:


void init_user_lib(MPI_Comm comm, user_lib_t **handle)

{

user_lib_t *save;

user_lib_initsave(&save); /* local */

MPI_Comm_dup(comm, &(save -? comm));

/* other inits */

...

*handle = save;

}


Старьовый код потребителя :


void user_start_op(user_lib_t *handle, void *data)

{

MPI_Irecv( ..., handle-?comm, &(handle -? irecv_handle) );

MPI_Isend( ..., handle-?comm, &(handle -? isend_handle) );

}


Код очистки связи потребителя:


void user_end_op(user_lib_t *handle)

{

MPI_Status *status;

MPI_Wait(handle -? isend_handle, status);

MPI_Wait(handle -? irecv_handle, status);

}


Код очистки объекта потребителя :


void uninit_user_lib(user_lib_t *handle)

{

MPI_Comm_free(&(handle -? comm));

free(handle);

}


5.5.6 Библиотечный Пример #2


Основная программа:

main(int argc, char **argv)

{

int ma, mb;

MPI_Group MPI_GROUP_WORLD, group_a, group_b;

MPI_Comm commЧa, commЧb;

static int listЧa[] = {0, 1};

#if defined(EXAMPLE_2B) --- defined(EXAMPLE_2C)

static int list_b[] = {0, 2 ,3};

#else /* EXAMPLE_2A */

static int list_b[] = {0, 2};

#endif

int size_list_a = sizeof(list_a)/sizeof(int);

int size_list_b = sizeof(list_b)/sizeof(int);

...

MPI_Init(&argc, &argv);

MPI_Comm_group(MPI_COMM_WORLD, &MPI_GROUP_WORLD);

MPI_Group_incl(MPI_GROUP_WORLD, size_list_a, list_a, &group_a);

MPI_Group_incl(MPI_GROUP_WORLD, size_list_b, list_b, &group_b);

MPI_Comm_create(MPI_COMM_WORLD, group-a, &comm_a);

MPI_Comm_create(MPI_COMM_WORLD, group_b, &comm_b);

if(comm_a != MPI_COMM_NULL) MPI_Comm_rank(comm_a, &ma);

if(comm_a != MPI_COMM_NULL) MPI_Comm_rank(comm_b, &mb);

if(comm_a != MPI_COMM_NULL) lib_call(comm_a);

if(comm_b != MPI_COMM_NULL)

{

lib_call(comm_b);

lib_call(comm_b);

}

if(comm_a != MPI_COMM_NULL) MPI_Comm_free(&comm_a);

if(comm_b != MPI_COMM_NULL) MPI_Comm_free(&comm_b);

MPIЧGroupЧfree(&group_a);

MPIЧGroupЧfree(&group_b);

MPI_Group_free(&MPI_GROUP_WORLD);

MPI_Finalize();

}


Библиотека:


void lib_call(MPI_Comm comm)

{

int me, done = 0;

MPI_Comm_rank(comm, &me);

if(me == 0)

while(!done)

{

MPI_Recv(..., MPI_ANY_SOURCE, MPI_ANY_TAG, comm);

...

}

else

{ /* work */

MPI_Send(..., 0, ARBITRARY_TAG, comm);

....

}


#ifdef EXAMPLE_2C

/* include (resp, exclude) for safety (resp, no safety): */

MPI_Barrier(comm);

#endif

}


5.6 МЕЖСВЯЗЬ

( Связь между группами )


Этот раздел вводит понятие межсвязи и описывает процедуры MPI, которые поддерживают это понятие. Вся сканирующая связь описанная до сих пор включала связь между процессами, которые являются участниками одной и той же группы. Этот тип связи назван связью интра и используемые коммуникаторы - коммуникаторы интра.

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

Межсвязь - сканирующая связь между процессами находящихся в разных группах. Группа, содержащая процесс, который использует межсвязь названа локальной группой,а группа с которой устанавливают межсвязь называется дистанционной. Как и в связи интра, целевой процесс определяется парой (коммуникатор, ранг). Особенности межсвязи и межкоммуникаторов:


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

  • целевой процесс адресуется своим рангом в дистанционной группе и для приема и для передачи.

  • Связь, использующая межкоммуникатор гарантирует не противоречить с любой другой связью, которая использует другой коммуникатор.

  • межкоммуникатор не может использоваться для коллективной связи.

  • коммуникатор неможет обеспечивать интра- и межсвязь одновременно.


MPI_COMM_TEST_INTER определяет принадлежность коммуникатора к коммуникатору интра.


5.6.1 Команды использующие межкоммуникаторы


MPI_COMM_TEST_INTER(comm, flag)

IN comm - коммуникатор (handle)

OUT flag - флаг (logical)


int MPI_Comm_test_inter(MPI Comm comm, int *flag)

MPI_COMM_TEST_INTER(COMM, FLAG, IERROR)

INTEGER COMM, IERROR LOGICAL FLAG


Эта команда позволяет определить тип коммуникатора. Команда возвращает true если это - межкоммуникатор, в противном случае false. Если проверяемый коммуникатор есть межкоммуникатор то возможно использование следующих команд :


MPI_СОММ * Функциональное поведение


MPI_COMM_SIZE - возвращает размер локальной группы.

MPI_COMM_GROUP - возвращает локальную группу.

MPI_COMM_RANK - возвращает ранг в локальной группе.

MPI_COMM_COMPARE - сравнивает коммуникаторы (оба коммуникатора

должны быть либо интра либо ежкомуникаторами.

В противном случае результат будет

MPI_UNEQUAL.


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


MPI_COMM_REMOTE_SIZE(comm, size)

IN comm - межкоммуникатор (handle)

OUT size - число процессов в дистанционной группе comm (integer)


int MPI_Comm_remote_size(MPI Comm comm, int *size)

MPI_COMM_REMOTE_SIZE(COMM, SIZE, IERROR)

INTEGER COMM, SIZE, IERROR


MPI_COMM_REMOTE_GROUP(comm, group)

IN comm - межкоммуникатор (handle)

OUT group - дистанционная группа соответствующая comm (handle)


int MPI_Comm_remote_group(MPI Comm comm, MPI Group *group)

MPI_COMM_REMOTE_GROUP(COMM, GROUP, IERROR)

INTEGER COMM, GROUP, IERROR


5.6.2 Операции межкоммуникатора


Этот раздел вводит четыре блокировочные операции с использованием межкоммуникаторами. MPI_INTERCOMM_CREATE используется для связи двух коммуникаторов интра в межкоммуникатор; MPI_INTERCOMM_MERGE создает коммуникатор интра объединяя локальные и дистанционные группы межкоммуникатора. MPI_COMM_DUP и MPI_COMM_FREE введены для дублирования и освобождения межкоммуникатор соответственно.

MPI_INTERCOMM_CREATE может создавать межкоммуникатор от двух существующих коммуникаторов интра в следующей ситуации:

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

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


MPI_INTERCOMM_CREATE(local comm, local leader, peer comm, remote

leader, tag, newintercomm)

IN local comm - локальный коммуникатор интра (handle)

IN local leader - ранг лидера локальной группы в comm (integer)

IN peer comm - сверсник коммуникатора; значимый только для локального

лидера (handle)

IN remote leader - ранг сверсника группового лидера для comm (integer)

IN tag - этикетка (integer)

OUT newintercomm - полученный межкоммуникатор (handle)


int MPI_Intercomm_create(MPI Comm local comm, int local leader, MPI_Comm_peer

comm, int remote leader, int tag, MPI Comm *newintercomm)

MPI_INTERCOMM_CREATE(LOCAL COMM, LOCAL LEADER, PEER COMM, REMOTE LEADER,

TAG, NEWINTERCOMM, IERROR)

INTEGER LOCAL COMM, LOCAL LEADER, PEER COMM, REMOTE LEADER, TAG,

NEWINTERCOMM, IERROR


Этот вызов создает межкоммуникатор. Для дистанционного лидера, ло-

кального лидера и этикетки.


MPI_INTERCOMM_MERGE(intercomm, high, newintracomm)

IN intercomm - межкоммуникатор (handle)

IN high - (logical)

OUT newintracomm - полученный коммуникатор интра (handle)


int MPI_Intercomm_merge(MPI Comm intercomm, int high,

MPI Comm *newintracomm)

MPI_INTERCOMM_MERGE(INTERCOMM, HIGH, INTRACOMM, IERROR)

INTEGER INTERCOMM, INTRACOMM, IERROR LOGICAL HIGH


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


5.6.3 Примеры межсвязи


Примера 1: Трех-Групповой ``Конвейер'' Группируются 0 и 1. Группируются 1 и 2. Следовательно, групп 0 требует один межкоммуникатор, группа 1 требует два межкоммуникатора, и группа 2 требует 1 межкоммуникатор.


main(int argc, char **argv)

{

MPI_Comm myComm; /* коммуникатор интра локальной подгруппы */

MPI_Comm myFirstComm; /* межкоммуникаторы */

MPI_Comm mySecondComm; /* второй межкоммуникатор (группа 1) */

int membershipKey;

int rank;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

/* Код пользователя должен сгенерировать membershipKey в области [0,1,2] */

membershipKey = rank % 3;

/* Объявление коммуникатора интра для локальной подгруппы */

MPI_Comm_split(MPI_COMM_WORLD, membershipKey, rank, &myComm);

/* Объявление межкоммуникатора. Этикетка - hard-coded. */

if (membershipKey == 0)

{ /* группа 0 сообщается с группой 1. */

MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 1,1, &myFirstComm);

}

else if (membershipKey == 1)

{ /* группа 1 сообщаются с группами 0 и 2. */

MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 0,1, &myFirstComm);

MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 2,12, &mySecondComm);

}

else if (membershipKey == 2)

{ /* группа 2 сообщаются с группой 1 */

MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 1,12, &myFirstComm);

}


/* Выполнение ... */

switch(membershipKey) /* освобождение коммуникаторов */

{

case 1: MPI_Comm_free(&mySecondComm);

case 0:

case 2: MPI_Comm_free(&myFirstComm);

break;

}

MPI_Finalize();

}


Пример 2: Трех-групповое "Кольцо" Группируются 0 и 1. Группируются 1 и 2. Группируются 0 и 2. Следовательно, каждая группа требует два межкоммуникатора.


main(int argc, char **argv)

{

MPI_Comm myComm; /* коммуникатор интра локальной подгруппы */

MPI_Comm myFirstComm; /* межкоммуникаторы */

MPI_Comm mySecondComm;

MPI_Status status;

int membershipKey;

int rank;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);

...

/* Код пользователя должен сгенерировать membershipKey с рангами[0,1,2] */

membershipKey = rank % 3;

/* Объявление коммуникатора интра для локальной подгруппы */

MPI_Comm_split(MPI_COMM_WORLD, membershipKey, rank, &myComm);

/* Объявление межкоммуникатора. Этикетка - hard-coded. */

if (membershipKey == 0)

{ /* группа 0 сообщаются с группами 1 и 2. */

MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 1,

1, &myFirstComm);

MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 2,

2, &mySecondComm);

}

else if (membershipKey == 1)

{ /* группа 1 сообщаются с группами 0 и 2. */

MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 0,

1, &myFirstComm);

MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 2,

12, &mySecondComm);

}

else if (membershipKey == 2)

{ /* группа 2 сообщаются с группами 0 и 1. */

MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 0,

2, &myFirstComm);

MPI_Intercomm_create( myComm, 0, MPI_COMM_WORLD, 1,

12, &mySecondComm);

}

/* Выполнение какойто работы ... */

/* Освобождение коммуникаторов и завершение */

MPI_Comm_free(&myFirstComm);

MPI_Comm_free(&mySecondComm);

MPI_Comm_free(&myComm);

MPI_Finalize();

}


5.7 Кэширование


MPI обеспечивает возможность "кэширования", которая позволяет приложению подключать произвольные части информации к атрибутам коммуникатора. Средства кэширования позволяют делать следующее:


  • передачу информации в интра- или межкоммуникаторах,

  • быстро извлекать информацию

  • гарантирует, что устаревшая информация никогда не извлечется.


Кэширование требуется в некоторых случаях коллективной связи и для топологии.


5.7.1 Функциональное назначение


Атрибуты в C void* типа. Такой атрибут это указатель на структуру, которая содержит дальнейшую информацию, или указатель на MPI объект. В Fortran атрибуты INTEGER типа.


Функции используемые для атрибуттов :

  • определение атрибута ;

  • получение величины атрибута ;


MPI обеспечивает следующие услуги связанные с кэшированием :


MPI_KEYVAL_CREATE(copy fn, delete fn, keyval, extra state)

IN copy fn - функция для копии keyval

IN delete fn - функция для удаления keyval

OUT keyval - ключевая величина для будущего доступа (integer)

IN extra state - функция для дополнительного состояния


int MPI_Keyval_create(MPI Copy function *copy fn, MPI Delete function

delete fn, int *keyval, void* extra state)

MPI_KEYVAL_CREAТE(COPY FN, DELETE FN, KEYVAL, EXTRA STATE, IERROR)

EXTERNAL COPY FN, DELETE FN

INTEGER KEYVAL, EXTRA STATE, IERROR


Генерирует новый вспомогательный ключ. Ключи локально уникальные в процессе и невидимые потребителю. Ключ имеет доступ к атрибутам коммуникатора.

copy fn - функция выполняемая при дублировании коммуникатора (MPI_СОММ_DUP). copy fn должна быть типом MPI_Copy_function, который определяется :


typedef int MPI_Copy_function(MPI_Comm oldcomm, int keyval, void extra_state, void *attribute_val_in, void *attribute_val_out, int *flag)


Объявление для Fortran этой функции следующее :

SUBROUTINE_COPY_FUNCTION(OLDCOMM, KEYVAL, EXTRA_STATE, ATTRIBUTE_VAL_IN,

ATTRIBUTE_VAL_OUT, FLAG, IERR)

INTEGER OLDCOMM, KEYVAL, EXTRA STATE, ATTRIBUTE VAL IN,

ATTRIBUTE VAL OUT, IERR LOGICAL FLAG


Функция копирования вводится для каждого ключа oldcomm. Каждый вызов этой функции возвращает копию сделанную с ключа и соответствующего атрибута. Если функция копирования возвращает флаг = 0, то атрибут удаляется в дублированном коммуникаторе. В противном случае (флаг = 1), attribut_vаl устанавливается в значение attribut_val_out.

copy_fn может возвращать значения MPI_NULL_COPY_FN или MPI_DUP_FN.


MPI_NULL_COPY_FN - возвращает флаг = 0 и MPI_SUCCESS.

MPI DUP FN - устанавливает флаг = 1, attribute_val_out =

attribute_val_in и возвращает MPI_SUCCESS.


Функция delete_fn запускается когда коммуникатор удаляется

MPI_СОММ_FREE или, когда вызов сделан явно командой MPI_ATTR_DELETE.

delete_fn должна быть типом MPI_Delete_function, который определяется :


MPI_Delete_function(MPI_Comm comm, int keyval, void *attribute_val, void

*extra_state);


Объявление для Fortran этой функции следующее :


SUBROUTINE DELETE FUNCTION(COMM, KEYVAL, ATTRIBUTE VAL, EXTRA STATE, IERR)

INTEGER COMM, KEYVAL, ATTRIBUTE VAL, EXTRA STATE, IERR


delete_fn может возвращать значение MPI_NULL_DELETE_FN

MPI_NULL_DELETE_FN - функция, которая не делает ничего, кроме

возврата MPI_SUCCESS.


MPI_KEYVAL_FREE(keyval)

INOUT keyval - уничтожаемый ключ (integer)


int MPI_Keyval_free(int *keyval)

MPI_KEYVAL_FREE(KEYVAL, IERROR)

INTEGER KEYVAL, IERROR


Эта функция устанавливает величину keyval в MPI_KEYVAL_INVALID.


MPI_ATTR_PUT(comm, keyval, attribute val)

IN comm - коммуникатор в который добавляется атрибут (handle)

IN keyval - ключ атрибута полученный после MPI_KEYVAL_CREATE (integer)

IN attribute_val - значение атрибута


int MPI_Attr_put(MPI Comm comm, int keyval, void* attribute val)

MPI_ATTR_PUT(COMM, KEYVAL, ATTRIBUTE VAL, IERROR)

INTEGER COMM, KEYVAL, ATTRIBUTE VAL, IERROR


Эта функция загружает или перезаписует (если значение уже существует) значение attribut_val.


MPI_ATTR_GET(comm, keyval, attribute val, flag)

IN comm - коммуникатор в который добавлялся атрибут (handle)

IN keyval - ключ (integer)

OUT attribute val - начение атрибута lag = false

OUT flag - флаг


int MPI_Attr_get(MPI Comm comm, int keyval, void *attribute val, int *flag)

MPI_ATTR_GET(COMM, KEYVAL, ATTRIBUTE VAL, FLAG, IERROR)

INTEGER COMM, KEYVAL, ATTRIBUTE VAL, IERROR LOGICAL FLAG


Флаг устанавливается в false если никакой атрибут не связын с этим клачем.


MPI_ATTR_DELETE(comm, keyval)

IN comm - коммуникатор в который добавлялся атрибут (handle)

IN keyval - ключ удаляемого атрибута (integer)


int MPI_Attr_delete(MPI Comm comm, int keyval)

MPI_ATTR_DELETE(COMM, KEYVAL, IERROR)

INTEGER COMM, KEYVAL, IERROR


Эта функция производит удаление атрибута и ключа на него указывающего из коммуникатора comm.


5.7.2 Пример кэширования


Этот пример показывает написание программу для коллективной связи, которая использует кэширование.


/* ключ для этих модульных вещей: */

static int gop_key = MPI_KEYVAL_INVALID;

typedef struct

{

int ref_count; /* число ссылок */

/* чтонибудь еще */

}

gop_stuff_type;

Efficient_Collective_Op (comm, ...)

MPI_Comm comm;

{

gop_stuff_type *gop_stuff;

MPI_Group group;

int foundflag;

MPI_Comm_group(comm, &group);

if (gop_key == MPI_KEYVAL_INVALID) /* получение key на первом вызове */

{

if ( ! MPI_keyval_create( gop_stuff_copier, gop_stuff_destructor,

&gop_key, (void *)0));

/* получение key */

MPI_Abort (comm, 99);

}

MPI_Attr_get (comm, gop_key, &gop_stuff, &foundflag);

if (foundflag)

{ /* В этой группе сначало выполняется этот модуль.

Используется кеш информация */

}

else

{ gop_stuff = (gop_stuff_type *) malloc (sizeof(gop_stuff_type));

if (gop_stuff == NULL) { /* выход - ошибка памяти */ }

gop_stuff -> ref_count = 1;

/* Заполнение *gop_stuff. Эта часть не показана здесь */

MPI_Attr_put ( comm, gop_key, gop_stuff);

}

/* Определение global op, используя содержимое *gop_stuff... */

}


/* Программа вызывающаяся MPI при освобождении группы */

gop_stuff_destructor (comm, keyval, gop_stuff, extra)

MPI_Comm comm;

int keyval;

gop_stuff_type *gop_stuff;

void *extra;

{

if (keyval != gop_key) { /* обработка ошибок */ }

/* Освобождение группы удалением пот одной ссылке в gop_stuff */

gop_stuff -> ref_count -= 1;

/* Если ссылок больше нет, то освобождаем память */

if (gop_stuff -> ref_count == 0)

{

free((void *)gop_stuff);

}

}


/* Программа вызывающаяся MPI при копировании группы */

gop_stuff_copier (comm, keyval, extra, gop_stuff_in, gop_stuff_out, flag)

MPI_Comm comm;

int keyval;

gop_stuff_type *gop_stuff_in, *gop_stuff_out;

void *extra;

{

if (keyval != gop_key) {/* обработка ошибок */ }

/* Новая группа добавляет одну ссылку к gop_stuff */

gop_stuff -> ref_count += 1;

gop_stuff_out = gop_stuff_in;

}

Схожі:

Группы Контексты, и Коммуникаторы iconГраф логической структуры темы: «пародонтиты у детей» локализованный пародонтит
В границах отдельных зубов или группы зубов, чаще фронтальной группы верхней и нижней челюстей
Группы Контексты, и Коммуникаторы iconТема 17. Комплектование малых групп понятие группы
...
Группы Контексты, и Коммуникаторы iconА. Ф. Хохловым положение о кураторе академической группы
Вузе является куратор академической группы, особенно на 1-2 курсах обучения, когда происходит адаптация вчерашнего школьника к новым...
Группы Контексты, и Коммуникаторы iconМ. И. Меерович Лаборатория «триз-педагогика Украины», Одесса (Украина) Л. И. Шрагина ону имени И. И. Мечникова тоталитаризм как аспект глобализации (в контексте закон
Потребность повысить шансы на выживание привела живые организмы к необходимости объединяться в группы различной численности и степени...
Группы Контексты, и Коммуникаторы iconЛекція 3 "Економічна інформатика" Тема Системне забезпечення інформаційних процесів Системное обеспечение информационных процессов, это программно-аппаратные комплексы, с помощью которых автоматизируется процесс сбора, передачи и обработки данных
Специализированные компьютеры, например – серверы, машины баз данных, коммуникаторы
Группы Контексты, и Коммуникаторы iconЛекція 3 "Економічна інформатика" Тема 3-а. Системне забезпечення інформаційних процесів Системное обеспечение информационных процессов, это программно-аппаратные комплексы, с помощью которых автоматизируется процесс сбора, передачи и обработки данных
Специализированные компьютеры, например – серверы, машины баз данных, коммуникаторы
Группы Контексты, и Коммуникаторы iconСписок літератури акимов О. Е. Дискретная математика. Логика, группы, графы. М.: Лаборатория Базовых Знаний, 2003
Акимов О. Е. Дискретная математика. Логика, группы, графы. М.: Лаборатория Базовых Знаний, 2003. – 376 с
Группы Контексты, и Коммуникаторы iconІі общая характеристика группы инфекционных болезней с фекально-оральнЫм механизмом передачи. Брюшной тиф. Паратифы а и в продолжительность
Общая характеристика группы инфекционных болезней с фекально-оральнЫм механизмом передачи. Брюшной тиф. Паратифы а и В
Группы Контексты, и Коммуникаторы iconН. И. Пирогова кафедра эндокринологии с курсом последиплом
Куратор: студент курса группы факультета
Группы Контексты, и Коммуникаторы iconТворческие группы
Використання педагогічних програмних засобів – ефективний шлях проходження старшокласників зно
Группы Контексты, и Коммуникаторы iconТворческие группы
Для педагогов, участвующих в апробации учебной литературы, авторских курсов, программ
Додайте кнопку на своєму сайті:
Документи


База даних захищена авторським правом ©zavantag.com 2000-2013
При копіюванні матеріалу обов'язкове зазначення активного посилання відкритою для індексації.
звернутися до адміністрації
Документи