Reference documentation for deal.II version 9.3.2
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
multithread_info.cc
Go to the documentation of this file.
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2020 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
17 #include <deal.II/base/utilities.h>
18 
19 #include <algorithm>
20 #include <cstdlib> // for std::getenv
21 #include <thread>
22 
23 #ifdef DEAL_II_WITH_TBB
24 # include <tbb/task_scheduler_init.h>
25 #endif
26 
27 
29 
30 
31 unsigned int
33 {
34  // There is a slight semantic change between our n_cores() call and the
35  // std::thread alternative: in case of an error the latter one returns 0
36  // in contrast to a 1 that n_cores() used to do. For compatibility, let's
37  // translate to our numbering scheme:
38  const unsigned int n_cores = std::thread::hardware_concurrency();
39  return n_cores == 0 ? 1 : n_cores;
40 }
41 
42 
43 void
44 MultithreadInfo::set_thread_limit(const unsigned int max_threads)
45 {
46  // set the maximal number of threads to the given value as specified
47  n_max_threads = max_threads;
48 
49  // then also see if something was given in the environment
50  {
51  if (const char *penv = std::getenv("DEAL_II_NUM_THREADS"))
52  {
53  unsigned int max_threads_env = numbers::invalid_unsigned_int;
54  try
55  {
56  max_threads_env = Utilities::string_to_int(std::string(penv));
57  }
58  catch (...)
59  {
61  false,
62  ExcMessage(
63  std::string(
64  "When specifying the <DEAL_II_NUM_THREADS> environment "
65  "variable, it needs to be something that can be interpreted "
66  "as an integer. The text you have in the environment "
67  "variable is <") +
68  penv + ">"));
69  }
70 
71  AssertThrow(max_threads_env > 0,
72  ExcMessage(
73  "When specifying the <DEAL_II_NUM_THREADS> environment "
74  "variable, it needs to be a positive number."));
75 
77  n_max_threads = std::min(n_max_threads, max_threads_env);
78  else
79  n_max_threads = max_threads_env;
80  }
81  }
82 
83  // If we have not set the number of allowed threads yet, just default to
84  // the number of available cores
87 
88 #ifdef DEAL_II_WITH_TBB
89  // Initialize the scheduler and destroy the old one before doing so
90  static tbb::task_scheduler_init dummy(tbb::task_scheduler_init::deferred);
91  if (dummy.is_active())
92  dummy.terminate();
93  dummy.initialize(n_max_threads);
94 #endif
95 }
96 
97 
98 
99 unsigned int
101 {
103  return n_max_threads;
104 }
105 
106 
107 
108 bool
110 {
111  return n_threads() == 1;
112 }
113 
114 
115 
116 std::size_t
118 {
119  // only simple data elements, so use sizeof operator
120  return sizeof(MultithreadInfo);
121 }
122 
123 
124 
125 void
127 {
128  static bool done = false;
129  if (done)
130  return;
131 
133  done = true;
134 }
135 
137 
138 namespace
139 {
140  // Force the first call to set_thread_limit happen before any tasks in TBB are
141  // used. This is necessary as tbb::task_scheduler_init has no effect if TBB
142  // got automatically initialized (which happens the first time we use it).
143  struct DoOnce
144  {
145  DoOnce()
146  {
148  }
149  } do_once;
150 } // namespace
151 
static unsigned int n_max_threads
MultithreadInfo()=delete
static bool is_running_single_threaded()
static void initialize_multithreading()
static unsigned int n_cores()
static unsigned int n_threads()
static void set_thread_limit(const unsigned int max_threads=numbers::invalid_unsigned_int)
static std::size_t memory_consumption()
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:396
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:397
static ::ExceptionBase & ExcInternalError()
#define Assert(cond, exc)
Definition: exceptions.h:1465
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
Definition: exceptions.h:1575
int string_to_int(const std::string &s)
Definition: utilities.cc:608
static const unsigned int invalid_unsigned_int
Definition: types.h:196