(come) scrivere simulazioni più veloci?


16

Ho iniziato a usare Python come linguaggio di programmazione per svolgere tutti i miei compiti in CFD. Ho poca esperienza nella programmazione. Sono un esperto in ingegneria meccanica e sto perseguendo un'istruzione superiore in ingegneria aerospaziale.

a volte l'aspetto informatico del CFD diventa più noioso che manipolare le equazioni o fare la matematica.

Quali sono le linee guida generali che rendono più veloce l'esecuzione del nostro programma? Quali sono i trucchi per fare le cose in parallelo? Come scrivere i codici che funzionano più velocemente?

Dove ottengo le risorse (facili da capire per un laico come me) che rispondono alle domande precedenti?



@ Dan, io non la penso così. Chiedo "qualsiasi" possibile risorsa che possa aiutare a comprendere le tattiche di programmazione di un nuovo arrivato. Non ho requisiti specifici o condizioni imposte. Più specificamente, sto chiedendo le risorse che aiuteranno a rendere i codici più eleganti.
Subodh

Sei riparato su Python o considereresti C ++? In questo caso, suggerirei due cose: imparare C ++, trovare una libreria open source (nel mio caso OpenFOAM), non sviluppare cose da zero, ma imparare, scavare attraverso un pezzo di codice avanzato, conoscere il suo aspetto, cambiare e esperimento, tutto guidato con uno scopo specifico: nel tuo caso, ad esempio simulazioni aerodinamiche.
Tmaric,

@ tomislav-maric, grazie mille. Non sono un "pitone" rigoroso. In effetti, essendo un nuovo arrivato sul campo, penso di avere molte opzioni disponibili davanti a me. Sto imparando anche OpenFOAM. Quindi sono d'accordo con le tue opinioni sul fatto che si dovrebbe iniziare a lavorare su un progetto e imparare attraverso quello (o in breve sporcarsi le mani), che è esattamente quello che dovrei fare! Grazie.
Subodh

@smj btw, anch'io vengo da un bacino di ingegneria meccanica e ora sono uno studente laureato in scienze computazionali (mech. ingegneria NON mi ha preparato per questo) ... Se stai lavorando con OF, cerca il libro C ++ elencare sullo stack overflow e iniziare l'apprendimento. Hai bisogno di 3 cose: C ++, OpenFOAM e conoscenza della scienza computazionale. OpenFOAM e scienze computazionali, puoi imparare in modo dendritico: trova un compito e fallo, imparando lungo ciò di cui hai bisogno. Avere qualcosa finito ti motiverà. Per quanto riguarda il C ++: inizia con il C ++ Primer e imparalo. In bocca al lupo! :)
tmaric,

Risposte:


19

Cercherò di rispondere alla tua domanda considerando che stai chiedendo specificamente Python. Descriverò il mio metodo per affrontare un problema di simulazione. Strategie per simulazioni più veloci sono riportate in questa descrizione.

Innanzitutto, prototipo di nuove simulazioni in Python. Certo, cerco di usare NumPy e SciPy il più possibile. Mentre NumPy fornisce un tipo di dati array adatto per simulazioni numeriche, SciPy offre una vasta gamma numerica che funziona con gli array NumPy.

Una volta che i prototipi funzionano più o meno, provo ad imparare quali parti del programma o script sono il collo di bottiglia. Ci sono candidati tipici per questo:

  • I loop in Python sono lenti. Molto lento.
  • Poiché Python utilizza la tipizzazione duck , le funzioni di chiamata possono essere lente.

Uso una semplice strategia di profilazione per sapere dove viene impiegato tutto il tempo di esecuzione. Usando la shell IPython (che non posso raccomandare abbastanza), eseguo il mio script

%timeit script.py

Questo "comando magico" farà la profilazione (usando timeit ) per te e ti presenterà un elenco con i tempi una volta terminato lo script. Usa questo elenco per scoprire dove il tuo codice è troppo lento.

Dopo aver inchiodato le parti che devono essere accelerate, è possibile prendere in considerazione l'uso di linguaggi compilati. Indicherò due soluzioni.

Innanzitutto c'è il linguaggio Cython . Cython è un linguaggio di programmazione molto simile a Python (in effetti, il codice Python è spesso anche un codice Python valido); tuttavia, il compilatore Cython converte i file Cython in codice C, che può quindi essere compilato in un modulo utilizzabile da Python. Cython comprende gli array NumPy. Esistono due modi in cui l'utilizzo di Cython può aiutarti: in primo luogo, è possibile introdurre tipi di dati. Ciò accelererà le chiamate di funzione. Inoltre, se si esegue l'iterazione su array, il ciclo verrà eseguito più rapidamente (in effetti, se si digitano sia la variabile fittizia che l'array, si ottiene un ciclo C semplice!). In secondo luogo, nei miei esperimenti anche gli script non tipizzati funzionano un po 'più velocemente a causa del fatto che sono compilati anziché interpretati.

L'altro linguaggio compilato che ti sarà utile è Fortran. Esistono diversi modi per utilizzare Fortran con Python ( f2py , fortwrap , Cython ). Quanto a me personalmente, f2py sembra essere il modo più semplice, descriverò rapidamente cosa fa. f2py può compilare il codice Fortran in moduli Python. Ti permetterà di usare gli array NumPy come variabili di input e output dallo spazio Python. Nello spazio Fortran, questi saranno normali array Fortran. Puoi operare su quelli alla massima velocità di Fortran.

Personalmente, tendo a usare Cython dove il numero di chiamate di funzione è il collo di bottiglia. Per roba pesante, preferisco f2py (forse perché ho un forte background Fortran).

Nota aggiuntiva su Fortran: il moderno Fortran legge e scrive in modo molto simile a NumPy: la sintassi è molto vicina. Ciò semplifica la conversione del codice NumPy in codice Fortran.

Nota che sia Cython che f2py supportano il paralleismo in qualche modo. Per Cython, troverai aiuto qui , mentre per Fortran ci sono tecniche standard come OpenMP o MPI. Inoltre, ci sono anche wrapper P ython per MPI . Personalmente, utilizzo mpi4py a livello Python e OpenMP in Fortran.

Lasciami consigliare un po 'di letteratura: il libro Python Scripting For Computational Science di H.-P. Langtangen è una grande risorsa su Python in generale e sulle strategie per rendere Python un po 'più veloce. Sfortunatamente, AFAIR, non menziona nulla su Cython. Come seconda risorsa puoi guardare queste diapositive . Questi forniscono esempi per tutto ciò che ho menzionato in questo post (vedi anche il codice e le fonti qui ). Ci sono molte altre buone serie di diapositive su Internet.

Se hai domande più specifiche, saremo tutti felici di aiutarti!


1
Vedi anche lezioni di scipy sull'ottimizzazione del codice per una panoramica dei profiler di Python.
denis,

7

Per CFD + Python esiste una soluzione: http://pythonflu.wikidot.com/ Questi sono i collegamenti Python in cima a OpenFOAM (che è già stato menzionato nei commenti alle domande). Questi collegamenti consentono la programmazione a "livello del risolutore" (ci sono esempi in cui i solutori OpenFOAM originali sono replicati in Python e non sono più lenti degli originali - i cicli lenti citati in un'altra risposta non sono un problema qui quando si verificano i "circuiti interni" nel C ++ - codice di OpenFOAM).

Il vantaggio di questi collegamenti è anche che tutta la parallelizzazione in OpenFOAM avviene al di sotto del livello del risolutore, quindi non devi preoccuparti di esso (così come le altre cose che il core OpenFOAM si occupa di: input / output, risolutore lineare, discretizzazione dell'operatore)

Quindi, se vuoi solo scrivere un nuovo risolutore e non aggiungere nuove funzionalità al core OF (condizioni al contorno, risolutore lineare, ecc.), PythonFlu potrebbe essere sufficiente per te e puoi evitare C ++ (che ha una cura di apprendimento molto più alta di Pitone)

PS: originariamente volevo aggiungere questo come commento alla discussione della domanda originale, ma la mia reputazione non me lo consente


Ciao Bernhard! Benvenuto in scicomp! :)
tmaric,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.