<commit_before>//-------------------------------------------------------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2006, 2008, 2009, 2010, 2011 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//-------------------------------------------------------------------------

/**
 * @defgroup threads Parallel computing with multiple processors accessing shared memory
 * @ingroup Parallel
 *
 * @brief A module discussing the use of parallelism on shared memory
 * machines. See the detailed documentation and
 * @ref MTToC "Table of Contents" below the lenghty list of members
 * of this module.
 *
 * On machines with more than one processor (or multicore processors),
 * it is often profitable to run several parts of the computations in
 * %parallel. For example, one could have several threads running in
 * %parallel, each of which assembles the cell matrices of a subset of
 * the triangulation and then writes them into the global
 * matrix. Since assembling matrices is often an expensive operation,
 * this frequently leads to significant savings in compute time on
 * multiprocessor machines.
 *
 * deal.II supports operations running in %parallel on shared-memory
 * (SMP) machines through the functions and classes in the Threads
 * namespace. The MultithreadInfo class allows to query certain
 * properties of the system, such as the number of CPUs. These
 * facilities for %parallel computing are described in the
 * following. The step-9, step-13, step-14, step-32, step-35 and
 * step-37 tutorial programs also show their use in practice, with the
 * ones starting with step-32 using a more modern style of doing
 * things in which essentially we describe <i>what</i> can be done in
 * %parallel, while the older tutorial programs describe <i>how</i>
 * things have to be done in %parallel.
 *
 * On the other hand, programs running on distributed memory machines
 * (i.e. clusters) need a different programming model built on top of MPI and
 * PETSc or Trilinos. This is described in the step-17, step-18 and step-32
 * example programs.
 *
 * @anchor MTToC
 * <table class="tutorial" width="50%">
 * <tr><th><b>%Table of contents</b></th></tr>
 * <tr><td width="100%" valign="top">
 * <ol>
 *  <li> @ref MTTasks "Task-based parallelism"
 *  <li> @ref MTUsing "Using tasks from within deal.II"
 *  <li> @ref MTHow "How scheduling tasks works and when task-based programming is not efficient"
 *  <li> @ref MTSimpleLoops "Abstractions for tasks: Simple loops"
 *  <li> @ref MTComplexLoops "Abstractions for tasks: More complex loops"
 *  <li> @ref MTWorkStream "Abstractions for tasks: Work streams"
 *  <li> @ref MTTaskSynchronization "Tasks and synchronization"
 *  <li> @ref MTThreads "Thread-based parallelism"
 *  <li> @ref MTTaskThreads "Controlling the number of threads used for tasks"
 * </ol> </td> </tr> </table>
 *
 *
 * @anchor MTTasks
 * <h3>Task-based parallelism</h3>
 *
 * The traditional view of parallelism on shared memory machines has been to
 * decompose a program into <i>threads</i>, i.e. running different parts of
 * the program in %parallel <i>at the same time</i> (if there are more threads
 * than processor cores on your machine, the operating system will run each
 * thread round-robin for a brief amount of time before switching execution to
 * another thread, thereby simulating that threads run
 * concurrently). deal.II's facilities for threads are described below (see
 * @ref MTThreads "Thread-based parallelism"), but we would first like to
 * discuss an abstraction that is often more suitable than threads:
 * <i>tasks</i>.
 *
 * Tasks are essentially the individual parts of a program. Some of them are
 * independent, whereas others depend on previous tasks to be completed
 * first. By way of example, consider the typical layout of a part of the
 * <code>setup_dofs</code> function that most of the tutorial programs have:
 * @code
1  dof_handler.distribute_dofs (fe);
2  DoFTools::make_hanging_node_constraints (dof_handler, hanging_node_constraints);
3  DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
4  hanging_node_constraints.condense (sparsity_pattern);
 * @endcode
 *
 * Here, each of the operations require a significant amount of
 * computations. But note that not all of them depend on each other: clearly
 * we can not run statements 2-4 before 1, and 4 needs to wait for the
 * completion of statements 2 and 3. But statements 2 and 3 are independent:
 * they could be run in any order, or in %parallel. In essence, we have
 * identified four <i>tasks</i>, some of which are dependent on each other,
 * whereas others are independent. In the current example, tasks are
 * identified with individual C++ statements, but often they more
 * generally coincide with entire code blocks.
 *
 * The point here is this: To exploit the independence of tasks 2 and 3, we
 * could start two threads and run each task on its own thread; we would then
 * wait for the two threads to finish (an operation called "joining a thread")
 * and go on with statement 4. As discussed in more detail below, code to
 * achieve this would look like this:<commit_msg>add a TODO<commit_after>//-------------------------------------------------------------------------
//    $Id$
//    Version: $Name$
//
//    Copyright (C) 2006, 2008, 2009, 2010, 2011 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//-------------------------------------------------------------------------

/**
 * @defgroup threads Parallel computing with multiple processors accessing shared memory
 * @ingroup Parallel
 *
 * @brief A module discussing the use of parallelism on shared memory
 * machines. See the detailed documentation and
 * @ref MTToC "Table of Contents" below the lenghty list of members
 * of this module.
 *
 * On machines with more than one processor (or multicore processors),
 * it is often profitable to run several parts of the computations in
 * %parallel. For example, one could have several threads running in
 * %parallel, each of which assembles the cell matrices of a subset of
 * the triangulation and then writes them into the global
 * matrix. Since assembling matrices is often an expensive operation,
 * this frequently leads to significant savings in compute time on
 * multiprocessor machines.
 *
 * deal.II supports operations running in %parallel on shared-memory
 * (SMP) machines through the functions and classes in the Threads
 * namespace. The MultithreadInfo class allows to query certain
 * properties of the system, such as the number of CPUs. These
 * facilities for %parallel computing are described in the
 * following. The step-9, step-13, step-14, step-32, step-35 and
 * step-37 tutorial programs also show their use in practice, with the
 * ones starting with step-32 using a more modern style of doing
 * things in which essentially we describe <i>what</i> can be done in
 * %parallel, while the older tutorial programs describe <i>how</i>
 * things have to be done in %parallel.
 *
 * On the other hand, programs running on distributed memory machines
 * (i.e. clusters) need a different programming model built on top of MPI and
 * PETSc or Trilinos. This is described in the step-17, step-18 and step-32
 * example programs.
 *
 * @anchor MTToC
 * <table class="tutorial" width="50%">
 * <tr><th><b>%Table of contents</b></th></tr>
 * <tr><td width="100%" valign="top">
 * <ol>
 *  <li> @ref MTTasks "Task-based parallelism"
 *  <li> @ref MTUsing "Using tasks from within deal.II"
 *  <li> @ref MTHow "How scheduling tasks works and when task-based programming is not efficient"
 *  <li> @ref MTSimpleLoops "Abstractions for tasks: Simple loops"
 *  <li> @ref MTComplexLoops "Abstractions for tasks: More complex loops"
 *  <li> @ref MTWorkStream "Abstractions for tasks: Work streams"
 *  <li> @ref MTTaskSynchronization "Tasks and synchronization"
 *  <li> @ref MTThreads "Thread-based parallelism"
 *  <li> @ref MTTaskThreads "Controlling the number of threads used for tasks"
 * </ol> </td> </tr> </table>
 *
 *
 * @anchor MTTasks
 * <h3>Task-based parallelism</h3>
 *
 * The traditional view of parallelism on shared memory machines has been to
 * decompose a program into <i>threads</i>, i.e. running different parts of
 * the program in %parallel <i>at the same time</i> (if there are more threads
 * than processor cores on your machine, the operating system will run each
 * thread round-robin for a brief amount of time before switching execution to
 * another thread, thereby simulating that threads run
 * concurrently). deal.II's facilities for threads are described below (see
 * @ref MTThreads "Thread-based parallelism"), but we would first like to
 * discuss an abstraction that is often more suitable than threads:
 * <i>tasks</i>.
 *
 * Tasks are essentially the individual parts of a program. Some of them are
 * independent, whereas others depend on previous tasks to be completed
 * first. By way of example, consider the typical layout of a part of the
 * <code>setup_dofs</code> function that most of the tutorial programs have:
 * @code
1  dof_handler.distribute_dofs (fe);
2  DoFTools::make_hanging_node_constraints (dof_handler, hanging_node_constraints);
3  DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern);
4  hanging_node_constraints.condense (sparsity_pattern);
 * @endcode
 *
 * Here, each of the operations require a significant amount of
 * computations. But note that not all of them depend on each other: clearly
 * we can not run statements 2-4 before 1, and 4 needs to wait for the
 * completion of statements 2 and 3. But statements 2 and 3 are independent:
 * they could be run in any order, or in %parallel. In essence, we have
 * identified four <i>tasks</i>, some of which are dependent on each other,
 * whereas others are independent. In the current example, tasks are
 * identified with individual C++ statements, but often they more
 * generally coincide with entire code blocks.
 *
 * @todo The following does not seem to be about task based, but
 * rather thread based parallelism. I am not yet sufficiently familiar
 * with the content of this page to remove it with confidence,
 * though. GK
 * 
 * The point here is this: To exploit the independence of tasks 2 and 3, we
 * could start two threads and run each task on its own thread; we would then
 * wait for the two threads to finish (an operation called "joining a thread")
 * and go on with statement 4. As discussed in more detail below, code to
 * achieve this would look like this:
{'fraction_non_alphanumeric': 0.10301369863013699, 'fraction_numerical': 0.011141552511415525, 'mean_word_length': 3.538334024036469, 'pattern_counts': {'":': 0, '<': 81, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1877264', 'n_tokens_mistral': 2977, 'n_tokens_neox': 2835, 'n_words': 1470}