Как узнать количество ядер, доступных для MPI(4PY)?

Как узнать количество ядер, доступных для MPI(4PY)?


Мотивация

Моя программа на Python создает экземпляры MPI иерархически.

Первый спаун всегда происходит и создает 4 экземпляра. Увеличивать это число не имеет смысла из-за структуры моих вычислений, поэтому я жестко запрограммировал его.

В зависимости от параметров командной строки основной программы каждый из 4 экземпляров затем вызывает внешнее программное обеспечение Python, которое масштабируется почти линейно.

Я называю это внешним программным обеспечением, используя

N=3
child=MPI.COMM_SELF.Spawn(sys.executable,args=[`external.py`],maxprocs=N)

На данный момент я использую N=3, так что 4 экземпляра первого экземпляра порождают каждый по 3 экземпляра внешней программы, что дает в общей сложности 12 экземпляров, что соответствует количеству ядер на моей рабочей станции.

Однако для переносимости я хотел бы сделать

N_avail = <MPI.N_CORES> #on my workstation: N_avail=12
N = N_avail/MPI.COMM_WORLD.Get_size() #on my workstation: N=12/4=3

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

Возможно ли это и есть ли смысл?


Примечания

Я надеялся, что не указание maxprocs поможет, так же как mpirun без -np порождает столько экземпляров, сколько доступно ядер. Однако Spawn по умолчанию принимает значение maxprocs=1.

Вызов внешней библиотеки блокируется, поэтому я не буду (не буду) вычитать 4 экземпляра из первого спавна из N_avail.

Я не могу просто использовать multiprocessing.cpu_count(), так как это даст мне только ядра на текущем узле (в настройках кластера). Я планирую запустить свой код в кластере с помощью планировщика SLURM.


person Bananach    schedule 13.11.2017    source источник
comment
если вы используете SLURM, вы можете использовать $SLURM_NTASKS, чтобы выяснить, сколько слотов было выделено.   -  person Gilles Gouaillardet    schedule 13.11.2017


Ответы (1)


Существует атрибут мирового коммуникатора, который может указывать общее количество ожидаемых процессов: MPI_UNIVERSE_SIZE. См. стандарты MPI, http://mpi-forum.org/docs/mpi-3.1/mpi31-report/node253.htm#Node253

MPI предоставляет атрибуты MPI_COMM_WORLD, MPI_UNIVERSE_SIZE, которые позволяют приложению получать эту информацию переносимым способом. Этот атрибут указывает общее количество ожидаемых процессов. ... Приложение обычно вычитает размер MPI_COMM_WORLD из MPI_UNIVERSE_SIZE, чтобы узнать, сколько процессов оно должно создать. ...

В mpi4py это можно распечатать как:

from mpi4py import MPI

version= MPI.Get_version()
print "mpi version is ",version

comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
print "size is ",size

universe_size=comm.Get_attr(MPI.UNIVERSE_SIZE)
print "universe size is ",universe_size

После размера вселенной OpenMPI mpirun эту функцию можно протестировать, попробовав:

mpirun -np 1 -H localhost,localhost,localhost python main.py

Если ваша версия MPI выше или равна 3, MPI_Info MPI_INFO_ENV может вам помочь. В нем есть два ключа, которые могут предоставить некоторую информацию:

maxprocs Максимальное количество запускаемых процессов MPI.

soft Допустимые значения количества процессоров.

Чтобы использовать его в mpi4py, вы можете попробовать:

soft=MPI.INFO_ENV.get("soft")
print soft
maxprocs=MPI.INFO_ENV.get("maxprocs")
print maxprocs
person francis    schedule 13.11.2017
comment
Первый подход: он может воспроизвести количество раз, которое я набрал localhost. Однако я хотел бы запустить main.py без mpirun, а затем выяснить, сколько ядер доступно. Даже если я запускаю mpirun -np 4 python main.py, т.е. не использую флаг -H, этот подход всегда возвращает 1 - person Bananach; 14.11.2017
comment
Второй подход: оба возвращают аргумент, переданный -np, или 1, если он запущен без mpirun. - person Bananach; 14.11.2017