GPU에서 ODE 시스템을 해결하기위한 옵션?


16

나는 '사소한 병렬화'설정으로 ODE 시스템을 GPU에 농사 짓고 싶습니다. 예를 들어 512 개의 서로 다른 파라미터 세트로 감도 분석을 수행합니다.

이상적으로 Forward Euler와 같은 고정 된 시간 단계가 아니라 CVODE와 같은 스마트 적응 형 시간 단계 솔버를 사용하여 ODE를 해결하고 싶지만 CPU 대신 NVIDIA GPU에서 실행하고 싶습니다.

누구든지 이것을 했습니까? 라이브러리가 있습니까?


따라서 괄호! 노드에서 ODE를 해결하여 PDE의 소스 용어를 얻은 다음 다음 반복을 위해 ODE 매개 변수를 변경하는 운영자 분할 기반 기술 (심장 전기 생리학 시뮬레이션)을 고려하고 있습니다.
mirams


1
모든 ODE에 동일한 타임 스텝핑을 사용할지 여부를 지정하는 것이 중요합니다.
Christian Clason

또한 이중 도메인 (또는 단일 도메인) 방정식에 특히 관심이있는 경우 CARP가 수행하는 방식을 살펴볼 있습니다.
Christian Clason

다른 시간 단계, 방법이 적응 적이라면 다른 매개 변수 세트에 대해 필요합니다 ... CARP 가하는 일에 대한 링크 덕분에-올바르게 읽으면 고정 된 시간 단계 Rush Larsen ODE 솔버.
mirams

답변:


6

Boost의 odeint 라이브러리Thrust 를 살펴볼 수 있습니다 . 여기에 설명 된대로 결합 할 수 있습니다 .


이것은 약간 다른 것처럼 보입니다-GPU의 대규모 ODE 시스템을 병렬로 (통신과 함께) 해결합니다. 이 링크는 "우리는 GPU를 최대한 활용하기 위해 병렬화되는 벡터 크기가 10 ^ 6 정도 여야한다는 것을 경험했습니다." 나는 O (10) 또는 O (100) 벡터 크기의 사소한 병렬화 가능한 ODE를 해결하는 좋은 방법을 찾고 있습니다.
mirams

cuda 또는 openCL로 직접 작성하는 것에 대해 생각해 보셨습니까? 내가 제대로 이해하지 못하면, 당신이하고있는 일은 각 스레드에서 ODE 방정식을 개별적으로 반복하는 것입니다. 직접 작성하는 것이 어렵지 않아야합니다.
Hydro Guy

모든 GPU 프로세스가 동일한 타임 스텝을 사용하는 상당히 쉬운 포워드 오일러 또는 기타 고정 타임 스텝 방법을 코딩하는 것이 가능하다고 생각합니다. GPGPU에서 효율적으로 만드는 것이 불가능합니까?
mirams

gpu의 문제점은 데이터 병렬 코드를 작성해야한다는 것입니다. 동일한 적응 루틴을 작성하지만 일부 매개 변수의 값에 대한 모든 유연성을 흡수하는 경우 아마도 GPU에서 효율적으로 코딩 할 수 있습니다. 그것은 또한 명령에 분기를 사용할 수 없다는 것을 의미합니다. 아마도 그렇게 할 수 없을 것이라고 생각합니다.
하이드로 가이

1
@mirams 당신이 찾고있는 것을 정확하게 다루는 odeint에 대한 예제가 있습니다 : boost.org/doc/libs/1_59_0/libs/numeric/odeint/doc/html/… , github.com/boostorg/odeint/blob/ 참조 master / examples / thrust /… . 또한, odeint 지원은 CVODE 같이 다단계 방법을 적응 적 : github.com/boostorg/odeint/blob/master/examples/...
기독교 Clason

13

DifferentialEquations.jl 라이브러리는 ODE 시스템을 GPU의 병렬 솔루션에 대한 최적화 된 버전으로 자동 변환하는 도구가있는 고급 언어 (Julia) 용 라이브러리입니다. 채택 할 수있는 병렬 처리에는 크게 ODE 시스템에 대한 어레이 기반 병렬 처리와 상대적으로 작은 (<100) ODE 시스템에 대한 파라미터 연구에 대한 매개 변수 병렬 처리의 두 가지 형태가 있습니다. 높은 수준의 암시 적 및 명시 적 방법을 지원 하고 벤치 마크에서 다른 시스템보다 성능이 우수하거나 일상적으로 일치합니다 (적어도 다른 시스템을 래핑하여 쉽게 확인하고 사용할 수 있습니다).

이 특정 기능에 대해서는 자동화 된 매개 변수 병렬 처리를위한 모듈 인 DiffEqGPU.jl 을 살펴볼 수 있습니다 . DifferentialEquations.jl 라이브러리 에는 병렬 매개 변수 연구 기능 이 있으며이 모듈은 기존 구성을 보강하여 연구가 자동으로 병렬로 수행되도록합니다. 하나는 기존 ODEProblem(또는 다른 DEProblem것과 같이 SDEProblem)을로 변환하고 프로토 타입에서 다른 문제가 생성되는 방식으로 EnsembleProblem지정 prob_func합니다. 다음은 고차 명시 적 적응 방법으로 GPU에서 Lorenz 방정식의 10,000 궤적을 해결합니다.

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을 사용하면 멀티 스레드 병렬 처리를 갖춘 16 코어 Xeon 시스템을 사용하는 것보다 5 배 향상된 성능으로 벤치 마크됩니다. 그런 다음 README에서 여러 GPU 활용 및 전체 GPU 클러스터를 동시에 사용하기위한 멀티 프로세싱 + GPU 수행 방법을 확인할 수 있습니다 . 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에서 사용하기 위해 Jacobian을 제공해야하지만 (현재 곧 수정 될 예정 임) DifferentialEquations.jl 설명서 는 숫자로 정의 된 함수에서 자동으로 상징적 인 Jacobian 계산을 수행하는 방법을 보여 주므로 여전히 수동은 없습니다 여기서 노동하십시오. CVODE와 같은 메소드의 분기 논리는 일반적으로 스레드 비 동기화를 유발하고 어쨌든 이러한 유형의 시나리오에서 Rosenbrock 메소드만큼 성능이 좋지 않기 때문에 이러한 알고리즘을 적극 권장합니다.

DifferentialEquations.jl 을 사용하면이 GPU 가속을 사용할 수있는 전역 감도 분석 과 같은 기능이 포함 된 전체 라이브러리에 액세스 할 수 있습니다. 또한 빠른 로컬 감도 분석을 위해 이중 숫자 와 호환됩니다 . GPU 기반 코드는 이벤트 처리다양한 유형의 문제에 최적화 된 대규모 ODE 솔버 와 같이 DifferentialEquations.jl의 모든 기능을 가져옵니다 . 이는 단순한 일회성 GPU ODE 솔버가 아니라 대신 효율적인 GPU 지원을 제공하는 완전한 기능을 갖춘 시스템의 일부입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.