DifferentialEquations.jl kütüphanesi, ODE sistemini otomatik olarak GPU'larda paralel çözüm için optimize edilmiş bir sürüme dönüştürmek için araçlara sahip üst düzey bir dil (Julia) için bir kütüphanedir. Kullanılabilecek iki paralellik biçimi vardır: büyük ODE sistemleri için dizi tabanlı paralellik ve nispeten küçük (<100) ODE sistemlerinde parametre çalışmaları için parametre paralellik. Yüksek dereceli örtük ve açık yöntemleri destekler ve rutin olarak diğer sistemlerde kıyaslamalardan daha iyi performans gösterir veya bunlarla eşleşir (en azından diğerlerini sarar, böylece kontrol etmek ve kullanmak kolaydır!)
Bu özel işlevsellik için, otomatik parametre paralelliğinin modülü olan DiffEqGPU.jl dosyasına göz atmak isteyebilirsiniz . DifferentialEquations.jl kütüphanesi , paralel parametre etütleri için işlevselliğe sahiptir ve bu modül, etüdün otomatik olarak paralel gerçekleşmesini sağlamak için mevcut konfigürasyonları artırır. Bunlardan biri, mevcut ODEProblem
(veya başka bir DEProblem
benzerini SDEProblem
) 'e dönüştürür EnsembleProblem
ve prob_func
diğer problemlerin prototipten nasıl üretildiğini belirtir . Aşağıda GPU üzerindeki 10.000 yörünge yüksek dereceli açık uyarlamalı yöntemle çözülmektedir:
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)
Kullanıcının GPU kodu yazması gerekmediğine dikkat edin ve tek bir RTX 2080 ile bu kıyaslamalar, çok iş parçacıklı paralelli 16 çekirdekli bir Xeon makinesi kullanmaya kıyasla 5 kat iyileştirme olarak değerlendirilir. Daha sonra , birden fazla GPU kullanmak ve aynı anda tam bir GPU kümesi kullanmak için çoklu işlem + GPU yapmak gibi şeylerin nasıl yapılacağı konusunda README'ye göz atabilirsiniz . GPU yerine çoklu iş parçacığına geçmenin bir satır değişiklik olduğunu unutmayın: EnsembleThreads()
yerine EnsembleGPUArray()
.
Sonra örtük çözücüler için aynı arayüz geçerlidir. Örneğin, yüksek dereceli Rosenbrock ve örtük Runge-Kutta yöntemleri kullanılır:
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)
Bu form, GPU'da kullanılmak üzere bir Jacobian vermenizi gerektirse de (şu anda yakında düzeltilecektir), DifferentialEquations.jl belgeleri , sayısal olarak tanımlanmış işlevlerde otomatik sembolik Jacobian hesaplamalarının nasıl yapılacağını göstermektedir , bu yüzden hala manuel yok emek. Bu algoritmaları şiddetle tavsiye ediyorum çünkü CVODE gibi bir yöntemin dallanma mantığı genellikle iplik desync'e neden olur ve yine de bu tür senaryolarda bir Rosenbrock yöntemi gibi performans göstermez.
DifferentialEquations.jl dosyasını kullanarak , bu GPU hızlandırmadan yararlanabilecek global duyarlılık analizi gibi işlevler içeren tam kitaplığa da erişebilirsiniz . Hızlı yerel hassasiyet analizi için çift sayılarla da uyumludur . GPU tabanlı kod, olay işleme ve farklı sorun türleri için optimize edilmiş geniş ODE çözücüleri seti gibi tüm DifentialEquations.jl özelliklerinin tümünü alır , yani sadece bir kerelik basit bir GPU ODE çözücü değil etkin GPU desteğine sahip olan tam özellikli bir sistemin parçası.