diff --git a/test/problems/goddard2.jl b/test/problems/goddard2.jl new file mode 100644 index 00000000..536455b1 --- /dev/null +++ b/test/problems/goddard2.jl @@ -0,0 +1,42 @@ +# Goddard2 problem (version for :exa) +# free final time, fixed final mass, max altitude +# constraint on max speed + +function goddard2(; vmax=0.1, Tmax=3.5) + # constants + Cd = 310 + β = 500 + b = 2 + r0 = 1 + v0 = 0 + m0 = 1 + mf = 0.6 + x0 = [r0, v0, m0] + + goddard2 = @def begin + tf ∈ R, variable + t ∈ [0, tf], time + x = (r, v, m) ∈ R^3, state + u ∈ R, control + tf ≥ 0.01 + x(0) == x0 + m(tf) == mf + r0 ≤ r(t) ≤ r0 + 0.1 + v0 ≤ v(t) ≤ vmax + mf ≤ m(t) ≤ m0 + 0 ≤ u(t) ≤ 1 + + ∂(r)(t) == v(t) + ∂(v)(t) == -Cd * v(t)^2 * exp(-β * (r(t) - 1)) / m(t) - 1 / r(t)^2 + u(t) * Tmax / m(t) + ∂(m)(t) == -b * Tmax * u(t) + + r(tf) → max + end + + return (( + ocp=goddard2, + obj=1.01257, + name="goddard2", + init=(state=[1.01, 0.05, 0.8],), + )) +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 1f9e6584..cc996949 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -30,10 +30,11 @@ macro ignore(e) :() end # run either usual test suite on CPU, or GPU tests only @testset verbose = true showtiming = true "Test CTDirect" begin if "GPU" in ARGS - # GPU tests only (moonshot workflow) - include("test_gpu.jl") + # ExaModels tests only on CPU + GPU (moonshot workflow) + include("test_exa.jl") else # CPU: run all scripts in subfolder suite/ include.(filter(contains(r".jl$"), readdir("./suite"; join=true))) + include("test_exa.jl") # will only run CPU tests if GPU is not available end end \ No newline at end of file diff --git a/test/test_exa.jl b/test/test_exa.jl new file mode 100644 index 00000000..70129822 --- /dev/null +++ b/test/test_exa.jl @@ -0,0 +1,71 @@ +# ExaModels tests, CPU + GPU (when available) +import ExaModels +using MadNLP +using MadNLPGPU +using CUDA + +# beam2 + +if !isdefined(Main, :beam2) + include("./problems/beam2.jl") +end + +if !isdefined(Main, :goddard2) + include("./problems/goddard2.jl") +end + +# test_exa for all backends (CPU + GPU) + +function test_exa(exa_backend) + + # beam2 + + @testset verbose = true showtiming = true "beam2 :examodel :euler" begin + prob = beam2() + sol = solve(prob.ocp, :madnlp, :exa; disc_method = :euler, exa_backend = exa_backend, display = display) + @test sol.objective ≈ prob.obj rtol = 1e-2 + end + + @testset verbose = true showtiming = true "beam2 :examodel :trapeze" begin + prob = beam2() + sol = solve(prob.ocp, :madnlp, :exa; disc_method = :trapeze, exa_backend = exa_backend, display = display) + @test sol.objective ≈ prob.obj rtol = 1e-2 + end + + @testset verbose = true showtiming = true "beam2 :examodel :trapeze :grid_size" begin + prob = beam2() + sol = solve(prob.ocp, :madnlp, :exa; disc_method = :trapeze, exa_backend = exa_backend, display = display, grid_size = 1000) + @test sol.objective ≈ prob.obj rtol = 1e-2 + end + + @testset verbose = true showtiming = true "beam2 :examodel :trapeze :init" begin + prob = beam2() + sol = solve(prob.ocp, :madnlp, :exa; disc_method = :trapeze, exa_backend = exa_backend, display = display, init=(control=6.66,), max_iter = 0) + @test control(sol)(0.5) == 6.66 + end + + # goddard2 + + @testset verbose = true showtiming = true "goddard2 :examodel :trapeze :grid_size" begin + prob = goddard2() + sol = solve(prob.ocp, :madnlp, :exa; disc_method = :trapeze, exa_backend = exa_backend, display = display, grid_size = 1000) + @test sol.objective ≈ prob.obj rtol = 1e-2 + end + +end + +# CPU tests + +display = true +println("testing: CPU with ExaModels + MadNLP") +test_exa(nothing) # CPU tests + +# GPU tests + +display = true +if CUDA.functional() + println("testing: GPU with ExaModels + MadNLPGPU + CUDA") + test_exa(CUDABackend()) # GPU tests +else + println("********** CUDA is not available") +end \ No newline at end of file diff --git a/test/test_gpu.jl b/test/test_gpu.jl deleted file mode 100644 index feef8bb4..00000000 --- a/test/test_gpu.jl +++ /dev/null @@ -1,49 +0,0 @@ -# GPU tests -import ExaModels -using MadNLPGPU -using CUDA - -# beam2 -if !isdefined(Main, :beam2) - include("./problems/beam2.jl") -end - -println("testing: GPU with ExaModels / MadNLPGPU / CUDA") -display = true - -if CUDA.functional() - println("********** CUDA is available") - exa_backend = CUDA.functional() ? CUDABackend() : nothing -else - error("********** CUDA is not available") - exa_backend = nothing -end - -if !isnothing(exa_backend) -println("GPU tests with ", exa_backend) -@testset verbose = true showtiming = true ":examodel :GPU :euler" begin - prob = beam2() - sol = solve(prob.ocp, :madnlp, :exa; disc_method = :euler, exa_backend = exa_backend, display = display) - @test sol.objective ≈ prob.obj rtol = 1e-2 -end -@testset verbose = true showtiming = true ":examodel :GPU :trapeze :init" begin - prob = beam2() - sol = solve(prob.ocp, :madnlp, :exa; disc_method = :trapeze, exa_backend = exa_backend, display = display, init=(control=6.66,), max_iter = 0) - @test control(sol)(0.5) == 6.66 -end -else - println("skipping GPU tests") -end - -@ignore begin # debug -# swimmer2 -if !isdefined(Main, :swimmer2) - include("../problems/swimmer2.jl") -end - -@testset verbose = true showtiming = true ":examodel :cpu :swimmer2" begin - prob = swimmer2() - sol = solve(prob.ocp, :madnlp, :exa; disc_method = :trapeze, display = display) - @test sol.objective ≈ prob.obj rtol = 1e-2 -end -end # debug \ No newline at end of file