Skip to content

Commit

Permalink
more disentangle backend
Browse files Browse the repository at this point in the history
  • Loading branch information
jalving committed Jul 3, 2024
1 parent e3838d5 commit be691a2
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 49 deletions.
4 changes: 2 additions & 2 deletions src/aggregate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ function _copy_variables!(
for nvref in source_variables
new_variable_index = next_variable_index(new_node)
new_vref = NodeVariableRef(new_node, new_variable_index)
_add_variable_to_backend(dest, new_vref)
MOI.add_variable(dest, new_vref)
index_map[graph_index(nvref)] = graph_index(new_vref)
ref_map[nvref] = new_vref
end
Expand Down Expand Up @@ -216,7 +216,7 @@ function _copy_constraints!(

# create new MOI function
new_func = MOIU.map_indices(index_map, src_func)
dest_index = _add_element_constraint_to_backend(
dest_index = MOI.add_constraint(
dest, new_cref, new_func, src_set
)

Expand Down
72 changes: 58 additions & 14 deletions src/backends/moi_backend.jl
Original file line number Diff line number Diff line change
Expand Up @@ -393,12 +393,14 @@ end

### Variables and Constraints

function _add_variable_to_backend(graph_backend::GraphMOIBackend, vref::NodeVariableRef)
# return if variable already in backend
function MOI.add_variable(graph_backend::GraphMOIBackend, vref::NodeVariableRef)
# return if variable already exists in backend
vref in keys(graph_backend.element_to_graph_map.var_map) && return nothing

# add variable, track index
# add the variable
graph_var_index = MOI.add_variable(graph_backend.moi_backend)

# map reference to index
graph_backend.element_to_graph_map[vref] = graph_var_index
graph_backend.graph_to_element_map[graph_var_index] = vref

Expand All @@ -410,20 +412,57 @@ function _add_variable_to_backend(graph_backend::GraphMOIBackend, vref::NodeVari
return graph_var_index
end

function _add_element_constraint_to_backend(
graph_backend::GraphMOIBackend, cref::ConstraintRef, func::F, set::S
function MOI.add_constraint(
backend::GraphMOIBackend,
cref::ConstraintRef,
moi_func::F,
moi_set::S;
add_variables=false
) where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet}
cref in keys(graph_backend.element_to_graph_map.con_map) && return nothing
if !haskey(graph_backend.element_constraints, cref.model)
# return if reference already mapped to element
cref in keys(backend.element_to_graph_map.con_map) && return nothing

# create key for element if necessary
if !haskey(backend.element_constraints, cref.model)
graph_backend.element_constraints[cref.model] = MOI.ConstraintIndex[]
end
graph_con_index = MOI.add_constraint(graph_backend.moi_backend, func, set)
graph_backend.element_to_graph_map[cref] = graph_con_index
graph_backend.graph_to_element_map[graph_con_index] = cref
push!(graph_backend.element_constraints[cref.model], graph_con_index)

# create the constraint
graph_con_index = MOI.add_constraint(backend.moi_backend, moi_func, moi_set)

# map reference to index
backend.element_to_graph_map[cref] = graph_con_index
backend.graph_to_element_map[graph_con_index] = cref

# add index to element map
push!(backend.element_constraints[cref.model], graph_con_index)
return graph_con_index
end

function MOI.add_constraint(
backend::GraphMOIBackend,
cref::ConstraintRef,
jump_func::F,
moi_set::S;
add_variables=false
) where {F<:JuMP.AbstractJuMPScalar,S<:MOI.AbstractSet}
# add backend variables if necessary (such as adding links across graphs)
if add_variables
_add_backend_variables(backend, jump_func)
end

# assemble MOI function for graph backend
moi_func = JuMP.moi_function(jump_func)
moi_func_graph = _create_graph_moi_func(backend, moi_func, jump_func)
return MOI.add_constraint(
backend,
cref,
moi_func_graph,
moi_set;
add_variables=add_variables
)
end

### Graph MOI Utilities
# These utilities are meant to take model expressions defined over optinodes and
# map them to the underlying optigraph backend indices. This way, nodes and edges
Expand Down Expand Up @@ -553,7 +592,8 @@ end
function _add_backend_variables(backend::GraphMOIBackend, vars::Vector{NodeVariableRef})
vars_to_add = setdiff(vars, keys(backend.element_to_graph_map.var_map))
for var in vars_to_add
_add_variable_to_backend(backend, var)
# _add_variable_to_backend(backend, var)
MOI.add_variable(backend, var)
end
return nothing
end
Expand Down Expand Up @@ -698,7 +738,8 @@ function _copy_node_variables(
vars_to_add = setdiff(node_variables, keys(dest.element_to_graph_map.var_map))
for var in vars_to_add
src_graph_index = graph_index(var)
dest_graph_index = _add_variable_to_backend(dest, var)
#dest_graph_index = _add_variable_to_backend(dest, var)
dest_graph_index = MOI.add_variable(dest, var)
index_map[src_graph_index] = dest_graph_index
end

Expand Down Expand Up @@ -753,7 +794,10 @@ function _copy_element_constraints(

# avoid creating duplicate constraints if destination already has reference
cref in keys(dest.element_to_graph_map.con_map) && return nothing
dest_index = _add_element_constraint_to_backend(
# dest_index = _add_element_constraint_to_backend(
# dest, cref, MOIU.map_indices(index_map, func), set
# )
dest_index = MOI.add_constraint(
dest, cref, MOIU.map_indices(index_map, func), set
)
index_map_FS[ci] = dest_index
Expand Down
8 changes: 4 additions & 4 deletions src/node_variables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,16 @@ end
function _moi_add_node_variable(node::OptiNode, v::JuMP.AbstractVariable)
# get a new variable index and create a reference
variable_index = next_variable_index(node)
vref = NodeVariableRef(node, variable_index)
nvref = NodeVariableRef(node, variable_index)

# add variable to all containing optigraphs
for graph in containing_optigraphs(node)
_add_variable_to_backend(graph_backend(graph), vref)
MOI.add_variable(graph_backend(graph), nvref)
end

# constrain node variable (hits all graph backends)
_moi_constrain_node_variable(vref, v.info, Float64)
return vref
_moi_constrain_node_variable(nvref, v.info, Float64)
return nvref
end

function _moi_constrain_node_variable(nvref::NodeVariableRef, info, ::Type{T}) where {T}
Expand Down
20 changes: 8 additions & 12 deletions src/optiedge.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ end
### Edge Variables

function JuMP.all_variables(edge::OptiEdge)
gb = graph_backend(edge)
con_refs = getindex.(Ref(gb.graph_to_element_map), gb.element_constraints[edge])
con_refs = JuMP.all_constraints(edge)
vars = vcat(_extract_variables.(con_refs)...)
return unique(vars)
end
Expand Down Expand Up @@ -98,18 +97,15 @@ function _moi_add_edge_constraint(edge::OptiEdge, con::JuMP.AbstractConstraint)
)::MOI.ConstraintIndex{typeof(moi_func),typeof(moi_set)}
cref = ConstraintRef(edge, constraint_index, JuMP.shape(con))

# update graph backends
# TODO: disentangle backend interface
# add to each containing optigraph
for graph in containing_optigraphs(edge)
# add backend variables if linking across optigraphs
_add_backend_variables(graph_backend(graph), jump_func)

# update the moi function variable indices
moi_func_graph = _create_graph_moi_func(graph_backend(graph), moi_func, jump_func)

# add the constraint to the backend
_add_element_constraint_to_backend(
graph_backend(graph), cref, moi_func_graph, moi_set
MOI.add_constraint(
graph_backend(graph),
cref,
jump_func,
moi_set;
add_variables=true
)
end
return cref
Expand Down
8 changes: 1 addition & 7 deletions src/optimizer_interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ end
# set optimizer
#

# TODO: call to backend
# TODO: do not use private methods
function JuMP.mode(graph::OptiGraph)
return JuMP._moi_mode(JuMP.backend(graph))
end
Expand All @@ -89,12 +89,6 @@ function JuMP.set_optimizer(
else
optimizer = MOI.instantiate(optimizer_constructor)
end
# Update the backend to create a new, concretely typed CachingOptimizer
# using the existing `model_cache`.
# gb = graph_backend(graph)
# return gb.moi_backend = MOIU.CachingOptimizer(
# JuMP.backend(graph).model_cache, optimizer
# )
return JuMP.set_optimizer(graph_backend(graph), optimizer)
end

Expand Down
21 changes: 11 additions & 10 deletions src/optinode.jl
Original file line number Diff line number Diff line change
Expand Up @@ -154,21 +154,22 @@ function _moi_add_node_constraint(node::OptiNode, con::JuMP.AbstractConstraint)
moi_func = JuMP.moi_function(con)
moi_set = JuMP.moi_set(con)

# create constraint reference
# create constraint index and reference
constraint_index = next_constraint_index(
node, typeof(moi_func), typeof(moi_set)
)::MOI.ConstraintIndex{typeof(moi_func),typeof(moi_set)}
cref = ConstraintRef(node, constraint_index, JuMP.shape(con))

# add to each containing optigraph
for graph in containing_optigraphs(node)
# update func variable indices
moi_func_graph = _create_graph_moi_func(graph_backend(graph), moi_func, jump_func)

# add contraint to backend
_add_element_constraint_to_backend(
graph_backend(graph), cref, moi_func_graph, moi_set
)
# # update func variable indices
# moi_func_graph = _create_graph_moi_func(graph_backend(graph), moi_func, jump_func)

# # add contraint to backend
# _add_element_constraint_to_backend(
# graph_backend(graph), cref, moi_func_graph, moi_set
# )
MOI.add_constraint(graph_backend(graph), cref, jump_func, moi_set)
end
return cref
end
Expand Down Expand Up @@ -234,7 +235,7 @@ function _copy_model_to!(node::OptiNode, model::JuMP.Model)
for vref in source_variables
new_variable_index = next_variable_index(node)
new_vref = NodeVariableRef(node, new_variable_index)
_add_variable_to_backend(dest, new_vref)
MOI.add_variable(dest, new_vref)
index_map[JuMP.index(vref)] = graph_index(new_vref)
end

Expand All @@ -256,7 +257,7 @@ function _copy_model_to!(node::OptiNode, model::JuMP.Model)
# new optinode cref
new_cref = ConstraintRef(node, constraint_index, JuMP.shape(con))
new_func = MOIU.map_indices(index_map, src_func)
dest_index = _add_element_constraint_to_backend(
dest_index = MOI.add_constraint(
dest, new_cref, new_func, src_set
)
index_map_FS[ci] = dest_index
Expand Down

0 comments on commit be691a2

Please sign in to comment.