Revert "replace deprecated tbb functionality"
							parent
							
								
									3ab3f466c0
								
							
						
					
					
						commit
						f819b1a03f
					
				| 
						 | 
					@ -158,8 +158,9 @@ void DepthFirstForestParallel(FOREST& forest, DATA& rootData,
 | 
				
			||||||
  // Typedefs
 | 
					  // Typedefs
 | 
				
			||||||
  typedef typename FOREST::Node Node;
 | 
					  typedef typename FOREST::Node Node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  tbb::task::spawn_root_and_wait(
 | 
				
			||||||
      internal::CreateRootTask<Node>(forest.roots(), rootData, visitorPre,
 | 
					      internal::CreateRootTask<Node>(forest.roots(), rootData, visitorPre,
 | 
				
			||||||
      visitorPost, problemSizeThreshold);
 | 
					          visitorPost, problemSizeThreshold));
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
  DepthFirstForest(forest, rootData, visitorPre, visitorPost);
 | 
					  DepthFirstForest(forest, rootData, visitorPre, visitorPost);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@
 | 
				
			||||||
#include <boost/make_shared.hpp>
 | 
					#include <boost/make_shared.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef GTSAM_USE_TBB
 | 
					#ifdef GTSAM_USE_TBB
 | 
				
			||||||
#include <tbb/task_group.h>         // tbb::task_group
 | 
					#include <tbb/task.h>               // tbb::task, tbb::task_list
 | 
				
			||||||
#include <tbb/scalable_allocator.h> // tbb::scalable_allocator
 | 
					#include <tbb/scalable_allocator.h> // tbb::scalable_allocator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace gtsam {
 | 
					namespace gtsam {
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,7 @@ namespace gtsam {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /* ************************************************************************* */
 | 
					      /* ************************************************************************* */
 | 
				
			||||||
      template<typename NODE, typename DATA, typename VISITOR_PRE, typename VISITOR_POST>
 | 
					      template<typename NODE, typename DATA, typename VISITOR_PRE, typename VISITOR_POST>
 | 
				
			||||||
      class PreOrderTask
 | 
					      class PreOrderTask : public tbb::task
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
      public:
 | 
					      public:
 | 
				
			||||||
        const boost::shared_ptr<NODE>& treeNode;
 | 
					        const boost::shared_ptr<NODE>& treeNode;
 | 
				
			||||||
| 
						 | 
					@ -42,30 +42,28 @@ namespace gtsam {
 | 
				
			||||||
        VISITOR_PRE& visitorPre;
 | 
					        VISITOR_PRE& visitorPre;
 | 
				
			||||||
        VISITOR_POST& visitorPost;
 | 
					        VISITOR_POST& visitorPost;
 | 
				
			||||||
        int problemSizeThreshold;
 | 
					        int problemSizeThreshold;
 | 
				
			||||||
        tbb::task_group& tg;
 | 
					 | 
				
			||||||
        bool makeNewTasks;
 | 
					        bool makeNewTasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Keep track of order phase across multiple calls to the same functor
 | 
					        bool isPostOrderPhase;
 | 
				
			||||||
        mutable bool isPostOrderPhase;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        PreOrderTask(const boost::shared_ptr<NODE>& treeNode, const boost::shared_ptr<DATA>& myData,
 | 
					        PreOrderTask(const boost::shared_ptr<NODE>& treeNode, const boost::shared_ptr<DATA>& myData,
 | 
				
			||||||
                     VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost, int problemSizeThreshold,
 | 
					                     VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost, int problemSizeThreshold,
 | 
				
			||||||
                     tbb::task_group& tg, bool makeNewTasks = true)
 | 
					                     bool makeNewTasks = true)
 | 
				
			||||||
            : treeNode(treeNode),
 | 
					            : treeNode(treeNode),
 | 
				
			||||||
              myData(myData),
 | 
					              myData(myData),
 | 
				
			||||||
              visitorPre(visitorPre),
 | 
					              visitorPre(visitorPre),
 | 
				
			||||||
              visitorPost(visitorPost),
 | 
					              visitorPost(visitorPost),
 | 
				
			||||||
              problemSizeThreshold(problemSizeThreshold),
 | 
					              problemSizeThreshold(problemSizeThreshold),
 | 
				
			||||||
              tg(tg),
 | 
					 | 
				
			||||||
              makeNewTasks(makeNewTasks),
 | 
					              makeNewTasks(makeNewTasks),
 | 
				
			||||||
              isPostOrderPhase(false) {}
 | 
					              isPostOrderPhase(false) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void operator()() const
 | 
					        tbb::task* execute() override
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          if(isPostOrderPhase)
 | 
					          if(isPostOrderPhase)
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            // Run the post-order visitor since this task was recycled to run the post-order visitor
 | 
					            // Run the post-order visitor since this task was recycled to run the post-order visitor
 | 
				
			||||||
            (void) visitorPost(treeNode, *myData);
 | 
					            (void) visitorPost(treeNode, *myData);
 | 
				
			||||||
 | 
					            return nullptr;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
| 
						 | 
					@ -73,10 +71,14 @@ namespace gtsam {
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              if(!treeNode->children.empty())
 | 
					              if(!treeNode->children.empty())
 | 
				
			||||||
              {
 | 
					              {
 | 
				
			||||||
 | 
					                // Allocate post-order task as a continuation
 | 
				
			||||||
 | 
					                isPostOrderPhase = true;
 | 
				
			||||||
 | 
					                recycle_as_continuation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                bool overThreshold = (treeNode->problemSize() >= problemSizeThreshold);
 | 
					                bool overThreshold = (treeNode->problemSize() >= problemSizeThreshold);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // If we have child tasks, start subtasks and wait for them to complete
 | 
					                tbb::task* firstChild = 0;
 | 
				
			||||||
                tbb::task_group ctg;
 | 
					                tbb::task_list childTasks;
 | 
				
			||||||
                for(const boost::shared_ptr<NODE>& child: treeNode->children)
 | 
					                for(const boost::shared_ptr<NODE>& child: treeNode->children)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                  // Process child in a subtask.  Important:  Run visitorPre before calling
 | 
					                  // Process child in a subtask.  Important:  Run visitorPre before calling
 | 
				
			||||||
| 
						 | 
					@ -84,30 +86,37 @@ namespace gtsam {
 | 
				
			||||||
                  // allocated an extra child, this causes a TBB error.
 | 
					                  // allocated an extra child, this causes a TBB error.
 | 
				
			||||||
                  boost::shared_ptr<DATA> childData = boost::allocate_shared<DATA>(
 | 
					                  boost::shared_ptr<DATA> childData = boost::allocate_shared<DATA>(
 | 
				
			||||||
                      tbb::scalable_allocator<DATA>(), visitorPre(child, *myData));
 | 
					                      tbb::scalable_allocator<DATA>(), visitorPre(child, *myData));
 | 
				
			||||||
                  ctg.run(PreOrderTask(child, childData, visitorPre, visitorPost,
 | 
					                  tbb::task* childTask =
 | 
				
			||||||
                      problemSizeThreshold, ctg, overThreshold));
 | 
					                      new (allocate_child()) PreOrderTask(child, childData, visitorPre, visitorPost,
 | 
				
			||||||
 | 
					                                                          problemSizeThreshold, overThreshold);
 | 
				
			||||||
 | 
					                  if (firstChild)
 | 
				
			||||||
 | 
					                    childTasks.push_back(*childTask);
 | 
				
			||||||
 | 
					                  else
 | 
				
			||||||
 | 
					                    firstChild = childTask;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                ctg.wait();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Allocate post-order task as a continuation
 | 
					                // If we have child tasks, start subtasks and wait for them to complete
 | 
				
			||||||
                isPostOrderPhase = true;
 | 
					                set_ref_count((int)treeNode->children.size());
 | 
				
			||||||
                tg.run(*this);
 | 
					                spawn(childTasks);
 | 
				
			||||||
 | 
					                return firstChild;
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
              else
 | 
					              else
 | 
				
			||||||
              {
 | 
					              {
 | 
				
			||||||
                // Run the post-order visitor in this task if we have no children
 | 
					                // Run the post-order visitor in this task if we have no children
 | 
				
			||||||
                (void) visitorPost(treeNode, *myData);
 | 
					                (void) visitorPost(treeNode, *myData);
 | 
				
			||||||
 | 
					                return nullptr;
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
              // Process this node and its children in this task
 | 
					              // Process this node and its children in this task
 | 
				
			||||||
              processNodeRecursively(treeNode, *myData);
 | 
					              processNodeRecursively(treeNode, *myData);
 | 
				
			||||||
 | 
					              return nullptr;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void processNodeRecursively(const boost::shared_ptr<NODE>& node, DATA& myData) const
 | 
					        void processNodeRecursively(const boost::shared_ptr<NODE>& node, DATA& myData)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          for(const boost::shared_ptr<NODE>& child: node->children)
 | 
					          for(const boost::shared_ptr<NODE>& child: node->children)
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
| 
						 | 
					@ -122,7 +131,7 @@ namespace gtsam {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /* ************************************************************************* */
 | 
					      /* ************************************************************************* */
 | 
				
			||||||
      template<typename ROOTS, typename NODE, typename DATA, typename VISITOR_PRE, typename VISITOR_POST>
 | 
					      template<typename ROOTS, typename NODE, typename DATA, typename VISITOR_PRE, typename VISITOR_POST>
 | 
				
			||||||
      class RootTask
 | 
					      class RootTask : public tbb::task
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
      public:
 | 
					      public:
 | 
				
			||||||
        const ROOTS& roots;
 | 
					        const ROOTS& roots;
 | 
				
			||||||
| 
						 | 
					@ -130,30 +139,37 @@ namespace gtsam {
 | 
				
			||||||
        VISITOR_PRE& visitorPre;
 | 
					        VISITOR_PRE& visitorPre;
 | 
				
			||||||
        VISITOR_POST& visitorPost;
 | 
					        VISITOR_POST& visitorPost;
 | 
				
			||||||
        int problemSizeThreshold;
 | 
					        int problemSizeThreshold;
 | 
				
			||||||
        tbb::task_group& tg;
 | 
					 | 
				
			||||||
        RootTask(const ROOTS& roots, DATA& myData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost,
 | 
					        RootTask(const ROOTS& roots, DATA& myData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost,
 | 
				
			||||||
          int problemSizeThreshold, tbb::task_group& tg) :
 | 
					          int problemSizeThreshold) :
 | 
				
			||||||
          roots(roots), myData(myData), visitorPre(visitorPre), visitorPost(visitorPost),
 | 
					          roots(roots), myData(myData), visitorPre(visitorPre), visitorPost(visitorPost),
 | 
				
			||||||
          problemSizeThreshold(problemSizeThreshold), tg(tg) {}
 | 
					          problemSizeThreshold(problemSizeThreshold) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void operator()() const
 | 
					        tbb::task* execute() override
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          typedef PreOrderTask<NODE, DATA, VISITOR_PRE, VISITOR_POST> PreOrderTask;
 | 
					          typedef PreOrderTask<NODE, DATA, VISITOR_PRE, VISITOR_POST> PreOrderTask;
 | 
				
			||||||
          // Create data and tasks for our children
 | 
					          // Create data and tasks for our children
 | 
				
			||||||
 | 
					          tbb::task_list tasks;
 | 
				
			||||||
          for(const boost::shared_ptr<NODE>& root: roots)
 | 
					          for(const boost::shared_ptr<NODE>& root: roots)
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            boost::shared_ptr<DATA> rootData = boost::allocate_shared<DATA>(tbb::scalable_allocator<DATA>(), visitorPre(root, myData));
 | 
					            boost::shared_ptr<DATA> rootData = boost::allocate_shared<DATA>(tbb::scalable_allocator<DATA>(), visitorPre(root, myData));
 | 
				
			||||||
            tg.run(PreOrderTask(root, rootData, visitorPre, visitorPost, problemSizeThreshold, tg));
 | 
					            tasks.push_back(*new(allocate_child())
 | 
				
			||||||
 | 
					              PreOrderTask(root, rootData, visitorPre, visitorPost, problemSizeThreshold));
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					          // Set TBB ref count
 | 
				
			||||||
 | 
					          set_ref_count(1 + (int) roots.size());
 | 
				
			||||||
 | 
					          // Spawn tasks
 | 
				
			||||||
 | 
					          spawn_and_wait_for_all(tasks);
 | 
				
			||||||
 | 
					          // Return nullptr
 | 
				
			||||||
 | 
					          return nullptr;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      template<typename NODE, typename ROOTS, typename DATA, typename VISITOR_PRE, typename VISITOR_POST>
 | 
					      template<typename NODE, typename ROOTS, typename DATA, typename VISITOR_PRE, typename VISITOR_POST>
 | 
				
			||||||
      void CreateRootTask(const ROOTS& roots, DATA& rootData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost, int problemSizeThreshold)
 | 
					      RootTask<ROOTS, NODE, DATA, VISITOR_PRE, VISITOR_POST>&
 | 
				
			||||||
 | 
					        CreateRootTask(const ROOTS& roots, DATA& rootData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost, int problemSizeThreshold)
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
          typedef RootTask<ROOTS, NODE, DATA, VISITOR_PRE, VISITOR_POST> RootTask;
 | 
					          typedef RootTask<ROOTS, NODE, DATA, VISITOR_PRE, VISITOR_POST> RootTask;
 | 
				
			||||||
          tbb::task_group tg;
 | 
					          return *new(tbb::task::allocate_root()) RootTask(roots, rootData, visitorPre, visitorPost, problemSizeThreshold);
 | 
				
			||||||
          tg.run_and_wait(RootTask(roots, rootData, visitorPre, visitorPost, problemSizeThreshold, tg));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue