GPU'larda ODE sistemlerini çözme seçenekleri?


16

ODE'lerin sistemlerini GPU'lara 'çok paralellikle paralel' bir ortamda çözmek istiyorum. Örneğin, 512 farklı parametre seti ile duyarlılık analizi yapmak.

İdeal olarak, ODE çözmeyi Forward Euler gibi sabit bir zaman çizelgesi yerine CVODE gibi akıllı bir uyarlanabilir zaman çizelgesi çözücüsü ile yapmak istiyorum, ancak CPU yerine bir NVIDIA GPU üzerinde çalıştırıyorum.

Bunu yapan var mı? Bunun için kütüphaneler var mı?


Bu yüzden parantezler! Ben PDE için bir kaynak terimi almak için düğümlerde ODE'leri çözmek, sonra sonraki yineleme için bir ODE parametresini değiştirmek, bir operatör bölme tabanlı teknik (kardiyak elektrofizyoloji simülasyonları) düşünüyorum.
mirams


1
Her ODE için aynı zaman adımını kullanmak isteyip istemediğinizi belirtmek önemlidir.
Christian Clason

Ayrıca, özellikle bidomain (veya monodomain) denklemleri ile ilgileniyorsanız, CARP'ın bunu nasıl yaptığına bakmak isteyebilirsiniz .
Christian Clason

Farklı zaman hızları, eğer yöntem uyarlanabilirse, farklı parametre setleri için onlara ihtiyaç duyacaktır ... CARP'nin ne yaptığına bağlantı için teşekkürler - doğru okuduğumda sabit bir zaman akışı Rush Larsen ODE çözücü.
mirams

Yanıtlar:


6

Sen içine bakmak isteyebilirsiniz Boost odeint kütüphanesinden ve Thrust . Burada tartışıldığı gibi birleştirilebilirler .


Bu biraz farklı gibi görünüyor - GPU'daki paralel (iletişim ile) büyük ODE sistemlerini çözmek. Bu bağlantı, "GPU'dan tam olarak faydalanabilmek için paralel hale getirilmiş vektör boyutunun 10 ^ 6 civarında olması gerektiğini deneyimledik." O (10) veya O (100) vektör önemsiz paralelleştirilebilir ODE
çözülür

Doğrudan cuda veya openCL'de yazmayı düşündünüz mü? Doğru anladıysam, yaptığınız şey her bir iş parçacığındaki bazı ODE denklemi üzerinde ayrı ayrı yinelemek, doğrudan yazmak zor olmamalı.
Hydro Guy

Her GPU işleminin aynı zaman çizelgesini, oldukça kolay bir şekilde kullandığı bir İleri Euler veya başka bir sabit zaman çizelgesi yöntemini kodlamanın mümkün olacağını hayal ediyorum, herkesin CVODE gibi uyarlanabilir zaman çizelgesi almayı başarabildiğini veya bu GPGPU'da verimli hale getirmek imkansız mı?
mirams

gpu ile ilgili sorun veri paralel kod yazmanız gerektiğidir. Aynı uyarlamalı rutini yazarsanız, ancak bazı parametrelerin değerleri üzerindeki tüm bu esnekliği emerseniz, muhtemelen gpu üzerinde verimli bir şekilde kodlamak mümkündür. Bu aynı zamanda talimatlarda dallanmayı kullanamayacağınız anlamına gelir, bu muhtemelen bunu yapmayı imkansız hale getireceğini düşünüyorsunuz.
Hydro Guy

1
mirams tam olarak aradığınızı kapsayan odeint için bir örnek var: boost.org/doc/libs/1_59_0/libs/numeric/odeint/doc/html/… , ayrıca github.com/boostorg/odeint/blob/ adresine bakın. usta / örnekler / itme /… . Ayrıca, odeint, CVODE'deki gibi adaptif çok adımlı yöntemleri destekler: github.com/boostorg/odeint/blob/master/examples/…
Christian Clason

13

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 DEProblembenzerini SDEProblem) 'e dönüştürür EnsembleProblemve prob_funcdiğ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ı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.