Skip to content

Commit 8f3b7b4

Browse files
Split MTK test into separate file for macro availability at parse time
Julia macros like @parameters must be available at parse time, but conditional `using` inside `if` blocks only executes at runtime. Split the MTK test into a separate file that's conditionally included. Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 937afed commit 8f3b7b4

File tree

2 files changed

+54
-53
lines changed

2 files changed

+54
-53
lines changed

test/gpu_kernel_de/stiff_ode/gpu_ode_modelingtoolkit_dae.jl

Lines changed: 3 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -110,59 +110,9 @@ end
110110

111111
# ModelingToolkit is an optional test dependency — skip this test if not available.
112112
# This avoids compat conflicts in the alldeps minimum-version resolution test.
113-
const HAS_MTK = Base.identify_package("ModelingToolkit") !== nothing
114-
115-
if HAS_MTK
116-
using ModelingToolkit
117-
using ModelingToolkit: t_nounits as t, D_nounits as D
118-
# NOTE: This test is currently broken because ModelingToolkit problems with initialization
119-
# data contain MTKParameters which use Vector types that cannot be stored inline in CuArrays.
120-
# This is a known limitation: GPU kernels require element types that are allocated inline.
121-
# Once MTK supports GPU-compatible parameter storage, this test can be re-enabled.
122-
@testset "MTK Pendulum DAE with initialization" begin
123-
@parameters g = 9.81 L = 1.0
124-
@variables px(t) py(t) [state_priority = 10] (t)
125-
126-
eqs = [
127-
D(D(px)) ~* px / L
128-
D(D(py)) ~* py / L - g
129-
px^2 + py^2 ~ L^2
130-
]
131-
132-
@mtkcompile pendulum = ODESystem(eqs, t, [px, py, pλ], [g, L])
133-
134-
mtk_prob = ODEProblem(
135-
pendulum, [py => 0.99], (0.0, 1.0),
136-
guesses = [pλ => 0.0, px => 0.1, D(px) => 0.0, D(py) => 0.0]
137-
)
138-
139-
# Verify it has initialization data and a mass matrix
140-
@test SciMLBase.has_initialization_data(mtk_prob.f)
141-
@test mtk_prob.f.mass_matrix !== LinearAlgebra.I
142-
143-
# Reference solution with OrdinaryDiffEq
144-
ref_sol = solve(mtk_prob, Rodas5P())
145-
@test ref_sol.retcode == SciMLBase.ReturnCode.Success
146-
147-
# GPU ensemble solve - currently broken due to MTKParameters containing non-inline types
148-
# Skip actual GPU solve test until MTK supports GPU-compatible parameters
149-
if backend isa CPU
150-
monteprob_mtk = EnsembleProblem(mtk_prob, safetycopy = false)
151-
sol_mtk = solve(
152-
monteprob_mtk, GPURodas5P(), EnsembleGPUKernel(backend),
153-
trajectories = 2,
154-
dt = 0.01,
155-
adaptive = false
156-
)
157-
@test length(sol_mtk.u) == 2
158-
@test !any(isnan, sol_mtk.u[1][end])
159-
160-
# GPU solution should be close to reference (fixed step so moderate tolerance)
161-
@test norm(sol_mtk.u[1][end] - ref_sol.u[end]) < 1.0
162-
else
163-
@test_broken false # MTK DAE with initialization not yet supported on GPU
164-
end
165-
end
113+
# The MTK test is in a separate file because macros need to be available at parse time.
114+
if Base.identify_package("ModelingToolkit") !== nothing
115+
include("gpu_ode_modelingtoolkit_dae_mtk.jl")
166116
else
167117
@info "ModelingToolkit not available, skipping MTK DAE test"
168118
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using ModelingToolkit
2+
using ModelingToolkit: t_nounits as t, D_nounits as D
3+
4+
# NOTE: This test is currently broken because ModelingToolkit problems with initialization
5+
# data contain MTKParameters which use Vector types that cannot be stored inline in CuArrays.
6+
# This is a known limitation: GPU kernels require element types that are allocated inline.
7+
# Once MTK supports GPU-compatible parameter storage, this test can be re-enabled.
8+
@testset "MTK Pendulum DAE with initialization" begin
9+
@parameters g = 9.81 L = 1.0
10+
@variables px(t) py(t) [state_priority = 10] (t)
11+
12+
eqs = [
13+
D(D(px)) ~* px / L
14+
D(D(py)) ~* py / L - g
15+
px^2 + py^2 ~ L^2
16+
]
17+
18+
@mtkcompile pendulum = ODESystem(eqs, t, [px, py, pλ], [g, L])
19+
20+
mtk_prob = ODEProblem(
21+
pendulum, [py => 0.99], (0.0, 1.0),
22+
guesses = [pλ => 0.0, px => 0.1, D(px) => 0.0, D(py) => 0.0]
23+
)
24+
25+
# Verify it has initialization data and a mass matrix
26+
@test SciMLBase.has_initialization_data(mtk_prob.f)
27+
@test mtk_prob.f.mass_matrix !== LinearAlgebra.I
28+
29+
# Reference solution with OrdinaryDiffEq
30+
ref_sol = solve(mtk_prob, Rodas5P())
31+
@test ref_sol.retcode == SciMLBase.ReturnCode.Success
32+
33+
# GPU ensemble solve - currently broken due to MTKParameters containing non-inline types
34+
# Skip actual GPU solve test until MTK supports GPU-compatible parameters
35+
if backend isa CPU
36+
monteprob_mtk = EnsembleProblem(mtk_prob, safetycopy = false)
37+
sol_mtk = solve(
38+
monteprob_mtk, GPURodas5P(), EnsembleGPUKernel(backend),
39+
trajectories = 2,
40+
dt = 0.01,
41+
adaptive = false
42+
)
43+
@test length(sol_mtk.u) == 2
44+
@test !any(isnan, sol_mtk.u[1][end])
45+
46+
# GPU solution should be close to reference (fixed step so moderate tolerance)
47+
@test norm(sol_mtk.u[1][end] - ref_sol.u[end]) < 1.0
48+
else
49+
@test_broken false # MTK DAE with initialization not yet supported on GPU
50+
end
51+
end

0 commit comments

Comments
 (0)