Коллективных операций 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 2

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-коммуникации инициируются другими процессами.

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

Стандарт говорит, что ваша программа не верна. На практике это, скорее всего, приведет к тупику / зависанию.