Групповой процесс MPI на основе флага - PullRequest
0 голосов
/ 08 декабря 2018

Мне нужно создать субкоммуникатор (mi_comm_world_2) на основе большего MPI-коммуникатора (mpi_comm_world).

В частности, после цикла обнаружения, такого как

, еслиsomething существует внутри процедуры proc

Мне нужно собрать в новом коммуникаторе mpi_comm_world_2 весь процесс, помеченный как истинный в отношении проверки.

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

1 Ответ

0 голосов
/ 08 декабря 2018

Хороший вопрос!

Для этого подходит команда MPI_Comm_split .

Определение

int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *newcomm)

Аргументы

  • comm : Дескриптор к коммуникатору, который вы хотите построить, из нового цвета

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

  • ключ : целое число, которое управляет присвоением ранга.Ранги всегда присваиваются от 0 количеству процессов в коммуникаторе.Ключ определяет относительный порядок рангов процессов в новом коммуникаторе.

  • newcomm : новый коммуникатор

  • int : функция возвращает целое число, указывающее, было ли оно успешным или нет.

Более подробные объяснения

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

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

Например, если вы определили color = rank%4 (см. Пример 4 ниже), вы бы создали (глобально) четыре новых коммуникатора.Имейте в виду, что каждый процесс будет видеть только один из этих новых коммуникаторов, частью которого он является.Другими словами, цвет определяет, какие «команды» вы создадите, например цвет футболки футбольных команд.

ключ будет определять, как процессы ранжируются в новых коммуникаторах, частью которых они являются.,Если вы установите key = rank, то порядок ранжирования (не самого ранжирования) в каждом новом коммуникаторе newcomm будет соответствовать порядку ранжирования в исходном коммуникаторе comm.Если два или более значения ключа имеют одно и то же значение, то процесс с более низким рангом в comm имеет более низкий ранг в newcomm.(См. Пример 2 ниже.)

Примеры

Вот несколько наглядных примеров, которые я дублирую в приведенном ниже коде.Пример № 5 отвечает на ваш конкретный вопрос.

Examples of MPI_Comm_split

Код для примеров

//Compile with mpic++ main.cpp
#include <mpi.h>

int main(int argc, char **argv){
  int world_size, world_rank;

  MPI_Init(&argc, &argv);

  MPI_Comm_size(MPI_COMM_WORLD, &world_size);  //Get the number of processes
  MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);  //Get the rank of the process

  MPI_Comm comm = MPI_COMM_WORLD;
  MPI_Comm newcomm1, newcomm2, newcomm3, newcomm4, newcomm5;

  //Example 1: Duplicate the existing communicator. The command `MPI_Comm_dup()`
  //           does exactly this.
  MPI_Comm_split(comm, 0, world_rank, &newcomm1);

  //Example 2: Duplicate the existing communicator, but reverse the 
  //           rankings
  MPI_Comm_split(comm, 0, world_size-world_rank, &newcomm2);
  int rank2;                           //Get the rank of the process
  MPI_Comm_rank(newcomm2, &rank2);     //in the new communicator


  //Example 3: Split each process into its own communicator. This is the
  //           equivalent of using `MPI_COMM_SELF` for each process.
  MPI_Comm_split(comm, world_rank, world_rank, &newcomm3);

  //Example 4: Split processes into communicators based on their colouring. Use
  //           their rank in the existing communicator to determine their 
  //           relative rank order in the new communicator.
  int color = world_rank / 4;
  MPI_Comm_split(comm, color, world_rank, &newcomm4);
  int rank4;                           //Get the rank of the process
  MPI_Comm_rank(newcomm2, &rank4);     //in the new communicator

  //Example 5: Group only some of the processes into a new communicator based on
  //a flag.
  int flag = world_rank%2==0;          //An example flag
  MPI_Comm_split(comm, flag?0:MPI_UNDEFINED, world_rank, &newcomm5);

  MPI_Finalize();
}

Дополнительная информация

  • На этой странице есть хорошее руководство по коммуникаторам и группам.
  • Файл SVG, который я разработал для примеров, доступен здесь
...