Access underlying graph from Vertex or Edge
It would be nice if one could access the underlying graph from Vertex
/Edge
context.
The primary motivation is that in order to set a property of a vertex/edge, you need to do it through Graph.vertex_properties
/Graph.edge_properties
, thus needing the Graph
object itself.
I don't know the implementation details of graphtool
, but I can see that internally, there is some kind of access to the underlying graph from Vertex
/Edge
context:
>>> import graph_tool.all as gt
>>> g = gt.Graph()
>>> v1 = g.add_vertex()
>>> e1 = g.add_edge(v1,v1)
>>> v1.is_valid()
True
>>> e1.is_valid()
True
>>> del g
>>> v1.is_valid()
False
>>> e1.is_valid()
False

Replying to [ticket:94 Wojciech Waśko ]:
The primary motivation is that in order to set a property of a vertex/edge, you need to do it through
Graph.vertex_properties
/Graph.edge_properties
, thus needing theGraph
object itself.This is not true; all you need is access to the [/doc/graph_tool.html#graph_tool.PropertyMap PropertyMap] object, not the graph itself. E.g. if you are dealing with internal properties:
prop = g.vertex_properties["myprop"] v = g.vertex(0) prop[v] = 42 # No need to reference the graph "g"
Note that the property map object does have an internal reference to its owner graph:
g = prop.get_graph() # Should be the same as "g" above
I'm hesitant to include an explicit reference to the graph from the vertex/edge descriptors, since one should rely on them being lightweight. Internally this (weak) reference exists in order to test for validity, but it may be removed in the future. In general, it is an easy thing to provide the graph object with the descriptors, so this is not really a necessity.

Replying to [comment:1 tiago peixoto]:
Replying to [ticket:94 Wojciech Waśko ]:
The primary motivation is that in order to set a property of a vertex/edge, you need to do it through
Graph.vertex_properties
/Graph.edge_properties
, thus needing theGraph
object itself.This is not true; all you need is access to the [/doc/graph_tool.html#graph_tool.PropertyMap PropertyMap] object, not the graph itself. E.g. if you are dealing with internal properties:
prop = g.vertex_properties["myprop"] v = g.vertex(0) prop[v] = 42 # No need to reference the graph "g"
Maybe I provide some more details about the motivation. I'm developing a library which serves as an interface between
graphtool
and some other lib (namely,pyevolve
). The primary goal is modularity and replaceability of the underlying graph processing engine.For this reason, I'd like to provide a consistent interface to the graph library. There are some functions in the my library's userspace which have only one argument  a vertex or an edge. I'd like to keep it this way, i.e. I'd like the user to be able to access a given edge's properties without having to refer to the graph object explicitly. Or having to accept a
PropertyMap
as an argument, for that matter.Since the vertex/edge/graph property logic in
graphtool
is well... quite exotic (though efficient), I solved it by modifying (from within my library) each instance ofgraph_tool.Vertex
/graph_tool.Edge
I "dispense" so that it contains a weakref to the underlying graph object. Then (in setup code of my lib), I added methods which return the most heavily used properties, e.g. (I'm writing this off the top of my head):import graph_tool.all as gt def v_type(self): return self.g().vertex_properties["type"][self] # self.g is a weakref to the graph object setattr(gt.Vertex, 'type', v_type)
I'm concerned, however, that creating a ''new''
weakref
for each Vertex instance will cause a performance hit (haven't tested it thoroughly yet). It's also the weakest point  if I don't keep vertex dispensing in one method, I may sooner or later make an error and start "dispensing" vertices without the weakref from some method, which would be quite hard to debug.Besides, I (personally) believe that not giving access to the underlying graph from
Vertex
/Edge
context severely limitsgraphtool
user's possibilities. The example I provided is a quite specialized one, but I guess one could come up with something more straightforward and common.Have you done any testing as to how big a performance gain one would get from removing the weakrefs from
Vertex
andEdge
classes? 
Replying to [comment:2 Wojciech Waśko ]:
Besides, I (personally) believe that not giving access to the underlying graph from
Vertex
/Edge
context severely limitsgraphtool
user's possibilities. The example I provided is a quite specialized one, but I guess one could come up with something more straightforward and common.Well, I suppose if the underlying reference is there in the first place, it should not hurt to provide access to it. I'll implement this soon.
Have you done any testing as to how big a performance gain one would get from removing the weakrefs from
Vertex
andEdge
classes?No really. But in the end of the day it should not be much of an issue, since the user can always store the vertex index (i.e. an int) as a cheap alternative to storing vertex descriptors, since they can be easily obtained with the Graph.vertex() method. The same thing holds for vertex index pairs and edge descriptors (although the Graph.edge() may be slower if the graph has vertices with large degrees).

Since this recently became a blocker issue for me, I coded a quick fix which allows me to get past this problem.
I added a
weakref
to the owner graph inGraphInterface
which is later served throughVertex
/Edge
"g()
" method. (If anyone's interested, you can get it from6a98e435459
at [git://merlotatnight.com/gt]; beware, that's a dirty and kludgy hack coined just to bypass this issue.)However, I do think that implementing it through
GraphInterface
is the best one can do; so, Tiago, if you want to, feel free to reuse my "code" :)

Please register or login to post a comment