24 #include <tbb/task_group.h>
25 #include <tbb/scalable_allocator.h>
30 namespace treeTraversal {
35 template<
typename NODE,
typename DATA,
typename VISITOR_PRE,
typename VISITOR_POST>
39 const std::shared_ptr<NODE>&
treeNode;
40 std::shared_ptr<DATA> myData;
41 VISITOR_PRE& visitorPre;
42 VISITOR_POST& visitorPost;
43 int problemSizeThreshold;
48 mutable bool isPostOrderPhase;
50 PreOrderTask(
const std::shared_ptr<NODE>&
treeNode,
const std::shared_ptr<DATA>& myData,
51 VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost,
int problemSizeThreshold,
52 tbb::task_group& tg,
bool makeNewTasks =
true)
55 visitorPre(visitorPre),
56 visitorPost(visitorPost),
57 problemSizeThreshold(problemSizeThreshold),
59 makeNewTasks(makeNewTasks),
60 isPostOrderPhase(false) {}
67 (void) visitorPost(
treeNode, *myData);
75 bool overThreshold = (
treeNode->problemSize() >= problemSizeThreshold);
79 for(
const std::shared_ptr<NODE>& child:
treeNode->children)
84 std::shared_ptr<DATA> childData = std::allocate_shared<DATA>(
85 tbb::scalable_allocator<DATA>(), visitorPre(child, *myData));
86 ctg.run(PreOrderTask(child, childData, visitorPre, visitorPost,
87 problemSizeThreshold, ctg, overThreshold));
92 isPostOrderPhase =
true;
98 (void) visitorPost(
treeNode, *myData);
104 processNodeRecursively(
treeNode, *myData);
109 void processNodeRecursively(
const std::shared_ptr<NODE>& node, DATA& myData)
const
111 for(
const std::shared_ptr<NODE>& child: node->children)
113 DATA childData = visitorPre(child, myData);
114 processNodeRecursively(child, childData);
118 (void) visitorPost(node, myData);
123 template<
typename ROOTS,
typename NODE,
typename DATA,
typename VISITOR_PRE,
typename VISITOR_POST>
129 VISITOR_PRE& visitorPre;
130 VISITOR_POST& visitorPost;
131 int problemSizeThreshold;
133 RootTask(
const ROOTS& roots, DATA& myData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost,
134 int problemSizeThreshold, tbb::task_group& tg) :
135 roots(roots), myData(myData), visitorPre(visitorPre), visitorPost(visitorPost),
136 problemSizeThreshold(problemSizeThreshold), tg(tg) {}
140 typedef PreOrderTask<NODE, DATA, VISITOR_PRE, VISITOR_POST> PreOrderTask;
142 for(
const std::shared_ptr<NODE>& root: roots)
144 std::shared_ptr<DATA> rootData = std::allocate_shared<DATA>(tbb::scalable_allocator<DATA>(), visitorPre(root, myData));
145 tg.run(PreOrderTask(root, rootData, visitorPre, visitorPost, problemSizeThreshold, tg));
150 template<
typename NODE,
typename ROOTS,
typename DATA,
typename VISITOR_PRE,
typename VISITOR_POST>
151 void CreateRootTask(
const ROOTS& roots, DATA& rootData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost,
int problemSizeThreshold)
153 typedef RootTask<ROOTS, NODE, DATA, VISITOR_PRE, VISITOR_POST> RootTask;
155 tg.run_and_wait(RootTask(roots, rootData, visitorPre, visitorPost, problemSizeThreshold, tg));