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日 10分
- マージ済み PR(30日)
- 12
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
jump-dev/MathOptInterface.jl のほかの issue
-
[Bridges] MultirowChange in set_map.jl drops zero coefficients対応中かも @odow が 6 日前に担当しました。 オープン
jump-dev/MathOptInterface.jl#3106 · コメント 2 件 · 担当者 1 名 ·
メンテナーはふだん 1 日以内に返信
-
Precision loss in Hessian computation対応中かも @blegat が 6 日前に担当しました。 オープン
難易度 5/5 1週間以上 初心者へのやさしさ 15/100
jump-dev/MathOptInterface.jl#3104 · コメント 11 件 ·
メンテナーはふだん 1 日以内に返信
-
Layer instantiatorオープン
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
jump-dev/MathOptInterface.jl#2986 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
jump-dev/MathOptInterface.jl#2969 · コメント 2 件 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Add Batched{S} setオープンType: Set Request
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
jump-dev/MathOptInterface.jl#2904 · コメント 15 件 · リアクション 7 件 ·
メンテナーはふだん 1 日以内に返信
jump-dev/MathOptInterface.jl の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
OpenSourceAWE/SymbolicAWEModels.jl#431 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
EnzymeAD/Reactant.jl#3549 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
bug help wanted
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
JuliaGeometry/Meshes.jl#1469 ·
メンテナーはふだん 1 日以内に返信