(як) писати симуляції, які працюють швидше?


16

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

іноді обчислювальний аспект CFD стає більш втомливим, ніж маніпулювання рівняннями або виконання математики.

Які загальні вказівки дозволяють запустити нашу програму швидше? Які прийоми робити речі паралельно? Як записати коди, які працюють швидше?

Де я можу отримати ресурси (легко зрозуміти для мирян, як я), які відповідають на вищезазначені запитання?



@ Ден, я не думаю, що так. Я прошу "будь-який" можливий ресурс, який допоможе зрозуміти нову тактику програмування. У мене немає жодних конкретних вимог чи умов. Більш конкретно, я прошу ресурси, які допоможуть зробити коди більш витонченими.
Subodh

Ви фіксуєте на python чи вважаєте C ++? У цьому випадку я б запропонував дві речі: вивчити C ++, знайти бібліотеку з відкритим кодом (у моєму випадку OpenFOAM), не розробляти речі з нуля, а вчитися, перекопувати вдосконалений фрагмент коду, дізнаватися про його аспект, змінювати та експеримент, який рухається з певною метою: у вашому випадку, наприклад, аеродинамічні моделювання.
tmaric

@ tomislav-maric, дуже дякую Я не суворий "пітонік". Насправді, будучи новачком у цій галузі, я думаю, що в мене є багато варіантів, що знаходяться перед собою. Я також навчаюсь OpenFOAM. Тож я погоджуюся з вашими думками, що варто почати працювати над проектом і вчитися через це (або, коротше кажучи, забруднити руки), що саме я повинен зробити! Спасибі
Subodh

@smj btw, я також походить з інженерії машинобудування, і тепер я аспірант з обчислювальної науки (мех. інженерія НЕ готувала мене до цього) ... Якщо ви працюєте з 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 може допомогти вам: спочатку ви можете ввести типи даних. Це пришвидшить функціональні дзвінки. Крім того, якщо ви перейдете до масивів, ваш цикл запуститься швидше (адже, якщо ви введете і манекенну змінну, і масив, ви отримаєте звичайний цикл С!). По-друге, в моїх експериментах навіть нетипізовані сценарії працюють трохи швидше через те, що вони складені замість інтерпретованих.

Інша складена мова, яка буде корисною для вас, - Fortran. Існують різні способи використання Fortran з Python ( f2py , fortwrap , Cython ). Щодо мене особисто f2py здається найпростішим способом, я швидко опишу, що він робить. f2py може компілювати код Fortran в модулі Python. Це дозволить використовувати масиви NumPy як вхідні та вихідні змінні з простору Python. У просторі Fortran це будуть звичайні масиви Fortran. Ви можете працювати з ними на повній швидкості Fortran.

Особисто я схильний використовувати Cython, де кількість викликів функцій є вузьким місцем. Що стосується важких циклів, я віддаю перевагу f2py (можливо тому, що у мене сильний фон Fortran).

Додатково про Fortran: сучасний Fortran читає і пише дуже схоже на NumPy - синтаксис дуже близький. Це дозволяє легко перетворити код NumPy в код Fortran.

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

Дозвольте порекомендувати трохи літератури: книгу Python Scripting For Computation Science від H.-P. Langtangen - це чудовий ресурс як для Python, так і для стратегій зробити Python трохи швидшим. На жаль, AFAIR, на Cython нічого не згадується. Як я другий ресурс, ви можете переглянути ці слайди . Вони наводять приклади всього, про що я згадував у цій публікації (див. Також код та джерела тут ). В Інтернеті є багато інших хороших наборів слайдів.

Якщо у вас є більш конкретні запитання, ми всі раді допомогти!


1
Дивіться також наукові лекції з оптимізації коду для огляду профілів Python.
denis

7

Для CFD + Python є рішення: http://pythonflu.wikidot.com/ Це Python-прив'язки поверх OpenFOAM (про що вже говорилося в коментарях до питань). Ці прив'язки дозволяють програмувати на рівні "solver" (є приклади, коли оригінальні вирішувачі OpenFOAM копіюються в Python, і вони не повільніші за оригінали - повільні цикли, згадані в іншій відповіді, тут не є проблемою, оскільки трапляються "внутрішні петлі" в C ++ - код OpenFOAM).

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

Отже, якщо ви просто хочете написати новий вирішувач і не додати нових функцій до ядра OF (граничні умови, лінійний вирішувач тощо), то PythonFlu може бути достатнім для вас, і ви можете уникнути C ++ (який має набагато вищий курс навчання, ніж Python)

PS: Спочатку хотів додати це як коментар до обговорення оригінального питання, але моя репутація мені цього не дозволяє


Привіт, Бернхард! Ласкаво просимо до scicomp! :)
tmaric
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.