@@ -129,8 +129,6 @@ struct _VectorNonlinearOracle <: MOI.AbstractVectorSet
129
129
eval_jacobian:: Function
130
130
hessian_lagrangian_structure:: Vector{Tuple{Int,Int}}
131
131
eval_hessian_lagrangian:: Union{Nothing,Function}
132
- # Temporary storage
133
- x:: Vector{Float64}
134
132
135
133
function _VectorNonlinearOracle (;
136
134
dimension:: Int ,
@@ -154,8 +152,6 @@ struct _VectorNonlinearOracle <: MOI.AbstractVectorSet
154
152
eval_jacobian,
155
153
hessian_lagrangian_structure,
156
154
eval_hessian_lagrangian,
157
- # Temporary storage
158
- zeros (dimension),
159
155
)
160
156
end
161
157
end
@@ -174,6 +170,18 @@ function Base.show(io::IO, s::_VectorNonlinearOracle)
174
170
return
175
171
end
176
172
173
+ mutable struct _VectorNonlinearOracleCache
174
+ set:: _VectorNonlinearOracle
175
+ x:: Vector{Float64}
176
+ eval_f_timer:: Float64
177
+ eval_jacobian_timer:: Float64
178
+ eval_hessian_lagrangian_timer:: Float64
179
+
180
+ function _VectorNonlinearOracleCache (set:: _VectorNonlinearOracle )
181
+ return new (set, zeros (set. input_dimension), 0.0 , 0.0 , 0.0 )
182
+ end
183
+ end
184
+
177
185
"""
178
186
Optimizer()
179
187
@@ -202,7 +210,7 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
202
210
barrier_iterations:: Int
203
211
ad_backend:: MOI.Nonlinear.AbstractAutomaticDifferentiation
204
212
vector_nonlinear_oracle_constraints:: Vector {
205
- Tuple{MOI. VectorOfVariables,_VectorNonlinearOracle },
213
+ Tuple{MOI. VectorOfVariables,_VectorNonlinearOracleCache },
206
214
}
207
215
208
216
function Optimizer ()
@@ -228,7 +236,7 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
228
236
nothing ,
229
237
0 ,
230
238
MOI. Nonlinear. SparseReverseMode (),
231
- Tuple{MOI. VectorOfVariables,_VectorNonlinearOracle }[],
239
+ Tuple{MOI. VectorOfVariables,_VectorNonlinearOracleCache }[],
232
240
)
233
241
end
234
242
end
@@ -847,7 +855,8 @@ function MOI.add_constraint(
847
855
s:: S ,
848
856
) where {F<: MOI.VectorOfVariables ,S<: _VectorNonlinearOracle }
849
857
model. inner = nothing
850
- push! (model. vector_nonlinear_oracle_constraints, (f, s))
858
+ cache = _VectorNonlinearOracleCache (s)
859
+ push! (model. vector_nonlinear_oracle_constraints, (f, cache))
851
860
n = length (model. vector_nonlinear_oracle_constraints)
852
861
return MOI. ConstraintIndex {F,S} (n)
853
862
end
@@ -859,10 +868,10 @@ function row(
859
868
offset = length (model. qp_data)
860
869
for i in 1 : (ci. value- 1 )
861
870
_, s = model. vector_nonlinear_oracle_constraints[i]
862
- offset += s. output_dimension
871
+ offset += s. set . output_dimension
863
872
end
864
873
_, s = model. vector_nonlinear_oracle_constraints[ci. value]
865
- return offset .+ (1 : s. output_dimension)
874
+ return offset .+ (1 : s. set . output_dimension)
866
875
end
867
876
868
877
function MOI. get (
@@ -890,7 +899,7 @@ function MOI.get(
890
899
_jacobian_structure (J, 0 , f, s)
891
900
J_val = zeros (length (J))
892
901
_eval_constraint_jacobian (J_val, 0 , model. inner. x, f, s)
893
- dual = zeros (MOI. dimension (s))
902
+ dual = zeros (MOI. dimension (s. set ))
894
903
# dual = λ' * J(x)
895
904
col_to_index = Dict (x. value => j for (j, x) in enumerate (f. variables))
896
905
for ((row, col), J_rc) in zip (J, J_val)
@@ -1184,14 +1193,14 @@ function _eval_constraint(
1184
1193
offset:: Int ,
1185
1194
x:: AbstractVector ,
1186
1195
f:: MOI.VectorOfVariables ,
1187
- s:: _VectorNonlinearOracle ,
1196
+ s:: _VectorNonlinearOracleCache ,
1188
1197
)
1189
- for i in 1 : s. input_dimension
1198
+ for i in 1 : s. set . input_dimension
1190
1199
s. x[i] = x[f. variables[i]. value]
1191
1200
end
1192
- ret = view (g, offset .+ (1 : s. output_dimension))
1193
- s. eval_f (ret, s. x)
1194
- return offset + s. output_dimension
1201
+ ret = view (g, offset .+ (1 : s. set . output_dimension))
1202
+ s. eval_f_timer += @elapsed s . set . eval_f (ret, s. x)
1203
+ return offset + s. set . output_dimension
1195
1204
end
1196
1205
1197
1206
function MOI. eval_constraint (model:: Optimizer , g, x)
@@ -1211,12 +1220,12 @@ function _jacobian_structure(
1211
1220
ret:: AbstractVector ,
1212
1221
row_offset:: Int ,
1213
1222
f:: MOI.VectorOfVariables ,
1214
- s:: _VectorNonlinearOracle ,
1223
+ s:: _VectorNonlinearOracleCache ,
1215
1224
)
1216
- for (i, j) in s. jacobian_structure
1225
+ for (i, j) in s. set . jacobian_structure
1217
1226
push! (ret, (row_offset + i, f. variables[j]. value))
1218
1227
end
1219
- return row_offset + s. output_dimension
1228
+ return row_offset + s. set . output_dimension
1220
1229
end
1221
1230
1222
1231
function MOI. jacobian_structure (model:: Optimizer )
@@ -1241,13 +1250,14 @@ function _eval_constraint_jacobian(
1241
1250
offset:: Int ,
1242
1251
x:: AbstractVector ,
1243
1252
f:: MOI.VectorOfVariables ,
1244
- s:: _VectorNonlinearOracle ,
1253
+ s:: _VectorNonlinearOracleCache ,
1245
1254
)
1246
- for i in 1 : s. input_dimension
1255
+ for i in 1 : s. set . input_dimension
1247
1256
s. x[i] = x[f. variables[i]. value]
1248
1257
end
1249
- nnz = length (s. jacobian_structure)
1250
- s. eval_jacobian (view (values, offset .+ (1 : nnz)), s. x)
1258
+ nnz = length (s. set. jacobian_structure)
1259
+ s. eval_jacobian_timer +=
1260
+ @elapsed s. set. eval_jacobian (view (values, offset .+ (1 : nnz)), s. x)
1251
1261
return offset + nnz
1252
1262
end
1253
1263
@@ -1267,9 +1277,9 @@ end
1267
1277
function _hessian_lagrangian_structure (
1268
1278
ret:: AbstractVector ,
1269
1279
f:: MOI.VectorOfVariables ,
1270
- s:: _VectorNonlinearOracle ,
1280
+ s:: _VectorNonlinearOracleCache ,
1271
1281
)
1272
- for (i, j) in s. hessian_lagrangian_structure
1282
+ for (i, j) in s. set . hessian_lagrangian_structure
1273
1283
push! (ret, (f. variables[i]. value, f. variables[j]. value))
1274
1284
end
1275
1285
return
@@ -1291,16 +1301,17 @@ function _eval_hessian_lagrangian(
1291
1301
μ:: AbstractVector ,
1292
1302
μ_offset:: Int ,
1293
1303
f:: MOI.VectorOfVariables ,
1294
- s:: _VectorNonlinearOracle ,
1304
+ s:: _VectorNonlinearOracleCache ,
1295
1305
)
1296
- for i in 1 : s. input_dimension
1306
+ for i in 1 : s. set . input_dimension
1297
1307
s. x[i] = x[f. variables[i]. value]
1298
1308
end
1299
- H_nnz = length (s. hessian_lagrangian_structure)
1309
+ H_nnz = length (s. set . hessian_lagrangian_structure)
1300
1310
H_view = view (H, H_offset .+ (1 : H_nnz))
1301
- μ_view = view (μ, μ_offset .+ (1 : s. output_dimension))
1302
- s. eval_hessian_lagrangian (H_view, s. x, μ_view)
1303
- return H_offset + H_nnz, μ_offset + s. output_dimension
1311
+ μ_view = view (μ, μ_offset .+ (1 : s. set. output_dimension))
1312
+ s. eval_hessian_lagrangian_timer +=
1313
+ @elapsed s. set. eval_hessian_lagrangian (H_view, s. x, μ_view)
1314
+ return H_offset + H_nnz, μ_offset + s. set. output_dimension
1304
1315
end
1305
1316
1306
1317
function MOI. eval_hessian_lagrangian (model:: Optimizer , H, x, σ, μ)
@@ -1359,7 +1370,7 @@ function _setup_model(model::Optimizer)
1359
1370
! isempty (model. vector_nonlinear_oracle_constraints)
1360
1371
has_hessian = :Hess in MOI. features_available (model. nlp_data. evaluator)
1361
1372
for (_, s) in model. vector_nonlinear_oracle_constraints
1362
- if s. eval_hessian_lagrangian === nothing
1373
+ if s. set . eval_hessian_lagrangian === nothing
1363
1374
has_hessian = false
1364
1375
break
1365
1376
end
@@ -1403,8 +1414,8 @@ function _setup_model(model::Optimizer)
1403
1414
end
1404
1415
g_L, g_U = copy (model. qp_data. g_L), copy (model. qp_data. g_U)
1405
1416
for (_, s) in model. vector_nonlinear_oracle_constraints
1406
- append! (g_L, s. l)
1407
- append! (g_U, s. u)
1417
+ append! (g_L, s. set . l)
1418
+ append! (g_U, s. set . u)
1408
1419
end
1409
1420
for bound in model. nlp_data. constraint_bounds
1410
1421
push! (g_L, bound. lower)
@@ -1532,6 +1543,12 @@ function MOI.optimize!(model::Optimizer)
1532
1543
end
1533
1544
return true
1534
1545
end
1546
+ # Clear timers
1547
+ for (_, s) in model. vector_nonlinear_oracle_constraints
1548
+ s. eval_f_timer = 0.0
1549
+ s. eval_jacobian_timer = 0.0
1550
+ s. eval_hessian_lagrangian_timer = 0.0
1551
+ end
1535
1552
Ipopt. SetIntermediateCallback (inner, _moi_callback)
1536
1553
Ipopt. IpoptSolve (inner)
1537
1554
model. solve_time = time () - start_time
@@ -1696,7 +1713,7 @@ function row(
1696
1713
)
1697
1714
offset = length (model. qp_data)
1698
1715
for (_, s) in model. vector_nonlinear_oracle_constraints
1699
- offset += s. output_dimension
1716
+ offset += s. set . output_dimension
1700
1717
end
1701
1718
return offset + ci. value
1702
1719
end
0 commit comments