Бібліотека DifferentialEquations.jl - це бібліотека для мови високого рівня (Julia), яка має інструменти для автоматичного перетворення системи ODE в оптимізовану версію для паралельного рішення на графічних процесорах. Можна використовувати дві форми паралелізму: паралелізм на основі масиву для великих систем ODE та паралелізм параметрів для досліджень параметрів щодо відносно невеликих (<100) систем ODE. Він підтримує неявні та явні методи високого порядку та звичайно перевершує чи відповідає іншим системам у показниках (принаймні, він обертає інші, тому їх легко перевірити та використовувати!)
Для цієї конкретної функціональності ви можете поглянути на DiffEqGPU.jl, який є модулем автоматизованого паралелізму параметрів. Бібліотека DifferentialEquations.jl має функціональні можливості для паралельних досліджень параметрів , і цей модуль розширює існуючі конфігурації, щоб зробити дослідження відбувається автоматично паралельно. Що можна зробити, це перетворити їхні існуючі ODEProblem
(або інші DEProblem
подібні SDEProblem
) в EnsembleProblem
та вказати, prob_func
як інші проблеми генеруються з прототипу. Далі розв’язується 10000 траєкторій рівняння Лоренца на графічному процесорі чітким адаптивним адаптивним методом:
using OrdinaryDiffEq, DiffEqGPU
function lorenz(du,u,p,t)
@inbounds begin
du[1] = p[1]*(u[2]-u[1])
du[2] = u[1]*(p[2]-u[3]) - u[2]
du[3] = u[1]*u[2] - p[3]*u[3]
end
nothing
end
u0 = Float32[1.0;0.0;0.0]
tspan = (0.0f0,100.0f0)
p = (10.0f0,28.0f0,8/3f0)
prob = ODEProblem(lorenz,u0,tspan,p)
prob_func = (prob,i,repeat) -> remake(prob,p=rand(Float32,3).*p)
monteprob = EnsembleProblem(prob, prob_func = prob_func)
@time sol = solve(monteprob,Tsit5(),EnsembleGPUArray(),trajectories=10_000,saveat=1.0f0)
Зауважте, що користувачеві не потрібно писати код GPU, і за допомогою одного RTX 2080 цей показник є 5-кратним покращенням порівняно з використанням 16-ядерної машини Xeon з багатопотоковою паралельністю. Потім можна ознайомитись з README щодо того, як робити такі речі, як використовувати декілька графічних процесорів та робити багатопроцесорні + графічні процесори для одночасного використання повного кластера графічних процесорів . Зауважте, що перехід на багатопотокове замість GPU - це одна зміна рядка: EnsembleThreads()
замість EnsembleGPUArray()
.
Тоді для неявних розв'язків зберігається той самий інтерфейс. Наприклад, нижче використовуються методи Rosenbrock високого порядку та неявні методи Runge-Kutta:
function lorenz_jac(J,u,p,t)
@inbounds begin
σ = p[1]
ρ = p[2]
β = p[3]
x = u[1]
y = u[2]
z = u[3]
J[1,1] = -σ
J[2,1] = ρ - z
J[3,1] = y
J[1,2] = σ
J[2,2] = -1
J[3,2] = x
J[1,3] = 0
J[2,3] = -x
J[3,3] = -β
end
nothing
end
function lorenz_tgrad(J,u,p,t)
nothing
end
func = ODEFunction(lorenz,jac=lorenz_jac,tgrad=lorenz_tgrad)
prob_jac = ODEProblem(func,u0,tspan,p)
monteprob_jac = EnsembleProblem(prob_jac, prob_func = prob_func)
@time solve(monteprob_jac,Rodas5(linsolve=LinSolveGPUSplitFactorize()),EnsembleGPUArray(),dt=0.1,trajectories=10_000,saveat=1.0f0)
@time solve(monteprob_jac,TRBDF2(linsolve=LinSolveGPUSplitFactorize()),EnsembleGPUArray(),dt=0.1,trajectories=10_000,saveat=1.0f0)
Хоча ця форма вимагає надати якобіан, щоб використовувати його в GPU (зараз він буде виправлений), в документації DifferentialEquations.jl продемонстровано, як робити автоматичні символічні обчислення якобіана для числово визначених функцій , так що досі немає посібника праці тут. Я настійно рекомендую ці алгоритми, оскільки логіка розгалуження такого методу, як CVODE, як правило, викликає десинхронізацію потоку і, здається, не працює так добре, як метод Розенброк у таких випадках.
Використовуючи DifferentialEquations.jl, ви також отримуєте доступ до повної бібліотеки, яка включає такі функції, як аналіз глобальної чутливості, який може використовувати це прискорення GPU. Він також сумісний з подвійними числами для швидкого аналізу локальної чутливості . Код на основі графічного процесора отримує всі функції DifferentialEquations.jl, як обробка подій та великий набір вирішувачів ODE, оптимізованих під різні типи проблем , тобто це не просто простий одноразовий вирішувач ODE GPU, а замість цього частина повнофункціональної системи, яка також має ефективну підтримку GPU.