(как) написать симуляции, которые работают быстрее?

16

Я начал использовать python в качестве языка программирования для выполнения всех моих заданий в CFD. У меня очень мало опыта в программировании. Я из области машиностроения и продолжаю получать высшее образование в области аэрокосмической техники.

иногда вычислительный аспект CFD становится более утомительным, чем манипулирование уравнениями или математика.

Каковы общие рекомендации, которые заставляют нашу программу работать быстрее? Какие уловки нужно делать параллельно? Как написать коды, которые работают быстрее?

Где я могу получить ресурсы (понятные для такого непрофессионала, как я), которые отвечают на поставленные выше вопросы?

Subodh
источник
@ Дэн, я так не думаю. Я прошу «любой» возможный ресурс, который поможет понять тактику программирования новичка. У меня нет особых требований или условий. Более конкретно, я прошу ресурсы, которые помогут сделать коды более элегантными.
Subodh
Вы исправлены на Python или вы рассматриваете C ++? В этом случае я хотел бы предложить две вещи: изучить C ++, найти библиотеку с открытым исходным кодом (в моем случае OpenFOAM), не разрабатывать вещи с нуля, а учиться, копаться в сложном фрагменте кода, узнавать о его аспектах, изменять и экспериментируйте, руководствуясь определенной целью: в вашем случае, например, аэродинамическим моделированием.
tmaric
@ tomislav-maric, большое спасибо. Я не строгий «питон». На самом деле, будучи новичком в этой области, я думаю, что передо мной есть много вариантов. Я тоже учусь OpenFOAM. Поэтому я согласен с вашими взглядами, что нужно начать работать над проектом и научиться этому (или, короче, пачкать руки), что я и должен делать! Спасибо.
Subodh
@ Smm Кстати, я тоже из области машиностроения и теперь я аспирант в области вычислительной техники (механика НЕ ​​подготовила меня к этому) ... Если вы работаете с OF, найдите книгу по C ++ список переполнения стека и начать обучение. Вам нужно 3 вещи: C ++, OpenFOAM и знания вычислительной науки. OpenFOAM и вычислительная наука, вы можете учиться дендритным способом: найти задание и выполнить его, изучая то, что вам нужно. Завершение чего-либо будет мотивировать вас. Что касается C ++: начните с C ++ Primer и изучите его. Удачи! :)
tmaric

Ответы:

19

Я постараюсь ответить на ваш вопрос, учитывая, что вы просите Python специально. Я опишу свой собственный метод решения проблемы моделирования. Стратегии для более быстрого моделирования приведены в этом описании.

Сначала я создаю новые модели в Python. Конечно, я стараюсь максимально использовать NumPy и SciPy . В то время как NumPy предоставляет подходящий тип данных массива для численного моделирования, SciPy предлагает широкие числовые процедуры для работы с массивами NumPy.

Когда прототипы работают более или менее, я пытаюсь понять, какие части программы или сценария являются узким местом. Для этого есть типичные кандидаты:

  • Циклы в Python медленные. Очень медленно.
  • Поскольку Python использует типизацию утилит , вызов функций может быть медленным.

Я использую простую стратегию профилирования, чтобы узнать, на что тратится все время выполнения. Используя оболочку IPython (которую я не могу рекомендовать достаточно), я запускаю свой скрипт с

%timeit script.py

Эта «волшебная команда» выполнит профилирование (используя timeit ) за вас и предоставит вам список со временем, как только ваш скрипт завершит работу. Используйте этот список, чтобы узнать, где ваш код слишком медленный.

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

Во-первых, это язык Cython . Cython - это язык программирования, очень похожий на Python (фактически, код Python также часто является допустимым кодом Python); однако компилятор Cython преобразует файлы Cython в код C, который затем может быть скомпилирован в модуль, используемый из Python. Cython понимает массивы NumPy. Существует два способа использования Cython: во-первых, вы можете вводить типы данных. Это ускорит вызовы функций. Также, если вы перебираете массивы, ваш цикл будет работать быстрее (фактически, если вы введете как фиктивную переменную, так и массив, вы получите простой цикл C!). Во-вторых, в моих экспериментах даже нетипизированные скрипты работают немного быстрее из-за того, что они компилируются, а не интерпретируются.

Другой скомпилированный язык, который будет вам полезен, это Fortran. Существуют разные способы использования Fortran с Python ( f2py , fortwrap , Cython ). Лично для меня f2py кажется самым простым способом, я быстро опишу, что он делает. f2py может компилировать код Фортрана в модули Python. Это позволит вам использовать массивы NumPy в качестве входных и выходных переменных из пространства Python. В пространстве Фортрана это будут обычные массивы Фортрана. Вы можете работать с ними на полной скорости Фортрана.

Лично я склонен использовать Cython, где количество вызовов функций является узким местом. Для вещей с большим количеством петель я предпочитаю f2py (возможно, потому что у меня сильный фон Fortran).

На дополнительном замечании о Фортране: современный Фортран читает и пишет очень похоже на NumPy - синтаксис очень близок. Это позволяет легко конвертировать код NumPy в код Fortran.

Обратите внимание, что и Cython, и f2py поддерживают параллелизм в некотором роде. Для Cython вы найдете здесь помощь , тогда как для Fortran существуют стандартные методы, такие как OpenMP или MPI. Кроме того, существуют также обертки для Python для MPI . Лично я использую mpi4py на уровне Python, а также OpenMP в Fortran.

Позвольте мне порекомендовать немного литературы: книгу « Сценарии Python для вычислительной науки » Х.-П. Langtangen - отличный ресурс по Python в целом, а также по стратегиям, позволяющим сделать Python немного быстрее. К сожалению, AFAIR, он ничего не упоминает о Cython. В качестве второго ресурса вы можете посмотреть на эти слайды . Они дают примеры для всего, что я упомянул в этом посте (см. Также код и источники здесь ). Есть много других хороших слайдов в Интернете.

Если у вас есть более конкретные вопросы, мы все рады помочь!

AlexE
источник
1
Смотрите также scipy-лекции по оптимизации кода для обзора профилировщиков Python.
Денис
7

Для CFD + Python есть решение: http://pythonflu.wikidot.com/ Это Python-привязки поверх OpenFOAM (которая уже упоминалась в комментариях к вопросам). Эти привязки позволяют программировать на «уровне решателя» (есть примеры, когда исходные решатели OpenFOAM реплицируются в Python, и они не медленнее, чем оригиналы - медленные циклы, упомянутые в другом ответе, здесь не проблема, поскольку происходят «внутренние циклы» в C ++ - код OpenFOAM).

Преимущество этих привязок также состоит в том, что все распараллеливание в OpenFOAM происходит ниже уровня решателя, поэтому вам не нужно беспокоиться об этом (а также о других вещах, которые ядро ​​OpenFOAM заботится: ввод / вывод, линейный решатель, оператор дискретизации)

Так что если вы просто хотите написать новый решатель и не добавлять новые функции в OF-ядро (граничные условия, линейный решатель и т. Д.), То PythonFlu может быть достаточно для вас, и вы можете избежать C ++ (который имеет гораздо более высокий уровень обучения, чем Python)

PS: изначально хотел добавить это как комментарий к обсуждению исходного вопроса, но моя репутация не позволяет мне этого

bgschaid
источник
Привет Бернхард! Добро пожаловать в Scicomp! :)
tmaric