1
- import MathOptInterface as MOI
2
- include (" Type_wrappers.jl" )
3
-
4
1
const PARAM_SPLITTER = " __"
5
2
const PARAM_FIELD_NAME_TO_INSTANCE_DICT = Dict (
6
3
" gscip" => GScipParameters (),
@@ -53,6 +50,10 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
53
50
# Indicator of whether an objective has been set
54
51
objective_set:: Bool
55
52
53
+ # Store solve results
54
+ # This structure is update after running the optimize! function
55
+ solve_result:: Union{SolveResultProto,Nothing}
56
+
56
57
# Constructor with optional parameters
57
58
function Optimizer (;
58
59
model_name:: String = " " ,
@@ -81,6 +82,7 @@ mutable struct Optimizer <: MOI.AbstractOptimizer
81
82
Set {Tuple{Type,Type}} (),
82
83
constraint_indices_dict,
83
84
false ,
85
+ nothing ,
84
86
)
85
87
end
86
88
end
@@ -103,6 +105,7 @@ function MOI.empty!(model::Optimizer)
103
105
model. constraint_types_present = Set {Tuple{Type,Type}} ()
104
106
model. constraint_indices_dict = Dict ()
105
107
model. objective_set = false
108
+ model. solve_result = nothing
106
109
107
110
return nothing
108
111
end
@@ -111,7 +114,8 @@ function MOI.is_empty(model::Optimizer)
111
114
return isnothing (model. model) &&
112
115
isnothing (model. parameters) &&
113
116
model. solver_type == SolverType. SOLVER_TYPE_UNSPECIFIED &&
114
- ! model. objective_set
117
+ ! model. objective_set &&
118
+ isnothing (model. solve_result)
115
119
end
116
120
117
121
"""
@@ -1166,20 +1170,21 @@ end
1166
1170
# Helper function to create a dictionary of terms to combine coefficients
1167
1171
# of terms(variables) if they are repeated.
1168
1172
# For example: 3x + 5x <= 10 will be combined to 8x <= 10.
1169
- function get_terms_dict (
1173
+ function get_terms_pairs (
1170
1174
terms:: Vector{MOI.ScalarAffineTerm{T}} ,
1171
- ):: Dict{ Int64,Float64} where {T<: Real }
1172
- terms_dict = Dict {Int64,Float64} ()
1175
+ ):: Vector{Pair{ Int64,Float64} } where {T<: Real }
1176
+ terms_pairs = Dict {Int64,Float64} ()
1173
1177
1174
1178
for term in terms
1175
- if ! haskey (terms_dict , term. variable. value)
1176
- terms_dict [term. variable. value] = term. coefficient
1179
+ if ! haskey (terms_pairs , term. variable. value)
1180
+ terms_pairs [term. variable. value] = term. coefficient
1177
1181
else
1178
- terms_dict [term. variable. value] += term. coefficient
1182
+ terms_pairs [term. variable. value] += term. coefficient
1179
1183
end
1180
1184
end
1181
1185
1182
- return terms_dict
1186
+ sorted_pairs = sort (collect (terms_pairs), by = x -> x[1 ])
1187
+ return sorted_pairs
1183
1188
end
1184
1189
1185
1190
function MOI. add_constraint (
@@ -1204,17 +1209,17 @@ function MOI.add_constraint(
1204
1209
push! (model. model. linear_constraints. upper_bounds, upper_bound)
1205
1210
push! (model. model. linear_constraints. names, " " )
1206
1211
1207
- terms_dict = get_terms_dict (terms)
1212
+ terms_pairs = get_terms_pairs (terms)
1208
1213
1209
1214
# Update the LinearConstaintMatrix (SparseDoubleVectorProto)
1210
1215
# linear_constraint_matrix.row_ids are elements of linear_constraints.ids.
1211
1216
# linear_constraint_matrix.column_ids are elements of variables.ids.
1212
1217
# Matrix entries not specified are zero.
1213
1218
# linear_constraint_matrix.coefficients must all be finite.
1214
- for term_index in keys (terms_dict)
1219
+ for term_index in terms_pairs
1215
1220
push! (model. model. linear_constraint_matrix. row_ids, constraint_index)
1216
- push! (model. model. linear_constraint_matrix. column_ids, term_index)
1217
- push! (model. model. linear_constraint_matrix. coefficients, terms_dict[ term_index])
1221
+ push! (model. model. linear_constraint_matrix. column_ids, term_index[ 1 ] )
1222
+ push! (model. model. linear_constraint_matrix. coefficients, term_index[ 2 ])
1218
1223
end
1219
1224
1220
1225
# Update the associated metadata.
@@ -1316,7 +1321,7 @@ end
1316
1321
function MOI. get (
1317
1322
model:: Optimizer ,
1318
1323
:: MOI.ConstraintFunction ,
1319
- c:: MOI.ConstraintIndex{MOI.VariableIndex,Any} ,
1324
+ c:: MOI.ConstraintIndex{MOI.VariableIndex,<: Any} ,
1320
1325
)
1321
1326
if ! MOI. is_empty (model)
1322
1327
return MOI. VariableIndex (c. value)
@@ -1406,12 +1411,12 @@ function MOI.set(
1406
1411
)
1407
1412
end
1408
1413
1409
- terms_dict = get_terms_dict (terms)
1414
+ terms_pairs = get_terms_pairs (terms)
1410
1415
1411
- for term_index in keys (terms_dict)
1416
+ for term_index in terms_pairs
1412
1417
push! (model. model. linear_constraint_matrix. row_ids, c. value)
1413
- push! (model. model. linear_constraint_matrix. column_ids, term_index)
1414
- push! (model. model. linear_constraint_matrix. coefficients, terms_dict[ term_index])
1418
+ push! (model. model. linear_constraint_matrix. column_ids, term_index[ 1 ] )
1419
+ push! (model. model. linear_constraint_matrix. coefficients, term_index[ 2 ])
1415
1420
end
1416
1421
1417
1422
return nothing
@@ -1810,11 +1815,11 @@ function MOI.set(
1810
1815
1811
1816
terms = objective_function. terms
1812
1817
1813
- terms_dict = get_terms_dict (terms)
1818
+ terms_pairs = get_terms_pairs (terms)
1814
1819
1815
- for term in keys (terms_dict)
1816
- push! (model. model. objective. linear_coefficients. ids, term)
1817
- push! (model. model. objective. linear_coefficients. values, terms_dict[ term])
1820
+ for term in terms_pairs
1821
+ push! (model. model. objective. linear_coefficients. ids, term[ 1 ] )
1822
+ push! (model. model. objective. linear_coefficients. values, term[ 2 ])
1818
1823
end
1819
1824
1820
1825
model. model. objective. offset = Float64 (objective_function. constant)
@@ -1880,6 +1885,42 @@ function MOI.supports(
1880
1885
end
1881
1886
1882
1887
function MOI. optimize! (model:: Optimizer )
1883
- # TODO : b/384662497 implement this
1888
+ status_msg = Ref (pointer (zeros (Int8, 1 )))
1889
+
1890
+ # Serialize the model
1891
+ io = IOBuffer ()
1892
+ e = PB. ProtoEncoder (io)
1893
+ PB. encode (e, to_proto_struct (model. model))
1894
+ model_proto = take! (io)
1895
+ model_size = encoded_model_size (model. model)[1 ]
1896
+
1897
+ # Result proto with its accompanying size
1898
+ solve_result_proto = Ref {Ptr{Cvoid}} ()
1899
+ result_size = Ref {Csize_t} (0 )
1900
+
1901
+ result = MathOptSolve (
1902
+ model_proto,
1903
+ model_size,
1904
+ Int (model. solver_type),
1905
+ MathOptNewInterrupter (),
1906
+ solve_result_proto,
1907
+ result_size,
1908
+ status_msg,
1909
+ )
1910
+
1911
+ # A non-null status_msg indicates a failure in executing the solve call.
1912
+ if status_msg[] != C_NULL
1913
+ failure_status_message = unsafe_string (status_msg[])
1914
+ # TODO : b/407544202 - Add error to SolveResult instead of printing it.
1915
+ @error " The following failure was encountered when executing the solve call: $failure_status_message "
1916
+ return
1917
+ end
1918
+
1919
+ solve_result_proto =
1920
+ unsafe_wrap (Vector{UInt8}, Ptr {UInt8} (solve_result_proto[]), result_size[])
1921
+ io = IOBuffer (solve_result_proto)
1922
+ d = PB. ProtoDecoder (io)
1923
+ model. solve_result = PB. decode (d, SolveResultProto)
1924
+
1884
1925
return nothing
1885
1926
end
0 commit comments