#include <deal.II/base/function.h>
#include <deal.II/base/logstream.h>
#include <deal.II/base/table_handler.h>
+#include <deal.II/base/thread_management.h>
#include <deal.II/base/work_stream.h>
#include <deal.II/lac/vector.h>
#include <deal.II/lac/full_matrix.h>
Vector<double> rhs;
};
-#ifdef DEAL_II_WITH_THREADS
-
- // Tasks in TBB must be derived from tbb::task and override tbb::task*
- // execute.
- // The purpose of HangingNodeTask is to apply execute DoFTools::make_hanging_node_constraints.
- struct HangingNodeTask : public tbb::task
- {
- HangingNodeTask (const DoFHandler<dim> &dof_handler,ConstraintMatrix &hanging_node_constraints) :
- dof_handler(&dof_handler),
- hanging_node_constraints(& hanging_node_constraints) {}
-
- tbb::task* execute()
- {
- DoFTools::make_hanging_node_constraints(*dof_handler,*hanging_node_constraints);
-
- return NULL;
- }
-
- const DoFHandler<dim>* dof_handler;
- ConstraintMatrix* hanging_node_constraints;
- };
-
-
-
- // The purpose of SparsityPatternTask is to create the sparsity pattern.
- struct SparsityPatternTask : public tbb::task
- {
- SparsityPatternTask (const DoFHandler<dim> &dof_handler,SparsityPattern &sparsity_pattern) :
- dof_handler(&dof_handler),
- sparsity_pattern(&sparsity_pattern) {}
-
- tbb::task* execute()
- {
- sparsity_pattern->reinit (dof_handler->n_dofs(),
- dof_handler->n_dofs(),
- dof_handler->max_couplings_between_dofs());
- DoFTools::make_sparsity_pattern (*dof_handler, *sparsity_pattern);
-
- return NULL;
- }
-
- const DoFHandler<dim>* dof_handler;
- SparsityPattern* sparsity_pattern;
- };
-
-#endif
// Finally, there is a pair of functions which will be used to assemble
// the actual system matrix. It calls the virtual function assembling
{
hanging_node_constraints.clear ();
-#ifdef DEAL_II_WITH_THREADS
- tbb::task_scheduler_init init;
- // Create an empty task to be the parent of the two tasks that we need.
- tbb::empty_task* empty_task = new (tbb::task::allocate_root()) tbb::empty_task;
- // Set the reference count to 3 (number of children+1 because
- // wati_for_all returns when ref_count is one).
- empty_task->set_ref_count(3);
-
- HangingNodeTask* hanging_node_task =
- new (empty_task->allocate_child()) HangingNodeTask(dof_handler,hanging_node_constraints);
- SparsityPatternTask* sparsity_pattern_task =
- new (empty_task->allocate_child()) SparsityPatternTask(dof_handler,sparsity_pattern);
-
- // Spawn the two tasks
- empty_task->spawn(*hanging_node_task);
- empty_task->spawn(*sparsity_pattern_task);
-
- // Wait for children to finish
- empty_task->wait_for_all();
- // empty_task must be destroy manually because it does not return.
- empty_task->destroy(*empty_task);
-#else
- DoFTools::make_hanging_node_constraints(dof_handler,hanging_node_constraints);
+ void (*mhnc_p) (const DoFHandler<dim> &,
+ ConstraintMatrix &)
+ = &DoFTools::make_hanging_node_constraints;
+
+ // Start a side task then continue on the main thread
+ Threads::Task<> side_task(std_cxx1x::bind(mhnc_p,std_cxx1x::cref(dof_handler),
+ std_cxx1x::ref(hanging_node_constraints)));
sparsity_pattern.reinit (dof_handler.n_dofs(),
dof_handler.n_dofs(),
dof_handler.max_couplings_between_dofs());
DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
-#endif
+
+ // Wait for the side task to be done before going further
+ side_task.join();
hanging_node_constraints.close ();
hanging_node_constraints.condense (sparsity_pattern);
#include <deal.II/base/quadrature_lib.h>
#include <deal.II/base/function.h>
#include <deal.II/base/logstream.h>
+#include <deal.II/base/thread_management.h>
#include <deal.II/base/work_stream.h>
#include <deal.II/lac/vector.h>
#include <deal.II/lac/full_matrix.h>
Vector<double> rhs;
};
-#ifdef DEAL_II_WITH_THREADS
-
- struct HangingNodeTask : public tbb::task
- {
- HangingNodeTask (const DoFHandler<dim> &dof_handler,ConstraintMatrix &hanging_node_constraints) :
- dof_handler(&dof_handler),
- hanging_node_constraints(& hanging_node_constraints) {}
-
- tbb::task* execute()
- {
- DoFTools::make_hanging_node_constraints(*dof_handler,*hanging_node_constraints);
-
- return NULL;
- }
-
- const DoFHandler<dim>* dof_handler;
- ConstraintMatrix* hanging_node_constraints;
- };
-
- struct SparsityPatternTask : public tbb::task
- {
- SparsityPatternTask (const DoFHandler<dim> &dof_handler,SparsityPattern &sparsity_pattern) :
- dof_handler(&dof_handler),
- sparsity_pattern(&sparsity_pattern) {}
-
- tbb::task* execute()
- {
- sparsity_pattern->reinit (dof_handler->n_dofs(),
- dof_handler->n_dofs(),
- dof_handler->max_couplings_between_dofs());
- DoFTools::make_sparsity_pattern (*dof_handler, *sparsity_pattern);
-
- return NULL;
- }
-
- const DoFHandler<dim>* dof_handler;
- SparsityPattern* sparsity_pattern;
- };
-
-#endif
void
assemble_linear_system (LinearSystem &linear_system);
{
hanging_node_constraints.clear ();
-#ifdef DEAL_II_WITH_THREADS
- tbb::task_scheduler_init init;
- // Create an empty task to be the parent of the two tasks that we need.
- tbb::empty_task* empty_task = new (tbb::task::allocate_root()) tbb::empty_task;
- // Set the reference count to 3 (number of children+1)
- empty_task->set_ref_count(3);
-
- HangingNodeTask* hanging_node_task =
- new (empty_task->allocate_child()) HangingNodeTask(dof_handler,hanging_node_constraints);
- SparsityPatternTask* sparsity_pattern_task =
- new (empty_task->allocate_child()) SparsityPatternTask(dof_handler,sparsity_pattern);
-
- empty_task->spawn(*hanging_node_task);
- empty_task->spawn(*sparsity_pattern_task);
+ void (*mhnc_p) (const DoFHandler<dim> &,
+ ConstraintMatrix &)
+ = &DoFTools::make_hanging_node_constraints;
- // Wait for children to finish
- empty_task->wait_for_all();
- empty_task->destroy(*empty_task);
-#else
- DoFTools::make_hanging_node_constraints(dof_handler,hanging_node_constraints);
+ Threads::Task<> side_task(std_cxx1x::bind(mhnc_p,std_cxx1x::cref(dof_handler),
+ std_cxx1x::ref(hanging_node_constraints)));
sparsity_pattern.reinit (dof_handler.n_dofs(),
- dof_handler.n_dofs(),
- dof_handler.max_couplings_between_dofs());
+ dof_handler.n_dofs(),
+ dof_handler.max_couplings_between_dofs());
DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
-#endif
+
+ side_task.join();
hanging_node_constraints.close ();
hanging_node_constraints.condense (sparsity_pattern);
void
WeightedResidual<dim>::solve_problem ()
{
- Threads::ThreadGroup<> threads;
- threads += Threads::new_thread (&WeightedResidual<dim>::solve_primal_problem,
- *this);
- threads += Threads::new_thread (&WeightedResidual<dim>::solve_dual_problem,
- *this);
- threads.join_all ();
+ Threads::TaskGroup<> tasks;
+ tasks += Threads::Task<> (std_cxx1x::bind(&WeightedResidual<dim>::solve_primal_problem,
+ std_cxx1x::ref(*this)));
+ tasks += Threads::Task<> (std_cxx1x::bind(&WeightedResidual<dim>::solve_dual_problem,
+ std_cxx1x::ref(*this)));
+ tasks.join_all();
}