VTK  9.1.20211115
vtkSMPThreadLocalAPI.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkSMPThreadLocalAPI.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
16 #ifndef vtkSMPThreadLocalAPI_h
17 #define vtkSMPThreadLocalAPI_h
18 
19 #include <array>
20 #include <iterator>
21 #include <memory>
22 
24 #include "SMP/Common/vtkSMPToolsAPI.h" // For GetBackendType(), DefaultBackend
25 #include "vtkSMP.h"
26 #include "vtkSystemIncludes.h"
27 
28 #if VTK_SMP_ENABLE_SEQUENTIAL
30 #endif
31 #if VTK_SMP_ENABLE_STDTHREAD
33 #endif
34 #if VTK_SMP_ENABLE_TBB
36 #endif
37 #if VTK_SMP_ENABLE_OPENMP
39 #endif
40 
41 namespace vtk
42 {
43 namespace detail
44 {
45 namespace smp
46 {
47 
48 template <typename T>
50 {
51 #if VTK_SMP_ENABLE_SEQUENTIAL
52  using ThreadLocalSequential = vtkSMPThreadLocalImpl<BackendType::Sequential, T>;
53 #endif
54 #if VTK_SMP_ENABLE_STDTHREAD
55  using ThreadLocalSTDThread = vtkSMPThreadLocalImpl<BackendType::STDThread, T>;
56 #endif
57 #if VTK_SMP_ENABLE_TBB
58  using ThreadLocalTBB = vtkSMPThreadLocalImpl<BackendType::TBB, T>;
59 #endif
60 #if VTK_SMP_ENABLE_OPENMP
61  using ThreadLocalOpenMP = vtkSMPThreadLocalImpl<BackendType::OpenMP, T>;
62 #endif
64 
65 public:
66  //--------------------------------------------------------------------------------
68  {
69  // XXX(c++14): use std::make_unique
70 #if VTK_SMP_ENABLE_SEQUENTIAL
71  this->BackendsImpl[static_cast<int>(BackendType::Sequential)] =
72  std::unique_ptr<ThreadLocalSequential>(new ThreadLocalSequential());
73 #endif
74 #if VTK_SMP_ENABLE_STDTHREAD
75  this->BackendsImpl[static_cast<int>(BackendType::STDThread)] =
76  std::unique_ptr<ThreadLocalSTDThread>(new ThreadLocalSTDThread());
77 #endif
78 #if VTK_SMP_ENABLE_TBB
79  this->BackendsImpl[static_cast<int>(BackendType::TBB)] =
80  std::unique_ptr<ThreadLocalTBB>(new ThreadLocalTBB());
81 #endif
82 #if VTK_SMP_ENABLE_OPENMP
83  this->BackendsImpl[static_cast<int>(BackendType::OpenMP)] =
84  std::unique_ptr<ThreadLocalOpenMP>(new ThreadLocalOpenMP());
85 #endif
86  }
87 
88  //--------------------------------------------------------------------------------
89  explicit vtkSMPThreadLocalAPI(const T& exemplar)
90  {
91  // XXX(c++14): use std::make_unique
92 #if VTK_SMP_ENABLE_SEQUENTIAL
93  this->BackendsImpl[static_cast<int>(BackendType::Sequential)] =
94  std::unique_ptr<ThreadLocalSequential>(new ThreadLocalSequential(exemplar));
95 #endif
96 #if VTK_SMP_ENABLE_STDTHREAD
97  this->BackendsImpl[static_cast<int>(BackendType::STDThread)] =
98  std::unique_ptr<ThreadLocalSTDThread>(new ThreadLocalSTDThread(exemplar));
99 #endif
100 #if VTK_SMP_ENABLE_TBB
101  this->BackendsImpl[static_cast<int>(BackendType::TBB)] =
102  std::unique_ptr<ThreadLocalTBB>(new ThreadLocalTBB(exemplar));
103 #endif
104 #if VTK_SMP_ENABLE_OPENMP
105  this->BackendsImpl[static_cast<int>(BackendType::OpenMP)] =
106  std::unique_ptr<ThreadLocalOpenMP>(new ThreadLocalOpenMP(exemplar));
107 #endif
108  }
109 
110  //--------------------------------------------------------------------------------
111  T& Local()
112  {
113  BackendType backendType = this->GetSMPBackendType();
114  return this->BackendsImpl[static_cast<int>(backendType)]->Local();
115  }
116 
117  //--------------------------------------------------------------------------------
118  size_t size()
119  {
120  BackendType backendType = this->GetSMPBackendType();
121  return this->BackendsImpl[static_cast<int>(backendType)]->size();
122  }
123 
124  //--------------------------------------------------------------------------------
125  class iterator : public std::iterator<std::forward_iterator_tag, T> // for iterator_traits
126  {
127  public:
128  iterator() = default;
129 
130  iterator(const iterator& other)
131  : ImplAbstract(other.ImplAbstract->Clone())
132  {
133  }
134 
135  iterator& operator=(const iterator& other)
136  {
137  if (this != &other)
138  {
139  this->ImplAbstract = other.ImplAbstract->Clone();
140  }
141  return *this;
142  }
143 
145  {
146  this->ImplAbstract->Increment();
147  return *this;
148  }
149 
151  {
152  iterator copy = *this;
153  this->ImplAbstract->Increment();
154  return copy;
155  }
156 
157  bool operator==(const iterator& other)
158  {
159  return this->ImplAbstract->Compare(other.ImplAbstract.get());
160  }
161 
162  bool operator!=(const iterator& other)
163  {
164  return !this->ImplAbstract->Compare(other.ImplAbstract.get());
165  }
166 
167  T& operator*() { return this->ImplAbstract->GetContent(); }
168 
169  T* operator->() { return this->ImplAbstract->GetContentPtr(); }
170 
171  private:
172  std::unique_ptr<ItImplAbstract> ImplAbstract;
173 
174  friend class vtkSMPThreadLocalAPI<T>;
175  };
176 
177  //--------------------------------------------------------------------------------
179  {
180  BackendType backendType = this->GetSMPBackendType();
181  iterator iter;
182  iter.ImplAbstract = this->BackendsImpl[static_cast<int>(backendType)]->begin();
183  return iter;
184  };
185 
186  //--------------------------------------------------------------------------------
188  {
189  BackendType backendType = this->GetSMPBackendType();
190  iterator iter;
191  iter.ImplAbstract = this->BackendsImpl[static_cast<int>(backendType)]->end();
192  return iter;
193  }
194 
195  // disable copying
198 
199 private:
200  std::array<std::unique_ptr<vtkSMPThreadLocalImplAbstract<T>>, VTK_SMP_MAX_BACKENDS_NB>
201  BackendsImpl;
202 
203  //--------------------------------------------------------------------------------
204  BackendType GetSMPBackendType()
205  {
206  auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
207  return SMPToolsAPI.GetBackendType();
208  }
209 };
210 
211 } // namespace smp
212 } // namespace detail
213 } // namespace vtk
214 
215 #endif
vtkSMPThreadLocalAPI & operator=(const vtkSMPThreadLocalAPI &)=delete
vtkSMPThreadLocalAPI(const vtkSMPThreadLocalAPI &)=delete
static vtkSMPToolsAPI & GetInstance()
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
#define VTK_SMP_MAX_BACKENDS_NB