VTK-m  2.0
TryExecute.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_cont_TryExecute_h
11 #define vtk_m_cont_TryExecute_h
12 
16 #include <vtkm/cont/Logging.h>
18 
19 
20 namespace vtkm
21 {
22 namespace cont
23 {
24 
25 namespace detail
26 {
27 
28 VTKM_CONT_EXPORT void HandleTryExecuteException(vtkm::cont::DeviceAdapterId,
30  const std::string& functorName);
31 
32 template <typename DeviceTag, typename Functor, typename... Args>
33 inline bool TryExecuteIfValid(std::true_type,
34  DeviceTag tag,
35  Functor&& f,
38  Args&&... args)
39 {
40  if ((tag == devId || devId == DeviceAdapterTagAny()) && tracker.CanRunOn(tag))
41  {
42  try
43  {
44  if (tracker.CheckForAbortRequest())
45  {
47  }
48 
49  return f(tag, std::forward<Args>(args)...);
50  }
51  catch (...)
52  {
53  detail::HandleTryExecuteException(tag, tracker, vtkm::cont::TypeToString<Functor>());
54  }
55  }
56 
57  // If we are here, then the functor was either never run or failed.
58  return false;
59 }
60 
61 template <typename DeviceTag, typename Functor, typename... Args>
62 inline bool TryExecuteIfValid(std::false_type,
63  DeviceTag,
64  Functor&&,
67  Args&&...)
68 {
69  return false;
70 }
71 
72 struct TryExecuteWrapper
73 {
74  template <typename DeviceTag, typename Functor, typename... Args>
75  inline void operator()(DeviceTag tag,
76  Functor&& f,
79  bool& ran,
80  Args&&... args) const
81  {
82  if (!ran)
83  {
84  ran = TryExecuteIfValid(std::integral_constant<bool, DeviceTag::IsEnabled>(),
85  tag,
86  std::forward<Functor>(f),
87  devId,
88  std::forward<decltype(tracker)>(tracker),
89  std::forward<Args>(args)...);
90  }
91  }
92 };
93 
94 template <typename Functor, typename DeviceList, typename... Args>
95 inline bool TryExecuteImpl(vtkm::cont::DeviceAdapterId devId,
96  Functor&& functor,
97  std::true_type,
98  DeviceList list,
99  Args&&... args)
100 {
101  bool success = false;
102  auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
103  TryExecuteWrapper task;
104  vtkm::ListForEach(task,
105  list,
106  std::forward<Functor>(functor),
107  devId,
108  tracker,
109  success,
110  std::forward<Args>(args)...);
111  return success;
112 }
113 
114 template <typename Functor, typename... Args>
115 inline bool TryExecuteImpl(vtkm::cont::DeviceAdapterId devId,
116  Functor&& functor,
117  std::false_type,
118  Args&&... args)
119 {
120  bool success = false;
121  auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
122  TryExecuteWrapper task;
123  vtkm::ListForEach(task,
125  std::forward<Functor>(functor),
126  devId,
127  tracker,
128  success,
129  std::forward<Args>(args)...);
130  return success;
131 }
132 } // namespace detail
133 
177 template <typename Functor>
179 {
180  //we haven't been passed either a runtime tracker or a device list
181  return detail::TryExecuteImpl(devId, std::forward<Functor>(functor), std::false_type{});
182 }
183 template <typename Functor, typename Arg1, typename... Args>
185  Functor&& functor,
186  Arg1&& arg1,
187  Args&&... args)
188 {
189  //determine if we are being passed a device adapter or runtime tracker as our argument
190  using is_deviceAdapter = vtkm::internal::IsList<Arg1>;
191 
192  return detail::TryExecuteImpl(devId,
193  std::forward<Functor>(functor),
194  is_deviceAdapter{},
195  std::forward<Arg1>(arg1),
196  std::forward<Args>(args)...);
197 }
198 
200 
243 template <typename Functor, typename... Args>
244 VTKM_CONT bool TryExecute(Functor&& functor, Args&&... args)
245 {
246  return TryExecuteOnDevice(
247  vtkm::cont::DeviceAdapterTagAny(), std::forward<Functor>(functor), std::forward<Args>(args)...);
248 }
249 
250 
252 }
253 } // namespace vtkm::cont
254 
255 #endif //vtk_m_cont_TryExecute_h
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
RuntimeDeviceTracker.h
vtkm::cont::RuntimeDeviceTracker::CheckForAbortRequest
VTKM_CONT bool CheckForAbortRequest() const
DeviceAdapterTag.h
DeviceAdapterList.h
vtkm::ListForEach
VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_CONT void ListForEach(Functor &&f, vtkm::List< Ts... >, Args &&... args)
Definition: List.h:720
vtkm::cont::TryExecuteOnDevice
VTKM_CONT bool TryExecuteOnDevice(vtkm::cont::DeviceAdapterId devId, Functor &&functor)
Try to execute a functor on a specific device selected at runtime.
Definition: TryExecute.h:178
ErrorUserAbort.h
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::cont::ErrorUserAbort
This class is thrown when vtk-m detects a request for aborting execution in the current thread.
Definition: ErrorUserAbort.h:25
vtkm::cont::RuntimeDeviceTracker
RuntimeDeviceTracker is the central location for determining which device adapter will be active for ...
Definition: RuntimeDeviceTracker.h:47
VTKM_DEFAULT_DEVICE_ADAPTER_LIST
#define VTKM_DEFAULT_DEVICE_ADAPTER_LIST
Definition: DeviceAdapterList.h:14
vtkm::cont::DeviceAdapterId
Definition: DeviceAdapterTag.h:52
vtkm::cont::RuntimeDeviceTracker::CanRunOn
VTKM_CONT bool CanRunOn(DeviceAdapterId deviceId) const
Returns true if the given device adapter is supported on the current machine.
vtkm::cont::GetRuntimeDeviceTracker
VTKM_CONT_EXPORT VTKM_CONT vtkm::cont::RuntimeDeviceTracker & GetRuntimeDeviceTracker()
Get the RuntimeDeviceTracker for the current thread.
Logging.h
Logging utilities.
vtkm::cont::TryExecute
VTKM_CONT bool TryExecute(Functor &&functor, Args &&... args)
Try to execute a functor on a set of devices until one succeeds.
Definition: TryExecute.h:244