Skip to content
This repository was archived by the owner on May 15, 2025. It is now read-only.

Commit 0a1fdce

Browse files
authored
Merge pull request #124 from SciML/ap/fast_testing
Run tests in Parallel using XUnit
2 parents ba3b5a4 + d2c6a4e commit 0a1fdce

File tree

11 files changed

+96
-112
lines changed

11 files changed

+96
-112
lines changed

.github/workflows/CI.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ jobs:
3232
${{ runner.os }}-
3333
- uses: julia-actions/julia-buildpkg@v1
3434
- uses: julia-actions/julia-runtest@v1
35+
with:
36+
annotate: true
3537
env:
3638
GROUP: ${{ matrix.group }}
37-
JULIA_NUM_THREADS: 11
39+
JULIA_NUM_THREADS: "auto"
3840
- uses: julia-actions/julia-processcoverage@v1
3941
- uses: codecov/codecov-action@v3
4042
with:

test/23_test_problems.jl

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using SimpleNonlinearSolve, LinearAlgebra, NonlinearProblemLibrary, DiffEqBase, Test
1+
using SimpleNonlinearSolve, LinearAlgebra, NonlinearProblemLibrary, DiffEqBase, XUnit
22

33
problems = NonlinearProblemLibrary.problems
44
dicts = NonlinearProblemLibrary.dicts
@@ -37,49 +37,51 @@ function test_on_library(problems, dicts, alg_ops, broken_tests, ϵ = 1e-4;
3737
end
3838
end
3939

40-
@testset "SimpleNewtonRaphson 23 Test Problems" begin
41-
alg_ops = (SimpleNewtonRaphson(),)
40+
@testset "23 Test Problems" begin
41+
@testcase "SimpleNewtonRaphson 23 Test Problems" begin
42+
alg_ops = (SimpleNewtonRaphson(),)
4243

43-
# dictionary with indices of test problems where method does not converge to small residual
44-
broken_tests = Dict(alg => Int[] for alg in alg_ops)
45-
broken_tests[alg_ops[1]] = []
44+
# dictionary with indices of test problems where method does not converge to small residual
45+
broken_tests = Dict(alg => Int[] for alg in alg_ops)
46+
broken_tests[alg_ops[1]] = []
4647

47-
test_on_library(problems, dicts, alg_ops, broken_tests)
48-
end
48+
test_on_library(problems, dicts, alg_ops, broken_tests)
49+
end
4950

50-
@testset "SimpleTrustRegion 23 Test Problems" begin
51-
alg_ops = (SimpleTrustRegion(),)
51+
@testcase "SimpleTrustRegion 23 Test Problems" begin
52+
alg_ops = (SimpleTrustRegion(),)
5253

53-
# dictionary with indices of test problems where method does not converge to small residual
54-
broken_tests = Dict(alg => Int[] for alg in alg_ops)
55-
broken_tests[alg_ops[1]] = [3, 6, 15, 16, 21]
54+
# dictionary with indices of test problems where method does not converge to small residual
55+
broken_tests = Dict(alg => Int[] for alg in alg_ops)
56+
broken_tests[alg_ops[1]] = [3, 6, 15, 16, 21]
5657

57-
test_on_library(problems, dicts, alg_ops, broken_tests)
58-
end
58+
test_on_library(problems, dicts, alg_ops, broken_tests)
59+
end
5960

60-
@testset "SimpleDFSane 23 Test Problems" begin
61-
alg_ops = (SimpleDFSane(),)
61+
@testcase "SimpleDFSane 23 Test Problems" begin
62+
alg_ops = (SimpleDFSane(),)
6263

63-
broken_tests = Dict(alg => Int[] for alg in alg_ops)
64-
broken_tests[alg_ops[1]] = [1, 2, 3, 4, 5, 6, 11, 21]
64+
broken_tests = Dict(alg => Int[] for alg in alg_ops)
65+
broken_tests[alg_ops[1]] = [1, 2, 3, 4, 5, 6, 11, 21]
6566

66-
test_on_library(problems, dicts, alg_ops, broken_tests)
67-
end
67+
test_on_library(problems, dicts, alg_ops, broken_tests)
68+
end
6869

69-
@testset "SimpleBroyden 23 Test Problems" begin
70-
alg_ops = (SimpleBroyden(),)
70+
@testcase "SimpleBroyden 23 Test Problems" begin
71+
alg_ops = (SimpleBroyden(),)
7172

72-
broken_tests = Dict(alg => Int[] for alg in alg_ops)
73-
broken_tests[alg_ops[1]] = [1, 5, 11]
73+
broken_tests = Dict(alg => Int[] for alg in alg_ops)
74+
broken_tests[alg_ops[1]] = [1, 5, 11]
7475

75-
test_on_library(problems, dicts, alg_ops, broken_tests)
76-
end
76+
test_on_library(problems, dicts, alg_ops, broken_tests)
77+
end
7778

78-
@testset "SimpleKlement 23 Test Problems" begin
79-
alg_ops = (SimpleKlement(),)
79+
@testcase "SimpleKlement 23 Test Problems" begin
80+
alg_ops = (SimpleKlement(),)
8081

81-
broken_tests = Dict(alg => Int[] for alg in alg_ops)
82-
broken_tests[alg_ops[1]] = [1, 2, 4, 5, 11, 12, 22]
82+
broken_tests = Dict(alg => Int[] for alg in alg_ops)
83+
broken_tests[alg_ops[1]] = [1, 2, 4, 5, 11, 12, 22]
8384

84-
test_on_library(problems, dicts, alg_ops, broken_tests)
85+
test_on_library(problems, dicts, alg_ops, broken_tests)
86+
end
8587
end

test/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
1212
SciMLSensitivity = "1ed8b502-d754-442c-8d5d-10ac956f44a1"
1313
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1414
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
15+
XUnit = "3e3c03f2-1a94-11e9-2981-050a4ca824ab"
1516
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
1617

1718
[compat]

test/adjoint.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
using ForwardDiff, SciMLSensitivity, SimpleNonlinearSolve, Test, Zygote
1+
using ForwardDiff, SciMLSensitivity, SimpleNonlinearSolve, XUnit, Zygote
22

3-
@testset "Simple Adjoint Test" begin
3+
@testcase "Simple Adjoint Test" begin
44
ff(u, p) = u .^ 2 .- p
55

66
function solve_nlprob(p)

test/basictests.jl

Lines changed: 26 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using AllocCheck, LinearSolve, SimpleNonlinearSolve, StaticArrays, Random,
2-
LinearAlgebra, Test, ForwardDiff, DiffEqBase
2+
LinearAlgebra, XUnit, ForwardDiff, DiffEqBase
33
import PolyesterForwardDiff
44

55
_nameof(x) = applicable(nameof, x) ? nameof(x) : _nameof(typeof(x))
@@ -25,33 +25,29 @@ const TERMINATION_CONDITIONS = [
2525
AbsSafeTerminationMode(), RelSafeBestTerminationMode(), AbsSafeBestTerminationMode(),
2626
]
2727

28-
# --- SimpleNewtonRaphson tests ---
29-
30-
@testset "$(alg)" for alg in (SimpleNewtonRaphson, SimpleTrustRegion)
31-
# Eval else the alg is type unstable
32-
@eval begin
33-
function benchmark_nlsolve_oop(f, u0, p = 2.0; autodiff = nothing)
34-
prob = NonlinearProblem{false}(f, u0, p)
35-
return solve(prob, $(alg)(; autodiff), abstol = 1e-9)
36-
end
28+
function benchmark_nlsolve_oop(f::F, u0, p = 2.0; solver) where {F}
29+
prob = NonlinearProblem{false}(f, u0, p)
30+
return solve(prob, solver; abstol = 1e-9)
31+
end
32+
function benchmark_nlsolve_iip(f!::F, u0, p = 2.0; solver) where {F}
33+
prob = NonlinearProblem{true}(f!, u0, p)
34+
return solve(prob, solver; abstol = 1e-9)
35+
end
3736

38-
function benchmark_nlsolve_iip(f, u0, p = 2.0; autodiff = nothing)
39-
prob = NonlinearProblem{true}(f, u0, p)
40-
return solve(prob, $(alg)(; autodiff), abstol = 1e-9)
41-
end
42-
end
37+
# --- SimpleNewtonRaphson tests ---
4338

39+
@testcase "$(alg)" for alg in (SimpleNewtonRaphson, SimpleTrustRegion)
4440
@testset "AutoDiff: $(_nameof(autodiff))" for autodiff in (AutoFiniteDiff(),
4541
AutoForwardDiff(), AutoPolyesterForwardDiff())
4642
@testset "[OOP] u0: $(typeof(u0))" for u0 in ([1.0, 1.0], @SVector[1.0, 1.0], 1.0)
4743
u0 isa SVector && autodiff isa AutoPolyesterForwardDiff && continue
48-
sol = benchmark_nlsolve_oop(quadratic_f, u0; autodiff)
44+
sol = benchmark_nlsolve_oop(quadratic_f, u0; solver = alg(; autodiff))
4945
@test SciMLBase.successful_retcode(sol)
5046
@test all(abs.(sol.u .* sol.u .- 2) .< 1e-9)
5147
end
5248

5349
@testset "[IIP] u0: $(typeof(u0))" for u0 in ([1.0, 1.0],)
54-
sol = benchmark_nlsolve_iip(quadratic_f!, u0; autodiff)
50+
sol = benchmark_nlsolve_iip(quadratic_f!, u0; solver = alg(; autodiff))
5551
@test SciMLBase.successful_retcode(sol)
5652
@test all(abs.(sol.u .* sol.u .- 2) .< 1e-9)
5753
end
@@ -67,16 +63,11 @@ end
6763

6864
# --- SimpleHalley tests ---
6965

70-
@testset "SimpleHalley" begin
71-
function benchmark_nlsolve_oop(f, u0, p = 2.0; autodiff = nothing)
72-
prob = NonlinearProblem{false}(f, u0, p)
73-
return solve(prob, SimpleHalley(; autodiff), abstol = 1e-9)
74-
end
75-
66+
@testcase "SimpleHalley" begin
7667
@testset "AutoDiff: $(_nameof(autodiff))" for autodiff in (AutoFiniteDiff(),
7768
AutoForwardDiff())
7869
@testset "[OOP] u0: $(typeof(u0))" for u0 in ([1.0, 1.0], @SVector[1.0, 1.0], 1.0)
79-
sol = benchmark_nlsolve_oop(quadratic_f, u0; autodiff)
70+
sol = benchmark_nlsolve_oop(quadratic_f, u0; solver = SimpleHalley(; autodiff))
8071
@test SciMLBase.successful_retcode(sol)
8172
@test all(abs.(sol.u .* sol.u .- 2) .< 1e-9)
8273
end
@@ -92,27 +83,17 @@ end
9283

9384
# --- SimpleBroyden / SimpleKlement / SimpleLimitedMemoryBroyden tests ---
9485

95-
@testset "$(_nameof(alg))" for alg in [SimpleBroyden(), SimpleKlement(), SimpleDFSane(),
86+
@testcase "$(_nameof(alg))" for alg in [SimpleBroyden(), SimpleKlement(), SimpleDFSane(),
9687
SimpleLimitedMemoryBroyden(), SimpleBroyden(; linesearch = Val(true)),
9788
SimpleLimitedMemoryBroyden(; linesearch = Val(true))]
98-
function benchmark_nlsolve_oop(f, u0, p = 2.0)
99-
prob = NonlinearProblem{false}(f, u0, p)
100-
return solve(prob, alg, abstol = 1e-9)
101-
end
102-
103-
function benchmark_nlsolve_iip(f, u0, p = 2.0)
104-
prob = NonlinearProblem{true}(f, u0, p)
105-
return solve(prob, alg, abstol = 1e-9)
106-
end
107-
10889
@testset "[OOP] u0: $(typeof(u0))" for u0 in ([1.0, 1.0], @SVector[1.0, 1.0], 1.0)
109-
sol = benchmark_nlsolve_oop(quadratic_f, u0)
90+
sol = benchmark_nlsolve_oop(quadratic_f, u0; solver = alg)
11091
@test SciMLBase.successful_retcode(sol)
11192
@test all(abs.(sol.u .* sol.u .- 2) .< 1e-9)
11293
end
11394

11495
@testset "[IIP] u0: $(typeof(u0))" for u0 in ([1.0, 1.0],)
115-
sol = benchmark_nlsolve_iip(quadratic_f!, u0)
96+
sol = benchmark_nlsolve_iip(quadratic_f!, u0; solver = alg)
11697
@test SciMLBase.successful_retcode(sol)
11798
@test all(abs.(sol.u .* sol.u .- 2) .< 1e-9)
11899
end
@@ -126,16 +107,11 @@ end
126107
end
127108

128109
@testset "Newton Fails" begin
129-
function benchmark_nlsolve_oop(f, u0, p, alg)
130-
prob = NonlinearProblem{false}(f, u0, p)
131-
return solve(prob, alg; abstol = 1e-9)
132-
end
133-
134110
u0 = [-10.0, -1.0, 1.0, 2.0, 3.0, 4.0, 10.0]
135111
p = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
136112

137-
for alg in (SimpleDFSane(), SimpleTrustRegion(), SimpleHalley())
138-
sol = benchmark_nlsolve_oop(newton_fails, u0, p, alg)
113+
@testcase "$(alg)" for alg in (SimpleDFSane(), SimpleTrustRegion(), SimpleHalley())
114+
sol = benchmark_nlsolve_oop(newton_fails, u0, p; solver = alg)
139115
@test SciMLBase.successful_retcode(sol)
140116
@test all(abs.(newton_fails(sol.u, p)) .< 1e-9)
141117
end
@@ -144,7 +120,7 @@ end
144120
# --- Allocation Checks ---
145121

146122
## SimpleDFSane needs to allocate a history vector
147-
@testset "Allocation Checks: $(_nameof(alg))" for alg in (SimpleNewtonRaphson(),
123+
@testcase "Allocation Checks: $(_nameof(alg))" for alg in (SimpleNewtonRaphson(),
148124
SimpleHalley(), SimpleBroyden(), SimpleKlement(), SimpleLimitedMemoryBroyden(),
149125
SimpleTrustRegion(), SimpleDFSane(), SimpleBroyden(; linesearch = Val(true)),
150126
SimpleLimitedMemoryBroyden(; linesearch = Val(true)))
@@ -173,7 +149,7 @@ end
173149

174150
# --- Interval Nonlinear Problems ---
175151

176-
@testset "Interval Nonlinear Problem: $(alg)" for alg in (Bisection(), Falsi(), Ridder(),
152+
@testcase "Interval Nonlinear Problem: $(alg)" for alg in (Bisection(), Falsi(), Ridder(),
177153
Brent(), ITP(), Alefeld())
178154
tspan = (1.0, 20.0)
179155

@@ -215,7 +191,8 @@ end
215191
end
216192
end
217193

218-
@testset "Tolerance Tests Interval Methods: $(alg)" for alg in (Bisection(), Falsi(), ITP())
194+
@testcase "Tolerance Tests Interval Methods: $(alg)" for alg in (Bisection(), Falsi(),
195+
ITP())
219196
tspan = (1.0, 20.0)
220197
probB = IntervalNonlinearProblem(quadratic_f, tspan, 2.0)
221198
tols = [0.1, 0.01, 0.001, 0.0001, 1e-5, 1e-6, 1e-7]
@@ -228,7 +205,7 @@ end
228205
end
229206
end
230207

231-
@testset "Tolerance Tests Interval Methods: $(alg)" for alg in (Ridder(), Brent())
208+
@testcase "Tolerance Tests Interval Methods: $(alg)" for alg in (Ridder(), Brent())
232209
tspan = (1.0, 20.0)
233210
probB = IntervalNonlinearProblem(quadratic_f, tspan, 2.0)
234211
tols = [0.1] # Ridder and Brent converge rapidly so as we lower tolerance below 0.01, it converges with max precision to the solution
@@ -241,7 +218,7 @@ end
241218
end
242219
end
243220

244-
@testset "Flipped Signs and Reversed Tspan: $(alg)" for alg in (Alefeld(), Bisection(),
221+
@testcase "Flipped Signs and Reversed Tspan: $(alg)" for alg in (Alefeld(), Bisection(),
245222
Falsi(), Brent(), ITP(), Ridder())
246223
f1(u, p) = u * u - p
247224
f2(u, p) = p - u * u

test/cuda.jl

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
using SimpleNonlinearSolve, StaticArrays, CUDA, Test
1+
using SimpleNonlinearSolve, StaticArrays, CUDA, XUnit
22

33
CUDA.allowscalar(false)
44

55
f(u, p) = u .* u .- 2
66
f!(du, u, p) = du .= u .* u .- 2
77

88
@testset "Solving on GPUs" begin
9-
for alg in (SimpleNewtonRaphson(), SimpleDFSane(), SimpleTrustRegion(), SimpleBroyden(),
10-
SimpleLimitedMemoryBroyden(), SimpleKlement(), SimpleHalley(),
11-
SimpleBroyden(; linesearch = Val(true)),
9+
@testcase "$(alg)" for alg in (SimpleNewtonRaphson(), SimpleDFSane(),
10+
SimpleTrustRegion(), SimpleBroyden(), SimpleLimitedMemoryBroyden(), SimpleKlement(),
11+
SimpleHalley(), SimpleBroyden(; linesearch = Val(true)),
1212
SimpleLimitedMemoryBroyden(; linesearch = Val(true)))
13-
@info "Testing $alg on CUDA"
14-
1513
# Static Arrays
1614
u0 = @SVector[1.0f0, 1.0f0]
1715
probN = NonlinearProblem{false}(f, u0)
@@ -27,12 +25,13 @@ f!(du, u, p) = du .= u .* u .- 2
2725
@test maximum(abs, sol.resid) 1.0f-6
2826

2927
# Regular Arrays Inplace
30-
alg isa SimpleHalley && continue
31-
u0 = [1.0, 1.0]
32-
probN = NonlinearProblem{true}(f!, u0)
33-
sol = solve(probN, alg; abstol = 1.0f-6)
34-
@test SciMLBase.successful_retcode(sol)
35-
@test maximum(abs, sol.resid) 1.0f-6
28+
if !(alg isa SimpleHalley)
29+
u0 = [1.0, 1.0]
30+
probN = NonlinearProblem{true}(f!, u0)
31+
sol = solve(probN, alg; abstol = 1.0f-6)
32+
@test SciMLBase.successful_retcode(sol)
33+
@test maximum(abs, sol.resid) 1.0f-6
34+
end
3635
end
3736
end
3837

@@ -44,7 +43,8 @@ end
4443
@testset "CUDA Kernel Launch Test" begin
4544
prob = NonlinearProblem{false}(f, @SVector[1.0f0, 1.0f0])
4645

47-
for alg in (SimpleNewtonRaphson(), SimpleDFSane(), SimpleTrustRegion(), SimpleBroyden(),
46+
@testcase "$(alg)" for alg in (SimpleNewtonRaphson(), SimpleDFSane(),
47+
SimpleTrustRegion(), SimpleBroyden(),
4848
SimpleLimitedMemoryBroyden(), SimpleKlement(), SimpleHalley(),
4949
SimpleBroyden(; linesearch = Val(true)),
5050
SimpleLimitedMemoryBroyden(; linesearch = Val(true)))

test/cuda/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
33
SimpleNonlinearSolve = "727e6d20-b764-4bd8-a329-72de5adea6c7"
44
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
55
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
6+
XUnit = "3e3c03f2-1a94-11e9-2981-050a4ca824ab"

test/forward_ad.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using ForwardDiff, SimpleNonlinearSolve, StaticArrays, Test, LinearAlgebra
1+
using ForwardDiff, SimpleNonlinearSolve, StaticArrays, XUnit, LinearAlgebra
22
import SimpleNonlinearSolve: AbstractSimpleNonlinearSolveAlgorithm
33

44
test_f!(du, u, p) = (@. du = u^2 - p)
@@ -35,7 +35,7 @@ __compatible(::AbstractSimpleNonlinearSolveAlgorithm, ::Val{:iip}) = true
3535
__compatible(::AbstractSimpleNonlinearSolveAlgorithm, ::Val{:oop}) = true
3636
__compatible(::SimpleHalley, ::Val{:iip}) = false
3737

38-
@testset "ForwardDiff.jl Integration: $(alg)" for alg in (SimpleNewtonRaphson(),
38+
@testcase "ForwardDiff.jl Integration: $(alg)" for alg in (SimpleNewtonRaphson(),
3939
SimpleTrustRegion(), SimpleHalley(), SimpleBroyden(), SimpleKlement(), SimpleDFSane())
4040
us = (2.0, @SVector[1.0, 1.0], [1.0, 1.0], ones(2, 2), @SArray ones(2, 2))
4141

test/least_squares.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using SimpleNonlinearSolve, LinearAlgebra, Test
1+
using SimpleNonlinearSolve, LinearAlgebra, XUnit
22

33
true_function(x, θ) = @. θ[1] * exp(θ[2] * x) * cos(θ[3] * x + θ[4])
44

@@ -14,7 +14,8 @@ end
1414
θ_init = θ_true .+ 0.1
1515
prob_oop = NonlinearLeastSquaresProblem{false}(loss_function, θ_init, x)
1616

17-
for solver in [SimpleNewtonRaphson(AutoForwardDiff()), SimpleGaussNewton(AutoForwardDiff()),
17+
@testcase "Solver: $(solver)" for solver in [SimpleNewtonRaphson(AutoForwardDiff()),
18+
SimpleGaussNewton(AutoForwardDiff()),
1819
SimpleNewtonRaphson(AutoFiniteDiff()), SimpleGaussNewton(AutoFiniteDiff())]
1920
sol = solve(prob_oop, solver)
2021
@test norm(sol.resid) < 1e-12

test/matrix_resizing_tests.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
using SimpleNonlinearSolve
1+
using SimpleNonlinearSolve, XUnit
22

33
ff(u, p) = u .* u .- p
44
u0 = ones(2, 3)
55
p = 2.0
66
vecprob = NonlinearProblem(ff, vec(u0), p)
77
prob = NonlinearProblem(ff, u0, p)
88

9-
@testset "$(alg)" for alg in (SimpleKlement(), SimpleBroyden(), SimpleNewtonRaphson(),
9+
@testcase "$(alg)" for alg in (SimpleKlement(), SimpleBroyden(), SimpleNewtonRaphson(),
1010
SimpleDFSane(), SimpleLimitedMemoryBroyden(; threshold = Val(2)), SimpleTrustRegion())
1111
@test vec(solve(prob, alg).u) solve(vecprob, alg).u
1212
end

0 commit comments

Comments
 (0)