Viskores  1.0
TryExecute.h
Go to the documentation of this file.
1 //============================================================================
2 // The contents of this file are covered by the Viskores license. See
3 // LICENSE.txt for details.
4 //
5 // By contributing to this file, all contributors agree to the Developer
6 // Certificate of Origin Version 1.1 (DCO 1.1) as stated in DCO.txt.
7 //============================================================================
8 
9 //============================================================================
10 // Copyright (c) Kitware, Inc.
11 // All rights reserved.
12 // See LICENSE.txt for details.
13 //
14 // This software is distributed WITHOUT ANY WARRANTY; without even
15 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 // PURPOSE. See the above copyright notice for more information.
17 //============================================================================
18 #ifndef viskores_cont_TryExecute_h
19 #define viskores_cont_TryExecute_h
20 
24 #include <viskores/cont/Logging.h>
26 
27 
28 namespace viskores
29 {
30 namespace cont
31 {
32 
33 namespace detail
34 {
35 
36 VISKORES_CONT_EXPORT void HandleTryExecuteException(viskores::cont::DeviceAdapterId,
38  const std::string& functorName);
39 
40 template <typename DeviceTag, typename Functor, typename... Args>
41 inline bool TryExecuteIfValid(std::true_type,
42  DeviceTag tag,
43  Functor&& f,
46  Args&&... args)
47 {
48  if ((tag == devId || devId == DeviceAdapterTagAny()) && tracker.CanRunOn(tag))
49  {
50  try
51  {
52  if (tracker.CheckForAbortRequest())
53  {
55  }
56 
57  return f(tag, std::forward<Args>(args)...);
58  }
59  catch (...)
60  {
61  detail::HandleTryExecuteException(tag, tracker, viskores::cont::TypeToString<Functor>());
62  }
63  }
64 
65  // If we are here, then the functor was either never run or failed.
66  return false;
67 }
68 
69 template <typename DeviceTag, typename Functor, typename... Args>
70 inline bool TryExecuteIfValid(std::false_type,
71  DeviceTag,
72  Functor&&,
75  Args&&...)
76 {
77  return false;
78 }
79 
80 struct TryExecuteWrapper
81 {
82  template <typename DeviceTag, typename Functor, typename... Args>
83  inline void operator()(DeviceTag tag,
84  Functor&& f,
87  bool& ran,
88  Args&&... args) const
89  {
90  if (!ran)
91  {
92  ran = TryExecuteIfValid(std::integral_constant<bool, DeviceTag::IsEnabled>(),
93  tag,
94  std::forward<Functor>(f),
95  devId,
96  std::forward<decltype(tracker)>(tracker),
97  std::forward<Args>(args)...);
98  }
99  }
100 };
101 
102 template <typename Functor, typename DeviceList, typename... Args>
103 inline bool TryExecuteImpl(viskores::cont::DeviceAdapterId devId,
104  Functor&& functor,
105  std::true_type,
106  DeviceList list,
107  Args&&... args)
108 {
109  bool success = false;
110  auto& tracker = viskores::cont::GetRuntimeDeviceTracker();
111  TryExecuteWrapper task;
113  list,
114  std::forward<Functor>(functor),
115  devId,
116  tracker,
117  success,
118  std::forward<Args>(args)...);
119  return success;
120 }
121 
122 template <typename Functor, typename... Args>
123 inline bool TryExecuteImpl(viskores::cont::DeviceAdapterId devId,
124  Functor&& functor,
125  std::false_type,
126  Args&&... args)
127 {
128  bool success = false;
129  auto& tracker = viskores::cont::GetRuntimeDeviceTracker();
130  TryExecuteWrapper task;
133  std::forward<Functor>(functor),
134  devId,
135  tracker,
136  success,
137  std::forward<Args>(args)...);
138  return success;
139 }
140 } // namespace detail
141 
185 template <typename Functor>
187 {
188  //we haven't been passed either a runtime tracker or a device list
189  return detail::TryExecuteImpl(devId, std::forward<Functor>(functor), std::false_type{});
190 }
191 template <typename Functor, typename Arg1, typename... Args>
193  Functor&& functor,
194  Arg1&& arg1,
195  Args&&... args)
196 {
197  //determine if we are being passed a device adapter or runtime tracker as our argument
198  using is_deviceAdapter = viskores::internal::IsList<Arg1>;
199 
200  return detail::TryExecuteImpl(devId,
201  std::forward<Functor>(functor),
202  is_deviceAdapter{},
203  std::forward<Arg1>(arg1),
204  std::forward<Args>(args)...);
205 }
206 
208 
251 template <typename Functor, typename... Args>
252 VISKORES_CONT bool TryExecute(Functor&& functor, Args&&... args)
253 {
255  std::forward<Functor>(functor),
256  std::forward<Args>(args)...);
257 }
258 
259 
261 }
262 } // namespace viskores::cont
263 
264 #endif //viskores_cont_TryExecute_h
RuntimeDeviceTracker.h
viskores::cont::GetRuntimeDeviceTracker
viskores::cont::RuntimeDeviceTracker & GetRuntimeDeviceTracker()
Get the RuntimeDeviceTracker for the current thread.
DeviceAdapterTag.h
DeviceAdapterList.h
viskores::cont::DeviceAdapterTagAny
Tag for a device adapter used to specify that any device may be used for an operation.
Definition: DeviceAdapterTag.h:194
viskores::cont::ErrorUserAbort
This class is thrown when viskores detects a request for aborting execution in the current thread.
Definition: ErrorUserAbort.h:33
ErrorUserAbort.h
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::cont::TryExecute
bool TryExecute(Functor &&functor, Args &&... args)
Try to execute a functor on a set of devices until one succeeds.
Definition: TryExecute.h:252
viskores::cont::TryExecuteOnDevice
bool TryExecuteOnDevice(viskores::cont::DeviceAdapterId devId, Functor &&functor)
Try to execute a functor on a specific device selected at runtime.
Definition: TryExecute.h:186
viskores::cont::DeviceAdapterId
An object used to specify a device.
Definition: DeviceAdapterTag.h:66
viskores::ListForEach
void ListForEach(Functor &&f, viskores::List< Ts... >, Args &&... args)
For each typename represented by the list, call the functor with a default instance of that type.
Definition: List.h:745
viskores::cont::RuntimeDeviceTracker
RuntimeDeviceTracker is the central location for determining which device adapter will be active for ...
Definition: RuntimeDeviceTracker.h:55
viskores::cont::RuntimeDeviceTracker::CanRunOn
bool CanRunOn(DeviceAdapterId deviceId) const
Returns true if the given device adapter is supported on the current machine.
Logging.h
Logging utilities.
VISKORES_DEFAULT_DEVICE_ADAPTER_LIST
#define VISKORES_DEFAULT_DEVICE_ADAPTER_LIST
Definition: DeviceAdapterList.h:22
viskores::cont::RuntimeDeviceTracker::CheckForAbortRequest
bool CheckForAbortRequest() const