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

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

mpirun -n 8 -npernode 2 <prg>

запускает 8 процессов в целом. То есть 2 процесса на узел и 4 узла в целом. (OpenMPI 1.5). Где узел содержит 1 CPU (двухъядерный), а сетевое соединение между узлами-InfiniBand.

Итак, порядковый номер (или номер процесса) может быть определен с

int myrank;
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

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

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

4 ответов


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

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

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

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


Я считаю, что вы можете достичь этого с 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);

эта точная проблема обсуждается в блоге Маркуса Виттмана,MPI Node-определение локального ранга.

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

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

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


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

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, однако он предлагает немного больше свободы, чтобы разделить ваш коммуникатор, как вы хотите.