Коллективных операций 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-коммуникации инициируются другими процессами.Стандарт говорит, что ваша программа не верна. На практике это, скорее всего, приведет к тупику / зависанию.