В чем разница между импортом модуля внутри `if __name__ == ‘__main__» или снаружи с помощью OpenMPI?

#python #openmpi

#питон #openmpi

Вопрос:

У меня есть два исполняемых скрипта Python3, которые выглядят следующим образом.

сценарий 1:

 #/usr/bin/env python import sys from mymodule import launch  if __name__ == '__main__':  sys.exit(launch())  

и

сценарий 2:

 #/usr/bin/env python import sys  if __name__ == '__main__':  from mymodule import launch  sys.exit(launch())  

Мое понимание CPython заключается в том, что эти два сценария должны работать одинаково.

Однако, если я попытаюсь запустить ./script1 скрипт, используя OpenMPI, вот mpirun так:

 $ mpirun -np 2 ./script1  

он выходит из строя (в Debian linux) со следующими ошибками:

 -------------------------------------------------------------------------- It looks like orte_init failed for some reason; your parallel process is likely to abort. There are many reasons that a parallel process can fail during orte_init; some of which are due to configuration or environment problems. This failure appears to be an internal failure; here's some additional information (which may only be relevant to an Open MPI developer):   getting local rank failed  --gt; Returned value No permission (-17) instead of ORTE_SUCCESS -------------------------------------------------------------------------- -------------------------------------------------------------------------- It looks like orte_init failed for some reason; your parallel process is likely to abort. There are many reasons that a parallel process can fail during orte_init; some of which are due to configuration or environment problems. This failure appears to be an internal failure; here's some additional information (which may only be relevant to an Open MPI developer):   orte_ess_init failed  --gt; Returned value No permission (-17) instead of ORTE_SUCCESS -------------------------------------------------------------------------- -------------------------------------------------------------------------- It looks like MPI_INIT failed for some reason; your parallel process is likely to abort. There are many reasons that a parallel process can fail during MPI_INIT; some of which are due to configuration or environment problems. This failure appears to be an internal failure; here's some additional information (which may only be relevant to an Open MPI developer):   ompi_mpi_init: ompi_rte_init failed  --gt; Returned "No permission" (-17) instead of "Success" (0) -------------------------------------------------------------------------- *** An error occurred in MPI_Init_thread *** on a NULL communicator *** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort, *** and potentially your MPI job) [3018108860e1:05983] Local abort before MPI_INIT completed completed successfully, but am not able to aggregate error messages, and not able to guarantee that all other processes were killed!  

Но если я побегу:

 $ mpirun -np 2 ./script2  

он работает без ошибок.

Я хотел бы привести вам автономный, краткий пример mymodule модуля и go функции, которая воспроизводит эту ошибку. Я пытался сократить свой большой производственный код до чего-то небольшого, что воспроизводит проблему, но каждый раз, когда я пытаюсь сократить производственный код до чего-то небольшого, ошибка не воспроизводима. Итак, сказав это, я не прошу вас всех сказать мне, где мой жучок.

Вместо этого мне интересно, есть ли у кого-нибудь из вас какие-либо идеи относительно того, почему два сценария запуска могут вести себя по-разному?

Ответ №1:

Импорт модуля под if __name__ == "__main__" защитой указывает на то, что он не используется никаким другим кодом в модуле. То есть, если вы импортируете модуль как библиотеку в какой-либо другой скрипт, он будет работать так, как задумано, без этого импорта.

Импорт некоторых модулей может занять много времени, поэтому рекомендуется избегать их импорта без необходимости.

Комментарии:

1. Спасибо @kindal за ваш ответ. Я думаю, что понимаю, на что вы указываете, но мое понимание этого конкретного случая использования заключается в том, что оба сценария (импорт модуля под if __name__ == '__main__' защитой или нет) должны давать одинаковые результаты при выполнении из командной строки. Поэтому я до сих пор не понимаю, почему они вообще могут давать разные результаты.

2. Код под защитой использует импортированную библиотеку. Например, он может использоваться argparse для анализа аргументов командной строки, подготовительных к вызову других функций. Если он импортирован в какой-то другой скрипт, он этого не делает и поэтому в этом нет необходимости argparse .

3. ДА. Спасибо, @kindal, но это все равно не объясняет, почему два приведенных выше примера ведут себя по-разному при выполнении из командной строки. В обоих случаях содержимое if __name__ == '__main__' блока будет выполнено . Следовательно, выполняемые строки в обоих сценариях одинаковы. Единственная разница в том, что оператор импорта выполняется внутри или за пределами области действия if -блока, но я не понимаю, почему это может изменить поведение.