21 #include <boost/shared_ptr.hpp> 22 #include <boost/make_shared.hpp> 26 #include <tbb/scalable_allocator.h> 31 namespace treeTraversal {
36 template<
typename NODE,
typename DATA,
typename VISITOR_PRE,
typename VISITOR_POST>
37 class PreOrderTask :
public tbb::task
40 const boost::shared_ptr<NODE>&
treeNode;
41 boost::shared_ptr<DATA> myData;
42 VISITOR_PRE& visitorPre;
43 VISITOR_POST& visitorPost;
44 int problemSizeThreshold;
47 bool isPostOrderPhase;
49 PreOrderTask(
const boost::shared_ptr<NODE>& treeNode,
const boost::shared_ptr<DATA>& myData,
50 VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost,
int problemSizeThreshold,
51 bool makeNewTasks =
true)
54 visitorPre(visitorPre),
55 visitorPost(visitorPost),
56 problemSizeThreshold(problemSizeThreshold),
57 makeNewTasks(makeNewTasks),
58 isPostOrderPhase(false) {}
60 tbb::task* execute()
override 65 (void) visitorPost(treeNode, *myData);
72 if(!treeNode->children.empty())
75 isPostOrderPhase =
true;
76 recycle_as_continuation();
78 bool overThreshold = (treeNode->problemSize() >= problemSizeThreshold);
80 tbb::task* firstChild = 0;
81 tbb::task_list childTasks;
82 for(
const boost::shared_ptr<NODE>& child: treeNode->children)
87 boost::shared_ptr<DATA> childData = boost::allocate_shared<DATA>(
88 tbb::scalable_allocator<DATA>(), visitorPre(child, *myData));
89 tbb::task* childTask =
90 new (allocate_child()) PreOrderTask(child, childData, visitorPre, visitorPost,
91 problemSizeThreshold, overThreshold);
93 childTasks.push_back(*childTask);
95 firstChild = childTask;
99 set_ref_count((
int)treeNode->children.size());
106 (void) visitorPost(treeNode, *myData);
113 processNodeRecursively(treeNode, *myData);
119 void processNodeRecursively(
const boost::shared_ptr<NODE>& node, DATA& myData)
121 for(
const boost::shared_ptr<NODE>& child: node->children)
123 DATA childData = visitorPre(child, myData);
124 processNodeRecursively(child, childData);
128 (void) visitorPost(node, myData);
133 template<
typename ROOTS,
typename NODE,
typename DATA,
typename VISITOR_PRE,
typename VISITOR_POST>
134 class RootTask :
public tbb::task
139 VISITOR_PRE& visitorPre;
140 VISITOR_POST& visitorPost;
141 int problemSizeThreshold;
142 RootTask(
const ROOTS& roots, DATA& myData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost,
143 int problemSizeThreshold) :
144 roots(roots), myData(myData), visitorPre(visitorPre), visitorPost(visitorPost),
145 problemSizeThreshold(problemSizeThreshold) {}
147 tbb::task* execute()
override 149 typedef PreOrderTask<NODE, DATA, VISITOR_PRE, VISITOR_POST> PreOrderTask;
151 tbb::task_list tasks;
152 for(
const boost::shared_ptr<NODE>&
root: roots)
154 boost::shared_ptr<DATA> rootData = boost::allocate_shared<DATA>(tbb::scalable_allocator<DATA>(), visitorPre(
root, myData));
155 tasks.push_back(*
new(allocate_child())
156 PreOrderTask(
root, rootData, visitorPre, visitorPost, problemSizeThreshold));
159 set_ref_count(1 + (
int) roots.size());
161 spawn_and_wait_for_all(tasks);
167 template<
typename NODE,
typename ROOTS,
typename DATA,
typename VISITOR_PRE,
typename VISITOR_POST>
168 RootTask<ROOTS, NODE, DATA, VISITOR_PRE, VISITOR_POST>&
169 CreateRootTask(
const ROOTS& roots, DATA& rootData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost,
int problemSizeThreshold)
171 typedef RootTask<ROOTS, NODE, DATA, VISITOR_PRE, VISITOR_POST> RootTask;
172 return *
new(tbb::task::allocate_root()) RootTask(roots, rootData, visitorPre, visitorPost, problemSizeThreshold);
const boost::shared_ptr< NODE > & treeNode
const mpreal root(const mpreal &x, unsigned long int k, mp_rnd_t r=mpreal::get_default_rnd())
Included from all GTSAM files.