ранг в MPI_Bcast

MPI_Bcast(void *buffer,  int count,  MPI_Datatype datatype,  int root,  MPI_Comm comm)

Эта функция не требует параметра ранга. Как он узнает ранг каждого процесса?

Мы должны вызывать MPI_COMM_RANK() перед трансляцией, хранит ли какая-либо структура данных (например, коммуникатор) ранг процессов?


mpi
person suifengls    schedule 29.07.2012    source источник
comment
я бы также прочитал документацию, open-mpi.org /doc/v1.5/man3/MPI_Bcast.3.php, open-mpi содержит один из лучших документов по MPI.   -  person pyCthon    schedule 29.07.2012
comment
@pyCthon, документация Open MPI — это всего лишь man-удобная версия текста, найденного в Документ стандартов MPI-2.2 (и это нормально - не нужно изобретать велосипед и дублировать усилия, стоящие за отличной формулировкой в ​​стандарте).   -  person Hristo Iliev    schedule 29.07.2012


Ответы (4)


Возможно, вы не думали, что это возможно, но функции внутри библиотеки MPI могут выполнять внутри те же самые вызовы MPI, которые вы используете для получения ранга процесса или размера коммуникатора. Вот почему MPI_Bcast() не нужен ранг вызывающего процесса, потому что он просто вызывает внутреннюю реализацию MPI_Comm_rank(), чтобы получить его. Вот небольшой пример из одной из реализаций MPI_Bcast() в Open MPI (точнее, из реализации разделенного двоичного дерева в модуле tuned из фреймворка coll, который предоставляет алгоритмы, реализующие коллективные операции):

int
ompi_coll_tuned_bcast_intra_split_bintree ( void* buffer,
                                            int count, 
                                            struct ompi_datatype_t* datatype, 
                                            int root,
                                            struct ompi_communicator_t* comm,
                                            mca_coll_base_module_t *module,
                                            uint32_t segsize )
{
    ...
    int rank, size;
    ...

    size = ompi_comm_size(comm);
    rank = ompi_comm_rank(comm);

    ...
}

Как видите, он вызывает внутреннюю реализацию MPI_Comm_size() и MPI_Comm_rank(). Это очень дешевые вызовы в Open MPI. Ранг процесса сохраняется в группе процессов, связанной с коммуникатором, и копируется в поле в структуре коммуникатора (чтобы сэкономить несколько циклов ЦП при разыменовании указателя на группу) во время создание коммуникатора (подробнее см. openmpi-source/ompi/communicator/communicator.h и openmpi-source/ompi/group/group.h).

На самом деле ни один коммуникационный примитив MPI никогда явно не получает ранг вызывающего процесса - он всегда разрешается внутренне. Вы указываете только, куда отправлять данные (например, в MPI_SEND) или откуда получать данные (например, в MPI_RECV), или корень данных в тех коллективных операциях, у которых он есть.

person Hristo Iliev    schedule 29.07.2012

Рассмотрим три возможных реализации MPI_Bcast():

  1. root отправляет на root+1, затем на root+2, затем на root+3 и т. д. Это линейный порядок величины.
  2. Начиная с корня, каждый процесс, имеющий копию данных на итерации N, пересылает данные на rank xor 2^N. Это логарифмический порядок величины.
  3. root использует маршрутизатор для выполнения многоадресной рассылки каждому процессу в сети. Это постоянный порядок величины.

В каждом из этих сценариев функция MPI_Bcast() знает, какой процесс получит следующее сообщение. В первом и третьем случаях любой процесс не root просто получит данные; во втором каждый процесс продолжит процесс пересылки после получения данных. Однако во всех реализациях порядок отправки и получения определяется исходя из того, какой процесс является корневым. (Вот почему все процессы должны вызывать MPI_Bcast() независимо от того, являются ли они root или нет.)

person chrisaycock    schedule 29.07.2012
comment
Хорошее объяснение, но оно не затрагивает вопрос ОП. - person Hristo Iliev; 29.07.2012

Вы правы, ранг хранится в коммуникаторе и доступен для реализации MPI_Bcast внутри. Ранги присваиваются при создании коммуникатора. Например, MPI_COMM_WORLD создан MPI_Init.

MPI_Comm_rank просто получает значение ранга от коммуникатора. Нет необходимости вызывать его перед трансляцией. Однако знание ранга обычно необходимо для любого осмысленного программирования.

Обратите внимание, что поскольку MPI_Bcast является коллективным вызовом, его должны выполнять все процессы в коммуникаторе.

person Greg Inozemtsev    schedule 29.07.2012
comment
Уточню: rank — это идентификатор (индекс) процесса в группе процессов, связанной с конкретным коммуникатором. - person Hristo Iliev; 29.07.2012
comment
@HristoIliev Хорошо, я педантичен :) Другой ответ может ввести в заблуждение: вопрос явно спрашивает, требуется ли вызов MPI_Comm_rank перед MPI_Bcast, и ответ звучит так, как будто это так. - person Greg Inozemtsev; 29.07.2012
comment
Быть педантичным — это хорошо, особенно когда речь идет о стандартах :) - person Hristo Iliev; 29.07.2012

int root , это ранг широковещательного корня, по сути, широковещательная рассылка MPI отправляет сообщение из корня ранга всем остальным рангам

также я считаю "лучшей практикой" вызывать следующее после MPI_Init

  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

это назначит каждому процессору или ядру значение ранга int от 0 до n-1.

и

MPI_Comm_size( MPI_COMM_WORLD, &Numprocs);

это создаст int с Numproces, являющимся общим количеством процессоров

person pyCthon    schedule 29.07.2012
comment
Просто для уточнения: MPI_Comm_rank и MPI_Comm_size не назначают ранги или размеры. Это просто средства доступа для получения значений ранга и размера от коммуникатора. - person Greg Inozemtsev; 29.07.2012