(bagaimana) menulis simulasi yang berjalan lebih cepat?

16

Saya sudah mulai menggunakan python sebagai bahasa pemrograman untuk melakukan semua tugas saya di CFD. Saya memiliki sedikit pengalaman dalam pemrograman. Saya dari latar belakang teknik mesin dan sedang mengejar pendidikan tinggi di bidang teknik Aerospace.

terkadang aspek komputasi CFD menjadi lebih membosankan daripada memanipulasi persamaan atau mengerjakan matematika.

Apa pedoman umum yang membuat menjalankan program kami lebih cepat? Apa saja trik untuk melakukan hal-hal secara pararel? Bagaimana cara menulis kode yang berjalan lebih cepat?

Di mana saya mendapatkan sumber daya (mudah dipahami oleh orang awam seperti saya) yang menjawab pertanyaan di atas?

Subodh
sumber
@ Dan, kurasa tidak. Saya meminta 'sumber daya apa pun yang mungkin' yang akan membantu memahami taktik pemrograman pendatang baru. Saya tidak memiliki persyaratan atau ketentuan khusus yang diberlakukan. Lebih khusus saya meminta sumber daya yang akan membantu membuat kode lebih elegan.
Subodh
Apakah Anda memperbaiki python atau apakah Anda akan mempertimbangkan C ++? Dalam hal ini saya akan menyarankan dua hal: belajar C ++, menemukan perpustakaan open source (dalam kasus saya OpenFOAM), jangan mengembangkan hal-hal dari awal, tetapi belajar, menggali melalui sepotong kode canggih, belajar tentang aspeknya, mengubah dan Percobaan, semua didorong dengan tujuan tertentu: dalam kasus Anda, misalnya simulasi aerodinamis.
tmaric
@ Tomislav-maric, terima kasih banyak Saya bukan 'pythonian' yang ketat. Bahkan, sebagai pendatang baru di lapangan, saya pikir saya memiliki banyak pilihan di depan saya. Saya juga belajar OpenFOAM. Jadi saya setuju dengan pandangan Anda bahwa seseorang harus mulai bekerja pada sebuah proyek dan belajar melalui itu (atau singkatnya menjadi kotor tangan), itulah yang harus saya lakukan! Terima kasih.
Subodh
@smj btw, saya berasal dari bacground teknik mesin juga dan saya sekarang seorang mahasiswa pascasarjana dalam ilmu komputasi (mech. engineering TIDAK mempersiapkan saya untuk ini) ... Jika Anda bekerja dengan OF, cari buku C ++ daftar di stack overflow, dan mulai belajar. Anda memerlukan 3 hal: C ++, OpenFOAM dan pengetahuan dari ilmu komputasi. OpenFOAM dan ilmu komputasi, Anda dapat belajar dengan cara dendritik: menemukan tugas dan menyelesaikannya, belajar sepanjang apa yang Anda butuhkan. Memiliki sesuatu yang sudah selesai akan memotivasi Anda. Adapun C ++: mulai dengan C ++ Primer dan pelajari. Semoga berhasil! :)
tmaric

Jawaban:

19

Saya akan mencoba menjawab pertanyaan Anda mengingat Anda meminta Python secara khusus. Saya akan menjelaskan metode saya sendiri dalam mengatasi masalah simulasi. Strategi untuk simulasi yang lebih cepat diberikan dalam uraian ini.

Pertama, saya membuat prototipe simulasi baru dengan Python. Tentu saja, saya mencoba menggunakan NumPy dan SciPy sebanyak yang saya bisa. Sedangkan NumPy menyediakan tipe data array yang cocok untuk simulasi numerik, SciPy menawarkan berbagai rutinitas numerik yang bekerja dengan array NumPy.

Setelah prototipe berfungsi lebih atau kurang, saya mencoba mempelajari bagian mana dari program atau skrip yang menjadi penghambatnya. Ada beberapa kandidat untuk itu:

  • Loop di Python lambat. Sangat lambat.
  • Karena Python menggunakan mengetik bebek , fungsi panggilan bisa lambat.

Saya menggunakan strategi pembuatan profil sederhana untuk mempelajari di mana semua waktu yang digunakan dihabiskan. Menggunakan shell IPython (yang saya tidak bisa merekomendasikan cukup), saya menjalankan skrip saya dengan

%timeit script.py

"Perintah ajaib" ini akan melakukan pembuatan profil (menggunakan timeit ) untuk Anda dan memberi Anda daftar dengan waktu setelah skrip Anda dihentikan. Gunakan daftar ini untuk mencari tahu di mana kode Anda terlalu lambat.

Setelah Anda menemukan bagian-bagian yang perlu dipercepat, Anda dapat mempertimbangkan menggunakan bahasa yang dikompilasi. Saya akan menunjukkan dua solusi.

Pertama, ada bahasa Cython . Cython adalah bahasa pemrograman yang sangat mirip dengan Python (pada kenyataannya, kode Python sering juga merupakan kode Python yang valid); Namun, kompiler Cython mengubah file Cython menjadi kode C, yang kemudian dapat dikompilasi menjadi modul yang dapat digunakan dari Python. Cython memahami array NumPy. Ada dua cara di mana menggunakan Cython dapat membantu Anda: pertama, Anda dapat memperkenalkan tipe data. Ini akan mempercepat panggilan fungsi. Juga, jika Anda mengulangi lebih dari array, loop Anda akan berjalan lebih cepat (pada kenyataannya, jika Anda mengetik variabel dummy dan array, Anda mendapatkan loop C polos!). Kedua, dalam percobaan saya, bahkan skrip yang tidak diketik berjalan sedikit lebih cepat karena fakta bahwa mereka dikompilasi bukannya ditafsirkan.

Bahasa kompilasi lain yang akan berguna bagi Anda adalah Fortran. Ada berbagai cara untuk menggunakan Fortran dengan Python ( f2py , fortwrap , Cython ). Bagi saya pribadi f2py tampaknya menjadi cara termudah, saya akan segera menjelaskan apa fungsinya. f2py dapat mengkompilasi kode Fortran ke modul Python. Ini akan memungkinkan Anda untuk menggunakan array NumPy sebagai variabel input dan output dari ruang Python. Di ruang Fortran, ini akan menjadi array Fortran biasa. Anda dapat beroperasi pada kecepatan penuh Fortran.

Secara pribadi, saya cenderung menggunakan Cython di mana jumlah pemanggilan fungsi adalah bottleneck. Untuk hal-hal yang berat, saya lebih suka f2py (mungkin karena saya memiliki latar belakang Fortran yang kuat).

Pada catatan tambahan tentang Fortran: Fortran modern membaca dan menulis sangat mirip dengan NumPy - sintaksinya sangat dekat. Ini membuatnya mudah untuk mengkonversi kode NumPy ke kode Fortran.

Perhatikan bahwa Cython dan f2py mendukung paralleisme dalam beberapa cara. Untuk Cython, Anda akan menemukan bantuan di sini , sedangkan untuk Fortran, ada teknik standar seperti OpenMP atau MPI. Selain itu, ada pembungkus P ython untuk MPI juga. Secara pribadi, saya menggunakan mpi4py di tingkat Python dan juga OpenMP di Fortran.

Izinkan saya merekomendasikan sedikit literatur: buku Python Scripting For Computational Science oleh H.-P. Langtangen adalah sumber yang bagus untuk Python secara umum dan juga strategi untuk membuat Python sedikit lebih cepat. Sayangnya, AFAIR, tidak menyebutkan apa pun di Cython. Saat saya sumber kedua, Anda dapat melihat slide ini . Ini memberikan contoh untuk semua yang saya sebutkan di posting ini (lihat juga kode dan sumber di sini ). Ada banyak set slide lain yang bagus di internet.

Jika Anda memiliki pertanyaan yang lebih spesifik, kami semua dengan senang hati membantu!

AlexE
sumber
1
Lihat juga ceramah-ceramah tentang mengoptimalkan kode untuk tinjauan umum profiler Python.
denis
7

Untuk CFD + Python ada solusinya: http://pythonflu.wikidot.com/ Ini adalah Python-binding di atas OpenFOAM (yang sudah disebutkan dalam komentar untuk pertanyaan). Binding ini memungkinkan pemrograman pada "level solver" (ada beberapa contoh di mana solver OpenFOAM asli direplikasi dalam Python dan mereka tidak lebih lambat dari aslinya - loop lambat yang disebutkan dalam jawaban lain tidak menjadi masalah di sini karena "loop batin" terjadi dalam C ++ - kode OpenFOAM).

Keuntungan dari binding ini adalah bahwa semua paralelisasi di OpenFOAM terjadi di bawah level solver, jadi Anda tidak perlu repot dengan itu (juga hal-hal lain yang ditangani oleh core OpenFOAM: input / output, pemecah linear, diskritisasi operator)

Jadi jika Anda hanya ingin menulis solver baru dan tidak menambahkan fitur baru ke OF-core (kondisi batas, solver linier, dll) maka PythonFlu mungkin cukup untuk Anda dan Anda dapat menghindari C ++ (yang memiliki penyembuhan belajar yang jauh lebih tinggi daripada Python)

PS: awalnya ingin menambahkan ini sebagai komentar pada diskusi tentang pertanyaan awal, tetapi reputasi saya tidak mengizinkan saya untuk ini

bgschaid
sumber
Hai Bernhard! Selamat datang di scicomp! :)
tmaric