Лаборатория Параллельных информационных технологий НИВЦ МГУ
Опубликован: 22.04.2008 | Доступ: свободный | Студентов: 1177 / 413 | Оценка: 4.30 / 4.19 | Длительность: 08:05:00
Специальности: Программист
Лекция 5:

Группы и коммуникаторы

< Лекция 4 || Лекция 5: 12 || Лекция 6 >

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

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

Следующие коммуникаторы создаются сразу после вызова процедуры MPI_INIT:

  • MPI_COMM_WORLD - коммуникатор, объединяющий все процессы приложения;
  • MPI_COMM_NULL - значение, используемое для ошибочного коммуникатора;
  • MPI_COMM_SELF - коммуникатор, включающий только вызвавший процесс.

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

MPI_COMM_DUP(COMM, NEWCOMM, IERR) INTEGER COMM, NEWCOMM, IERR

Создание нового коммуникатора NEWCOMM с той же группой процессов и атрибутами, что и у коммуникатора сомм.

MPI_COMM_CREATE(COMM, GROUP, NEWCOMM, IERR) INTEGER COMM, GROUP, NEWCOMM, IERR

Создание нового коммуникатора NEWCOMM из коммуникатора сомм для группы процессов GROUP, которая должна являться подмножеством группы, связанной с коммуникатором сомм. Вызов должен встретиться во всех процессах коммуникатора сомм. На процессах, не принадлежащих группе GROUP, будет возвращено значение MPI_COMM_NULL.

В следующем примере создается две новых группы, одна из которых содержит первую половину процессов, а вторая - вторую половину. При нечетном числе процессов во вторую группу войдет на один процесс больше. Каждая группа создается только на тех процессах, которые в нее входят. Для каждой новой группы создается соответствующий ей коммуникатор new_comm, и операция MPI_ALLREDUCE выполняется по отдельности для процессов, входящих в разные группы.

call MPI_COMM_GROUP(MPI_COMM_WORLD, group, ierr)
do i = 1, size/2 ranks(i) = i-1
end do
if (rank .lt. size/2) then
call MPI_GROUP_INCL(group, size/2, ranks,
& new_group, ierr)
else
call MPI_GROUP_EXCL(group, size/2, ranks,
& new_group, ierr)
end if
call MPI_COMM_CREATE(MPI_COMM_WORLD, new_group,
& new_comm, ierr)
call MPI_ALLREDUCE(sbuf, rbuf, 1, MPI_INTEGER,
& MPI_SUM, new_comm, ierr)
call MPI_GROUP_RANK(new_group, new_rank, ierr)
print *, 'rank= ', rank, ' newrank= ', &        new rank, ' rbuf= ', rbuf
MPI_COMM_SPLIT(COMM, COLOR, KEY, NEWCOMM, IERR) 
INTEGER COMM, COLOR, KEY, NEWCOMM, IERR

Разбиение коммуникатора сомм на несколько новых коммуникаторов по числу значений параметра COLOR. В один коммуникатор попадают процессы с одним значением COLOR. Процессы с большим значением параметра KEY получат больший ранг в новой группе, при одинаковом значении параметра KEY порядок нумерации процессов выбирается системой.

Процессы, которые не должны войти в новые коммуникаторы, указывают в качестве параметра COLOR константу MPI_UNDEFINED. Им В параметре NEWCOMM вернется значение MPI_COMM_NULL.

В следующем примере коммуникатор MPI_COMM_WORLD разбивается на три части. В первую войдут процессы с номерами 0, 3, б и т.д., во вторую - 1, 4, 7 и т.д., а в третью - 2, 5, 8 и т.д. Задание в качестве параметра KEY переменной rank гарантирует, что порядок нумерации процессов в создаваемых группах соответствует порядку нумерации в исходной группе, то есть, порядку перечисления выше.

call MPI_COMM_SPLIT(MPI_COMM_WORLD, mod(rank, 3),
& rank, new_comm, ierr)
MPI_COMM_FREE(COMM, IERR) INTEGER COMM, IERR

Удаление коммуникатора сомм. После выполнения процедуры переменной сомм присваивается значение MPI_COMM_NULL. Если с этим коммуникатором к моменту вызова процедуры уже выполняется какая-то операция, то она будет завершена.

В следующем примере создается один новый коммуникатор comm_revs, в который входят все процессы приложения, пронумерованные в обратном порядке. Когда коммуникатор становится ненужным, он удаляется при помощи вызова процедуры MPI_COMM_FREE. Так можно использовать процедуру MPI_COMM_SPLIT для перенумерации процессов.

program example17 include 'mpif.h' integer ierr, rank, 
 size integer comm_revs, rank1 call MPI_INIT(ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD, size, ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr)
call MPI_COMM_SPLIT(MPI_COMM_WORLD, 1, size-rank,
& comm_revs, ierr)
call MPI_COMM_RANK(comm_revs, rank1, ierr) print *, 'rank = ', rank,' 
 rank1 = ', rank1 call MPI_COMM_FREE(comm_revs, ierr)
call MPI_FINALIZE(ierr) end

Задания

  • Какие группы процессов существуют при запуске приложения?
  • Могут ли группы процессов иметь непустое пересечение, не совпадающее ни с одной из них полностью?
  • В чем отличие между группой процессов и коммуникатором?
  • Могут ли обмениваться данными процессы, принадлежащие разным коммуникаторам ?
  • Может ли в какой-то группе не быть процесса с номером О?
  • Может ли в какую-либо группу не войти процесс с номером о в коммуникаторе MPI_COMM_WORLD?
  • Может ли только один процесс в некоторой группе вызвать процедуру МРI_GROUP_INCL?
  • Как создать новую группу из процессов 3, 4 и 7 коммуникатора МРI_COMM_WORLD?
  • Разбить все процессы приложения на три произвольных группы и напечатать ранги в MPI_COMM_WORLD тех процессов, что попали в первые две группы, но не попали в третью.
  • Какие коммуникаторы существуют при запуске приложения?
  • Можно ли в процессе выполнения программы изменить число процессов в коммуникаторе MPI_COMM_WORLD?
  • Может ли только один процесс в некотором коммуникаторе вызвать Процедуру MPI_COMM_CREATE?
  • Можно ли при помощи процедуры MPI_COMM_SPLIT создать ровно один новый коммуникатор?
  • Можно ли при помощи процедуры MPI_COMM_SPLIT создать столько новых коммуникаторов, сколько процессов входит в базовый коммуникатор?
  • Реализовать разбиение процессов на две группы, в одной из которых осуществляется обмен данными по кольцу, а в другой - коммуникации по схеме master-slave.
< Лекция 4 || Лекция 5: 12 || Лекция 6 >