Варіанти вирішення систем ODE на графічних процесорах?


16

Я хотів би розробити системи ODE на графічні процесори в умовах "тривіально паралелізуючого". Наприклад, роблячи аналіз чутливості з 512 різними наборами параметрів.

В ідеалі я хочу займатися вирішенням ODE за допомогою розумного адаптивного вирішення часового кроку, такого як CVODE, а не з фіксованим часовим кроком, як Forward Euler, але запускаючи його на NVIDIA GPU замість процесора.

Хтось робив це? Чи існують бібліотеки для цього?


Звідси дужки! Я розглядаю техніку, засновану на розщепленні оператора (симуляції серцевої електрофізіології), де ви вирішуєте ODE в вузлах, щоб отримати вихідний термін для PDE, а потім змінити параметр ODE для наступної ітерації.
mirams


1
Важливо вказати, хочете ви використовувати один і той же крок часу для кожного ODE чи ні.
Крістіан Класон

Крім того, якщо вас конкретно цікавлять рівняння бідомена (або монодомену), ви можете поглянути, як це робить CARP .
Крістіан Класон

Різні часові кроки, якщо метод адаптивний, тоді він знадобиться їм для різних наборів параметрів ... дякую за посилання на те, що робить CARP - фіксований часовий крок Rush Larsen ODE вирішувач, якщо я прочитав його правильно.
mirams

Відповіді:


6

Ви можете заглянути в бібліотеку залишків Boost і тягу . Їх можна комбінувати, як обговорювалося тут .


Це здається дещо іншим - паралельно (з комунікацією) вирішувати масивні системи ODE на графічному процесорі. Це посилання говорить: "Ми переконалися, що розмір вектора, над яким паралельний, повинен бути порядку 10 ^ 6, щоб повною мірою використовувати GPU." Я шукаю приємного способу вирощування O (10) або O (100) векторного розміру, який тривіально паралелізується ODE ...
mirams

Чи думали ви писати безпосередньо у cuda чи openCL? Якщо я подумав правильно, то, що ви робите, це повторення над деяким рівнянням ODE у кожній нитці окремо, це не повинно бути складно записати.
Hydro Guy

Я гадаю, що можна було б кодувати Forward Euler або інший фіксований метод часового кроку, де кожен процес GPU використовує один і той же часовий крок, досить легко, я хотів би знати, чи вдалося кому-небудь отримати адаптивний тайм-аут, як CVODE працює, чи це неможливо зробити ефективність на GPGPU?
mirams

Проблема з gpu полягає в тому, що вам потрібно написати паралельний коду даних. Якщо ви пишете ту саму адаптивну програму, але поглинаючи всю цю гнучкість на значеннях деяких параметрів, можливо, це можливо ефективно кодувати на gpu. Це також означає, що ви не можете використовувати розгалуження за інструкціями. Це, мабуть, те, що, на вашу думку, зробило б це неможливим.
Hydro Guy

1
@mirams є приклад odeint, який охоплює саме те, що ви шукаєте: boost.org/doc/libs/1_59_0/libs/numeric/odeint/doc/html/… , див. також github.com/boostorg/odeint/blob/ майстер / приклади / тяга /… . Також odeint підтримує адаптивні багатоступінчасті методи, як у CVODE: github.com/boostorg/odeint/blob/master/examples/…
Крістіан Классон

13

Бібліотека 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.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.