(cómo) escribir simulaciones que se ejecutan más rápido?


16

Comencé a usar python como lenguaje de programación para hacer todas mis tareas en CFD. Tengo muy poca experiencia en programación. Soy de formación en ingeniería mecánica y estoy cursando estudios superiores en ingeniería aeroespacial.

a veces el aspecto informático de CFD se vuelve más tedioso que manipular las ecuaciones o hacer los cálculos.

¿Cuáles son las pautas generales que hacen que nuestro programa sea más rápido? ¿Cuáles son los trucos para hacer las cosas en paralelo? ¿Cómo escribir los códigos que corren más rápido?

¿Dónde obtengo recursos (fáciles de entender para un laico como yo) que responden las preguntas anteriores?



@ Dan, no lo creo. Estoy pidiendo 'cualquier' recurso posible que ayude a comprender las tácticas de programación para recién llegados. No tengo requisitos o condiciones específicas impuestas. Más específicamente, solicito los recursos que ayudarán a que los códigos sean más elegantes.
Subodh

¿Está arreglado en Python o consideraría C ++? En este caso, sugeriría dos cosas: aprender C ++, encontrar una biblioteca de código abierto (en mi caso OpenFOAM), no desarrollar cosas desde cero, pero aprender, profundizar en un código avanzado, aprender sobre su aspecto, cambiar y experimento, todo conducido con un propósito específico: en su caso, por ejemplo, simulaciones aerodinámicas.
tmaric

@ tomislav-maric, muchas gracias. No soy un estricto 'pitón'. De hecho, al ser un recién llegado al campo, creo que tengo muchas opciones disponibles frente a mí. También estoy aprendiendo OpenFOAM. Por lo tanto, estoy de acuerdo con sus puntos de vista de que uno debe comenzar a trabajar en un proyecto y aprender a través de eso (o, en resumen, ensuciarse las manos), ¡eso es precisamente lo que debería hacer! Gracias.
Subodh

@smj por cierto, también vengo de una base de ingeniería mecánica y ahora soy un estudiante graduado en ciencias computacionales (la ingeniería mecánica NO me preparó para esto) ... Si está trabajando con OF, busque el libro C ++ lista en el desbordamiento de pila y comience a aprender. Necesita 3 cosas: C ++, OpenFOAM y conocimiento de la ciencia computacional. OpenFOAM y la ciencia computacional, puedes aprender de una manera dendrítica: encuentra una tarea y hazla, aprendiendo lo que necesitas. Tener algo terminado te motivará. En cuanto a C ++: comience con el C ++ Primer y aprenda. ¡Buena suerte! :)
tmaric

Respuestas:


19

Intentaré responder a su pregunta teniendo en cuenta que está solicitando Python específicamente. Describiré mi propio método para abordar un problema de simulación. En esta descripción se dan estrategias para simulaciones más rápidas.

Primero, prototipo de nuevas simulaciones en Python. Por supuesto, trato de usar NumPy y SciPy tanto como puedo. Mientras que NumPy proporciona un tipo de datos de matriz adecuado para simulaciones numéricas, SciPy ofrece una amplia gama de rutinas numéricas que funcionan con matrices NumPy.

Una vez que los prototipos funcionan más o menos, trato de aprender qué partes del programa o script son el cuello de botella. Hay candidatos típicos para eso:

  • Los bucles en Python son lentos. Muy lento.
  • Como Python usa la escritura de pato , las funciones de llamada pueden ser lentas.

Utilizo una estrategia de perfil simple para aprender dónde se pasa todo el tiempo de ejecución. Utilizando el shell de IPython (que no puedo recomendar lo suficiente), ejecuto mi script con

%timeit script.py

Este "comando mágico" hará el perfil (usando timeit ) por usted y le presentará una lista con los tiempos una vez que su script haya finalizado. Use esta lista para averiguar dónde su código es demasiado lento.

Una vez que haya precisado las partes que deben acelerarse, puede considerar usar lenguajes compilados. Señalaré dos soluciones.

Primero, está el lenguaje Cython . Cython es un lenguaje de programación muy similar a Python (de hecho, el código de Python a menudo también es un código válido de Python); sin embargo, el compilador de Cython convierte los archivos de Cython a código C, que luego puede compilarse en un módulo que se puede usar desde Python. Cython entiende las matrices NumPy. Hay dos formas en que el uso de Cython puede ayudarlo: primero, puede introducir tipos de datos. Esto acelerará las llamadas a funciones. Además, si itera sobre matrices, su ciclo se ejecutará más rápido (de hecho, si escribe tanto la variable ficticia como la matriz, ¡obtendrá un ciclo C simple!). En segundo lugar, en mis experimentos, incluso los scripts sin tipo se ejecutan un poco más rápido debido al hecho de que están compilados en lugar de interpretados.

El otro lenguaje compilado que será útil para usted es Fortran. Hay diferentes formas de usar Fortran con Python ( f2py , fortwrap , Cython ). En lo que a mí respecta, f2py parece ser la forma más fácil, describiré rápidamente lo que hace. f2py puede compilar código Fortran para módulos Python. Le permitirá usar matrices NumPy como variables de entrada y salida desde el espacio Python. En el espacio Fortran, estos serán arreglos Fortran ordinarios. Puede operar en aquellos a toda velocidad de Fortran.

Personalmente, tiendo a usar Cython donde el número de llamadas a funciones es el cuello de botella. Para cosas pesadas en bucle, prefiero f2py (tal vez porque tengo un fuerte fondo Fortran).

En una nota adicional sobre Fortran: Fortran moderno lee y escribe muy similar a NumPy: la sintaxis está muy cerca. Esto facilita la conversión del código NumPy al código Fortran.

Tenga en cuenta que tanto Cython como f2py admiten paralelismo de alguna manera. Para Cython, encontrará ayuda aquí , mientras que para Fortran, existen técnicas estándar como OpenMP o MPI. Además, también hay envoltorios P ython para MPI . Personalmente, uso mpi4py en el nivel de Python, así como OpenMP en Fortran.

Permítanme recomendar un poco de literatura: el libro Python Scripting For Computational Science de H.-P. Langtangen es un gran recurso en Python en general, así como en estrategias para hacer que Python sea un poco más rápido. Desafortunadamente, AFAIR, no menciona nada en Cython. Como segundo recurso, puede mirar estas diapositivas . Estos dan ejemplos de todo lo que mencioné en esta publicación (vea también el código y las fuentes aquí ). Hay muchas otras buenas diapositivas en Internet.

Si tiene preguntas más específicas, ¡todos estamos felices de ayudarlo!


1
Vea también conferencias magistrales sobre la optimización del código para una descripción general de los perfiladores de Python.
denis

7

Para CFD + Python hay una solución: http://pythonflu.wikidot.com/ Estos son enlaces de Python además de OpenFOAM (que ya se mencionó en los comentarios a las preguntas). Estos enlaces permiten programar en "nivel de solucionador" (hay ejemplos en los que los solucionadores de OpenFOAM originales se replican en Python y no son más lentos que los originales; los bucles lentos mencionados en otra respuesta no son un problema aquí, ya que los "bucles internos" suceden) en el código C ++ de OpenFOAM).

La ventaja de estos enlaces también es que toda la paralelización en OpenFOAM ocurre por debajo del nivel de solucionador, por lo que no tiene que molestarse con él (así como con las otras cosas de las que se ocupa el núcleo de OpenFOAM: entrada / salida, solucionador lineal, discretización del operador)

Entonces, si solo desea escribir un nuevo solucionador y no agregar nuevas características al núcleo OF (condiciones límite, solucionador lineal, etc.), PythonFlu podría ser suficiente para usted y puede evitar C ++ (que tiene una cura de aprendizaje mucho más alta que Pitón)

PD: originalmente quería agregar esto como un comentario a la discusión de la pregunta original, pero mi reputación no me permite esto


Hola bernhard Bienvenido a scicomp! :)
tmaric
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.