Как определить номер/номер MPI, локальный для сокета/узла

Скажем, я запускаю параллельную программу с использованием MPI. Команда выполнения

mpirun -n 8 -npernode 2 <prg>

запускает 8 процессов. Это всего 2 процесса на узел и 4 узла. (OpenMPI 1.5). Если узел содержит 1 процессор (двухъядерный) и сетевое соединение между узлами, это InfiniBand.

Теперь номер ранга (или номер процесса) можно определить с помощью

int myrank;
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

Это возвращает число от 0 до 7.

Но, как я могу определить номер узла (в данном случае число от 0 до 3) и номер процесса в узле (число от 0 до 1)?

Ответ 1

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

В открывшемся MPI есть некоторые переменные среды, которые могут помочь. OMPI_COMM_WORLD_LOCAL_RANK предоставит вам локальный ранг внутри узла - то есть. это номер процесса, который вы ищете. Поэтому вызов getenv будет отвечать на вашу проблему, но это не переносимо для других реализаций MPI.

См. Http://icl.cs.utk.edu/open-mpi/faq/?category=running#mpi-environmental-variables для (краткого) списка переменных в Open MPI.

Я не знаю соответствующего "номера узла".

Ответ 2

Я считаю, что вы можете добиться этого с помощью MPI-3 таким образом:

MPI_Comm shmcomm;
MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0,
                    MPI_INFO_NULL, &shmcomm);
int shmrank;
MPI_Comm_rank(shmcomm, &shmrank);

Ответ 3

Эта точная проблема обсуждается в блоге Markus Wittmann, определении узла локального ранга MPI.

Там предлагаются три стратегии:

  1. В наивном переносном решении используется MPI_Get_processor_name или gethostname для создания уникального идентификатора узла и выполнения MPI_Alltoall на нем. [...]
  2. [Метод 2] полагается на MPI_Comm_split, который обеспечивает простой способ разделить коммуникатор на подгруппы (суб-коммуникаторы). [...]
  3. Можно использовать общую память, если она доступна. [...]

Для некоторого рабочего кода (предположительно, LGPL лицензирован?), Wittmann ссылается на MpiNodeRank.cpp из библиотеки APSM.

Ответ 4

В качестве альтернативы вы можете использовать

int MPI_Get_processor_name( char *name, int *resultlen )

для получения имени узла, затем используйте его как цвет в

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

Это не так просто, как MPI_Comm_split_type, однако он предлагает немного больше свободы для разделения вашего comunicator так, как вы хотите.