Performance problem with deeply nested nonlinear expressions
維護者通常 1 天內回覆
評估
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 新手友好度
- 45/100
- Issue 類型
- 缺陷
- 描述清晰度
- 基本清楚
- 活躍度
- 冷清
- 技術堆疊
- julia
- 領域
- performance, tooling
研究方向
從提供的 Julia 重現開始,尤其是 N = 2 的 multistep RK4 模型和 N = 50 的 single-step 比較。將模型建構與最佳化分開進行基準測試,並檢查在重複展開 RK4 的過程中巢狀運算式如何增長。完成的標準是確定速度變慢究竟出在 JuMP/MathOptInterface 還是建模模式上,並提供一個最小基準測試和一份記錄在案的編碼方向。
由索引模型根據 Issue 內容生成。
描述
Hello, I am interested in switching from CasADi tu JuMP for optimal control (the system is quaternion kinematics, so not a lot of variables). My MATLAB CasADi model does multistep RK4 integration for multiple shooting (4 steps/interval, 10 intervals) and builds and solves the problem in < 2s. The equivalent JuMP code builds the model for many minutes, using up to 10GB of RAM, and is basically unusable. This is the JuMP code I wrote:
using ReferenceFrameRotations, DifferentialEquations, Plots
##
function qdot(X, u)
collect(dquat(Quaternion(X), u))
end
function RK4(f, X, u, dt)
k1 = dt*f(X , u)
k2 = dt*f(X+k1/2, u)
k3 = dt*f(X+k2/2, u)
k4 = dt*f(X+k3 , u)
X + (k1+2k2+2k3+k4)/6
end
model = Model(Ipopt.Optimizer)
DCMf = [
-1 0 0
0 0 1
0 1 0
]
# two quaternions represent the same orientation
qf = -convert(Quaternion, DCM(DCMf)) |> collect
N = 2
T = 1
dt = T / (N-1)
tabq = @variable(model, [1:4, 1:N], base_name="q")
tabu = @variable(model, [1:3, 1:N-1], base_name="ω_b")
cost = 0
for i = 1:N-1
F = [tabq[:, i]; cost]
for M = 1:4
F = RK4((X, u) -> [qdot(X[1:4], u); 1/2 * u' * u], F, tabu[:, i], dt)
end
@constraint(model, tabq[:, i+1] == F[1:4])
cost = F[end]
end
#traj constraints
@constraint(model, tabq[:, 1] == q0)
@constraint(model, tabq[:, N] == qf)
# @constraint(model, c[i=1:N], tabq[:, i]' * tabq[:, i] == 1)
@objective(model, Min, cost)
#start values
set_start_value.(tabq, q0)
I set N = 2 to prove it's slow even for a single step (similar problems happen with single-step high order RK schemes, such as RK8, which leads me to believe JuMP can't handle big expressions really well). For comparison, if I build a single-step model with 50 steps (approx. 4steps/interval x 10 intervals for the working CasADi model) like this:
model = Model(Ipopt.Optimizer)
DCMf = [
-1 0 0
0 0 1
0 1 0
]
# two quaternions represent the same orientation
qf = -convert(Quaternion, DCM(DCMf)) |> collect
N = 50
T = 1
dt = T / (N-1)
tabq = @variable(model, [1:4, 1:N], base_name="q")
tabu = @variable(model, [1:3, 1:N-1], base_name="ω_b")
cost = 0
for i = 1:N-1
#can't do multistep integration
F = RK4((X, u) -> [qdot(X[1:4], u); 1/2 * u' * u], [tabq[:, i]; cost], tabu[:, i], dt)
@constraint(model, tabq[:, i+1] == F[1:4])
cost = F[end]
end
#traj constraints
@constraint(model, tabq[:, 1] == q0)
@constraint(model, tabq[:, N] == qf)
# @constraint(model, c[i=1:N], tabq[:, i]' * tabq[:, i] == 1)
@objective(model, Min, cost)
#start values
set_start_value.(tabq, q0)
model
##
optimize!(model)
It then works reasonably fast. I don't understand why JuMP can't handle the first code; in my view, this is a big limitation. Is there a particular way of coding in JuMP I'm missing, or is this truly JuMP's fault?
- 主要語言
- Julia
- 星號
- 506
- 分支
- 103
- 平均合併
- 1 天 1 小時
- 30 天內合併 PR
- 9
環境準備
這個專案沒有提供開發容器、Dockerfile 或貢獻指南,環境需要你自己搭建:先看它的 README,通用步驟見我們的新手貢獻指南。
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
jump-dev/MathOptInterface.jl 的其他 Issue
-
難度 2/5 1-3 小時 新手友好度 78/100
jump-dev/MathOptInterface.jl#3113 ·
維護者通常 1 天內回覆
-
[Bridges] MultirowChange in set_map.jl drops zero coefficients可能已有人在做 @odow 於 7 天前認領。 未關閉
jump-dev/MathOptInterface.jl#3106 · 2 則留言 · 已指派 1 人 ·
維護者通常 1 天內回覆
-
Precision loss in Hessian computation可能已有人在做 @blegat 於 7 天前認領。 未關閉
難度 5/5 一週以上 新手友好度 15/100
jump-dev/MathOptInterface.jl#3104 · 11 則留言 ·
維護者通常 1 天內回覆
-
難度 5/5 一週以上 新手友好度 35/100
jump-dev/MathOptInterface.jl#2986 · 3 則留言 ·
維護者通常 1 天內回覆
-
難度 5/5 一週以上 新手友好度 25/100
jump-dev/MathOptInterface.jl#2969 · 2 則留言 · 1 個 reaction ·
維護者通常 1 天內回覆
查看 jump-dev/MathOptInterface.jl 的全部 Issue
相似的 Issue
-
bug
難度 2/5 1-3 小時 新手友好度 73/100
維護者通常 1 天內回覆
-
難度 1/5 1 小時以內 新手友好度 76/100
-
難度 1/5 1 小時以內 新手友好度 83/100
JuliaMath/Polynomials.jl#647 ·
-
reactant ☣
難度 2/5 1-3 小時 新手友好度 79/100
NumericalEarth/Breeze.jl#1110 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 74/100
OpenSourceAWE/SymbolicAWEModels.jl#431 ·
維護者通常 1 天內回覆