Me gustaría desarrollar sistemas de resolución de EDO en GPU, en un entorno 'trivialmente paralelo'. Por ejemplo, haciendo un análisis de sensibilidad con 512 conjuntos de parámetros diferentes.
Idealmente, quiero resolver ODE con un solucionador de paso de tiempo inteligente y adaptable como CVODE, en lugar de un paso de tiempo fijo como Forward Euler, pero ejecutándolo en una GPU NVIDIA en lugar de CPU.
¿Alguien ha hecho esto? ¿Hay bibliotecas para ello?
Respuestas:
Es posible que desee mirar en la biblioteca odeint de Boost y Thrust . Se pueden combinar como se discute aquí .
fuente
La biblioteca DifferentialEquations.jl es una biblioteca para un lenguaje de alto nivel (Julia) que tiene herramientas para transformar automáticamente el sistema ODE a una versión optimizada para una solución paralela en GPU. Se pueden emplear dos formas de paralelismo: paralelismo basado en matrices para sistemas ODE grandes y paralelismo de parámetros para estudios de parámetros en sistemas ODE relativamente pequeños (<100). Soporta métodos implícitos y explícitos de alto orden y rutinariamente supera o coincide con otros sistemas en los puntos de referencia (al menos, envuelve a los demás para que sea fácil verificarlos y usarlos)
Para esta funcionalidad específica, es posible que desee echar un vistazo a DiffEqGPU.jl, que es el módulo para el paralelismo automático de parámetros. La biblioteca DifferentialEquations.jl tiene funcionalidad para estudios de parámetros paralelos , y este módulo aumenta las configuraciones existentes para que el estudio se realice automáticamente en paralelo. Lo que uno hace es transformar su existente
ODEProblem
(u otroDEProblem
similarSDEProblem
) en unEnsembleProblem
y especificar con unprob_func
cómo se generan los otros problemas del prototipo. Lo siguiente resuelve 10,000 trayectorias de la ecuación de Lorenz en la GPU con un método adaptativo explícito de alto orden:Observe que el usuario no necesita escribir ningún código de GPU, y con un solo RTX 2080, este punto de referencia es una mejora 5 veces mayor que el uso de una máquina Xeon de 16 núcleos con paralelismo multiproceso. Luego, puede consultar el archivo README para saber cómo hacer cosas como utilizar múltiples GPU y hacer multiprocesamiento + GPU para utilizar un grupo completo de GPU simultáneamente . Tenga en cuenta que cambiar a subprocesos múltiples en lugar de GPU es un cambio de línea: en
EnsembleThreads()
lugar deEnsembleGPUArray()
.Luego, para los solucionadores implícitos, se mantiene la misma interfaz. Por ejemplo, lo siguiente utiliza Rosenbrock de alto orden y métodos implícitos de Runge-Kutta:
Si bien este formulario requiere que le dé un jacobiano para usarlo en la GPU (actualmente, se solucionará pronto), la documentación de DifferentialEquations.jl muestra cómo hacer cálculos automáticos simbólicos jacobianos en funciones definidas numéricamente , por lo que todavía no hay manual trabajo aquí. Recomiendo encarecidamente estos algoritmos porque la lógica de ramificación de un método como CVODE generalmente causa la desincronización de subprocesos y, de todos modos, no parece funcionar tan bien como un método de Rosenbrock en este tipo de escenarios.
Al usar DifferentialEquations.jl, también obtiene acceso a la biblioteca completa, que incluye funcionalidades como el análisis de sensibilidad global que puede hacer uso de esta aceleración de GPU. También es compatible con números duales para un rápido análisis de sensibilidad local . El código basado en GPU obtiene todas las características de DifferentialEquations.jl, como el manejo de eventos y el gran conjunto de solucionadores ODE que están optimizados para diferentes tipos de problemas , lo que significa que no es solo un simple solucionador ODE GPU único sino un parte de un sistema con todas las funciones que también tiene un eficiente soporte de GPU.
fuente