使用自定义容器并发向量在boost图形邻接列表中更改容器生成器

时间:2014-04-28 06:44:29

标签: c++ c++11 boost tbb boost-graph

注意

请删除此问题的重复标记。虽然错误是由于缺少-ltbb标志,但问题的主要动机是如何更改boost图中的container_generator以使用您自己的特定容器,例如TBB提供的并发向量。人们可能会忽略已回答的问题,因为它被标记为重复。


我试图为我的boost adjacency_list&lt;&gt;定义我的自定义容器的typedef。根据文档here,我尝试使用tbb::concurrent_vector<>作为自定义容器。这是我的代码,我收到以下错误:

#include <boost/graph/adjacency_list.hpp>
#include "tbb/concurrent_vector.h"

struct concVecS { };

namespace boost {
template <class ValueType>
    struct container_gen<concVecS, ValueType> {
    //typedef std::list<ValueType> type;
    typedef tbb::concurrent_vector<ValueType> type;
};

template<>
struct parallel_edge_traits<concVecS > {
    typedef allow_parallel_edge_tag type;
};

}

typedef boost::adjacency_list <concVecS, boost::vecS, boost::directedS> MyGraph;

int main(int, char*[]) 
{
    MyGraph g(5);

    return 0;
}

错误:

  

/tmp/cc3YbTER.o:在功能上   tbb::concurrent_vector<boost::detail::sep_<unsigned long, boost::no_property>, tbb::cache_aligned_allocator<boost::detail::sep_<unsigned long, boost::no_property> > >::~concurrent_vector()': /cm/shared/apps/intel-tbb-oss/intel64/42_20131003oss/include/tbb/concurrent_vector.h:888: undefined reference to TBB ::内部:: concurrent_vector_base_v3 :: internal_clear(空隙   ()(void ,unsigned long))'   /cm/shared/apps/intel-tbb-oss/intel64/42_20131003oss/include/tbb/concurrent_vector.h:890:   未定义的引用   tbb::internal::concurrent_vector_base_v3::~concurrent_vector_base_v3()' /cm/shared/apps/intel-tbb-oss/intel64/42_20131003oss/include/tbb/concurrent_vector.h:890: undefined reference to TBB ::内部:: concurrent_vector_base_v3 ::〜concurrent_vector_base_v3()”   /tmp/cc3YbTER.o:在功能上   tbb::cache_aligned_allocator<boost::detail::sep_<unsigned long, boost::no_property> >::deallocate(boost::detail::sep_<unsigned long, boost::no_property>*, unsigned long)': /cm/shared/apps/intel-tbb-oss/intel64/42_20131003oss/include/tbb/cache_aligned_allocator.h:96: undefined reference to TBB ::内部:: NFS_Free(无效*)”   /tmp/cc3YbTER.o:在功能上   tbb::cache_aligned_allocator<boost::detail::sep_<unsigned long, boost::no_property> >::allocate(unsigned long, void const*)': /cm/shared/apps/intel-tbb-oss/intel64/42_20131003oss/include/tbb/cache_aligned_allocator.h:91: undefined reference to tbb :: internal :: NFS_Allocate(unsigned long,   unsigned long,void *)'collect2:error:ld返回1退出状态

我不知道我在做什么错。我将容器更改为std::list并且工作正常。不知道它是什么我必须添加更多。根据文档,这至少足以创建一个简单的图形对象。

1 个答案:

答案 0 :(得分:1)

感谢Jeremy Siek博士在此链接here提供的评论,我能够定义自己的容器类型即。 concurrent_vector到boost / pending /文件夹中的container_traits.hpp文件。

我现在可以将vecS更改为concurrentVecS并使用我的算法。虽然std :: vector&lt;&gt;读取是线程安全的,我想用并发向量来尝试这个。

这是完成的代码。

//in container_traits.hpp  --> added the following code 
//boost/pending/container_traits.hpp  file

//concurrent vector
struct concurrent_vector_tag :
  virtual public random_access_container_tag,
  virtual public back_insertion_sequence_tag {  };

template <class T, class Alloc>
concurrent_vector_tag  container_category(const tbb::concurrent_vector<T, Alloc>&) {
  return concurrent_vector_tag();
}

template <class T, class Alloc>
unstable_tag  iterator_stability(const tbb::concurrent_vector<T, Alloc>&) {
  return unstable_tag();
}

 #if !defined BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION 
 template <class T, class Alloc>
 struct container_traits< tbb::concurrent_vector <T, Alloc> > {
   typedef  concurrent_vector_tag  category;
   typedef  unstable_tag  iterator_stability;
 };
 #endif


 //in my custom_container.hpp file     
#include "tbb/concurrent_vector.h"
#include <boost/graph/adjacency_list.hpp>

namespace boost {

struct cvecS {  };  //concurrent vector selector

template <class ValueType>
struct container_gen <cvecS, ValueType> {
    typedef tbb::concurrent_vector <ValueType> type;
};

template<>
struct parallel_edge_traits<cvecS > {
  typedef allow_parallel_edge_tag type;
};

}; //namespace



// in my main file 
typedef boost::adjacency_list <boost::cvecS, boost::cvecS, boost::undirectedS> Graph_t

Graph_t g (5);
Graph_t::vertex_descriptor v1, v2; 
 v1 = boost::add_vertex(g); 
 v2 = boost::add_vertex(g);
 boost::add_edge(v1, v2, g);

PS:我不确定,但我猜,在这种情况下不需要添加push()和erase()函数,因为concurrent_vector.h文件已经提供了它们。