- 3.0.2 core module.
CppadParallel.h
Go to the documentation of this file.
1 /**********************************************************************************************************************
2 This file is part of the Control Toolbox (https://github.com/ethz-adrl/control-toolbox), copyright by ETH Zurich.
3 Licensed under the BSD-2 license (see LICENSE file in main directory)
4 **********************************************************************************************************************/
5 
6 #pragma once
7 
8 #include <mutex>
9 #include <map>
10 #include <thread>
11 
12 namespace ct {
13 namespace core {
14 
15 #ifdef CPPAD
16 
21 class CppadParallel
22 {
23  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
24 
25 public:
26  static CppadParallel& getInstance()
27  {
28  static CppadParallel instance; // Guaranteed to be destroyed, instantiated on first use.
29  return instance;
30  }
31 
32  static void initParallel(size_t numThreads) { CppadParallel::getInstance().initParallelImpl(numThreads); }
33  static void resetParallel() { CppadParallel::getInstance().resetParallelImpl(); }
34 
35 private:
42  void initParallelImpl(size_t numThreads)
43  {
44  isSequential_ = true;
45  numThreads_ = numThreads;
46 
47  CppAD::thread_alloc::parallel_setup(numThreads_, in_parallel, thread_number);
48 
49  CppAD::thread_alloc::hold_memory(true);
50  CppAD::parallel_ad<double>();
51  isSequential_ = false;
52  }
53 
54  void resetParallelImpl()
55  {
56  threadMap_.clear();
57  isSequential_ = true;
58  CppAD::thread_alloc::parallel_setup(1, CPPAD_NULL, CPPAD_NULL);
59  CppAD::thread_alloc::hold_memory(false);
60  CppAD::parallel_ad<double>();
61  }
62 
63 
64  CppadParallel() : isSequential_(false), numThreads_(100) {}
65  bool isSequential_;
66  std::map<size_t, size_t> threadMap_;
67  size_t numThreads_;
68  std::mutex hashMutex_;
69 
76  static bool in_parallel(void) { return !(CppadParallel::getInstance().isSequential_); }
83  static size_t thread_number(void)
84  {
85  std::thread::id this_id = std::this_thread::get_id();
86  std::hash<std::thread::id> hasher;
87  size_t hashId = hasher(this_id);
88 
89  CppadParallel& instance = CppadParallel::getInstance();
90 
91  instance.hashMutex_.lock();
92  if (instance.threadMap_.size() < instance.numThreads_)
93  if (!instance.threadMap_.count(hashId))
94  instance.threadMap_.insert(std::make_pair(hashId, instance.threadMap_.size()));
95 
96  size_t threadNum = instance.threadMap_[hashId];
97  instance.hashMutex_.unlock();
98 
99  return threadNum;
100  }
101 
102  // singleton stuff
103 public:
104  CppadParallel(CppadParallel const&) = delete;
105  void operator=(CppadParallel const&) = delete;
106 };
107 
108 #endif
109 } // namespace core
110 } // namespace ct