Thư viện differentialEquations.jl là một thư viện dành cho ngôn ngữ cấp cao (Julia) có các công cụ để tự động chuyển đổi hệ thống ODE thành phiên bản tối ưu hóa cho giải pháp song song trên GPU. Có hai dạng song song có thể được sử dụng: song song dựa trên mảng cho các hệ thống ODE lớn và song song tham số cho các nghiên cứu tham số trên các hệ thống ODE tương đối nhỏ (<100). Nó hỗ trợ các phương thức ngầm và rõ ràng theo thứ tự cao và thường xuyên vượt trội hơn hoặc phù hợp với các hệ thống khác trong điểm chuẩn (ít nhất, nó bao bọc các phương thức khác để dễ dàng kiểm tra và sử dụng chúng!)
Đối với chức năng cụ thể này, bạn có thể muốn xem DiffEqGPU.jl , đây là mô-đun cho tính song song tham số tự động. Thư viện differentialEquations.jl có chức năng cho các nghiên cứu tham số song song và mô-đun này tăng cường các cấu hình hiện có để làm cho nghiên cứu diễn ra tự động song song. Những gì người ta làm là biến đổi hiện tại của họ ODEProblem
(hoặc khác DEProblem
như thế SDEProblem
) thành một EnsembleProblem
và chỉ định với prob_func
cách các vấn đề khác được tạo ra từ nguyên mẫu. Sau đây giải quyết 10.000 quỹ đạo của phương trình Lorenz trên GPU bằng phương pháp thích ứng rõ ràng bậc cao:
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)
Lưu ý rằng người dùng không cần viết mã GPU và với một RTX 2080, điểm chuẩn này là một cải tiến 5x so với việc sử dụng máy Xeon 16 lõi với khả năng song song đa luồng. Sau đó, người ta có thể kiểm tra README để biết cách thực hiện những việc như sử dụng nhiều GPU và thực hiện đa xử lý + GPU để sử dụng đồng thời một cụm GPU đầy đủ . Lưu ý rằng chuyển sang đa luồng thay vì GPU là một thay đổi dòng: EnsembleThreads()
thay vì EnsembleGPUArray()
.
Sau đó, đối với người giải quyết ngầm, giao diện tương tự giữ. Ví dụ: phần sau sử dụng phương pháp Rosenbrock bậc cao và ẩn 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)
Mặc dù biểu mẫu này yêu cầu bạn cung cấp Jacobian để được sử dụng trên GPU (hiện tại, sẽ được khắc phục sớm), tài liệu differentialEquations.jl trình bày cách thực hiện các phép tính Jacobian tượng trưng tự động trên các hàm được xác định bằng số , do đó vẫn không có hướng dẫn sử dụng lao động ở đây. Tôi rất khuyến nghị các thuật toán này bởi vì logic phân nhánh của một phương thức như CVODE thường gây ra sự không đồng bộ hóa luồng và dường như không thực hiện tốt như phương pháp Rosenbrock trong các loại kịch bản này.
Bằng cách sử dụng differentialEquations.jl, bạn cũng có quyền truy cập vào thư viện đầy đủ, bao gồm chức năng như phân tích độ nhạy toàn cầu có thể sử dụng khả năng tăng tốc GPU này. Nó cũng tương thích với các số kép để phân tích độ nhạy cục bộ nhanh . Mã dựa trên GPU có tất cả các tính năng của differentialEquations.jl, như xử lý sự kiện và bộ giải pháp ODE lớn được tối ưu hóa cho các loại vấn đề khác nhau , nghĩa là nó không chỉ là bộ giải ODE GPU đơn giản mà thay vào đó là một phần của một hệ thống đầy đủ tính năng cũng có hỗ trợ GPU hiệu quả.