Коллоквиум сұрақтары жауаптары (2) (копия). Коллоквиум сратары
Скачать 2 Mb.
|
Рис. 4.8. Графическая интерпретация операции Reduce. В качестве операции op можно использовать либо одну из предопределенных операций, либо операцию, сконструированную пользователем. Все предопределенные операции являются ассоциативными и коммутативными. Сконструированная пользователем операция, по крайней мере, должна быть ассоциативной. Порядок редукции определяется номерами процессов в группе. Тип datatype элементов должен быть совместим с операцией op. В таблице 4.1 представлен перечень предопределенных операций, которые могут быть использованы в функциях редукции MPI.
Функция MPI_Allreduce сохраняет результат редукции в адресном пространстве всех процессов, поэтому в списке параметров функции отсутствует идентификатор корневого процесса root. В остальном, набор параметров такой же, как и в предыдущей функции. С: int MPI_Allreduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) FORTRAN: MPI_ALLREDUCE (SENDBUF, RECVBUF, COUNT, DATATYPE, OP, COMM, IERROR) INTEGER COUNT, DATATYPE, OP, COMM, IERROR
На рис. 4.9 представлена графическая интерпретация операции Allreduce. Рис. 4.9. Графическая интерпретация операции Allreduce. Функция MPI_Reduce_scatter совмещает в себе операции редукции и распределения результата по процессам. С: MPI_Reduce_scatter(void* sendbuf, void* recvbuf, int *recvcounts, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) FORTRAN: MPI_REDUCE_SCATTER(SENDBUF,RECVBUF,RECVCOUNTS, DATATYPE, OP, COMM, IERROR) INTEGER RECVCOUNTS(*), DATATYPE, OP, COMM, IERROR
Функция MPI_Reduce_scatter отличается от MPI_Allreduce тем, что результат операции разрезается на непересекающиеся части по числу процессов в группе, i-ая часть посылается i-ому процессу в его буфер приема. Длины этих частей задает третий параметр, являющийся массивом. На рис. 4.10 представлена графическая интерпретация операции Reduce_scatter. Рис. 4.10. Графическая интерпретация операции Reduce_scatter. 23.Работа с группами и коммуникаторами. Функции работы с группами. Функции работы с группами. Функция определения числа процессов в группе MPI_Group_size С: MPI_Group_size(MPI_Group group, int *size) Функция возвращает число процессов в группе. Если group = MPI_GROUP_EMPTY, тогда size = 0. Функция определения номера процесса в группе MPI_Group_rank С: MPI_Group_rank(MPI_Group group, int *rank) Функция MPI_Group_rank возвращает номер в группе процесса, вызвавшего функцию. Если процесс не является членом группы, то возвращается значение MPI_UNDEFINED. Функция установки соответствия между номерами процессов в двух группах MPI_Group_translate_ranks С: MPI_Group_translate_ranks (MPI_Group group1, int n, int *ranks1, MPI_Group group2, int *ranks2) Функция определяет относительные номера одних и тех же процессов в двух разных группах. Если процесс во второй группе отсутствует, то для него устанавливается значениеа MPI_UNDEFINED. Для создания новых групп в MPI имеется 8 функций. Группа может быть создана либо с помощью коммуникатора, либо с помощью операций над множествами процессов других групп. Функции работы с коммуникаторами В данном подразделе рассматриваются функции работы с коммуникаторами. Они разделяются на функции доступа к коммуникаторам и функции создания коммуникаторов. Функции доступа являются локальными и не требуют коммуникаций, в отличие от функций создания, которые являются коллективными и могут потребовать межпроцессорных коммуникаций. Две основных функции доступа к коммуникатору, MPI_Comm_size - опрос числа процессов в области связи и MPI_Comm_rank - опрос идентификатора номера процесса в области связи, были рассмотрены в самом начале среди базовых функций MPI. Кроме них, имеется функция сравнения двух коммуникаторов MPI_Comm_compare. С: MPI_Comm_compare(MPI_Comm comm1,MPI_Comm comm2, int *result) Возможные значения результата сравнения:
Создание нового коммуникатора возможно с помощью одной из трех функций: MPI_Comm_dup, MPI_Comm_create, MPI_Comm_split. Функция дублирования коммуникатора MPI_Comm_dup С: MPI_Comm_dup(MPI_Comm comm, MPI_Comm *newcomm) Функция полезна для последующего создания коммуникаторов с новыми атрибутами. Функция создания коммуникатора MPI_Comm_create С: MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm) Эта функция создает коммуникатор для группы group. Для процессов, которые не являются членами группы, возвращается значение MPI_COMM_NULL. Функция возвращает код ошибки, если группа group не является подгруппой родительского коммуникатора. Функция расщепления коммуникатора MPI_Comm_split С: MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm) Функция расщепляет группу, связанную с родительским коммуникатором, на непересекающиеся подгруппы по одной на каждое значение признака подгруппы color. Значение color должно быть неотрицательным. Каждая подгруппа содержит процессы с одним и тем же значением color. Параметр key управляет упорядочиванием внутри новых групп: меньшему значению key соответствует меньшее значение идентификатора процесса. В случае равенства параметра key для нескольких процессов упорядочивание выполняется в соответствии с порядком в родительской группе. 24.Работа с группами и коммуникаторами. Функции работы с коммуникаторами. Каждому процессу в группе сопоставлен свой ранг. Операции с группами могут выполняться отдельно от операций с коммуникаторами, но в операциях обмена используются только коммуникаторы. • В MPI имеется специальная предопределенная пустая группа MPI_GROUP_EMPTY. Коммуникаторы бывают двух типов: 1. интракоммуникаторы - для операций внутри одной группы процессов; 2. интеркоммуникаторы - для двухточечного обмена между двумя группами процессов. Интракоммуникатором является MPI_COMM_WORLD. В MPI-программах чаще используются интракоммуникаторы. В функциях создания групп, как правило, нельзя использовать пустой коммуникатор MPI_COMM_NULL. Доступ к группе group, связанной с коммуникатором comm , можно получить, обратившись к функции MPI_Comm_group: int MPI_Comm_group(MPI_Comm comm, MPI_Group *group) Функция MPI_Comm_create создает новый коммуникатор (newcomm) из подмножества процессов (group) другого коммуникатора (oldcomm): int MPI_Comm_create(MPI_Comm oldcomm, MPI_Group group, MPI_Comm *newcomm) Функция MPI_Comm_free помечает коммуникатор comm для удаления: int MPI_Comm_free(MPI_Comm *comm) К числу операций управления коммуникаторами можно отнести операции MPI_Comm_size и MPI_Comm_rank. Они позволяют, в частности, распределить роли между процессами в модели masterslave. 25.Производные типы данных и передача упакованных данных. Производные типы MPI не являются в полном смысле типами данных, как это понимается в языках программирования. Они не могут использоваться ни в каких других операциях, кроме коммуникационных. Производные типы MPI следует понимать как описатели расположения в памяти элементов базовых типов. Производный тип MPI представляет собой скрытый (opaque) объект, который специфицирует две вещи: последовательность базовых типов и последовательность смещений. Производный тип строится из предопределенных типов MPI и ранее определенных производных типов с помощью специальных функций-конструкторов MPI_Type_contiguous, MPI_Type_vector, MPI_Type_hvector, MPI_Type_indexed, MPI_Type_hindexed, MPI_Type_struct. Новый производный тип регистрируется вызовом функции MPI_Type_commit. Только после регистрации новый производный тип можно использовать в коммуникационных подпрограммах и при конструировании других типов. Предопределенные типы MPI считаются зарегистрированными. Когда производный тип становится ненужным, он уничтожается функцией MPI_Type_free. Функция MPI_Pack упаковывает incount элементов типа datatype из области памяти с начальным адресом inbuf. Результат упаковки помещается в выходной буфер с начальным адресом outbuf и размером outsize байт. Параметр position указывает текущую позицию в байтах, начиная с которой будут размещаться упакованные данные. На выходе из подпрограммы значение position увеличивается на число упакованных байт, указывая на первый свободный байт. Параметр comm при последующей посылке упакованного сообщения будет использован как коммуникатор. Для посылки элементов разного типа из нескольких областей памяти их следует предварительно запаковать в один массив, последовательно обращаясь к функции упаковки MPI_Pack. При первом вызове функции упаковки параметр position, как правило, устанавливается в 0, чтобы упакованное представление размещалось с начала буфера. Для непрерывного заполнения буфера необходимо в каждом последующем вызове использовать значение параметра position, полученное из предыдущего вызова. Упакованный буфер пересылается любыми коммуникационными операциями с указанием типа MPI_PACKED и коммуникатора comm, который использовался при обращениях к функции MPI_Pack. |