daha hızlı çalışan simülasyonlar nasıl yazılır?


16

CFD'de tüm ödevlerimi yapmak için programlama dili olarak python kullanmaya başladım. Programlama konusunda çok az deneyimim var. Makine mühendisliği geçmişindeyim ve Havacılık ve Uzay mühendisliğinde yüksek öğrenim görüyorum.

bazen CFD'nin hesaplama yönü denklemleri manipüle etmekten veya matematiği yapmaktan daha sıkıcı olur.

Programımızı daha hızlı çalıştırmayı sağlayan genel yönergeler nelerdir? Şeyleri paralel olarak yapmanın püf noktaları nelerdir? Daha hızlı çalışan kodlar nasıl yazılır?

Yukarıdaki soruları cevaplayan kaynakları nereden alabilirim (benim gibi bir memur için anlaşılması kolay)?



@ Dan, sanmıyorum. Yeni gelen bir programlama taktiklerini anlamaya yardımcı olacak olası herhangi bir kaynağı istiyorum. Herhangi bir özel gereksinimim veya koşulum yok. Daha spesifik olarak, kodları daha zarif hale getirmeye yardımcı olacak kaynakları istiyorum.
Subodh

Python üzerinde sabit misiniz yoksa C ++ düşünür müsünüz? Bu durumda iki şey öneriyorum: C ++ öğrenmek, açık kaynak kitaplık bulmak (benim durumumda OpenFOAM), sıfırdan bir şeyler geliştirmeyin, ancak öğrenin, gelişmiş bir kod parçasıyla kazın, görünüşünü öğrenin, değiştirin ve deney, hepsi belirli bir amaç doğrultusunda yürütülür: sizin durumunuzda, örneğin aerodinamik simülasyonlar.
tmaric

@ tomislav-maric, çok teşekkür ederim. Ben katı bir 'pitoniyen' değilim. Aslında, sahaya yeni gelen biri olarak, önümde birçok seçeneğim olduğunu düşünüyorum. Ben de OpenFOAM öğreniyorum. Bu yüzden bir proje üzerinde çalışmaya başlamak ve (ya da kısacası eller kirli olsun) öğrenmek gerektiğini görüşlerine katılıyorum, tam olarak ne yapmalıyım!
Subodh

@smj btw, ben de bir makine mühendisliği ortamından geliyorum ve şu anda bilgisayar bilimi alanında yüksek lisans öğrencisiyim (makine mühendisliği beni bunun için hazırlamadı) ... OF ile çalışıyorsanız, C ++ kitabını arayın yığın taşmasını listeler ve öğrenmeye başlar. 3 şeye ihtiyacınız var: C ++, OpenFOAM ve bilgisayar bilimi bilgisi. OpenFOAM ve hesaplamalı bilim, dendritik bir şekilde öğrenebilirsiniz: bir ödevi bulun ve halledin, ihtiyacınız olanı öğrenin. Bir şeylerin bitmesi sizi motive edecektir. C ++ gelince: C ++ Primer ile başlayın ve öğrenin. İyi şanslar! :)
tmaric

Yanıtlar:


19

Özellikle Python'u istediğini düşünerek sorunuzu cevaplamaya çalışacağım. Ben bir simülasyon problemiyle başa çıkma yöntemimi tarif edeceğim. Daha hızlı simülasyonlar için stratejiler bu açıklamada verilmiştir.

İlk olarak, Python'da yeni simülasyonları prototiplendiriyorum. Tabii ki, ben yararlanmak için denemek numpy ve SciPy ben mümkün olduğunca çok. NumPy, sayısal simülasyonlar için uygun bir dizi veri türü sunarken SciPy, NumPy dizileriyle çalışan geniş bir sayısal rutin sunar.

Prototipler az çok çalıştığında, programın veya komut dosyasının hangi bölümlerinin darboğaz olduğunu öğrenmeye çalışırım. Bunun için tipik adaylar var:

  • Python'daki döngüler yavaş. Çok yavaş.
  • Python ördek yazmayı kullandığından , arama işlevleri yavaş olabilir.

Tüm çalışma süresinin nerede harcandığını öğrenmek için basit bir profil oluşturma stratejisi kullanıyorum. IPython kabuğunu kullanarak (yeterince öneremiyorum) , betiğimi

%timeit script.py

Bu "sihirli komut" sizin için profil oluşturmayı ( timeit kullanarak ) yapar ve betiğiniz sona erdikten sonra size bir liste sunar. Kodunuzun çok yavaş olduğunu bulmak için bu listeyi kullanın.

Hızlanması gereken parçaları çiviledikten sonra, derlenmiş dilleri kullanmayı düşünebilirsiniz. İki çözüme işaret edeceğim.

İlk olarak Cython dili var. Cython, Python'a çok benzer bir programlama dilidir (aslında, Python kodu genellikle geçerli Python kodudur); ancak, Cython derleyicisi Cython dosyalarını C koduna dönüştürür ve bu kod daha sonra Python'dan kullanılabilen bir modüle dönüştürülebilir. Cython NumPy dizilerini anlar. Cython'u kullanmanın size yardımcı olabileceği iki yol vardır: ilk olarak, veri türlerini tanıtabilirsiniz. Bu işlev çağrılarını hızlandıracaktır. Ayrıca, diziler üzerinde yineleme yaparsanız, döngünüz daha hızlı çalışır (aslında, hem kukla değişkeni hem de diziyi yazarsanız, düz bir C döngüsü alırsınız!). İkincisi, deneylerimde, yorumlanmamış komut dosyaları bile yorumlanmak yerine derlendikleri için biraz daha hızlı çalışır.

Sizin için yararlı olacak diğer derlenmiş dil Fortran'dır. Fortran'ı Python ile kullanmanın farklı yolları vardır ( f2py , fortwrap , Cython ). Bana göre f2py en kolay yol gibi görünüyor, ne yaptığını çabucak anlatacağım. f2py Fortran kodunu Python modüllerine derleyebilir. NumPy dizilerini Python uzayından giriş ve çıkış değişkenleri olarak kullanmanızı sağlar. Fortran uzayında bunlar sıradan Fortran dizileri olacak. Bunları tam Fortran hızında çalıştırabilirsiniz.

Şahsen, Cython'u işlev çağrısı sayısının darboğaz olduğu yerlerde kullanma eğilimindeyim. Döngü-ağır şeyler için, f2py'yi tercih ederim (belki de güçlü bir Fortran geçmişim olduğu için).

Fortran hakkında ek not: modern Fortran, NumPy'ye çok benziyor ve yazıyor - sözdizimi çok yakın. Bu, NumPy kodunu Fortran koduna dönüştürmeyi kolaylaştırır.

Hem Cython hem de f2py'nin bir şekilde paralleizmi desteklediğini unutmayın. Cython için burada yardım bulacaksınız , Fortran için ise OpenMP veya MPI gibi standart teknikler var . Ayrıca, MPI için de P ython sarmalayıcıları vardır . Şahsen ben Fortran'da PMPhon düzeyinde mpi4py ve OpenMP kullanıyorum.

Biraz edebiyat tavsiye edeyim: H.-P.'nin Hesaplamalı Bilim İçin Python Scripting kitabı. Langtangen genel olarak Python ve Python'u biraz daha hızlı hale getirme stratejileri için harika bir kaynaktır. Ne yazık ki, AFAIR, Cython'da hiçbir şeyden bahsetmiyor. İkinci kaynak olarak bu slaytlara bakabilirsiniz . Bu yazı belirtilen her şey için bu vermek örnekleri (aynı zamanda kod ve kaynaklarını görmek burada ). İnternette slaytlar çok iyi bir dizi vardır.

Daha spesifik sorularınız varsa, yardımcı olmaktan memnuniyet duyarız!


1
Ayrıca , Python profilerlerine genel bakış için kod optimizasyonu ile ilgili scipy-derslerine bakın .
denis

7

CFD + Python için bir çözüm var: http://pythonflu.wikidot.com/ Bunlar OpenFOAM'ın üstündeki Python bağlamalarıdır (soruların yorumlarında zaten belirtilmiştir). Bu bağlamalar "çözücü düzeyinde" programlamaya izin verir (orijinal OpenFOAM çözücülerinin Python'da çoğaltıldığı ve orijinallerden daha yavaş olmadığı örnekler vardır - başka bir yanıtta belirtilen yavaş döngüler burada "iç döngüler" olduğu için sorun değildir C ++ - OpenFOAM kodunda).

Bu bağların avantajı ayrıca OpenFOAM'daki tüm paralelliklerin çözücü seviyesinin altında gerçekleşmesidir, bu yüzden onunla uğraşmanıza gerek yoktur (OpenFOAM çekirdeğinin ilgilendiği diğer şeylerin yanı sıra: giriş / çıkış, doğrusal çözücü, operatör ayrıklığı)

Yani sadece yeni bir çözücü yazmak ve OF çekirdeğine yeni özellikler eklemek istemiyorsanız (sınır koşulları, doğrusal çözücü, vb.) PythonFlu sizin için yeterli olabilir ve C ++ 'dan (daha yüksek bir öğrenme kürüne sahiptir) Python)

Not: Aslında bunu orijinal sorunun tartışılmasına bir yorum olarak eklemek istedim, ancak itibarım buna izin vermiyor


Merhaba Bernhard! Scicomp'a Hoşgeldiniz! :)
tmaric
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.