Skip to content

Commit fe81bae

Browse files
authored
[Nonlinear] throw error if Hessian storage is insufficient (#2441)
1 parent 2ea481b commit fe81bae

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

src/Nonlinear/ReverseAD/forward_over_reverse.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ function _eval_hessian_inner(
106106
@inbounds input_ϵ[idx] = zero(T)
107107
end
108108
end
109+
want, got = nzcount + length(ex.hess_I), length(H)
110+
if want > got
111+
error(
112+
"Vector provided for Hessian storage has too few elements. Got " *
113+
"$got, want $want.",
114+
)
115+
end
109116
# TODO(odow): consider reverting to a view.
110117
output_slice = _UnsafeVectorView(nzcount, length(ex.hess_I), pointer(H))
111118
Coloring.recover_from_matmat!(

test/Nonlinear/ReverseAD.jl

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,35 @@ function test_constraint_gradient()
10511051
return
10521052
end
10531053

1054+
function test_hessian_length()
1055+
x = MOI.VariableIndex(1)
1056+
model = Nonlinear.Model()
1057+
Nonlinear.set_objective(model, :(log($x)))
1058+
evaluator = Nonlinear.Evaluator(model, Nonlinear.SparseReverseMode(), [x])
1059+
MOI.initialize(evaluator, [:Hess])
1060+
H = Float64[]
1061+
got, want = 0, 1
1062+
@test_throws(
1063+
ErrorException(
1064+
"Vector provided for Hessian storage has too few elements. Got " *
1065+
"$got, want $want.",
1066+
),
1067+
MOI.eval_hessian_lagrangian(evaluator, H, [1.0], 1.0, [1.0]),
1068+
)
1069+
return
1070+
end
1071+
1072+
function test_jacobian_length()
1073+
x = MOI.VariableIndex(1)
1074+
model = Nonlinear.Model()
1075+
Nonlinear.add_constraint(model, :(sin($x)), MOI.LessThan(0.5))
1076+
evaluator = Nonlinear.Evaluator(model, Nonlinear.SparseReverseMode(), [x])
1077+
MOI.initialize(evaluator, [:Jac])
1078+
J = Float64[]
1079+
@test_throws BoundsError MOI.eval_constraint_jacobian(evaluator, J, [1.0])
1080+
return
1081+
end
1082+
10541083
function test_timers()
10551084
x = MOI.VariableIndex(1)
10561085
model = Nonlinear.Model()
@@ -1064,10 +1093,14 @@ function test_timers()
10641093
MOI.eval_constraint(evaluator, g, y)
10651094
MOI.eval_objective_gradient(evaluator, g, y)
10661095
MOI.eval_constraint_gradient(evaluator, g, y, 1)
1067-
MOI.eval_constraint_jacobian(evaluator, g, y)
1068-
MOI.eval_hessian_objective(evaluator, g, y)
1069-
MOI.eval_hessian_constraint(evaluator, g, y, 1)
1070-
MOI.eval_hessian_lagrangian(evaluator, g, y, 1.0, [1.0])
1096+
J = zeros(length(MOI.jacobian_structure(evaluator)))
1097+
MOI.eval_constraint_jacobian(evaluator, J, y)
1098+
H = zeros(length(MOI.hessian_objective_structure(evaluator)))
1099+
MOI.eval_hessian_objective(evaluator, H, y)
1100+
H = zeros(length(MOI.hessian_constraint_structure(evaluator, 1)))
1101+
MOI.eval_hessian_constraint(evaluator, H, y, 1)
1102+
H = zeros(length(MOI.hessian_lagrangian_structure(evaluator)))
1103+
MOI.eval_hessian_lagrangian(evaluator, H, y, 1.0, [1.0])
10711104
timers = [
10721105
evaluator.initialize_timer,
10731106
evaluator.eval_objective_timer,

0 commit comments

Comments
 (0)