Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding nodes to a subgraph after the main graph's backend is initialized does not reset graph backend #101

Open
dlcole3 opened this issue Dec 19, 2023 · 2 comments

Comments

@dlcole3
Copy link
Collaborator

dlcole3 commented Dec 19, 2023

I have found that adding to a subgraph does not necessarily update the overall graph's backend. For example, the code below throws an error because the first incident_edges call sets the backend of the graph, and then when the second node is added, the backend on graph g0 is not updated. When Plasmo runs the second call of incident_edges, it does not have the extra_node in its hypermap.

using Plasmo

g0 = OptiGraph()
g1 = OptiGraph()
g2 = OptiGraph()

@optinode(g1, node)
@variable(node, x >= 0)

@optinode(g2, node)
@variable(node, x >= 0)

add_subgraph!(g0, g1)
add_subgraph!(g0, g2)

incident_edges(g0, all_nodes(g1))

@optinode(g1, extra_node)
@variable(extra_node, x >= -5)

incident_edges(g0, all_nodes(g1))

This does make sense since there is no mapping to go from the subgraph to its "owning" graph (only to go from the "owning" graph to the subgraph), so there is no way for the upper graph to know to update its backend. Currently, I get around this in my code by forcing the upper graph to reset the backend by calling Plasmo.set_graph_backend, but if there is an efficient way to fix this in the future, it could be nice.

@jalving
Copy link
Member

jalving commented Dec 31, 2023

This may be a good reason to maintain a reference from optinodes to each of their containing optigraphs. The original design of Plasmo.jl actually did this, but we opted to make nodes more modular at the time. This will be added to the roadmap in the re-write.

@jalving jalving added the bug label Aug 31, 2024
@jalving
Copy link
Member

jalving commented Sep 1, 2024

This is still an issue in v0.6. The main problem is that the projection used to query graph topology is not kept in sync with the optigraph. In this case, you need to create a new projection after you update the optigraph. Here is a working example:

using Plasmo

# setup example optigraph
g0 = OptiGraph()
g1 = OptiGraph()
g2 = OptiGraph()
@optinode(g1, nodes1[1:2])
@variable(nodes1[1], x >= 0)
@variable(nodes1[2], x >= 0)
add_edge(g1, nodes1[1], nodes1[2])
@optinode(g2, nodes2[1:2])
@variable(nodes2[1], x >= 0)
@variable(nodes2[2], x >= 0)
add_edge(g2, nodes2[1], nodes2[2])
add_subgraph(g0, g1)
add_subgraph(g0, g2)
add_edge(g0, nodes1[1], nodes2[1])

# create projection and query incident edges
projection = hyper_projection(g0)
incident_edges(projection, all_nodes(g1))

# update optigraph
@optinode(g1, extra_node)
@variable(extra_node, x >= -5)
add_edge(g1, extra_node, nodes1[1])

# this will fail because the projection is not kept in sync
incident_edges(projection, all_nodes(g1))

# create a new projection instead
new_projection = hyper_projection(g0)
incident_edges(new_projection, all_nodes(g1))

At some point, we should consider developing methods to update the projection in cases where a user needs to modify the projection extensively.

@jalving jalving added enhancement and removed bug labels Sep 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants