使用自定义容器并发向量更改提升图邻接列表中的容器生成器

Changing container generator in boost graph adjacency list using custom container concurrent vector

本文关键字:列表 并发 自定义 向量      更新时间:2023-10-16

注意

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


我试图为我的boost邻接列表定义我的自定义容器<>typedef。根据这里的文档,我尝试使用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::internal::concurrent_vector_base_v3::internal_clear(无效()(void,unsigned long))'/cm/shared/apps/intel tbb oss/intel64/42_2013003oss/include/tbb/courrent_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::internal::concurrent_vector_base_v3::~ concurrent_vactor_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::internal::NFS_Free(void*)'/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:错误:ld返回1退出状态

我不知道我做错了什么。我将容器更改为std::list,它运行良好。不知道是什么,我还得补充。根据文档,这至少足以创建一个简单的图形对象。

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

我现在可以将vecS更改为concurrentVecS并使用我的算法。尽管std::vector<>对于读取来说是线程安全的,我想用并发向量来尝试一下。

这是完整的代码。

//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);

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