bad_any_cast when reading graphml

I just tried to use your code to read a graphml file. I compile
graphml.cpp myself and have it linked to my executable.

Boost version is 1.33.1.

My code looks like this:

// system headers
#include <string>
#include <iostream>
#include <fstream>

// Boost graph library, including LEDA wrapper
// #include <boost/graph/leda_graph.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/dynamic_property_map.hpp>

// graph_tool: graphml reader
#include "graphml.hpp"

struct VertexProperties
{
   float x;
   float y;
};

struct EdgeProperties
{
   float length;
};

int main()
{
   using namespace boost;
   using namespace std;

   typedef adjacency_list<vecS, vecS, directedS, VertexProperties,

Graph;

   Graph g;
   dynamic_properties dp;
   dp.property("coord1", get(&VertexProperties::x, g));
   dp.property("coord2", get(&VertexProperties::y, g));
   dp.property("length", get(&EdgeProperties::length, g));

   std::ifstream in;
   in.open(options.inputgraph.c_str(), ios::in);

   read_graphml(in, g, dp);
}

options.inputgraph is a file that looks like this:

<?xml version="1.0"?>

<graphml
xmlns="http://graphml.graphdrawing.org/xmlns/1.0rc&quot;
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot;
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/1.0rc
                     graphml-structure-1.0rc.xsd

                     http://graphml.graphdrawing.org/xmlns/1.0rc
                     graphml-attributes-1.0rc.xsd"
>
   <key id="k0" for="node" attr.name="coord1" attr.type="double">
     <desc>First coordinate</desc>
     <default>0</default>
   </key>
   <key id="k1" for="node" attr.name="coord2" attr.type="double">
     <desc>Second coordinate</desc>
     <default>0</default>
   </key>
   <key id="k2" for="edge" attr.name="length" attr.type="double">
     <desc>Distance</desc>
     <default>1</default>
   </key>
   <graph edgedefault="directed">
     <node id="n0">
       <data key="k0">1.71661e-05</data>
       <data key="k1">0.636771</data>
     </node>

[and so on ...]

When running my program, I get:

$ ./separator -f test -i planar100k.graphml
terminate called after throwing an instance of 'boost::bad_any_cast'
   what(): boost::bad_any_cast: failed conversion using boost::any_cast
Aborted

If that's helpful, here is an gdb backtrace:

(gdb) r
Starting program:
/amd.home/home/jmueller/separator_devel/separator_jens/separator -f test
-i planar100k.graphml
[Thread debugging using libthread_db enabled]
[New Thread -1211508544 (LWP 4229)]
terminate called after throwing an instance of 'boost::bad_any_cast'
   what(): boost::bad_any_cast: failed conversion using boost::any_cast

Program received signal SIGABRT, Aborted.
[Switching to Thread -1211508544 (LWP 4229)]
0xffffe410 in __kernel_vsyscall ()
(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0xb7ce47d0 in raise () from /lib/libc.so.6
#2 0xb7ce5ea3 in abort () from /lib/libc.so.6
#3 0xb7ee63a0 in __gnu_cxx::__verbose_terminate_handler () from
/usr/lib/libstdc++.so.6
#4 0xb7ee3dc5 in std::set_unexpected () from /usr/lib/libstdc++.so.6
#5 0xb7ee3e02 in std::terminate () from /usr/lib/libstdc++.so.6
#6 0xb7ee3f3a in __cxa_throw () from /usr/lib/libstdc++.so.6
#7 0x080526d2 in boost::any_cast<std::string> (operand=@0xbfefc2a8) at
/usr/include/boost/throw_exception.hpp:39
#8 0x08053040 in
boost::detail::dynamic_property_map_adaptor<boost::bundle_property_map<boost::adjacency_list<boost::vecS,
boost::vecS, boost::directedS, VertexProperties, EdgeProperties,
boost::no_property, boost::listS>, unsigned int, VertexProperties,

>::put (this=0x8070a20, in_key=@0xbfefc2ac,

     in_value=@0xbfefc2a8) at
/usr/include/boost/dynamic_property_map.hpp:149
#9 0x080553fc in boost::put<unsigned int, double> (name=@0x807513c,
dp=@0xbfefdcd8, key=@0xbfefc31c, value=@0xbfefc350)
     at /usr/include/boost/dynamic_property_map.hpp:303
#10 0x0805f17c in
boost::mutate_graph_impl<boost::adjacency_list<boost::vecS, boost::vecS,
boost::directedS, VertexProperties, EdgeProperties, boost::no_property,
boost::listS> >::set_vertex_property (this=0xbfefd9dc, name=@0x807513c,
vertex=@0xbfefc3e4, value=@0xbfefc49c, value_type=@0x807515c)
     at graphml.hpp:203
#11 0x08063729 in graphml_reader::handle_property (this=0xbfefd8f4,
key_id=@0xbfefc4a4, descriptor=@0xbfefc4a0, is_vertex=true,
value=@0xbfefc49c)
     at graphml.cpp:365
#12 0x080643db in graphml_reader::handle_vertex (this=0xbfefd8f4,
v=@0xbfefc528) at graphml.cpp:293
#13 0x080659db in graphml_reader::on_start_element
(user_data=0xbfefd8f4, c_name=0x80751a0 "node", atts=0x8072fd8) at
graphml.cpp:152
#14 0xb7f1935c in XML_ParserCreate () from /usr/lib/libexpat.so.1
#15 0xb7f19e2d in XML_ParserCreate () from /usr/lib/libexpat.so.1
#16 0xb7f1aee4 in XML_ParserCreate () from /usr/lib/libexpat.so.1
#17 0xb7f1bdb5 in XML_ParserCreate () from /usr/lib/libexpat.so.1
#18 0xb7f1362b in XML_ParseBuffer () from /usr/lib/libexpat.so.1
#19 0xb7f1c292 in XML_Parse () from /usr/lib/libexpat.so.1
#20 0x0806649d in graphml_reader::run (this=0xbfefd8f4, in=@0xbfefdb0c)
at graphml.cpp:68
#21 0x08060058 in boost::read_graphml (in=@0xbfefdb0c, g=@0xbfefd9dc) at
graphml.cpp:408
#22 0x08051899 in boost::read_graphml<boost::adjacency_list<boost::vecS,
boost::vecS, boost::directedS, VertexProperties, EdgeProperties,
boost::no_property, boost::listS> > (in=@0xbfefdb0c, g=@0xbfefdcfc,
dp=@0xbfefdcd8) at graphml.hpp:235
#23 0x0804fe26 in main (argc=5 '\005', argv=0xbfefe054) at separator.cpp:328

Any help's appreciated, thanks.

Jens Müller wrote:

struct VertexProperties
{
   float x;
   float y;
};

struct EdgeProperties
{
   float length;
};

My fault - changed this to double, and it worked.

Well, nearly - now it crashes when it reaches the edges:

$ ./separator -f test -i planar100k.graphml
terminate called after throwing an instance of 'boost::property_not_found'
   what(): Property not found: length.
Aborted

Why isn't
   dp.property("length", get(&EdgeProperties::length, g));
sufficient?

Jens Müller wrote:

Jens Müller wrote:

struct VertexProperties
{
  float x;
  float y;
};

struct EdgeProperties
{
  float length;
};

My fault - changed this to double, and it worked.

Well, nearly - now it crashes when it reaches the edges:

$ ./separator -f test -i planar100k.graphml
terminate called after throwing an instance of 'boost::property_not_found'
   what(): Property not found: length.
Aborted

Why isn't
   dp.property("length", get(&EdgeProperties::length, g));
sufficient?

Program received signal SIGABRT, Aborted.
[Switching to Thread -1211529024 (LWP 5247)]
0xffffe410 in __kernel_vsyscall ()
(gdb) bt
#0 0xffffe410 in __kernel_vsyscall ()
#1 0xb7cdf7d0 in raise () from /lib/libc.so.6
#2 0xb7ce0ea3 in abort () from /lib/libc.so.6
#3 0xb7ee13a0 in __gnu_cxx::__verbose_terminate_handler () from
/usr/lib/libstdc++.so.6
#4 0xb7ededc5 in std::set_unexpected () from /usr/lib/libstdc++.so.6
#5 0xb7edee02 in std::terminate () from /usr/lib/libstdc++.so.6
#6 0xb7edef3a in __cxa_throw () from /usr/lib/libstdc++.so.6
#7 0x0805b3c8 in boost::put<boost::adjacency_list<boost::vecS,
boost::vecS, boost::directedS, VertexProperties, EdgeProperties,
boost::no_property, boost::listS>, double> (name=@0x807640c,
dp=@0xbfbfc9e4, key=@0xbfbfca08, value=@0xbfbfb130) at
/usr/include/boost/dynamic_property_map.hpp:284
#8 0x0805b8fe in
boost::mutate_graph_impl<boost::adjacency_list<boost::vecS, boost::vecS,
boost::directedS, VertexProperties, EdgeProperties, boost::no_property,
boost::listS> >::set_graph_property (this=0xbfbfc6ec, name=@0x807640c,
value=@0xbfbfb298, value_type=@0x807642c) at graphml.hpp:203
#9 0x08063805 in graphml_reader::handle_property (this=0xbfbfc604,
key_id=@0xbfbfb2a0, descriptor=@0xbfbfb29c, is_vertex=false,
value=@0xbfbfb298)
     at graphml.cpp:363
#10 0x0806518d in graphml_reader::handle_edge (this=0xbfbfc604,
e=@0xbfbfb320, u=@0xbfbfb31c, v=@0xbfbfb318) at graphml.cpp:355
#11 0x080660c9 in graphml_reader::on_start_element
(user_data=0xbfbfc604, c_name=0x80761a0 "edge", atts=0x8073fe0) at
graphml.cpp:181
#12 0xb7f1435c in XML_ParserCreate () from /usr/lib/libexpat.so.1
#13 0xb7f14e2d in XML_ParserCreate () from /usr/lib/libexpat.so.1
#14 0xb7f0e62b in XML_ParseBuffer () from /usr/lib/libexpat.so.1
#15 0xb7f17292 in XML_Parse () from /usr/lib/libexpat.so.1
#16 0x0806680d in graphml_reader::run (this=0xbfbfc604, in=@0xbfbfc818)
at graphml.cpp:68
#17 0x080603cc in boost::read_graphml (in=@0xbfbfc818, g=@0xbfbfc6ec) at
graphml.cpp:408
#18 0x08051c5b in boost::read_graphml<boost::adjacency_list<boost::vecS,
boost::vecS, boost::directedS, VertexProperties, EdgeProperties,
boost::no_property, boost::listS> > (in=@0xbfbfc818, g=@0xbfbfca08,
dp=@0xbfbfc9e4) at graphml.hpp:235
#19 0x0804fae9 in main (argc=5 '\005', argv=0xbfbfcd54) at separator.cpp:328

Is it trying to set a graph property instead of an edge property?!
-> boost::mutate_graph_impl<...>::set_graph_property (#8)

It seems like it is... Could you please send your graphml file attached,
if it's not very big, or a smaller version that shows the same problem?

Thanks.

Tiago de Paula Peixoto wrote:

Is it trying to set a graph property instead of an edge property?!
-> boost::mutate_graph_impl<...>::set_graph_property (#8)

It seems like it is... Could you please send your graphml file attached,
if it's not very big, or a smaller version that shows the same problem?

I just changed the following in the code:

void handle_property(std::string key_id, std::string descriptor,
                          bool is_vertex, std::string value)
     {
         if (false) // (descriptor == "") <-- workaround?!
             m_g.set_graph_property(m_key_name[key_id], value,
m_key_type[key_id]);
         else if (is_vertex)
             m_g.set_vertex_property(m_key_name[key_id],
get_vertex_descriptor(descriptor), value, m_key_type[key_id]);
         else
             m_g.set_edge_property(m_key_name[key_id],
get_edge_descriptor(descriptor), value, m_key_type[key_id]);
     }

(change in line 362 of graphml.cpp)

$ cat planar10.graphml
<?xml version="1.0"?>

<graphml
xmlns="http://graphml.graphdrawing.org/xmlns/1.0rc&quot;
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&quot;
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/1.0rc
                     graphml-structure-1.0rc.xsd

                     http://graphml.graphdrawing.org/xmlns/1.0rc
                     graphml-attributes-1.0rc.xsd"
>
   <key id="k0" for="node" attr.name="coord1" attr.type="double">
     <desc>First coordinate</desc>
     <default>0</default>
   </key>
   <key id="k1" for="node" attr.name="coord2" attr.type="double">
     <desc>Second coordinate</desc>
     <default>0</default>
   </key>
   <key id="k2" for="edge" attr.name="length" attr.type="double">
     <desc>Distance</desc>
     <default>1</default>
   </key>
   <graph edgedefault="directed">
     <node id="n0">
       <data key="k0">0.0351315</data>
       <data key="k1">0.118342</data>
     </node>
     <node id="n1">
       <data key="k0">0.118659</data>
       <data key="k1">0.691161</data>
     </node>
     <node id="n2">
       <data key="k0">0.166528</data>
       <data key="k1">0.382172</data>
     </node>
     <node id="n3">
       <data key="k0">0.196673</data>
       <data key="k1">0.640841</data>
     </node>
     <node id="n4">
       <data key="k0">0.275214</data>
       <data key="k1">0.517752</data>
     </node>
     <node id="n5">
       <data key="k0">0.382098</data>
       <data key="k1">0.0422192</data>
     </node>
     <node id="n6">
       <data key="k0">0.441136</data>
       <data key="k1">0.485064</data>
     </node>
     <node id="n7">
       <data key="k0">0.747237</data>
       <data key="k1">0.414742</data>
     </node>
     <node id="n8">
       <data key="k0">0.806262</data>
       <data key="k1">0.89162</data>
     </node>
     <node id="n9">
       <data key="k0">0.831375</data>
       <data key="k1">0.128477</data>
     </node>
     <edge source="n0" target="n1">
       <data key="k2">0.578877</data>
     </edge>
     <edge source="n1" target="n0">
       <data key="k2">0.578877</data>
     </edge>
     <edge source="n1" target="n8">
       <data key="k2">0.716227</data>
     </edge>
     <edge source="n8" target="n1">
       <data key="k2">0.716227</data>
     </edge>
   </graph>
</graphml>

should do just the same, but has less nodes :slight_smile:

Tiago de Paula Peixoto wrote:

         if (false) // (descriptor == "") <-- workaround?!

That just breaks graph properties...

     <edge source="n0" target="n1">
       <data key="k2">0.578877</data>
     </edge>

Where are your edge ids? You need them, just like for the nodes...

The graphml reader is not very resilient against xml data which does not
validade, i.e, it doesn't tell you anything. But you can always use a
3rd party xml validator if you want to check if the file is correct.

Ok, I just checked that the ids should be optional... That's a bug in
the reader then. I'll fix it.

Thanks.

Tiago de Paula Peixoto wrote:

Tiago de Paula Peixoto wrote:

        if (false) // (descriptor == "") <-- workaround?!

That just breaks graph properties...

    <edge source="n0" target="n1">
      <data key="k2">0.578877</data>
    </edge>

Where are your edge ids? You need them, just like for the nodes...

Do I?

http://graphml.graphdrawing.org/primer/graphml-primer.html#GraphEdge

"Optionally an identifier for the edge can be specified with the XML
Attribute id. The id XML-Attribute is used, when it is necessary to
reference the edge."

I just found those edge_id_t and vertex_id_t tag in graph.cpp, I will
add them soon ...

Maybe/Probably this is a problem, but I can't understand yet how that
will lead to the strange error message ...

Do I have to supply "edge_id" and "vertex_id" as a dynamic property?

Thanks for your help, and Merry Chrismas!

Jens

Where are your edge ids? You need them, just like for the nodes...

Do I?

GraphML Primer

"Optionally an identifier for the edge can be specified with the XML
Attribute id. The id XML-Attribute is used, when it is necessary to
reference the edge."

Yes, I saw it too (see my other message). I'll fix this later today, and
put it in svn. Meanwhile you can just set some indexes to your edges,
and everything should work.

I just found those edge_id_t and vertex_id_t tag in graph.cpp, I will
add them soon ...

Maybe/Probably this is a problem, but I can't understand yet how that
will lead to the strange error message ...

The problem is that the m_active_descriptor is set to the id of the edge
(which is empty) and later the code thinks that such descriptor means
that the property belongs to the graph, and tries to set the graph_property.

Do I have to supply "edge_id" and "vertex_id" as a dynamic property?

No. Those ids are only used to parse/write the graph, and don't belong
to the actually read/written graph.

Thanks for your help, and Merry Chrismas!

Likewise! And thanks for the bug report.

This should be fixed now in svn. Please tell me if you find any problems.

Ps. I also added xml namespace support, thus fixing
https://projects.forked.de/graph-tool/ticket/11

Tiago de Paula Peixoto wrote:

This should be fixed now in svn. Please tell me if you find any problems.

Thanks, works.