VTK  9.7.1
vtkSMPThreadLocalAPI.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
3 
4 #ifndef vtkSMPThreadLocalAPI_h
5 #define vtkSMPThreadLocalAPI_h
6 
7 #include <array>
8 #include <iterator>
9 #include <memory>
10 
12 #include "SMP/Common/vtkSMPToolsAPI.h" // For GetBackendType(), DefaultBackend
13 #include "vtkSMP.h"
14 #include "vtkSystemIncludes.h"
15 
16 #if VTK_SMP_ENABLE_SEQUENTIAL
18 #endif
19 #if VTK_SMP_ENABLE_STDTHREAD
21 #endif
22 #if VTK_SMP_ENABLE_TBB
24 #endif
25 #if VTK_SMP_ENABLE_OPENMP
27 #endif
28 
29 namespace vtk
30 {
31 namespace detail
32 {
33 namespace smp
34 {
35 VTK_ABI_NAMESPACE_BEGIN
36 
37 template <typename T>
39 {
40 #if VTK_SMP_ENABLE_SEQUENTIAL
41  using ThreadLocalSequential = vtkSMPThreadLocalImpl<BackendType::Sequential, T>;
42 #endif
43 #if VTK_SMP_ENABLE_STDTHREAD
44  using ThreadLocalSTDThread = vtkSMPThreadLocalImpl<BackendType::STDThread, T>;
45 #endif
46 #if VTK_SMP_ENABLE_TBB
47  using ThreadLocalTBB = vtkSMPThreadLocalImpl<BackendType::TBB, T>;
48 #endif
49 #if VTK_SMP_ENABLE_OPENMP
50  using ThreadLocalOpenMP = vtkSMPThreadLocalImpl<BackendType::OpenMP, T>;
51 #endif
53 
54 public:
55  //--------------------------------------------------------------------------------
57  {
58 #if VTK_SMP_ENABLE_SEQUENTIAL
59  this->BackendsImpl[static_cast<int>(BackendType::Sequential)] =
60  std::make_unique<ThreadLocalSequential>();
61 #endif
62 #if VTK_SMP_ENABLE_STDTHREAD
63  this->BackendsImpl[static_cast<int>(BackendType::STDThread)] =
64  std::make_unique<ThreadLocalSTDThread>();
65 #endif
66 #if VTK_SMP_ENABLE_TBB
67  this->BackendsImpl[static_cast<int>(BackendType::TBB)] = std::make_unique<ThreadLocalTBB>();
68 #endif
69 #if VTK_SMP_ENABLE_OPENMP
70  this->BackendsImpl[static_cast<int>(BackendType::OpenMP)] =
71  std::make_unique<ThreadLocalOpenMP>();
72 #endif
73  }
74 
75  //--------------------------------------------------------------------------------
76  explicit vtkSMPThreadLocalAPI(const T& exemplar)
77  {
78 #if VTK_SMP_ENABLE_SEQUENTIAL
79  this->BackendsImpl[static_cast<int>(BackendType::Sequential)] =
80  std::make_unique<ThreadLocalSequential>(exemplar);
81 #endif
82 #if VTK_SMP_ENABLE_STDTHREAD
83  this->BackendsImpl[static_cast<int>(BackendType::STDThread)] =
84  std::make_unique<ThreadLocalSTDThread>(exemplar);
85 #endif
86 #if VTK_SMP_ENABLE_TBB
87  this->BackendsImpl[static_cast<int>(BackendType::TBB)] =
88  std::make_unique<ThreadLocalTBB>(exemplar);
89 #endif
90 #if VTK_SMP_ENABLE_OPENMP
91  this->BackendsImpl[static_cast<int>(BackendType::OpenMP)] =
92  std::make_unique<ThreadLocalOpenMP>(exemplar);
93 #endif
94  }
95 
96  //--------------------------------------------------------------------------------
97  T& Local()
98  {
99  BackendType backendType = this->GetSMPBackendType();
100  return this->BackendsImpl[static_cast<int>(backendType)]->Local();
101  }
102 
103  //--------------------------------------------------------------------------------
104  size_t size()
105  {
106  BackendType backendType = this->GetSMPBackendType();
107  return this->BackendsImpl[static_cast<int>(backendType)]->size();
108  }
109 
110  //--------------------------------------------------------------------------------
111  class iterator
112  {
113  public:
114  using iterator_category = std::forward_iterator_tag;
115  using value_type = T;
116  using difference_type = std::ptrdiff_t;
117  using pointer = T*;
118  using reference = T&;
119 
120  iterator() = default;
121 
122  iterator(const iterator& other)
123  : ImplAbstract(other.ImplAbstract->Clone())
124  {
125  }
126 
127  iterator& operator=(const iterator& other)
128  {
129  if (this != &other)
130  {
131  this->ImplAbstract = other.ImplAbstract->Clone();
132  }
133  return *this;
134  }
135 
137  {
138  this->ImplAbstract->Increment();
139  return *this;
140  }
141 
143  {
144  iterator copy = *this;
145  this->ImplAbstract->Increment();
146  return copy;
147  }
148 
149  bool operator==(const iterator& other) const
150  {
151  return this->ImplAbstract->Compare(other.ImplAbstract.get());
152  }
153 
154  bool operator!=(const iterator& other) const
155  {
156  return !this->ImplAbstract->Compare(other.ImplAbstract.get());
157  }
158 
159  T& operator*() { return this->ImplAbstract->GetContent(); }
160 
161  T* operator->() { return this->ImplAbstract->GetContentPtr(); }
162 
163  private:
164  std::unique_ptr<ItImplAbstract> ImplAbstract;
165 
166  friend class vtkSMPThreadLocalAPI<T>;
167  };
168 
169  //--------------------------------------------------------------------------------
170  iterator begin()
171  {
172  BackendType backendType = this->GetSMPBackendType();
173  iterator iter;
174  iter.ImplAbstract = this->BackendsImpl[static_cast<int>(backendType)]->begin();
175  return iter;
176  }
177 
178  //--------------------------------------------------------------------------------
179  iterator end()
180  {
181  BackendType backendType = this->GetSMPBackendType();
182  iterator iter;
183  iter.ImplAbstract = this->BackendsImpl[static_cast<int>(backendType)]->end();
184  return iter;
185  }
186 
187  // disable copying
190 
191 private:
192  std::array<std::unique_ptr<vtkSMPThreadLocalImplAbstract<T>>, VTK_SMP_MAX_BACKENDS_NB>
193  BackendsImpl;
194 
195  //--------------------------------------------------------------------------------
196  BackendType GetSMPBackendType()
197  {
198  auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
199  return SMPToolsAPI.GetBackendType();
200  }
201 };
202 
203 VTK_ABI_NAMESPACE_END
204 } // namespace smp
205 } // namespace detail
206 } // namespace vtk
207 
208 #endif
209 /* VTK-HeaderTest-Exclude: vtkSMPThreadLocalAPI.h */
vtkSMPThreadLocalAPI & operator=(const vtkSMPThreadLocalAPI &)=delete
static vtkSMPToolsAPI & GetInstance()
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
#define VTK_SMP_MAX_BACKENDS_NB