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_Algorithm_h
11 #define vtk_m_cont_Algorithm_h
12 
13 #include <vtkm/Types.h>
14 
15 #include <vtkm/cont/BitField.h>
16 #include <vtkm/cont/DeviceAdapter.h>
17 #include <vtkm/cont/ExecutionObjectBase.h>
18 #include <vtkm/cont/Token.h>
19 #include <vtkm/cont/TryExecute.h>
20 
21 
22 namespace vtkm
23 {
24 namespace cont
25 {
26 /// @cond NONE
27 namespace detail
28 {
29 template <typename Device, typename T>
30 inline auto DoPrepareArgForExec(T&& object, vtkm::cont::Token& token, std::true_type) -> decltype(
31   vtkm::cont::internal::CallPrepareForExecution(std::forward<T>(object), Device{}, token))
32 {
33   VTKM_IS_EXECUTION_OBJECT(T);
34   return vtkm::cont::internal::CallPrepareForExecution(std::forward<T>(object), Device{}, token);
35 }
36 
37 template <typename Device, typename T>
DoPrepareArgForExec(T && object,vtkm::cont::Token &,std::false_type)38 inline T&& DoPrepareArgForExec(T&& object, vtkm::cont::Token&, std::false_type)
39 {
40   static_assert(!vtkm::cont::internal::IsExecutionObjectBase<T>::value,
41                 "Internal error: failed to detect execution object.");
42   return std::forward<T>(object);
43 }
44 
45 template <typename Device, typename T>
46 auto PrepareArgForExec(T&& object, vtkm::cont::Token& token)
47   -> decltype(DoPrepareArgForExec<Device>(std::forward<T>(object),
48                                           token,
49                                           vtkm::cont::internal::IsExecutionObjectBase<T>{}))
50 {
51   return DoPrepareArgForExec<Device>(
52     std::forward<T>(object), token, vtkm::cont::internal::IsExecutionObjectBase<T>{});
53 }
54 
55 struct BitFieldToUnorderedSetFunctor
56 {
57   vtkm::Id Result{ 0 };
58 
59   template <typename Device, typename... Args>
operatorBitFieldToUnorderedSetFunctor60   VTKM_CONT bool operator()(Device, Args&&... args)
61   {
62     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
63     vtkm::cont::Token token;
64     this->Result = vtkm::cont::DeviceAdapterAlgorithm<Device>::BitFieldToUnorderedSet(
65       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
66     return true;
67   }
68 };
69 
70 struct CopyFunctor
71 {
72   template <typename Device, typename... Args>
operatorCopyFunctor73   VTKM_CONT bool operator()(Device, Args&&... args) const
74   {
75     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
76     vtkm::cont::Token token;
77     vtkm::cont::DeviceAdapterAlgorithm<Device>::Copy(
78       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
79     return true;
80   }
81 };
82 
83 struct CopyIfFunctor
84 {
85 
86   template <typename Device, typename... Args>
operatorCopyIfFunctor87   VTKM_CONT bool operator()(Device, Args&&... args) const
88   {
89     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
90     vtkm::cont::Token token;
91     vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(
92       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
93     return true;
94   }
95 };
96 
97 struct CopySubRangeFunctor
98 {
99   bool valid;
100 
CopySubRangeFunctorCopySubRangeFunctor101   CopySubRangeFunctor()
102     : valid(false)
103   {
104   }
105 
106   template <typename Device, typename... Args>
operatorCopySubRangeFunctor107   VTKM_CONT bool operator()(Device, Args&&... args)
108   {
109     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
110     vtkm::cont::Token token;
111     valid = vtkm::cont::DeviceAdapterAlgorithm<Device>::CopySubRange(
112       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
113     return true;
114   }
115 };
116 
117 struct CountSetBitsFunctor
118 {
119   vtkm::Id PopCount{ 0 };
120 
121   template <typename Device, typename... Args>
operatorCountSetBitsFunctor122   VTKM_CONT bool operator()(Device, Args&&... args)
123   {
124     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
125     vtkm::cont::Token token;
126     this->PopCount = vtkm::cont::DeviceAdapterAlgorithm<Device>::CountSetBits(
127       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
128     return true;
129   }
130 };
131 
132 struct FillFunctor
133 {
134   template <typename Device, typename... Args>
operatorFillFunctor135   VTKM_CONT bool operator()(Device, Args&&... args)
136   {
137     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
138     vtkm::cont::Token token;
139     vtkm::cont::DeviceAdapterAlgorithm<Device>::Fill(
140       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
141     return true;
142   }
143 };
144 
145 struct LowerBoundsFunctor
146 {
147 
148   template <typename Device, typename... Args>
operatorLowerBoundsFunctor149   VTKM_CONT bool operator()(Device, Args&&... args) const
150   {
151     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
152     vtkm::cont::Token token;
153     vtkm::cont::DeviceAdapterAlgorithm<Device>::LowerBounds(
154       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
155     return true;
156   }
157 };
158 
159 template <typename U>
160 struct ReduceFunctor
161 {
162   U result;
163 
ReduceFunctorReduceFunctor164   ReduceFunctor()
165     : result(vtkm::TypeTraits<U>::ZeroInitialization())
166   {
167   }
168 
169   template <typename Device, typename... Args>
operatorReduceFunctor170   VTKM_CONT bool operator()(Device, Args&&... args)
171   {
172     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
173     vtkm::cont::Token token;
174     result = vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(
175       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
176     return true;
177   }
178 };
179 
180 struct ReduceByKeyFunctor
181 {
182   template <typename Device, typename... Args>
operatorReduceByKeyFunctor183   VTKM_CONT bool operator()(Device, Args&&... args) const
184   {
185     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
186     vtkm::cont::Token token;
187     vtkm::cont::DeviceAdapterAlgorithm<Device>::ReduceByKey(
188       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
189     return true;
190   }
191 };
192 
193 template <typename U>
194 struct ScanInclusiveResultFunctor
195 {
196   U result;
197 
ScanInclusiveResultFunctorScanInclusiveResultFunctor198   ScanInclusiveResultFunctor()
199     : result(vtkm::TypeTraits<U>::ZeroInitialization())
200   {
201   }
202 
203   template <typename Device, typename... Args>
operatorScanInclusiveResultFunctor204   VTKM_CONT bool operator()(Device, Args&&... args)
205   {
206     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
207     vtkm::cont::Token token;
208     result = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanInclusive(
209       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
210     return true;
211   }
212 };
213 
214 struct ScanInclusiveByKeyFunctor
215 {
ScanInclusiveByKeyFunctorScanInclusiveByKeyFunctor216   ScanInclusiveByKeyFunctor() {}
217 
218   template <typename Device, typename... Args>
operatorScanInclusiveByKeyFunctor219   VTKM_CONT bool operator()(Device, Args&&... args) const
220   {
221     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
222     vtkm::cont::Token token;
223     vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanInclusiveByKey(
224       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
225     return true;
226   }
227 };
228 
229 template <typename T>
230 struct ScanExclusiveFunctor
231 {
232   T result;
233 
ScanExclusiveFunctorScanExclusiveFunctor234   ScanExclusiveFunctor()
235     : result(T())
236   {
237   }
238 
239   template <typename Device, typename... Args>
operatorScanExclusiveFunctor240   VTKM_CONT bool operator()(Device, Args&&... args)
241   {
242     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
243     vtkm::cont::Token token;
244     result = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusive(
245       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
246     return true;
247   }
248 };
249 
250 struct ScanExclusiveByKeyFunctor
251 {
ScanExclusiveByKeyFunctorScanExclusiveByKeyFunctor252   ScanExclusiveByKeyFunctor() {}
253 
254   template <typename Device, typename... Args>
operatorScanExclusiveByKeyFunctor255   VTKM_CONT bool operator()(Device, Args&&... args) const
256   {
257     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
258     vtkm::cont::Token token;
259     vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusiveByKey(
260       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
261     return true;
262   }
263 };
264 
265 template <typename T>
266 struct ScanExtendedFunctor
267 {
268   template <typename Device, typename... Args>
operatorScanExtendedFunctor269   VTKM_CONT bool operator()(Device, Args&&... args)
270   {
271     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
272     vtkm::cont::Token token;
273     vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExtended(
274       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
275     return true;
276   }
277 };
278 
279 struct ScheduleFunctor
280 {
281   template <typename Device, typename... Args>
operatorScheduleFunctor282   VTKM_CONT bool operator()(Device, Args&&... args)
283   {
284     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
285     vtkm::cont::Token token;
286     vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(
287       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
288     return true;
289   }
290 };
291 
292 struct SortFunctor
293 {
294   template <typename Device, typename... Args>
operatorSortFunctor295   VTKM_CONT bool operator()(Device, Args&&... args) const
296   {
297     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
298     vtkm::cont::Token token;
299     vtkm::cont::DeviceAdapterAlgorithm<Device>::Sort(
300       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
301     return true;
302   }
303 };
304 
305 struct SortByKeyFunctor
306 {
307   template <typename Device, typename... Args>
operatorSortByKeyFunctor308   VTKM_CONT bool operator()(Device, Args&&... args) const
309   {
310     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
311     vtkm::cont::Token token;
312     vtkm::cont::DeviceAdapterAlgorithm<Device>::SortByKey(
313       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
314     return true;
315   }
316 };
317 
318 struct SynchronizeFunctor
319 {
320   template <typename Device>
operatorSynchronizeFunctor321   VTKM_CONT bool operator()(Device)
322   {
323     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
324     vtkm::cont::DeviceAdapterAlgorithm<Device>::Synchronize();
325     return true;
326   }
327 };
328 
329 struct TransformFunctor
330 {
331   template <typename Device, typename... Args>
operatorTransformFunctor332   VTKM_CONT bool operator()(Device, Args&&... args) const
333   {
334     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
335     vtkm::cont::Token token;
336     vtkm::cont::DeviceAdapterAlgorithm<Device>::Transform(
337       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
338     return true;
339   }
340 };
341 
342 struct UniqueFunctor
343 {
344   template <typename Device, typename... Args>
operatorUniqueFunctor345   VTKM_CONT bool operator()(Device, Args&&... args) const
346   {
347     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
348     vtkm::cont::Token token;
349     vtkm::cont::DeviceAdapterAlgorithm<Device>::Unique(
350       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
351     return true;
352   }
353 };
354 
355 struct UpperBoundsFunctor
356 {
357   template <typename Device, typename... Args>
operatorUpperBoundsFunctor358   VTKM_CONT bool operator()(Device, Args&&... args) const
359   {
360     VTKM_IS_DEVICE_ADAPTER_TAG(Device);
361     vtkm::cont::Token token;
362     vtkm::cont::DeviceAdapterAlgorithm<Device>::UpperBounds(
363       PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
364     return true;
365   }
366 };
367 } // namespace detail
368 /// @endcond
369 
370 struct Algorithm
371 {
372 
373   template <typename IndicesStorage>
BitFieldToUnorderedSetAlgorithm374   VTKM_CONT static vtkm::Id BitFieldToUnorderedSet(
375     vtkm::cont::DeviceAdapterId devId,
376     const vtkm::cont::BitField& bits,
377     vtkm::cont::ArrayHandle<Id, IndicesStorage>& indices)
378   {
379     detail::BitFieldToUnorderedSetFunctor functor;
380     vtkm::cont::TryExecuteOnDevice(devId, functor, bits, indices);
381     return functor.Result;
382   }
383 
384   template <typename IndicesStorage>
BitFieldToUnorderedSetAlgorithm385   VTKM_CONT static vtkm::Id BitFieldToUnorderedSet(
386     const vtkm::cont::BitField& bits,
387     vtkm::cont::ArrayHandle<Id, IndicesStorage>& indices)
388   {
389     detail::BitFieldToUnorderedSetFunctor functor;
390     vtkm::cont::TryExecute(functor, bits, indices);
391     return functor.Result;
392   }
393 
394   template <typename T, typename U, class CIn, class COut>
CopyAlgorithm395   VTKM_CONT static bool Copy(vtkm::cont::DeviceAdapterId devId,
396                              const vtkm::cont::ArrayHandle<T, CIn>& input,
397                              vtkm::cont::ArrayHandle<U, COut>& output)
398   {
399     // If we can use any device, prefer to use source's already loaded device.
400     if (devId == vtkm::cont::DeviceAdapterTagAny())
401     {
402       bool isCopied = vtkm::cont::TryExecuteOnDevice(
403         input.GetDeviceAdapterId(), detail::CopyFunctor(), input, output);
404       if (isCopied)
405       {
406         return true;
407       }
408     }
409     return vtkm::cont::TryExecuteOnDevice(devId, detail::CopyFunctor(), input, output);
410   }
411   template <typename T, typename U, class CIn, class COut>
CopyAlgorithm412   VTKM_CONT static void Copy(const vtkm::cont::ArrayHandle<T, CIn>& input,
413                              vtkm::cont::ArrayHandle<U, COut>& output)
414   {
415     Copy(vtkm::cont::DeviceAdapterTagAny(), input, output);
416   }
417 
418 
419   template <typename T, typename U, class CIn, class CStencil, class COut>
CopyIfAlgorithm420   VTKM_CONT static void CopyIf(vtkm::cont::DeviceAdapterId devId,
421                                const vtkm::cont::ArrayHandle<T, CIn>& input,
422                                const vtkm::cont::ArrayHandle<U, CStencil>& stencil,
423                                vtkm::cont::ArrayHandle<T, COut>& output)
424   {
425     vtkm::cont::TryExecuteOnDevice(devId, detail::CopyIfFunctor(), input, stencil, output);
426   }
427   template <typename T, typename U, class CIn, class CStencil, class COut>
CopyIfAlgorithm428   VTKM_CONT static void CopyIf(const vtkm::cont::ArrayHandle<T, CIn>& input,
429                                const vtkm::cont::ArrayHandle<U, CStencil>& stencil,
430                                vtkm::cont::ArrayHandle<T, COut>& output)
431   {
432     CopyIf(vtkm::cont::DeviceAdapterTagAny(), input, stencil, output);
433   }
434 
435 
436   template <typename T, typename U, class CIn, class CStencil, class COut, class UnaryPredicate>
CopyIfAlgorithm437   VTKM_CONT static void CopyIf(vtkm::cont::DeviceAdapterId devId,
438                                const vtkm::cont::ArrayHandle<T, CIn>& input,
439                                const vtkm::cont::ArrayHandle<U, CStencil>& stencil,
440                                vtkm::cont::ArrayHandle<T, COut>& output,
441                                UnaryPredicate unary_predicate)
442   {
443     vtkm::cont::TryExecuteOnDevice(
444       devId, detail::CopyIfFunctor(), input, stencil, output, unary_predicate);
445   }
446   template <typename T, typename U, class CIn, class CStencil, class COut, class UnaryPredicate>
CopyIfAlgorithm447   VTKM_CONT static void CopyIf(const vtkm::cont::ArrayHandle<T, CIn>& input,
448                                const vtkm::cont::ArrayHandle<U, CStencil>& stencil,
449                                vtkm::cont::ArrayHandle<T, COut>& output,
450                                UnaryPredicate unary_predicate)
451   {
452     CopyIf(vtkm::cont::DeviceAdapterTagAny(), input, stencil, output, unary_predicate);
453   }
454 
455 
456   template <typename T, typename U, class CIn, class COut>
457   VTKM_CONT static bool CopySubRange(vtkm::cont::DeviceAdapterId devId,
458                                      const vtkm::cont::ArrayHandle<T, CIn>& input,
459                                      vtkm::Id inputStartIndex,
460                                      vtkm::Id numberOfElementsToCopy,
461                                      vtkm::cont::ArrayHandle<U, COut>& output,
462                                      vtkm::Id outputIndex = 0)
463   {
464     detail::CopySubRangeFunctor functor;
465     vtkm::cont::TryExecuteOnDevice(
466       devId, functor, input, inputStartIndex, numberOfElementsToCopy, output, outputIndex);
467     return functor.valid;
468   }
469   template <typename T, typename U, class CIn, class COut>
470   VTKM_CONT static bool CopySubRange(const vtkm::cont::ArrayHandle<T, CIn>& input,
471                                      vtkm::Id inputStartIndex,
472                                      vtkm::Id numberOfElementsToCopy,
473                                      vtkm::cont::ArrayHandle<U, COut>& output,
474                                      vtkm::Id outputIndex = 0)
475   {
476     return CopySubRange(vtkm::cont::DeviceAdapterTagAny(),
477                         input,
478                         inputStartIndex,
479                         numberOfElementsToCopy,
480                         output,
481                         outputIndex);
482   }
483 
CountSetBitsAlgorithm484   VTKM_CONT static vtkm::Id CountSetBits(vtkm::cont::DeviceAdapterId devId,
485                                          const vtkm::cont::BitField& bits)
486   {
487     detail::CountSetBitsFunctor functor;
488     vtkm::cont::TryExecuteOnDevice(devId, functor, bits);
489     return functor.PopCount;
490   }
491 
CountSetBitsAlgorithm492   VTKM_CONT static vtkm::Id CountSetBits(const vtkm::cont::BitField& bits)
493   {
494     return CountSetBits(vtkm::cont::DeviceAdapterTagAny{}, bits);
495   }
496 
FillAlgorithm497   VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId,
498                              vtkm::cont::BitField& bits,
499                              bool value,
500                              vtkm::Id numBits)
501   {
502     detail::FillFunctor functor;
503     vtkm::cont::TryExecuteOnDevice(devId, functor, bits, value, numBits);
504   }
505 
FillAlgorithm506   VTKM_CONT static void Fill(vtkm::cont::BitField& bits, bool value, vtkm::Id numBits)
507   {
508     Fill(vtkm::cont::DeviceAdapterTagAny{}, bits, value, numBits);
509   }
510 
FillAlgorithm511   VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId,
512                              vtkm::cont::BitField& bits,
513                              bool value)
514   {
515     detail::FillFunctor functor;
516     vtkm::cont::TryExecuteOnDevice(devId, functor, bits, value);
517   }
518 
FillAlgorithm519   VTKM_CONT static void Fill(vtkm::cont::BitField& bits, bool value)
520   {
521     Fill(vtkm::cont::DeviceAdapterTagAny{}, bits, value);
522   }
523 
524   template <typename WordType>
FillAlgorithm525   VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId,
526                              vtkm::cont::BitField& bits,
527                              WordType word,
528                              vtkm::Id numBits)
529   {
530     detail::FillFunctor functor;
531     vtkm::cont::TryExecuteOnDevice(devId, functor, bits, word, numBits);
532   }
533 
534   template <typename WordType>
FillAlgorithm535   VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word, vtkm::Id numBits)
536   {
537     Fill(vtkm::cont::DeviceAdapterTagAny{}, bits, word, numBits);
538   }
539 
540   template <typename WordType>
FillAlgorithm541   VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId,
542                              vtkm::cont::BitField& bits,
543                              WordType word)
544   {
545     detail::FillFunctor functor;
546     vtkm::cont::TryExecuteOnDevice(devId, functor, bits, word);
547   }
548 
549   template <typename WordType>
FillAlgorithm550   VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word)
551   {
552     Fill(vtkm::cont::DeviceAdapterTagAny{}, bits, word);
553   }
554 
555   template <typename T, typename S>
FillAlgorithm556   VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId,
557                              vtkm::cont::ArrayHandle<T, S>& handle,
558                              const T& value)
559   {
560     detail::FillFunctor functor;
561     vtkm::cont::TryExecuteOnDevice(devId, functor, handle, value);
562   }
563 
564   template <typename T, typename S>
FillAlgorithm565   VTKM_CONT static void Fill(vtkm::cont::ArrayHandle<T, S>& handle, const T& value)
566   {
567     Fill(vtkm::cont::DeviceAdapterTagAny{}, handle, value);
568   }
569 
570   template <typename T, typename S>
FillAlgorithm571   VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId,
572                              vtkm::cont::ArrayHandle<T, S>& handle,
573                              const T& value,
574                              const vtkm::Id numValues)
575   {
576     detail::FillFunctor functor;
577     vtkm::cont::TryExecuteOnDevice(devId, functor, handle, value, numValues);
578   }
579 
580   template <typename T, typename S>
FillAlgorithm581   VTKM_CONT static void Fill(vtkm::cont::ArrayHandle<T, S>& handle,
582                              const T& value,
583                              const vtkm::Id numValues)
584   {
585     Fill(vtkm::cont::DeviceAdapterTagAny{}, handle, value, numValues);
586   }
587 
588   template <typename T, class CIn, class CVal, class COut>
LowerBoundsAlgorithm589   VTKM_CONT static void LowerBounds(vtkm::cont::DeviceAdapterId devId,
590                                     const vtkm::cont::ArrayHandle<T, CIn>& input,
591                                     const vtkm::cont::ArrayHandle<T, CVal>& values,
592                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& output)
593   {
594     vtkm::cont::TryExecuteOnDevice(devId, detail::LowerBoundsFunctor(), input, values, output);
595   }
596   template <typename T, class CIn, class CVal, class COut>
LowerBoundsAlgorithm597   VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
598                                     const vtkm::cont::ArrayHandle<T, CVal>& values,
599                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& output)
600   {
601     LowerBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output);
602   }
603 
604 
605   template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
LowerBoundsAlgorithm606   VTKM_CONT static void LowerBounds(vtkm::cont::DeviceAdapterId devId,
607                                     const vtkm::cont::ArrayHandle<T, CIn>& input,
608                                     const vtkm::cont::ArrayHandle<T, CVal>& values,
609                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& output,
610                                     BinaryCompare binary_compare)
611   {
612     vtkm::cont::TryExecuteOnDevice(
613       devId, detail::LowerBoundsFunctor(), input, values, output, binary_compare);
614   }
615   template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
LowerBoundsAlgorithm616   VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
617                                     const vtkm::cont::ArrayHandle<T, CVal>& values,
618                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& output,
619                                     BinaryCompare binary_compare)
620   {
621     LowerBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output, binary_compare);
622   }
623 
624 
625   template <class CIn, class COut>
LowerBoundsAlgorithm626   VTKM_CONT static void LowerBounds(vtkm::cont::DeviceAdapterId devId,
627                                     const vtkm::cont::ArrayHandle<vtkm::Id, CIn>& input,
628                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& values_output)
629   {
630     vtkm::cont::TryExecuteOnDevice(devId, detail::LowerBoundsFunctor(), input, values_output);
631   }
632   template <class CIn, class COut>
LowerBoundsAlgorithm633   VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle<vtkm::Id, CIn>& input,
634                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& values_output)
635   {
636     LowerBounds(vtkm::cont::DeviceAdapterTagAny(), input, values_output);
637   }
638 
639 
640   template <typename T, typename U, class CIn>
ReduceAlgorithm641   VTKM_CONT static U Reduce(vtkm::cont::DeviceAdapterId devId,
642                             const vtkm::cont::ArrayHandle<T, CIn>& input,
643                             U initialValue)
644   {
645     detail::ReduceFunctor<U> functor;
646     vtkm::cont::TryExecuteOnDevice(devId, functor, input, initialValue);
647     return functor.result;
648   }
649   template <typename T, typename U, class CIn>
ReduceAlgorithm650   VTKM_CONT static U Reduce(const vtkm::cont::ArrayHandle<T, CIn>& input, U initialValue)
651   {
652     return Reduce(vtkm::cont::DeviceAdapterTagAny(), input, initialValue);
653   }
654 
655 
656   template <typename T, typename U, class CIn, class BinaryFunctor>
ReduceAlgorithm657   VTKM_CONT static U Reduce(vtkm::cont::DeviceAdapterId devId,
658                             const vtkm::cont::ArrayHandle<T, CIn>& input,
659                             U initialValue,
660                             BinaryFunctor binary_functor)
661   {
662     detail::ReduceFunctor<U> functor;
663     vtkm::cont::TryExecuteOnDevice(devId, functor, input, initialValue, binary_functor);
664     return functor.result;
665   }
666   template <typename T, typename U, class CIn, class BinaryFunctor>
ReduceAlgorithm667   VTKM_CONT static U Reduce(const vtkm::cont::ArrayHandle<T, CIn>& input,
668                             U initialValue,
669                             BinaryFunctor binary_functor)
670   {
671     return Reduce(vtkm::cont::DeviceAdapterTagAny(), input, initialValue, binary_functor);
672   }
673 
674 
675   template <typename T,
676             typename U,
677             class CKeyIn,
678             class CValIn,
679             class CKeyOut,
680             class CValOut,
681             class BinaryFunctor>
ReduceByKeyAlgorithm682   VTKM_CONT static void ReduceByKey(vtkm::cont::DeviceAdapterId devId,
683                                     const vtkm::cont::ArrayHandle<T, CKeyIn>& keys,
684                                     const vtkm::cont::ArrayHandle<U, CValIn>& values,
685                                     vtkm::cont::ArrayHandle<T, CKeyOut>& keys_output,
686                                     vtkm::cont::ArrayHandle<U, CValOut>& values_output,
687                                     BinaryFunctor binary_functor)
688   {
689     vtkm::cont::TryExecuteOnDevice(devId,
690                                    detail::ReduceByKeyFunctor(),
691                                    keys,
692                                    values,
693                                    keys_output,
694                                    values_output,
695                                    binary_functor);
696   }
697   template <typename T,
698             typename U,
699             class CKeyIn,
700             class CValIn,
701             class CKeyOut,
702             class CValOut,
703             class BinaryFunctor>
ReduceByKeyAlgorithm704   VTKM_CONT static void ReduceByKey(const vtkm::cont::ArrayHandle<T, CKeyIn>& keys,
705                                     const vtkm::cont::ArrayHandle<U, CValIn>& values,
706                                     vtkm::cont::ArrayHandle<T, CKeyOut>& keys_output,
707                                     vtkm::cont::ArrayHandle<U, CValOut>& values_output,
708                                     BinaryFunctor binary_functor)
709   {
710     ReduceByKey(
711       vtkm::cont::DeviceAdapterTagAny(), keys, values, keys_output, values_output, binary_functor);
712   }
713 
714 
715   template <typename T, class CIn, class COut>
ScanInclusiveAlgorithm716   VTKM_CONT static T ScanInclusive(vtkm::cont::DeviceAdapterId devId,
717                                    const vtkm::cont::ArrayHandle<T, CIn>& input,
718                                    vtkm::cont::ArrayHandle<T, COut>& output)
719   {
720     detail::ScanInclusiveResultFunctor<T> functor;
721     vtkm::cont::TryExecuteOnDevice(devId, functor, input, output);
722     return functor.result;
723   }
724   template <typename T, class CIn, class COut>
ScanInclusiveAlgorithm725   VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
726                                    vtkm::cont::ArrayHandle<T, COut>& output)
727   {
728     return ScanInclusive(vtkm::cont::DeviceAdapterTagAny(), input, output);
729   }
730 
731 
732   template <typename T, class CIn, class COut, class BinaryFunctor>
ScanInclusiveAlgorithm733   VTKM_CONT static T ScanInclusive(vtkm::cont::DeviceAdapterId devId,
734                                    const vtkm::cont::ArrayHandle<T, CIn>& input,
735                                    vtkm::cont::ArrayHandle<T, COut>& output,
736                                    BinaryFunctor binary_functor)
737   {
738     detail::ScanInclusiveResultFunctor<T> functor;
739     vtkm::cont::TryExecuteOnDevice(devId, functor, input, output, binary_functor);
740     return functor.result;
741   }
742   template <typename T, class CIn, class COut, class BinaryFunctor>
ScanInclusiveAlgorithm743   VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
744                                    vtkm::cont::ArrayHandle<T, COut>& output,
745                                    BinaryFunctor binary_functor)
746   {
747     return ScanInclusive(vtkm::cont::DeviceAdapterTagAny(), input, output, binary_functor);
748   }
749 
750 
751   template <typename T,
752             typename U,
753             typename KIn,
754             typename VIn,
755             typename VOut,
756             typename BinaryFunctor>
ScanInclusiveByKeyAlgorithm757   VTKM_CONT static void ScanInclusiveByKey(vtkm::cont::DeviceAdapterId devId,
758                                            const vtkm::cont::ArrayHandle<T, KIn>& keys,
759                                            const vtkm::cont::ArrayHandle<U, VIn>& values,
760                                            vtkm::cont::ArrayHandle<U, VOut>& values_output,
761                                            BinaryFunctor binary_functor)
762   {
763     vtkm::cont::TryExecuteOnDevice(
764       devId, detail::ScanInclusiveByKeyFunctor(), keys, values, values_output, binary_functor);
765   }
766   template <typename T,
767             typename U,
768             typename KIn,
769             typename VIn,
770             typename VOut,
771             typename BinaryFunctor>
ScanInclusiveByKeyAlgorithm772   VTKM_CONT static void ScanInclusiveByKey(const vtkm::cont::ArrayHandle<T, KIn>& keys,
773                                            const vtkm::cont::ArrayHandle<U, VIn>& values,
774                                            vtkm::cont::ArrayHandle<U, VOut>& values_output,
775                                            BinaryFunctor binary_functor)
776   {
777     ScanInclusiveByKey(
778       vtkm::cont::DeviceAdapterTagAny(), keys, values, values_output, binary_functor);
779   }
780 
781 
782   template <typename T, typename U, typename KIn, typename VIn, typename VOut>
ScanInclusiveByKeyAlgorithm783   VTKM_CONT static void ScanInclusiveByKey(vtkm::cont::DeviceAdapterId devId,
784                                            const vtkm::cont::ArrayHandle<T, KIn>& keys,
785                                            const vtkm::cont::ArrayHandle<U, VIn>& values,
786                                            vtkm::cont::ArrayHandle<U, VOut>& values_output)
787   {
788     vtkm::cont::TryExecuteOnDevice(
789       devId, detail::ScanInclusiveByKeyFunctor(), keys, values, values_output);
790   }
791   template <typename T, typename U, typename KIn, typename VIn, typename VOut>
ScanInclusiveByKeyAlgorithm792   VTKM_CONT static void ScanInclusiveByKey(const vtkm::cont::ArrayHandle<T, KIn>& keys,
793                                            const vtkm::cont::ArrayHandle<U, VIn>& values,
794                                            vtkm::cont::ArrayHandle<U, VOut>& values_output)
795   {
796     ScanInclusiveByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values, values_output);
797   }
798 
799 
800   template <typename T, class CIn, class COut>
ScanExclusiveAlgorithm801   VTKM_CONT static T ScanExclusive(vtkm::cont::DeviceAdapterId devId,
802                                    const vtkm::cont::ArrayHandle<T, CIn>& input,
803                                    vtkm::cont::ArrayHandle<T, COut>& output)
804   {
805     detail::ScanExclusiveFunctor<T> functor;
806     vtkm::cont::TryExecuteOnDevice(devId, functor, input, output);
807     return functor.result;
808   }
809   template <typename T, class CIn, class COut>
ScanExclusiveAlgorithm810   VTKM_CONT static T ScanExclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
811                                    vtkm::cont::ArrayHandle<T, COut>& output)
812   {
813     return ScanExclusive(vtkm::cont::DeviceAdapterTagAny(), input, output);
814   }
815 
816 
817   template <typename T, class CIn, class COut, class BinaryFunctor>
ScanExclusiveAlgorithm818   VTKM_CONT static T ScanExclusive(vtkm::cont::DeviceAdapterId devId,
819                                    const vtkm::cont::ArrayHandle<T, CIn>& input,
820                                    vtkm::cont::ArrayHandle<T, COut>& output,
821                                    BinaryFunctor binaryFunctor,
822                                    const T& initialValue)
823   {
824     detail::ScanExclusiveFunctor<T> functor;
825     vtkm::cont::TryExecuteOnDevice(devId, functor, input, output, binaryFunctor, initialValue);
826     return functor.result;
827   }
828   template <typename T, class CIn, class COut, class BinaryFunctor>
ScanExclusiveAlgorithm829   VTKM_CONT static T ScanExclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
830                                    vtkm::cont::ArrayHandle<T, COut>& output,
831                                    BinaryFunctor binaryFunctor,
832                                    const T& initialValue)
833   {
834     return ScanExclusive(
835       vtkm::cont::DeviceAdapterTagAny(), input, output, binaryFunctor, initialValue);
836   }
837 
838 
839   template <typename T, typename U, typename KIn, typename VIn, typename VOut, class BinaryFunctor>
ScanExclusiveByKeyAlgorithm840   VTKM_CONT static void ScanExclusiveByKey(vtkm::cont::DeviceAdapterId devId,
841                                            const vtkm::cont::ArrayHandle<T, KIn>& keys,
842                                            const vtkm::cont::ArrayHandle<U, VIn>& values,
843                                            vtkm::cont::ArrayHandle<U, VOut>& output,
844                                            const U& initialValue,
845                                            BinaryFunctor binaryFunctor)
846   {
847     vtkm::cont::TryExecuteOnDevice(devId,
848                                    detail::ScanExclusiveByKeyFunctor(),
849                                    keys,
850                                    values,
851                                    output,
852                                    initialValue,
853                                    binaryFunctor);
854   }
855   template <typename T, typename U, typename KIn, typename VIn, typename VOut, class BinaryFunctor>
ScanExclusiveByKeyAlgorithm856   VTKM_CONT static void ScanExclusiveByKey(const vtkm::cont::ArrayHandle<T, KIn>& keys,
857                                            const vtkm::cont::ArrayHandle<U, VIn>& values,
858                                            vtkm::cont::ArrayHandle<U, VOut>& output,
859                                            const U& initialValue,
860                                            BinaryFunctor binaryFunctor)
861   {
862     ScanExclusiveByKey(
863       vtkm::cont::DeviceAdapterTagAny(), keys, values, output, initialValue, binaryFunctor);
864   }
865 
866 
867   template <typename T, typename U, class KIn, typename VIn, typename VOut>
ScanExclusiveByKeyAlgorithm868   VTKM_CONT static void ScanExclusiveByKey(vtkm::cont::DeviceAdapterId devId,
869                                            const vtkm::cont::ArrayHandle<T, KIn>& keys,
870                                            const vtkm::cont::ArrayHandle<U, VIn>& values,
871                                            vtkm::cont::ArrayHandle<U, VOut>& output)
872   {
873     vtkm::cont::TryExecuteOnDevice(
874       devId, detail::ScanExclusiveByKeyFunctor(), keys, values, output);
875   }
876   template <typename T, typename U, class KIn, typename VIn, typename VOut>
ScanExclusiveByKeyAlgorithm877   VTKM_CONT static void ScanExclusiveByKey(const vtkm::cont::ArrayHandle<T, KIn>& keys,
878                                            const vtkm::cont::ArrayHandle<U, VIn>& values,
879                                            vtkm::cont::ArrayHandle<U, VOut>& output)
880   {
881     ScanExclusiveByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values, output);
882   }
883 
884 
885   template <typename T, class CIn, class COut>
ScanExtendedAlgorithm886   VTKM_CONT static void ScanExtended(vtkm::cont::DeviceAdapterId devId,
887                                      const vtkm::cont::ArrayHandle<T, CIn>& input,
888                                      vtkm::cont::ArrayHandle<T, COut>& output)
889   {
890     detail::ScanExtendedFunctor<T> functor;
891     vtkm::cont::TryExecuteOnDevice(devId, functor, input, output);
892   }
893   template <typename T, class CIn, class COut>
ScanExtendedAlgorithm894   VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle<T, CIn>& input,
895                                      vtkm::cont::ArrayHandle<T, COut>& output)
896   {
897     ScanExtended(vtkm::cont::DeviceAdapterTagAny(), input, output);
898   }
899 
900 
901   template <typename T, class CIn, class COut, class BinaryFunctor>
ScanExtendedAlgorithm902   VTKM_CONT static void ScanExtended(vtkm::cont::DeviceAdapterId devId,
903                                      const vtkm::cont::ArrayHandle<T, CIn>& input,
904                                      vtkm::cont::ArrayHandle<T, COut>& output,
905                                      BinaryFunctor binaryFunctor,
906                                      const T& initialValue)
907   {
908     detail::ScanExtendedFunctor<T> functor;
909     vtkm::cont::TryExecuteOnDevice(devId, functor, input, output, binaryFunctor, initialValue);
910   }
911   template <typename T, class CIn, class COut, class BinaryFunctor>
ScanExtendedAlgorithm912   VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle<T, CIn>& input,
913                                      vtkm::cont::ArrayHandle<T, COut>& output,
914                                      BinaryFunctor binaryFunctor,
915                                      const T& initialValue)
916   {
917     ScanExtended(vtkm::cont::DeviceAdapterTagAny(), input, output, binaryFunctor, initialValue);
918   }
919 
920 
921   template <class Functor>
ScheduleAlgorithm922   VTKM_CONT static void Schedule(vtkm::cont::DeviceAdapterId devId,
923                                  Functor functor,
924                                  vtkm::Id numInstances)
925   {
926     vtkm::cont::TryExecuteOnDevice(devId, detail::ScheduleFunctor(), functor, numInstances);
927   }
928   template <class Functor>
ScheduleAlgorithm929   VTKM_CONT static void Schedule(Functor functor, vtkm::Id numInstances)
930   {
931     Schedule(vtkm::cont::DeviceAdapterTagAny(), functor, numInstances);
932   }
933 
934 
935   template <class Functor>
ScheduleAlgorithm936   VTKM_CONT static void Schedule(vtkm::cont::DeviceAdapterId devId,
937                                  Functor functor,
938                                  vtkm::Id3 rangeMax)
939   {
940     vtkm::cont::TryExecuteOnDevice(devId, detail::ScheduleFunctor(), functor, rangeMax);
941   }
942   template <class Functor>
ScheduleAlgorithm943   VTKM_CONT static void Schedule(Functor functor, vtkm::Id3 rangeMax)
944   {
945     Schedule(vtkm::cont::DeviceAdapterTagAny(), functor, rangeMax);
946   }
947 
948 
949   template <typename T, class Storage>
SortAlgorithm950   VTKM_CONT static void Sort(vtkm::cont::DeviceAdapterId devId,
951                              vtkm::cont::ArrayHandle<T, Storage>& values)
952   {
953     vtkm::cont::TryExecuteOnDevice(devId, detail::SortFunctor(), values);
954   }
955   template <typename T, class Storage>
SortAlgorithm956   VTKM_CONT static void Sort(vtkm::cont::ArrayHandle<T, Storage>& values)
957   {
958     Sort(vtkm::cont::DeviceAdapterTagAny(), values);
959   }
960 
961 
962   template <typename T, class Storage, class BinaryCompare>
SortAlgorithm963   VTKM_CONT static void Sort(vtkm::cont::DeviceAdapterId devId,
964                              vtkm::cont::ArrayHandle<T, Storage>& values,
965                              BinaryCompare binary_compare)
966   {
967     vtkm::cont::TryExecuteOnDevice(devId, detail::SortFunctor(), values, binary_compare);
968   }
969   template <typename T, class Storage, class BinaryCompare>
SortAlgorithm970   VTKM_CONT static void Sort(vtkm::cont::ArrayHandle<T, Storage>& values,
971                              BinaryCompare binary_compare)
972   {
973     Sort(vtkm::cont::DeviceAdapterTagAny(), values, binary_compare);
974   }
975 
976 
977   template <typename T, typename U, class StorageT, class StorageU>
SortByKeyAlgorithm978   VTKM_CONT static void SortByKey(vtkm::cont::DeviceAdapterId devId,
979                                   vtkm::cont::ArrayHandle<T, StorageT>& keys,
980                                   vtkm::cont::ArrayHandle<U, StorageU>& values)
981   {
982     vtkm::cont::TryExecuteOnDevice(devId, detail::SortByKeyFunctor(), keys, values);
983   }
984   template <typename T, typename U, class StorageT, class StorageU>
SortByKeyAlgorithm985   VTKM_CONT static void SortByKey(vtkm::cont::ArrayHandle<T, StorageT>& keys,
986                                   vtkm::cont::ArrayHandle<U, StorageU>& values)
987   {
988     SortByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values);
989   }
990 
991   template <typename T, typename U, class StorageT, class StorageU, class BinaryCompare>
SortByKeyAlgorithm992   VTKM_CONT static void SortByKey(vtkm::cont::DeviceAdapterId devId,
993                                   vtkm::cont::ArrayHandle<T, StorageT>& keys,
994                                   vtkm::cont::ArrayHandle<U, StorageU>& values,
995                                   BinaryCompare binary_compare)
996   {
997     vtkm::cont::TryExecuteOnDevice(devId, detail::SortByKeyFunctor(), keys, values, binary_compare);
998   }
999   template <typename T, typename U, class StorageT, class StorageU, class BinaryCompare>
SortByKeyAlgorithm1000   VTKM_CONT static void SortByKey(vtkm::cont::ArrayHandle<T, StorageT>& keys,
1001                                   vtkm::cont::ArrayHandle<U, StorageU>& values,
1002                                   BinaryCompare binary_compare)
1003   {
1004     SortByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values, binary_compare);
1005   }
1006 
1007 
SynchronizeAlgorithm1008   VTKM_CONT static void Synchronize(vtkm::cont::DeviceAdapterId devId)
1009   {
1010     vtkm::cont::TryExecuteOnDevice(devId, detail::SynchronizeFunctor());
1011   }
SynchronizeAlgorithm1012   VTKM_CONT static void Synchronize() { Synchronize(vtkm::cont::DeviceAdapterTagAny()); }
1013 
1014 
1015   template <typename T,
1016             typename U,
1017             typename V,
1018             typename StorageT,
1019             typename StorageU,
1020             typename StorageV,
1021             typename BinaryFunctor>
TransformAlgorithm1022   VTKM_CONT static void Transform(vtkm::cont::DeviceAdapterId devId,
1023                                   const vtkm::cont::ArrayHandle<T, StorageT>& input1,
1024                                   const vtkm::cont::ArrayHandle<U, StorageU>& input2,
1025                                   vtkm::cont::ArrayHandle<V, StorageV>& output,
1026                                   BinaryFunctor binaryFunctor)
1027   {
1028     vtkm::cont::TryExecuteOnDevice(
1029       devId, detail::TransformFunctor(), input1, input2, output, binaryFunctor);
1030   }
1031   template <typename T,
1032             typename U,
1033             typename V,
1034             typename StorageT,
1035             typename StorageU,
1036             typename StorageV,
1037             typename BinaryFunctor>
TransformAlgorithm1038   VTKM_CONT static void Transform(const vtkm::cont::ArrayHandle<T, StorageT>& input1,
1039                                   const vtkm::cont::ArrayHandle<U, StorageU>& input2,
1040                                   vtkm::cont::ArrayHandle<V, StorageV>& output,
1041                                   BinaryFunctor binaryFunctor)
1042   {
1043     Transform(vtkm::cont::DeviceAdapterTagAny(), input1, input2, output, binaryFunctor);
1044   }
1045 
1046 
1047   template <typename T, class Storage>
UniqueAlgorithm1048   VTKM_CONT static void Unique(vtkm::cont::DeviceAdapterId devId,
1049                                vtkm::cont::ArrayHandle<T, Storage>& values)
1050   {
1051     vtkm::cont::TryExecuteOnDevice(devId, detail::UniqueFunctor(), values);
1052   }
1053   template <typename T, class Storage>
UniqueAlgorithm1054   VTKM_CONT static void Unique(vtkm::cont::ArrayHandle<T, Storage>& values)
1055   {
1056     Unique(vtkm::cont::DeviceAdapterTagAny(), values);
1057   }
1058 
1059 
1060   template <typename T, class Storage, class BinaryCompare>
UniqueAlgorithm1061   VTKM_CONT static void Unique(vtkm::cont::DeviceAdapterId devId,
1062                                vtkm::cont::ArrayHandle<T, Storage>& values,
1063                                BinaryCompare binary_compare)
1064   {
1065     vtkm::cont::TryExecuteOnDevice(devId, detail::UniqueFunctor(), values, binary_compare);
1066   }
1067   template <typename T, class Storage, class BinaryCompare>
UniqueAlgorithm1068   VTKM_CONT static void Unique(vtkm::cont::ArrayHandle<T, Storage>& values,
1069                                BinaryCompare binary_compare)
1070   {
1071     Unique(vtkm::cont::DeviceAdapterTagAny(), values, binary_compare);
1072   }
1073 
1074 
1075   template <typename T, class CIn, class CVal, class COut>
UpperBoundsAlgorithm1076   VTKM_CONT static void UpperBounds(vtkm::cont::DeviceAdapterId devId,
1077                                     const vtkm::cont::ArrayHandle<T, CIn>& input,
1078                                     const vtkm::cont::ArrayHandle<T, CVal>& values,
1079                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& output)
1080   {
1081     vtkm::cont::TryExecuteOnDevice(devId, detail::UpperBoundsFunctor(), input, values, output);
1082   }
1083   template <typename T, class CIn, class CVal, class COut>
UpperBoundsAlgorithm1084   VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
1085                                     const vtkm::cont::ArrayHandle<T, CVal>& values,
1086                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& output)
1087   {
1088     UpperBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output);
1089   }
1090 
1091 
1092   template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
UpperBoundsAlgorithm1093   VTKM_CONT static void UpperBounds(vtkm::cont::DeviceAdapterId devId,
1094                                     const vtkm::cont::ArrayHandle<T, CIn>& input,
1095                                     const vtkm::cont::ArrayHandle<T, CVal>& values,
1096                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& output,
1097                                     BinaryCompare binary_compare)
1098   {
1099     vtkm::cont::TryExecuteOnDevice(
1100       devId, detail::UpperBoundsFunctor(), input, values, output, binary_compare);
1101   }
1102   template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
UpperBoundsAlgorithm1103   VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
1104                                     const vtkm::cont::ArrayHandle<T, CVal>& values,
1105                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& output,
1106                                     BinaryCompare binary_compare)
1107   {
1108     UpperBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output, binary_compare);
1109   }
1110 
1111 
1112   template <class CIn, class COut>
UpperBoundsAlgorithm1113   VTKM_CONT static void UpperBounds(vtkm::cont::DeviceAdapterId devId,
1114                                     const vtkm::cont::ArrayHandle<vtkm::Id, CIn>& input,
1115                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& values_output)
1116   {
1117     vtkm::cont::TryExecuteOnDevice(devId, detail::UpperBoundsFunctor(), input, values_output);
1118   }
1119   template <class CIn, class COut>
UpperBoundsAlgorithm1120   VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle<vtkm::Id, CIn>& input,
1121                                     vtkm::cont::ArrayHandle<vtkm::Id, COut>& values_output)
1122   {
1123     UpperBounds(vtkm::cont::DeviceAdapterTagAny(), input, values_output);
1124   }
1125 };
1126 }
1127 } // namespace vtkm::cont
1128 
1129 #endif //vtk_m_cont_Algorithm_h
1130