[Serialization][BGL] problem serializing an edge
Hi, I have a problem serializing an edge in a graph. This is my test case: #include <iostream> #include <boost/archive/text_oarchive.hpp> #include <boost/graph/adj_list_serialize.hpp> using namespace std; using namespace boost; int main() { typedef adjacency_list<listS, vecS, undirectedS> Graph; typedef graph_traits<Graph>::edge_descriptor Edge; Graph g; Edge e; boost::archive::text_oarchive oa(cout); oa << g; oa << e; return 0; } Compilation with gcc version 4.4.1 returns this error: /usr/include/boost/serialization/access.hpp:109: error: ‘class boost::detail::edge_desc_impl<boost::undirected_tag, unsigned int>’ has no member named ‘serialize’ I would appreciate it if someone could point out what the problem is and how to fix it. Thanks, Irek -- Ireneusz (Irek) Szczesniak http://www.irkos.org
Hi Irek, as far as I can see from the example and the error message, the error seems to be that there is no operator<< implemented for the edge_descriptor. So the serialization does not know how it should save this instance of an edge _descriptor. Same problem as when working with std::cout and custom classes that have no operator<< defined. I remember having encountered issues when first working with boost::serialize and boost graph lib. However, I don't exactly remember what the problems where. In any case, I managed to sucessfully serialize a graph with custom Vertex and Edge-Properties. You're adjacency_list is a rather straight-forward example and thus should work well. At least as long as you don't want to do/store more complex things with your vertices/edges ;) What I used there was the operator& instead of operator<<. So perhaps you might give it a try. Also you might be interested in the code: #include <iostream> #include <fstream> #include "Graph.hpp" #include "Properties.hpp" #include <boost/graph/adj_list_serialize.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_oarchive.hpp> using namespace boost; int main(int argc, char** argv) { typedef Graph<VertexProperties, EdgeProperties> MyGraph; std::list< std::pair< VertexProperties, VertexProperties> > v_props; v_props.push_back(std::make_pair(VertexProperties("a", "type_of_a"), VertexProperties("b", "type_of_b"))); MyGraph G(v_props); //Serialize it! std::ofstream ofs("./serialize_out.dat"); archive::text_oarchive oa(ofs); oa & G; //DEserialize it!!! std::ifstream ifs("./serialize_in.dat"); archive::text_iarchive ia(ifs); MyGraph g; ia & g; Graph<VertexProperties, EdgeProperties>::Vertex v = g.getFirstVertex(); std::cout << ((g.properties(v)).type) << std::endl; return 0; } There's not much of a difference to your example about it, except for the operator& and the custom Graph<>-class. I have not defined the operator& anywhere, so it might very well work for your problem out-of-the-box also. If it doesn't please let the mailinglist, and thus me, know. Best, Cedric On Monday, 19. July 2010 21:17:14 Ireneusz Szcześniak wrote:
Hi,
I have a problem serializing an edge in a graph. This is my test case:
#include <iostream> #include <boost/archive/text_oarchive.hpp> #include <boost/graph/adj_list_serialize.hpp>
using namespace std; using namespace boost;
int main() { typedef adjacency_list<listS, vecS, undirectedS> Graph; typedef graph_traits<Graph>::edge_descriptor Edge;
Graph g; Edge e;
boost::archive::text_oarchive oa(cout); oa << g; oa << e;
return 0; }
Compilation with gcc version 4.4.1 returns this error:
/usr/include/boost/serialization/access.hpp:109: error: ‘class boost::detail::edge_desc_impl<boost::undirected_tag, unsigned int>’ has no member named ‘serialize’
I would appreciate it if someone could point out what the problem is and how to fix it.
Thanks, Irek
Hi Cedric, Thanks for your response. My graph in my code is actually a bit more complicated than what I gave in my example. This is what I'm actually using: typedef adjacency_list <vecS, vecS, undirectedS, property<vertex_name_t, string, property<vertex_distance_t, vector<int>, property<vertex_predecessor_t, vector<Vertex>, property<vertex_bundle_t, vector<my_class> > > > >, property<edge_weight_t, int, property<edge_weight2_t, int> > > Graph; I have many data structures that have edge_descriptors as their fields, and I wouldn't like to refactor them only to make them vertex or edge properties. I agree that the reason for the compilation error is that the Serialization library doesn't know how to serialize an edge_descriptor. I don't know why the serialization code for the adjacency list doesn't deliver the serialization code for the edge_description. Should I write the serialization code for the edge_descriptor? If so, then how? I would appreciate it, if someone could fix the initial example, so that it compiles: #include <iostream> #include <boost/archive/text_oarchive.hpp> #include <boost/graph/adj_list_serialize.hpp> using namespace std; using namespace boost; int main() { typedef adjacency_list<listS, vecS, undirectedS> Graph; typedef graph_traits<Graph>::edge_descriptor Edge; Graph g; Edge e; boost::archive::text_oarchive oa(cout); oa << g; oa << e; return 0; } Thanks, Irek -- Ireneusz (Irek) Szczesniak http://www.irkos.org Cedric Laczny wrote:
Hi Irek,
as far as I can see from the example and the error message, the error seems to be that there is no operator<< implemented for the edge_descriptor. So the serialization does not know how it should save this instance of an edge _descriptor. Same problem as when working with std::cout and custom classes that have no operator<< defined. I remember having encountered issues when first working with boost::serialize and boost graph lib. However, I don't exactly remember what the problems where. In any case, I managed to sucessfully serialize a graph with custom Vertex and Edge-Properties. You're adjacency_list is a rather straight-forward example and thus should work well. At least as long as you don't want to do/store more complex things with your vertices/edges ;) What I used there was the operator& instead of operator<<. So perhaps you might give it a try.
Also you might be interested in the code: #include <iostream> #include <fstream> #include "Graph.hpp" #include "Properties.hpp" #include <boost/graph/adj_list_serialize.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_oarchive.hpp>
using namespace boost;
int main(int argc, char** argv) { typedef Graph<VertexProperties, EdgeProperties> MyGraph; std::list< std::pair< VertexProperties, VertexProperties> > v_props; v_props.push_back(std::make_pair(VertexProperties("a", "type_of_a"), VertexProperties("b", "type_of_b"))); MyGraph G(v_props);
//Serialize it! std::ofstream ofs("./serialize_out.dat"); archive::text_oarchive oa(ofs); oa & G;
//DEserialize it!!! std::ifstream ifs("./serialize_in.dat"); archive::text_iarchive ia(ifs); MyGraph g; ia & g; Graph<VertexProperties, EdgeProperties>::Vertex v = g.getFirstVertex(); std::cout << ((g.properties(v)).type) << std::endl;
return 0; }
There's not much of a difference to your example about it, except for the operator& and the custom Graph<>-class. I have not defined the operator& anywhere, so it might very well work for your problem out-of-the-box also. If it doesn't please let the mailinglist, and thus me, know.
Best,
Cedric
Hi Irek, you did not mention if you tried the operator& instead of operator<<. I could imagine that the fact, that you are using nested properties might impose problems to the operator<<. However, I am not sure if this can be fixed by using operator&, but it could be worth a try. Best, Cedric On Tuesday, 20. July 2010 19:03:23 Ireneusz Szcześniak wrote:
Hi Cedric,
Thanks for your response. My graph in my code is actually a bit more complicated than what I gave in my example. This is what I'm actually using:
typedef adjacency_list <vecS, vecS, undirectedS, property<vertex_name_t, string, property<vertex_distance_t, vector<int>, property<vertex_predecessor_t, vector<Vertex>, property<vertex_bundle_t, vector<my_class> > > > >, property<edge_weight_t, int, property<edge_weight2_t, int> > > Graph;
I have many data structures that have edge_descriptors as their fields, and I wouldn't like to refactor them only to make them vertex or edge properties.
I agree that the reason for the compilation error is that the Serialization library doesn't know how to serialize an edge_descriptor. I don't know why the serialization code for the adjacency list doesn't deliver the serialization code for the edge_description. Should I write the serialization code for the edge_descriptor? If so, then how?
I would appreciate it, if someone could fix the initial example, so that it compiles:
#include <iostream> #include <boost/archive/text_oarchive.hpp> #include <boost/graph/adj_list_serialize.hpp>
using namespace std; using namespace boost;
int main() { typedef adjacency_list<listS, vecS, undirectedS> Graph; typedef graph_traits<Graph>::edge_descriptor Edge;
Graph g; Edge e;
boost::archive::text_oarchive oa(cout); oa << g; oa << e;
return 0; }
Thanks, Irek
Hi Irek,
as far as I can see from the example and the error message, the error seems to be that there is no operator<< implemented for the edge_descriptor. So the serialization does not know how it should save this instance of an edge _descriptor. Same problem as when working with std::cout and custom classes that have no operator<< defined. I remember having encountered issues when first working with boost::serialize and boost graph lib. However, I don't exactly remember what the problems where. In any case, I managed to sucessfully serialize a graph with custom Vertex and Edge-Properties. You're adjacency_list is a rather straight-forward example and thus should work well. At least as long as you don't want to do/store more complex things with your vertices/edges ;) What I used there was the operator& instead of operator<<. So perhaps you might give it a try.
Also you might be interested in the code: #include <iostream> #include <fstream> #include "Graph.hpp" #include "Properties.hpp" #include <boost/graph/adj_list_serialize.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/archive/text_oarchive.hpp>
using namespace boost;
int main(int argc, char** argv) {
typedef Graph<VertexProperties, EdgeProperties> MyGraph; std::list< std::pair< VertexProperties, VertexProperties> > v_props; v_props.push_back(std::make_pair(VertexProperties("a", "type_of_a"),
VertexProperties("b", "type_of_b")));
MyGraph G(v_props);
//Serialize it! std::ofstream ofs("./serialize_out.dat"); archive::text_oarchive oa(ofs); oa & G;
//DEserialize it!!! std::ifstream ifs("./serialize_in.dat"); archive::text_iarchive ia(ifs); MyGraph g; ia & g; Graph<VertexProperties, EdgeProperties>::Vertex v = g.getFirstVertex(); std::cout << ((g.properties(v)).type) << std::endl;
return 0;
}
There's not much of a difference to your example about it, except for the operator& and the custom Graph<>-class. I have not defined the operator& anywhere, so it might very well work for your problem out-of-the-box also. If it doesn't please let the mailinglist, and thus me, know.
Best,
Cedric
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Hi Cedric and others, I tried to solve the problem non-intrusively by implementing the serialize function like this: namespace boost { namespace serialization { template<class Archive> void serialize(Archive &ar, Edge &g, const unsigned int version) {...} } } I wanted to serialize the edge e by serializing the vertexes of the edge, but to do this I need a reference to graph g. Having e and g, I would call source(e, g) and target(e, g) to get the vertexes. The problem is that in serializing an edge, I would have to pass to the serialize function a reference to graph g. Below there is a complete example that passes a pair of an edge and a graph for serialization. #include <cassert> #include <iostream> #include <sstream> #include <utility> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/graph/adj_list_serialize.hpp> using namespace std; using namespace boost; typedef adjacency_list<listS, vecS, undirectedS> Graph; typedef graph_traits<Graph>::vertex_descriptor Vertex; typedef graph_traits<Graph>::edge_descriptor Edge; typedef pair<Edge &, const Graph &> SEdge; namespace boost { namespace serialization { template<class A> void load(A &ar, SEdge &p, const unsigned int) { Vertex s, t; ar & s & t; p.first = edge(s, t, p.second).first; } template<class A> void save(A &ar, const SEdge &p, const unsigned int) { Vertex s = source(p.first, p.second); Vertex t = target(p.first, p.second); ar & s & t; } } } BOOST_SERIALIZATION_SPLIT_FREE(SEdge) int main() { stringstream str; { Graph g(2); add_edge(0, 1, g); Edge e = edge(0, 1, g).first; boost::archive::text_oarchive oa(str); oa << g; SEdge se(e, g); oa << se; } { Graph g; Edge e; boost::archive::text_iarchive ia(str); ia >> g; SEdge se(e, g); ia >> se; assert(source(e, g) == 0); assert(target(e, g) == 1); } return 0; } In my code, what I really want to serialize is a std::list, where the elements are of type Edge. I could make SEdge (defined in the example above), and then serialize the list with boost/serialization/list.hpp, but then I have to heavily modify my code, which I would like to avoid. One solution that comes to mind is to make the graph a global object, and so my code for serializing an edge would use that global object. However, this is an uglu hack, and I would like to avoid this too. Ideally, I would like to pass a function object to the serialization library. The serialization library would ask the function object to serialize an edge, and that function object would know how to do it, because one of its fields would be a reference to the graph object. Is there a way to pass such a function object to the serialization library? Thanks, Irek Cedric Laczny wrote:
Hi Irek,
you did not mention if you tried the operator& instead of operator<<. I could imagine that the fact, that you are using nested properties might impose problems to the operator<<. However, I am not sure if this can be fixed by using operator&, but it could be worth a try.
Best,
Cedric
-- Ireneusz (Irek) Szczesniak http://www.irkos.org
Ireneusz Szczesniak wrote:
I agree that the reason for the compilation error is that the Serialization library doesn't know how to serialize an edge_descriptor. I don't know why the serialization code for the adjacency list doesn't deliver the serialization code for the edge_description. Should I write the serialization code for the edge_descriptor? If so, then how?
This is described in the documentation for the serialization library. Robert Ramey
Hi Robert,
Ireneusz Szczesniak wrote:
I agree that the reason for the compilation error is that the Serialization library doesn't know how to serialize an edge_descriptor. I don't know why the serialization code for the adjacency list doesn't deliver the serialization code for the edge_description. Should I write the serialization code for the edge_descriptor? If so, then how?
This is described in the documentation for the serialization library.
Could you point out in which section? I've read the documentation, except sections like "Implementation Notes", and I couldn't find or infer that information. Thanks, Irek -- Ireneusz (Irek) Szczesniak http://www.irkos.org
participants (3)
-
Cedric Laczny
-
Ireneusz Szcześniak
-
Robert Ramey