Graph edges getting corrupted after vertex deletion
Bug reports:
Please follow the general troubleshooting steps first:
-
Are you running the latest graph-tool
version?- Yes as I don't see any newer commits that seem relevant so I'm staying with 2.46
I've found that after some edge manipulation, namely removal, I'm left with a graph that is likely corrupted. At times it will segfault when I call graph.edges()
but I've got it down to a relatively minimal example below which starts with a "random" graph and after some alterations ends up with an invalid edge.
import pprint
import graph_tool.all as gt
import numpy as np
# set random seed for repeatability
rng = np.random.default_rng(0)
# build "random" graph with edge distances
num_vertices = 10
graph = gt.random_graph(num_vertices, lambda: rng.integers(2, 5), False, random=False)
graph.edge_properties.dist = graph.new_edge_property(
"double", rng.exponential(size=graph.num_edges())
)
last_node = graph.vertex(num_vertices - 1)
print("Initial edges")
pprint.pprint(list(graph.edges()))
# disconnect last node
for edge in last_node.all_edges():
graph.remove_edge(edge)
print("Edges after deleting all connections to final node")
pprint.pprint(list(graph.edges()))
# shortcut all nodes to last node
for vertex in graph.get_vertices():
edge = graph.add_edge(vertex, last_node)
graph.edge_properties.dist[edge] = 0
print("Edges after adding an edge from final node to all other nodes")
pprint.pprint(list(graph.edges()))
# delete last node
graph.remove_vertex(last_node)
print("Edges after deleting last three node")
pprint.pprint(list(graph.edges()))
which results in the following output
Initial edges
[<Edge object with source '0' and target '9' at 0x7f70d40d5940>,
<Edge object with source '0' and target '1' at 0x7f70d40d59d0>,
<Edge object with source '0' and target '2' at 0x7f70d40d5a60>,
<Edge object with source '0' and target '3' at 0x7f70d40d5af0>,
<Edge object with source '2' and target '8' at 0x7f70d40d5b80>,
<Edge object with source '4' and target '3' at 0x7f70d40d5c10>,
<Edge object with source '4' and target '5' at 0x7f70d40d5ca0>,
<Edge object with source '6' and target '1' at 0x7f70d40d5d30>,
<Edge object with source '7' and target '6' at 0x7f70d40d5dc0>,
<Edge object with source '7' and target '5' at 0x7f70d40d5e50>,
<Edge object with source '9' and target '8' at 0x7f70d40d5ee0>,
<Edge object with source '9' and target '2' at 0x7f70d40d5f70>,
<Edge object with source '9' and target '1' at 0x7f70d4059040>]
Edges after deleting all connections to final node
[<Edge object with source '0' and target '1' at 0x7f70d40d5940>,
<Edge object with source '0' and target '2' at 0x7f70d40d59d0>,
<Edge object with source '2' and target '8' at 0x7f70d40d5af0>,
<Edge object with source '4' and target '3' at 0x7f70d40d5b80>,
<Edge object with source '4' and target '5' at 0x7f70d40d5c10>,
<Edge object with source '6' and target '1' at 0x7f70d40d5ca0>,
<Edge object with source '7' and target '6' at 0x7f70d40d5d30>,
<Edge object with source '7' and target '5' at 0x7f70d40d5dc0>,
<Edge object with source '9' and target '2' at 0x7f70d40d5e50>]
Edges after adding an edge from final node to all other nodes
[<Edge object with source '0' and target '1' at 0x7f70d40d5940>,
<Edge object with source '0' and target '2' at 0x7f70d40d59d0>,
<Edge object with source '0' and target '9' at 0x7f70d40d5af0>,
<Edge object with source '1' and target '9' at 0x7f70d40d5b80>,
<Edge object with source '2' and target '8' at 0x7f70d40d5c10>,
<Edge object with source '2' and target '9' at 0x7f70d40d5ca0>,
<Edge object with source '3' and target '9' at 0x7f70d40d5d30>,
<Edge object with source '4' and target '3' at 0x7f70d40d5dc0>,
<Edge object with source '4' and target '5' at 0x7f70d40d5e50>,
<Edge object with source '4' and target '9' at 0x7f70d40d5ee0>,
<Edge object with source '5' and target '9' at 0x7f70d40d5f70>,
<Edge object with source '6' and target '1' at 0x7f70d405a040>,
<Edge object with source '6' and target '9' at 0x7f70d405a0d0>,
<Edge object with source '7' and target '6' at 0x7f70d405a160>,
<Edge object with source '7' and target '5' at 0x7f70d405a1f0>,
<Edge object with source '7' and target '9' at 0x7f70d405a280>,
<Edge object with source '8' and target '9' at 0x7f70d405a310>,
<Edge object with source '9' and target '0' at 0x7f70d405a3a0>,
<Edge object with source '9' and target '9' at 0x7f70d405a430>]
Edges after deleting last three node
[<Edge object with source '0' and target '1' at 0x7f70d40d5940>,
<Edge object with source '0' and target '2' at 0x7f70d40d59d0>,
<invalid Edge object at 0x7f70d40d5af0>,
<Edge object with source '2' and target '8' at 0x7f70d40d5b80>,
<Edge object with source '4' and target '3' at 0x7f70d40d5c10>,
<Edge object with source '4' and target '5' at 0x7f70d40d5ca0>,
<Edge object with source '6' and target '1' at 0x7f70d40d5d30>,
<Edge object with source '7' and target '6' at 0x7f70d40d5dc0>,
<Edge object with source '7' and target '5' at 0x7f70d40d5e50>]
Process finished with exit code 0
Note the third edge is invalid after all this.
This is running in a docker container with Ubuntu 20.04, python 3.8.10, graph-tool '2.46 (commit ab460df4, Sun Feb 26 16:33:33 2023 +0100)' (from apt).
As an aside, when I import graph-tool I get the following despite having installed graphviz
, libcairo2-dev
, and python-cairo
through apt
. I don't think it's relevant, but I figure it's worth mentioning in case I'm wrong.
/usr/lib/python3/dist-packages/graph_tool/draw/cairo_draw.py:32: RuntimeWarning: Error importing cairo. Graph drawing will not work.
warnings.warn(msg, RuntimeWarning)
/usr/lib/python3/dist-packages/graph_tool/draw/cairo_draw.py:32: RuntimeWarning: Error importing cairo. Graph drawing will not work.
warnings.warn(msg, RuntimeWarning)
/usr/lib/python3/dist-packages/graph_tool/draw/cairo_draw.py:32: RuntimeWarning: Error importing cairo. Graph drawing will not work.
warnings.warn(msg, RuntimeWarning)
/usr/lib/python3/dist-packages/graph_tool/all.py:39: RuntimeWarning: Error importing draw module, proceeding nevertheless: No module named 'cairo'
warnings.warn(msg, RuntimeWarning)