Коллективных операций MPI и пожизненный процесс (с/C++)
Для проблемы, которую я хотел бы обсудить, давайте возьмем MPI_Barrier
в качестве примера. Стандарт MPI3 гласит
Поэтому мне было интересно-то же самое, по существу, относится ко всем коллективным операциям в целом - как это утверждение должно интерпретироваться в тех случаях, когда некоторые процессы контекст связи только что вышел (успешно) перед выполнением, Если комми-это intracommunicator, MPI_BARRIER блокирует абонент пока все члены группы вызвали его. Вызов возвращается только при любом процессе после того, как все члены группы вошли в вызов.
MPI_Barrier
: например, предположим, что у нас есть два процесса A и B и используем MPI_COMM_WORLD
в качестве коммуникатора и аргумента comm
к MPI_Barrier
. После вызова A и B MPI_Init
, Если B немедленно вызывает MPI_Finalize
и выходит, и если только a вызывает MPI_Barrier
перед вызовом MPI_Finalize
, блокируется ли A на вечность? Или набор "всех членов группы" определяется как набор всех первоначальных членов группы, которые еще не вышли? Я почти уверен, что A заблокирован навсегда, но может быть, стандарт MPI имеет больше сказать об этом?
Замечание: это не вопрос о синхронизирующих свойствах MPI_Barrier
, Ссылка на MPI_Barrier
просто предназначена для конкретного примера. Речь идет о корректности программы MPI, если выполняются коллективные операции. Смотрите комментарии.1 ответ:
Если B выходит прямо при запуске программы и только A вызывает MPI_Barrier, блокируется ли A навсегда?
В основном да. Но на самом деле, вам не позволено этого делать.
Проще говоря, вы должны вызватьMPI_Finalize
на всех процессах перед выходом. ИMPI_Finalize
действует как коллектив (наMPI_COMM_WORLD
), поэтому он обычно не завершается перед каждым вызовом процессаMPI_Finalize
. Итак, в вашем примере процесс B не вышел (по крайней мере, не правильно).Но я думаю, что стандарт MPI 3.1 в 8.7 объясняет это более ясно:
Обратите внимание, что последнее предложение также требует, чтобы вы завершили барьер в вашем вопросе.
MPI_Finalize
[...] Эта процедура очищает все состояние MPI. Если MPI программа завершается нормально (т. е. не из-за вызоваMPI_ABORT
или неустранимая ошибка), то каждый процесс должен вызватьMPI_FINALIZE
прежде чем он уйдет. Прежде чем процесс MPI вызоветMPI_FINALIZE
, процесс должен выполнить все вызовы MPI, необходимые для завершения его участия в MPI communications: он должен локально завершить все операции MPI что он инициировал и должен выполнить соответствующие вызовы, необходимые для полный MPI-коммуникации инициируются другими процессами.Стандарт говорит, что ваша программа не верна. На практике это, скорее всего, приведет к тупику / зависанию.