Как определить ранг 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-определение локального ранга.
там предлагаются три стратегии:
- наивное портативное решение использует MPI_Get_processor_name или gethostname для создания уникального идентификатора узла и выполняет MPI_Alltoall на нем. [...]
- [Способ 2] полагается на MPI_Comm_split, который обеспечивает простой способ разделить коммуникатор на подгруппы (суб-коммуникаторы). [...]
- общая память может быть использована, если таковые имеются. [...]
для некоторого рабочего кода (предположительно лицензированного 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
, однако он предлагает немного больше свободы, чтобы разделить ваш коммуникатор, как вы хотите.