Another method of small node agglomeration

release/4.3a0
Richard Roberts 2013-07-26 18:00:34 +00:00
parent 6f780ea87b
commit b5e221be89
1 changed files with 22 additions and 37 deletions

View File

@ -70,66 +70,51 @@ namespace gtsam {
VISITOR_PRE& visitorPre; VISITOR_PRE& visitorPre;
VISITOR_POST& visitorPost; VISITOR_POST& visitorPost;
int problemSizeThreshold; int problemSizeThreshold;
bool makeNewTasks;
PreOrderTask(const boost::shared_ptr<NODE>& treeNode, const DATA& myData, PreOrderTask(const boost::shared_ptr<NODE>& treeNode, const DATA& myData,
VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost, int problemSizeThreshold) : VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost, int problemSizeThreshold,
bool makeNewTasks = true) :
treeNode(treeNode), myData(myData), visitorPre(visitorPre), visitorPost(visitorPost), treeNode(treeNode), myData(myData), visitorPre(visitorPre), visitorPost(visitorPost),
problemSizeThreshold(problemSizeThreshold) {} problemSizeThreshold(problemSizeThreshold), makeNewTasks(makeNewTasks) {}
typedef ParallelTraversalNode<NODE, DATA> ParallelTraversalNode; typedef ParallelTraversalNode<NODE, DATA> ParallelTraversalNode;
tbb::task* execute() tbb::task* execute()
{ {
// Shared data
int problemSize = 0;
//std::cout << "New task: " << std::endl;
//BOOST_FOREACH(Key j, treeNode->keys)
// std::cout << j << " ";
//std::cout << std::endl;
// Process this node and its children // Process this node and its children
processNode(treeNode, myData, problemSize); processNode(treeNode, myData);
// Return NULL // Return NULL
return NULL; return NULL;
} }
void processNode(const boost::shared_ptr<NODE>& node, DATA& myData, int& problemSize) void processNode(const boost::shared_ptr<NODE>& node, DATA& myData)
{ {
tbb::task_list childTasks; if(makeNewTasks)
int nChildTasks = 0;
// Increment problem size for this node
problemSize += node->problemSize();
// Visit children until problem size exceeds a threshold, then spawn a new task
BOOST_FOREACH(const boost::shared_ptr<NODE>& child, node->children)
{ {
if(problemSize < problemSizeThreshold) bool overThreshold = (node->problemSize() >= problemSizeThreshold);
{
//std::cout << "problemSize = " << problemSize << std::endl; tbb::task_list childTasks;
//BOOST_FOREACH(Key j, child->keys) BOOST_FOREACH(const boost::shared_ptr<NODE>& child, node->children)
// std::cout << j << " ";
//std::cout << std::endl;
// Process child sequentially (recursive call will increase problem size for children
DATA childData = visitorPre(child, myData);
processNode(child, childData, problemSize);
}
else
{ {
// Process child in a subtask // Process child in a subtask
childTasks.push_back(*new(allocate_child()) childTasks.push_back(*new(allocate_child())
PreOrderTask(child, visitorPre(child, myData), visitorPre, visitorPost, problemSizeThreshold)); PreOrderTask(child, visitorPre(child, myData), visitorPre, visitorPost,
++ nChildTasks; problemSizeThreshold, overThreshold));
} }
}
// If we have child tasks, start subtasks and wait for them to complete // If we have child tasks, start subtasks and wait for them to complete
if(nChildTasks > 0) { set_ref_count(1 + node->children.size());
set_ref_count(1 + nChildTasks);
spawn(childTasks); spawn(childTasks);
wait_for_all(); wait_for_all();
} }
else
{
BOOST_FOREACH(const boost::shared_ptr<NODE>& child, node->children)
{
processNode(child, visitorPre(child, myData));
}
}
// Run the post-order visitor // Run the post-order visitor
(void) visitorPost(node, myData); (void) visitorPost(node, myData);