使用 GPU 在 Julia 中解决 DAE

计算科学 微分方程 显卡 朱莉娅
2021-12-02 09:37:00

我正在尝试在 Julia 中求解一个微分代数方程 (DAE),该方程使用 GPU 在计算上非常昂贵。我是 Julia 的新手,没有太多使用 GPU 编码的经验。下面的问题只是我试图解决的一个示例 DAE 问题。我得到的错误发生在代码的最后一行,是

MethodError: no method matching generate_problem(::DAEProblem{Vector{Float32}, Vector{Float32}, Tuple{Float32, Float32}, true, Vector{Float32}, DAEFunction{true, typeof(f1), Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}, Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, Vector{Float64}}, ::CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}, ::CuArray{Float32, 2, CUDA.Mem.DeviceBuffer}, ::Nothing, ::Nothing)

生成错误的代码如下,并基于来自的示例

https://github.com/SciML/DiffEqGPU.jl ### 这个例子我可以运行

我已经能够在不使用 GPU 的情况下使用以下链接 https://docs.juliahub.com/DifferentialEquations/UQdwS/6.15.0/tutorials/dae_example/中的代码解决 DAE

任何帮助是极大的赞赏

朱莉娅代码:

using Pkg
using Sundials
using DifferentialEquations
using CSV
using DataFrames
using CUDA, LinearAlgebra
using DiffEqGPU



function f1(out,du,u,p,t)
    out[1] = p[1]*(u[2]-u[1]) - du[1]
    out[2] = u[1]*(p[2]-u[3]) - u[2] - du[2]
    out[3] = u[1]*u[2] - p[3]*u[3] - du[3]
end

u₀= Float32[1.0;0.0;0.0]

du₀ = Float32[0.5;0.5;0.5]

tspan = (0.0f0,100.0f0)
p = [10.0f0,28.0f0,8/3f0]

#differential_vars = Float32.(ones(3))

differential_vars = ones(3)



prob = DAEProblem(f1,du₀,u₀,tspan,p,differential_vars = differential_vars)


prob_func = (prob,i,repeat) -> remake(prob,p=rand(Float32,3).*p)
monteprob = EnsembleProblem(prob, prob_func = prob_func, safetycopy=false)

### The below line is where the error occurs
@time sol = solve(monteprob,Tsit5(),EnsembleGPUArray(),trajectories=10_000,saveat=1.0f0)
1个回答

请注意,如果要将其与 DiffEqGPU 一起使用,则需要使用本机 DAE 求解器,并且在此合并后需要发布当这一切都在一起时,DFBDF将是兼容的算法,正确的代码将是:

using OrdinaryDiffEq
using DiffEqGPU

function f1(out,du,u,p,t)
    out[1] = p[1]*(u[2]-u[1]) - du[1]
    out[2] = u[1]*(p[2]-u[3]) - u[2] - du[2]
    out[3] = u[1]*u[2] - p[3]*u[3] - du[3]
end

u₀= Float32[1.0;0.0;0.0]
du₀ = Float32[0.5;0.5;0.5]
tspan = (0.0f0,100.0f0)
p = [10.0f0,28.0f0,8/3f0]
differential_vars = ones(3)

prob = DAEProblem(f1,du₀,u₀,tspan,p,differential_vars = differential_vars)
prob_func = (prob,i,repeat) -> remake(prob,p=rand(Float32,3).*p)
monteprob = EnsembleProblem(prob, prob_func = prob_func, safetycopy=false)

@time sol = solve(monteprob,DFBDF(),EnsembleGPUArray(),trajectories=1_000,saveat=1.0f0)

也就是说,目前 DFBDF 尚未优化,因此在 2022 年底之前它不太可能有用。