Skip to content

Commit db324ed

Browse files
committed
Add CuVector tests for linesearch
1 parent 4053e46 commit db324ed

File tree

1 file changed

+163
-109
lines changed

1 file changed

+163
-109
lines changed

test/test_linesearch.jl

Lines changed: 163 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,190 @@
1+
function test_line_model(::Type{S}) where {S}
2+
nlp = BROWNDEN(S)
3+
n = nlp.meta.nvar
4+
x = nlp.meta.x0
5+
d = fill!(S(undef, n), -1)
6+
lm = LineModel(nlp, x, d)
7+
g = fill!(S(undef, n), 0)
8+
9+
T = eltype(S)
10+
@test obj(lm, zero(T)) == obj(nlp, x)
11+
@test grad(lm, zero(T)) == dot(grad(nlp, x), d)
12+
@test grad!(lm, zero(T), g) == dot(grad(nlp, x), d)
13+
@test g == grad(nlp, x)
14+
@test derivative(lm, zero(T)) == dot(grad(nlp, x), d)
15+
@test derivative!(lm, zero(T), g) == dot(grad(nlp, x), d)
16+
@test g == grad(nlp, x)
17+
@test objgrad!(lm, one(T), g) == (obj(nlp, x + d), dot(grad(nlp, x + d), d))
18+
@test g == grad(nlp, x + d)
19+
@test objgrad(lm, zero(T)) == (obj(nlp, x), dot(grad(nlp, x), d))
20+
@test hess(lm, zero(T)) dot(d, hess(nlp, x) * d)
21+
@test hess!(lm, zero(T), g) == dot(d, hprod!(nlp, x, d, g))
22+
23+
@test obj(lm, one(T)) == obj(nlp, x + d)
24+
@test grad(lm, one(T)) == dot(grad(nlp, x + d), d)
25+
@test hess(lm, one(T)) dot(d, hess(nlp, x + d) * d)
26+
27+
@test neval_obj(lm) == 4
28+
@test neval_grad(lm) == 7
29+
@test neval_hess(lm) == 3
30+
end
31+
32+
function test_armijo_wolfe(::Type{S}) where {S}
33+
T = eltype(S)
34+
x0 = fill!(S(undef, 2), 1)
35+
nlp = ADNLPModel(x -> x[1]^2 + 4 * x[2]^2, x0, matrix_free = true)
36+
d = fill!(S(undef, 2), -1)
37+
lm = LineModel(nlp, nlp.meta.x0, d)
38+
g = fill!(S(undef, 2), 0)
39+
40+
t0 = zero(T)
41+
t, good_grad, ft, nbk, nbW = armijo_wolfe(lm, obj(lm, t0), grad(lm, t0), g)
42+
@test t == 1
43+
@test ft == 0
44+
@test nbk == 0
45+
@test nbW == 0
46+
47+
redirect!(lm, nlp.meta.x0, fill!(S(undef, 2), -1 // 2))
48+
t, good_grad, ft, nbk, nbW = armijo_wolfe(lm, obj(lm, t0), grad(lm, t0), g)
49+
@test t == 1
50+
@test ft == 1.25
51+
@test nbk == 0
52+
@test nbW == 0
53+
54+
redirect!(lm, nlp.meta.x0, fill!(S(undef, 2), -2))
55+
t, good_grad, ft, nbk, nbW = armijo_wolfe(lm, obj(lm, t0), grad(lm, t0), g)
56+
@test t < 1
57+
@test nbk > 0
58+
@test nbW == 0
59+
60+
nlp = ADNLPModel(x -> (x[1] - 1)^2 + 4 * (x[2] - x[1]^2)^2, fill!(S(undef, 2), 0), matrix_free = true)
61+
d = S([1.7; 3.2])
62+
lm = LineModel(nlp, nlp.meta.x0, d)
63+
t, good_grad, ft, nbk, nbW = armijo_wolfe(lm, obj(lm, t0), grad(lm, t0), g)
64+
@test t < 1
65+
@test nbk > 0
66+
@test nbW > 0
67+
end
68+
69+
function test_armijo_goldstein(::Type{S}) where {S}
70+
T = eltype(S)
71+
nlp = ADNLPModel(x -> x[1]^2 + 4 * x[2]^2, fill!(S(undef, 2), 1))
72+
lm = LineModel(nlp, nlp.meta.x0, fill!(S(undef, 2), -1))
73+
74+
t0 = zero(T)
75+
t, ft, nbk, nbG = armijo_goldstein(lm, obj(lm, t0), grad(lm, t0))
76+
@test t == 1
77+
@test ft == zero(T)
78+
@test nbk == 0
79+
@test nbG == 0
80+
81+
redirect!(lm, nlp.meta.x0, fill!(S(undef, 2), -1 // 2))
82+
t, ft, nbk, nbG = armijo_goldstein(lm, obj(lm, t0), grad(lm, t0))
83+
@test t == 1
84+
@test ft == 1.25
85+
@test nbk == 0
86+
@test nbG == 0
87+
88+
redirect!(lm, nlp.meta.x0, fill!(S(undef, 2), -2))
89+
t, ft, nbk, nbG = armijo_goldstein(lm, obj(lm, t0), grad(lm, t0))
90+
@test t < 1
91+
@test nbk > 0
92+
@test nbG == 0
93+
end
94+
95+
function test_armijo_goldstein2(::Type{S}) where {S}
96+
T = eltype(S)
97+
nlp = ADNLPModel(x -> (x[1] - 1)^2 + 4 * (x[2] - x[1]^2)^2, fill!(S(undef, 2), 0))
98+
lm = LineModel(nlp, nlp.meta.x0, S([1.7; 3.2]))
99+
100+
t0 = zero(T)
101+
t, ft, nbk, nbG =
102+
armijo_goldstein(lm, obj(lm, t0), grad(lm, t0); t = T(1), τ₀ = T(0.1), τ₁ = T(0.2))
103+
@test t < one(T)
104+
@test nbk == 4
105+
@test nbG == 10
106+
107+
t, ft, nbk, nbG = armijo_goldstein(
108+
lm,
109+
obj(lm, t0),
110+
grad(lm, t0);
111+
t = T(0.001),
112+
τ₀ = T(0.1),
113+
τ₁ = T(0.2),
114+
)
115+
@test t < 1.0
116+
@test nbk == 2
117+
@test nbG == 10
118+
end
119+
1120
@testset "Linesearch" begin
2121
@testset "LineModel" begin
3-
nlp = BROWNDEN()
4-
n = nlp.meta.nvar
5-
x = nlp.meta.x0
6-
d = -ones(n)
7-
lm = LineModel(nlp, x, d)
8-
g = zeros(n)
9-
10-
@test obj(lm, 0.0) == obj(nlp, x)
11-
@test grad(lm, 0.0) == dot(grad(nlp, x), d)
12-
@test grad!(lm, 0.0, g) == dot(grad(nlp, x), d)
13-
@test g == grad(nlp, x)
14-
@test derivative(lm, 0.0) == dot(grad(nlp, x), d)
15-
@test derivative!(lm, 0.0, g) == dot(grad(nlp, x), d)
16-
@test g == grad(nlp, x)
17-
@test objgrad!(lm, 1.0, g) == (obj(nlp, x + d), dot(grad(nlp, x + d), d))
18-
@test g == grad(nlp, x + d)
19-
@test objgrad(lm, 0.0) == (obj(nlp, x), dot(grad(nlp, x), d))
20-
@test hess(lm, 0.0) dot(d, hess(nlp, x) * d)
21-
@test hess!(lm, 0.0, g) == dot(d, hprod!(nlp, x, d, g))
22-
23-
@test obj(lm, 1.0) == obj(nlp, x + d)
24-
@test grad(lm, 1.0) == dot(grad(nlp, x + d), d)
25-
@test hess(lm, 1.0) dot(d, hess(nlp, x + d) * d)
26-
27-
@test neval_obj(lm) == 4
28-
@test neval_grad(lm) == 7
29-
@test neval_hess(lm) == 3
122+
test_line_model(Vector{Float64})
123+
end
124+
125+
if CUDA.functional()
126+
@testset "LineModel with CuArray" begin
127+
CUDA.allowscalar() do
128+
test_line_model(CuVector{Float64})
129+
end
130+
end
30131
end
31132

32133
@testset "Armijo-Wolfe" begin
33-
nlp = ADNLPModel(x -> x[1]^2 + 4 * x[2]^2, ones(2))
34-
lm = LineModel(nlp, nlp.meta.x0, -ones(2))
35-
g = zeros(2)
36-
37-
t, good_grad, ft, nbk, nbW = armijo_wolfe(lm, obj(lm, 0.0), grad(lm, 0.0), g)
38-
@test t == 1
39-
@test ft == 0.0
40-
@test nbk == 0
41-
@test nbW == 0
42-
43-
redirect!(lm, nlp.meta.x0, -ones(2) / 2)
44-
t, good_grad, ft, nbk, nbW = armijo_wolfe(lm, obj(lm, 0.0), grad(lm, 0.0), g)
45-
@test t == 1
46-
@test ft == 1.25
47-
@test nbk == 0
48-
@test nbW == 0
49-
50-
redirect!(lm, nlp.meta.x0, -2 * ones(2))
51-
t, good_grad, ft, nbk, nbW = armijo_wolfe(lm, obj(lm, 0.0), grad(lm, 0.0), g)
52-
@test t < 1
53-
@test nbk > 0
54-
@test nbW == 0
55-
56-
nlp = ADNLPModel(x -> (x[1] - 1)^2 + 4 * (x[2] - x[1]^2)^2, zeros(2))
57-
lm = LineModel(nlp, nlp.meta.x0, [1.7; 3.2])
58-
t, good_grad, ft, nbk, nbW = armijo_wolfe(lm, obj(lm, 0.0), grad(lm, 0.0), g)
59-
@test t < 1
60-
@test nbk > 0
61-
@test nbW > 0
134+
test_armijo_wolfe(Vector{Float64})
135+
end
136+
137+
if CUDA.functional()
138+
@testset "Armijo-Wolfe with CuArray" begin
139+
CUDA.allowscalar() do
140+
test_armijo_wolfe(CuVector{Float64})
141+
end
142+
end
62143
end
63144

64145
@testset "Armijo-Goldstein" begin
65-
nlp = ADNLPModel(x -> x[1]^2 + 4 * x[2]^2, ones(2))
66-
lm = LineModel(nlp, nlp.meta.x0, -ones(2))
67-
68-
T = Float64
69-
t, ft, nbk, nbG = armijo_goldstein(lm, obj(lm, 0.0), grad(lm, 0.0))
70-
@test t == 1
71-
@test ft == zero(T)
72-
@test nbk == 0
73-
@test nbG == 0
74-
75-
redirect!(lm, nlp.meta.x0, -ones(2) / 2)
76-
t, ft, nbk, nbG = armijo_goldstein(lm, obj(lm, 0.0), grad(lm, 0.0))
77-
@test t == 1
78-
@test ft == 1.25
79-
@test nbk == 0
80-
@test nbG == 0
81-
82-
redirect!(lm, nlp.meta.x0, -2 * ones(2))
83-
t, ft, nbk, nbG = armijo_goldstein(lm, obj(lm, 0.0), grad(lm, 0.0))
84-
@test t < 1
85-
@test nbk > 0
86-
@test nbG == 0
87-
88-
T = Float32
89-
90-
nlp = ADNLPModel(x -> (x[1] - 1)^2 + 4 * (x[2] - x[1]^2)^2, zeros(T, 2))
91-
lm = LineModel(nlp, nlp.meta.x0, T.([1.7; 3.2]))
92-
t, ft, nbk, nbG =
93-
armijo_goldstein(lm, obj(lm, T(0)), grad(lm, T(0)); t = T(1), τ₀ = T(0.1), τ₁ = T(0.2))
94-
@test t < one(T)
95-
@test nbk == 4
96-
@test nbG == 10
97-
98-
t, ft, nbk, nbG = armijo_goldstein(
99-
lm,
100-
obj(lm, T(0.0)),
101-
grad(lm, T(0.0));
102-
t = T(0.001),
103-
τ₀ = T(0.1),
104-
τ₁ = T(0.2),
105-
)
106-
@test t < 1.0
107-
@test nbk == 2
108-
@test nbG == 10
146+
@testset "Armijo-Goldstein Float64" begin
147+
test_armijo_goldstein(Vector{Float64})
148+
end
149+
150+
@testset "Armijo-Goldstein Float32" begin
151+
test_armijo_goldstein2(Vector{Float32})
152+
end
153+
154+
if CUDA.functional()
155+
@testset "Armijo-Goldstein with CuArray" begin
156+
CUDA.allowscalar() do
157+
test_armijo_goldstein(CuVector{Float64})
158+
end
159+
end
160+
end
109161
end
110162

111163
if VERSION v"1.6"
112164
@testset "Don't allocate" begin
113-
nlp = BROWNDEN()
165+
S = Vector{Float64}
166+
T = eltype(S)
167+
nlp = BROWNDEN(S)
114168
n = nlp.meta.nvar
115169
x = nlp.meta.x0
116-
g = zeros(n)
117-
d = -40 * ones(n)
170+
g = fill!(S(undef, n), 0)
171+
d = fill!(S(undef, n), -40)
118172
lm = LineModel(nlp, x, d)
119173

120-
al = @wrappedallocs obj(lm, 1.0)
174+
al = @wrappedallocs obj(lm, one(T))
121175
@test al == 0
122176

123-
al = @wrappedallocs grad!(lm, 1.0, g)
177+
al = @wrappedallocs grad!(lm, one(T), g)
124178
@test al == 0
125179

126-
al = @wrappedallocs objgrad!(lm, 1.0, g)
180+
al = @wrappedallocs objgrad!(lm, one(T), g)
127181
@test al == 0
128182

129-
al = @wrappedallocs hess!(lm, 1.0, g)
183+
al = @wrappedallocs hess!(lm, one(T), g)
130184
@test al == 0
131185

132-
h₀ = obj(lm, 0.0)
133-
slope = grad(lm, 0.0)
186+
h₀ = obj(lm, zero(T))
187+
slope = grad(lm, zero(T))
134188

135189
# armijo-wolfe
136190
(t, gg, ht, nbk, nbW) = armijo_wolfe(lm, h₀, slope, g)

0 commit comments

Comments
 (0)