Возможно, вы не думали, что это возможно, но функции внутри библиотеки 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
man
-удобная версия текста, найденного в Документ стандартов MPI-2.2 (и это нормально - не нужно изобретать велосипед и дублировать усилия, стоящие за отличной формулировкой в стандарте). - person Hristo Iliev   schedule 29.07.2012