Viskores  1.0
DeviceAdapterAlgorithmKokkos.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_kokkos_internal_DeviceAdapterAlgorithmKokkos_h
19 #define viskores_cont_kokkos_internal_DeviceAdapterAlgorithmKokkos_h
20 
28 
31 
33 
34 #include <viskoresstd/void_t.h>
35 
37 #include <Kokkos_Core.hpp>
38 #include <Kokkos_DualView.hpp>
39 #include <Kokkos_Sort.hpp>
41 
42 #include <type_traits>
43 
44 #if KOKKOS_VERSION_MAJOR > 3 || (KOKKOS_VERSION_MAJOR == 3 && KOKKOS_VERSION_MINOR >= 7)
45 #define VISKORES_VOLATILE
46 #else
47 #define VISKORES_VOLATILE volatile
48 #endif
49 
50 #if defined(VISKORES_ENABLE_KOKKOS_THRUST) && (defined(__HIP__) || defined(__CUDA__))
51 #define VISKORES_USE_KOKKOS_THRUST
52 #endif
53 
54 #if defined(VISKORES_USE_KOKKOS_THRUST)
55 #include <thrust/device_ptr.h>
56 #include <thrust/iterator/constant_iterator.h>
57 #include <thrust/sort.h>
58 #endif
59 
60 namespace viskores
61 {
62 namespace internal
63 {
64 
65 template <typename, typename = void>
66 struct is_type_complete : public std::false_type
67 {
68 };
69 
70 template <typename T>
71 struct is_type_complete<T, viskoresstd::void_t<decltype(sizeof(T))>> : public std::true_type
72 {
73 };
74 } // internal
75 
76 namespace cont
77 {
78 
79 namespace kokkos
80 {
81 namespace internal
82 {
83 
84 //----------------------------------------------------------------------------
85 template <typename BitsPortal>
86 struct BitFieldToBoolField : public viskores::exec::FunctorBase
87 {
88  VISKORES_EXEC_CONT BitFieldToBoolField() {}
89 
91  explicit BitFieldToBoolField(const BitsPortal& bp)
92  : Bits(bp)
93  {
94  }
95 
96  VISKORES_EXEC bool operator()(viskores::Id bitIdx) const { return this->Bits.GetBit(bitIdx); }
97 
98 private:
99  BitsPortal Bits;
100 };
101 
102 template <typename BitsPortal>
103 struct BitFieldCountSetBitsWord : public viskores::exec::FunctorBase
104 {
105  VISKORES_EXEC_CONT BitFieldCountSetBitsWord() {}
106 
108  explicit BitFieldCountSetBitsWord(const BitsPortal& bp)
109  : Bits(bp)
110  {
111  }
112 
113  VISKORES_EXEC viskores::Id operator()(viskores::Id wordIdx) const
114  {
115  auto word = this->Bits.GetWord(wordIdx);
116  if (wordIdx == (this->Bits.GetNumberOfWords() - 1))
117  {
118  word &= this->Bits.GetFinalWordMask();
119  }
120 
121  return viskores::CountSetBits(word);
122  }
123 
124 private:
125  BitsPortal Bits;
126 };
127 
128 //----------------------------------------------------------------------------
129 template <typename Operator, typename ResultType>
130 struct ReductionIdentity;
131 
132 template <typename ResultType>
133 struct ReductionIdentity<viskores::Sum, ResultType>
134 {
135  static constexpr ResultType value = Kokkos::reduction_identity<ResultType>::sum();
136 };
137 
138 template <typename ResultType>
139 struct ReductionIdentity<viskores::Add, ResultType>
140 {
141  static constexpr ResultType value = Kokkos::reduction_identity<ResultType>::sum();
142 };
143 
144 template <typename ResultType>
145 struct ReductionIdentity<viskores::Product, ResultType>
146 {
147  static constexpr ResultType value = Kokkos::reduction_identity<ResultType>::prod();
148 };
149 
150 template <typename ResultType>
151 struct ReductionIdentity<viskores::Multiply, ResultType>
152 {
153  static constexpr ResultType value = Kokkos::reduction_identity<ResultType>::prod();
154 };
155 
156 template <typename ResultType>
157 struct ReductionIdentity<viskores::Minimum, ResultType>
158 {
159  static constexpr ResultType value = Kokkos::reduction_identity<ResultType>::min();
160 };
161 
162 template <typename ResultType>
163 struct ReductionIdentity<viskores::Maximum, ResultType>
164 {
165  static constexpr ResultType value = Kokkos::reduction_identity<ResultType>::max();
166 };
167 
168 template <typename ResultType>
169 struct ReductionIdentity<viskores::MinAndMax<ResultType>, viskores::Vec<ResultType, 2>>
170 {
171  static constexpr viskores::Vec<ResultType, 2> value =
172  viskores::Vec<ResultType, 2>(Kokkos::reduction_identity<ResultType>::min(),
173  Kokkos::reduction_identity<ResultType>::max());
174 };
175 
176 template <typename ResultType>
177 struct ReductionIdentity<viskores::BitwiseAnd, ResultType>
178 {
179  static constexpr ResultType value = Kokkos::reduction_identity<ResultType>::band();
180 };
181 
182 template <typename ResultType>
183 struct ReductionIdentity<viskores::BitwiseOr, ResultType>
184 {
185  static constexpr ResultType value = Kokkos::reduction_identity<ResultType>::bor();
186 };
187 }
188 } // kokkos::internal
189 
190 //=============================================================================
191 template <>
193  : viskores::cont::internal::DeviceAdapterAlgorithmGeneral<
194  DeviceAdapterAlgorithm<viskores::cont::DeviceAdapterTagKokkos>,
195  viskores::cont::DeviceAdapterTagKokkos>
196 {
197 private:
198  using Superclass = viskores::cont::internal::DeviceAdapterAlgorithmGeneral<
201 
202  VISKORES_CONT_EXPORT static viskores::exec::internal::ErrorMessageBuffer
203  GetErrorMessageBufferInstance();
204  VISKORES_CONT_EXPORT static void CheckForErrors();
205 
206 public:
207  template <typename IndicesStorage>
209  const viskores::cont::BitField& bits,
211  {
212  viskores::cont::Token token;
213  auto bitsPortal = bits.PrepareForInput(DeviceAdapterTagKokkos{}, token);
214  auto bits2bools = kokkos::internal::BitFieldToBoolField<decltype(bitsPortal)>(bitsPortal);
215 
219  indices);
220 
221  return indices.GetNumberOfValues();
222  }
223 
225  {
226  viskores::cont::Token token;
227  auto bitsPortal = bits.PrepareForInput(DeviceAdapterTagKokkos{}, token);
228  auto countPerWord =
229  kokkos::internal::BitFieldCountSetBitsWord<decltype(bitsPortal)>(bitsPortal);
230 
232  viskores::cont::make_ArrayHandleImplicit(countPerWord, bitsPortal.GetNumberOfWords()),
233  viskores::Id{ 0 });
234  }
235 
236  //----------------------------------------------------------------------------
237  using Superclass::Copy;
238 
239  template <typename T>
242  {
243  const viskores::Id inSize = input.GetNumberOfValues();
244 
245  viskores::cont::Token token;
246 
247  auto portalIn = input.PrepareForInput(viskores::cont::DeviceAdapterTagKokkos{}, token);
248  auto portalOut =
250 
251 
252  kokkos::internal::KokkosViewConstExec<T> viewIn(portalIn.GetArray(), inSize);
253  kokkos::internal::KokkosViewExec<T> viewOut(portalOut.GetArray(), inSize);
254  Kokkos::deep_copy(
255  viskores::cont::kokkos::internal::GetExecutionSpaceInstance(), viewOut, viewIn);
256  }
257 
258  //----------------------------------------------------------------------------
259 #ifndef VISKORES_CUDA
260  // nvcc doesn't like the private class declaration so disable under CUDA
261 private:
262 #endif
263  template <typename ArrayHandle, typename BinaryOperator, typename ResultType>
264  VISKORES_CONT static ResultType ReduceImpl(const ArrayHandle& input,
265  BinaryOperator binaryOperator,
266  ResultType initialValue,
267  std::false_type)
268  {
269  return Superclass::Reduce(input, initialValue, binaryOperator);
270  }
271 
272  template <typename BinaryOperator, typename FunctorOperator, typename ResultType>
273  class KokkosReduceFunctor
274  {
275  public:
277  using value_type = ResultType;
278 
279  KOKKOS_INLINE_FUNCTION
281 
282  template <typename... Args>
283  KOKKOS_INLINE_FUNCTION explicit KokkosReduceFunctor(const BinaryOperator& op, Args... args)
284  : Operator(op)
285  , Functor(std::forward<Args>(args)...)
286  {
287  }
288 
289  KOKKOS_INLINE_FUNCTION
291  {
292  dst = this->Operator(dst, src);
293  }
294 
295  KOKKOS_INLINE_FUNCTION
296  void init(value_type& dst) const
297  {
298  dst = kokkos::internal::ReductionIdentity<BinaryOperator, value_type>::value;
299  }
300 
301  // Reduce operator
302  KOKKOS_INLINE_FUNCTION
303  void operator()(viskores::Id i, ResultType& update) const
304  {
305  this->Functor(this->Operator, i, update);
306  }
307 
308  // Scan operator
309  KOKKOS_INLINE_FUNCTION
310  void operator()(viskores::Id i, ResultType& update, const bool final) const
311  {
312  this->Functor(this->Operator, i, update, final);
313  }
314 
315  private:
316  BinaryOperator Operator;
317  FunctorOperator Functor;
318  };
319 
320  template <typename ArrayPortal, typename BinaryOperator, typename ResultType>
321  class ReduceOperator
322  {
323  public:
324  KOKKOS_INLINE_FUNCTION
326 
327  KOKKOS_INLINE_FUNCTION
328  explicit ReduceOperator(const ArrayPortal& portal)
329  : Portal(portal)
330  {
331  }
332 
333  KOKKOS_INLINE_FUNCTION
334  void operator()(const BinaryOperator& op, viskores::Id i, ResultType& update) const
335  {
336  update = op(update, this->Portal.Get(i));
337  }
338 
339  private:
341  };
342 
343  template <typename BinaryOperator, typename ArrayPortal, typename ResultType>
344  using ReduceFunctor = KokkosReduceFunctor<BinaryOperator,
345  ReduceOperator<ArrayPortal, BinaryOperator, ResultType>,
346  ResultType>;
347 
348  template <typename ArrayHandle, typename BinaryOperator, typename ResultType>
349  VISKORES_CONT static ResultType ReduceImpl(const ArrayHandle& input,
350  BinaryOperator binaryOperator,
351  ResultType initialValue,
352  std::true_type)
353  {
354  viskores::cont::Token token;
355  auto inputPortal = input.PrepareForInput(viskores::cont::DeviceAdapterTagKokkos{}, token);
356 
357  ReduceFunctor<BinaryOperator, decltype(inputPortal), ResultType> functor(binaryOperator,
358  inputPortal);
359 
360  ResultType result;
361 
362  Kokkos::RangePolicy<viskores::cont::kokkos::internal::ExecutionSpace, viskores::Id> policy(
363  viskores::cont::kokkos::internal::GetExecutionSpaceInstance(), 0, input.GetNumberOfValues());
364  Kokkos::parallel_reduce(policy, functor, result);
365 
366  return binaryOperator(initialValue, result);
367  }
368 
369  template <bool P1, typename BinaryOperator, typename ResultType>
370  struct UseKokkosReduceP1 : std::false_type
371  {
372  };
373 
374  template <typename BinaryOperator, typename ResultType>
375  struct UseKokkosReduceP1<true, BinaryOperator, ResultType>
376  : viskores::internal::is_type_complete<
377  kokkos::internal::ReductionIdentity<BinaryOperator, ResultType>>
378  {
379  };
380 
381  template <typename BinaryOperator, typename ResultType>
382  struct UseKokkosReduce
383  : UseKokkosReduceP1<
384  viskores::internal::is_type_complete<Kokkos::reduction_identity<ResultType>>::value,
385  BinaryOperator,
386  ResultType>
387  {
388  };
389 
390 public:
391  template <typename T, typename U, class CIn, class BinaryOperator>
393  U initialValue,
394  BinaryOperator binaryOperator)
395  {
397 
398  if (input.GetNumberOfValues() == 0)
399  {
400  return initialValue;
401  }
402  if (input.GetNumberOfValues() == 1)
403  {
404  return binaryOperator(initialValue, input.ReadPortal().Get(0));
405  }
406 
407 #if defined(VISKORES_KOKKOS_CUDA)
408  // Kokkos reduce is having some issues with the cuda backend. Please refer to issue #586.
409  // Following is a work around where we use the Superclass reduce implementation when using
410  // Cuda execution space.
411  std::integral_constant<
412  bool,
413  !std::is_same<viskores::cont::kokkos::internal::ExecutionSpace, Kokkos::Cuda>::value &&
414  UseKokkosReduce<BinaryOperator, U>::value>
415  use_kokkos_reduce;
416 #else
417  typename UseKokkosReduce<BinaryOperator, U>::type use_kokkos_reduce;
418 #endif
419  return ReduceImpl(input, binaryOperator, initialValue, use_kokkos_reduce);
420  }
421 
422  template <typename T, typename U, class CIn>
423  VISKORES_CONT static U Reduce(const viskores::cont::ArrayHandle<T, CIn>& input, U initialValue)
424  {
426 
427  return Reduce(input, initialValue, viskores::Add());
428  }
429 
430  //----------------------------------------------------------------------------
431 #ifndef VISKORES_CUDA
432  // nvcc doesn't like the private class declaration so disable under CUDA
433 private:
434 #endif
435  // Scan and Reduce have the same conditions
436  template <typename BinaryOperator, typename ResultType>
437  using UseKokkosScan = UseKokkosReduce<BinaryOperator, ResultType>;
438 
439  template <typename T, typename StorageIn, typename StorageOut, typename BinaryOperator>
442  BinaryOperator binaryOperator,
443  const T& initialValue,
444  std::false_type)
445  {
446  return Superclass::ScanExclusive(input, output, binaryOperator, initialValue);
447  }
448 
449  template <typename T, typename StorageIn, typename StorageOut, typename BinaryOperator>
450  class ScanExclusiveOperator
451  {
452  private:
455 
456  public:
457  KOKKOS_INLINE_FUNCTION
459 
460  KOKKOS_INLINE_FUNCTION
461  explicit ScanExclusiveOperator(const ArrayPortalIn& portalIn,
462  const ArrayPortalOut& portalOut,
463  const T& initialValue)
464  : PortalIn(portalIn)
465  , PortalOut(portalOut)
466  , InitialValue(initialValue)
467  {
468  }
469 
470  KOKKOS_INLINE_FUNCTION
471  void operator()(const BinaryOperator& op,
472  const viskores::Id i,
473  T& update,
474  const bool final) const
475  {
476  auto val = this->PortalIn.Get(i);
477  if (i == 0)
478  {
479  update = InitialValue;
480  }
481  if (final)
482  {
483  this->PortalOut.Set(i, update);
484  }
485  update = op(update, val);
486  }
487 
488  private:
492  };
493 
494  template <typename BinaryOperator, typename T, typename StorageIn, typename StorageOut>
495  using ScanExclusiveFunctor =
496  KokkosReduceFunctor<BinaryOperator,
497  ScanExclusiveOperator<T, StorageIn, StorageOut, BinaryOperator>,
498  T>;
499 
500  template <typename T, typename StorageIn, typename StorageOut, typename BinaryOperator>
503  BinaryOperator binaryOperator,
504  const T& initialValue,
505  std::true_type)
506  {
507  viskores::Id length = input.GetNumberOfValues();
508 
509  viskores::cont::Token token;
510  auto inputPortal = input.PrepareForInput(viskores::cont::DeviceAdapterTagKokkos{}, token);
511  auto outputPortal =
513 
515  binaryOperator, inputPortal, outputPortal, initialValue);
516 
518  Kokkos::RangePolicy<viskores::cont::kokkos::internal::ExecutionSpace, viskores::Id> policy(
519  viskores::cont::kokkos::internal::GetExecutionSpaceInstance(), 0, length);
520  Kokkos::parallel_scan(policy, functor, result);
521 
522  return result;
523  }
524 
525 public:
526  template <typename T, class CIn, class COut, class BinaryOperator>
529  BinaryOperator binaryOperator,
530  const T& initialValue)
531  {
533 
534  viskores::Id length = input.GetNumberOfValues();
535  if (length == 0)
536  {
537  output.ReleaseResources();
538  return initialValue;
539  }
540  if (length == 1)
541  {
542  auto v0 = input.ReadPortal().Get(0);
543  Fill(output, initialValue, 1);
544  return binaryOperator(initialValue, v0);
545  }
546 
547 #if defined(VISKORES_KOKKOS_CUDA)
548  // Kokkos scan for the cuda backend is not working correctly for int/uint types of 8 and 16 bits.
549  std::integral_constant<bool,
550  !(std::is_integral<T>::value && sizeof(T) < 4) &&
552  use_kokkos_scan;
553 #else
554  typename UseKokkosScan<BinaryOperator, T>::type use_kokkos_scan;
555 #endif
556  return ScanExclusiveImpl(input, output, binaryOperator, initialValue, use_kokkos_scan);
557  }
558 
559  template <typename T, class CIn, class COut>
562  {
564 
565  return ScanExclusive(
567  }
568 
569  //----------------------------------------------------------------------------
570 #ifndef VISKORES_CUDA
571  // nvcc doesn't like the private class declaration so disable under CUDA
572 private:
573 #endif
574  template <typename T, typename StorageIn, typename StorageOut, typename BinaryOperator>
577  BinaryOperator binaryOperator,
578  std::false_type)
579  {
580  return Superclass::ScanInclusive(input, output, binaryOperator);
581  }
582 
583  template <typename T, typename StorageIn, typename StorageOut, typename BinaryOperator>
584  class ScanInclusiveOperator
585  {
586  private:
589 
590  public:
591  KOKKOS_INLINE_FUNCTION
593 
594  KOKKOS_INLINE_FUNCTION
595  explicit ScanInclusiveOperator(const ArrayPortalIn& portalIn, const ArrayPortalOut& portalOut)
596  : PortalIn(portalIn)
597  , PortalOut(portalOut)
598  {
599  }
600 
601  KOKKOS_INLINE_FUNCTION
602  void operator()(const BinaryOperator& op,
603  const viskores::Id i,
604  T& update,
605  const bool final) const
606  {
607  update = op(update, this->PortalIn.Get(i));
608  if (final)
609  {
610  this->PortalOut.Set(i, update);
611  }
612  }
613 
614  private:
617  };
618 
619  template <typename BinaryOperator, typename T, typename StorageIn, typename StorageOut>
620  using ScanInclusiveFunctor =
621  KokkosReduceFunctor<BinaryOperator,
622  ScanInclusiveOperator<T, StorageIn, StorageOut, BinaryOperator>,
623  T>;
624 
625  template <typename T, typename StorageIn, typename StorageOut, typename BinaryOperator>
628  BinaryOperator binaryOperator,
629  std::true_type)
630  {
631  viskores::Id length = input.GetNumberOfValues();
632 
633  viskores::cont::Token token;
634  auto inputPortal = input.PrepareForInput(viskores::cont::DeviceAdapterTagKokkos{}, token);
635  auto outputPortal =
637 
639  binaryOperator, inputPortal, outputPortal);
640 
642  Kokkos::RangePolicy<viskores::cont::kokkos::internal::ExecutionSpace, viskores::Id> policy(
643  viskores::cont::kokkos::internal::GetExecutionSpaceInstance(), 0, length);
644  Kokkos::parallel_scan(policy, functor, result);
645 
646  return result;
647  }
648 
649 public:
650  template <typename T, class CIn, class COut, class BinaryOperator>
653  BinaryOperator binaryOperator)
654  {
656 
657  viskores::Id length = input.GetNumberOfValues();
658  if (length == 0)
659  {
661  }
662  if (length == 1)
663  {
664  auto result = input.ReadPortal().Get(0);
665  Fill(output, result, 1);
666  return result;
667  }
668 
669 #if defined(VISKORES_KOKKOS_CUDA)
670  // Kokkos scan for the cuda backend is not working correctly for int/uint types of 8 and 16 bits.
671  std::integral_constant<bool,
672  !(std::is_integral<T>::value && sizeof(T) < 4) &&
674  use_kokkos_scan;
675 #else
676  typename UseKokkosScan<BinaryOperator, T>::type use_kokkos_scan;
677 #endif
678  return ScanInclusiveImpl(input, output, binaryOperator, use_kokkos_scan);
679  }
680 
681  template <typename T, class CIn, class COut>
684  {
686 
687  return ScanInclusive(input, output, viskores::Add());
688  }
689 
690  //----------------------------------------------------------------------------
691  template <typename WType, typename IType, typename Hints>
693  viskores::exec::kokkos::internal::TaskBasic1D<WType, IType, Hints>& functor,
694  viskores::Id numInstances)
695  {
697 
698  if (numInstances < 1)
699  {
700  // No instances means nothing to run. Just return.
701  return;
702  }
703 
704  functor.SetErrorMessageBuffer(GetErrorMessageBufferInstance());
705 
706  constexpr viskores::IdComponent maxThreadsPerBlock =
707  viskores::cont::internal::HintFind<Hints,
708  viskores::cont::internal::HintThreadsPerBlock<0>,
710 
711  Kokkos::RangePolicy<viskores::cont::kokkos::internal::ExecutionSpace,
712  Kokkos::LaunchBounds<maxThreadsPerBlock, 0>,
713  Kokkos::IndexType<viskores::Id>>
714  policy(viskores::cont::kokkos::internal::GetExecutionSpaceInstance(), 0, numInstances);
715  Kokkos::parallel_for(policy, functor);
716  CheckForErrors(); // synchronizes
717  }
718 
719  template <typename WType, typename IType, typename Hints>
721  viskores::exec::kokkos::internal::TaskBasic3D<WType, IType, Hints>& functor,
722  viskores::Id3 rangeMax)
723  {
725 
726  if ((rangeMax[0] < 1) || (rangeMax[1] < 1) || (rangeMax[2] < 1))
727  {
728  // No instances means nothing to run. Just return.
729  return;
730  }
731 
732  functor.SetErrorMessageBuffer(GetErrorMessageBufferInstance());
733 
734  constexpr viskores::IdComponent maxThreadsPerBlock =
735  viskores::cont::internal::HintFind<Hints,
736  viskores::cont::internal::HintThreadsPerBlock<0>,
738 
739  Kokkos::MDRangePolicy<viskores::cont::kokkos::internal::ExecutionSpace,
740  Kokkos::LaunchBounds<maxThreadsPerBlock, 0>,
741  Kokkos::Rank<3>,
742  Kokkos::IndexType<viskores::Id>>
743  policy(viskores::cont::kokkos::internal::GetExecutionSpaceInstance(),
744  { 0, 0, 0 },
745  { rangeMax[0], rangeMax[1], rangeMax[2] });
746 
747  // Calling rangeMax[X] inside KOKKOS_LAMBDA confuses some compilers since
748  // at first it tries to use the non-const inline vec_base::operator[0]
749  // method, however, KOKKOS_LAMBDA DOES converts rangeMax to a const
750  // vec_base. This convertion is somehow catched by the compiler making it
751  // complain that we are using a non-const method for a const object.
752  const auto rMax_0 = rangeMax[0];
753  const auto rMax_1 = rangeMax[1];
754 
755  Kokkos::parallel_for(
756  policy, KOKKOS_LAMBDA(viskores::Id i, viskores::Id j, viskores::Id k) {
757  auto flatIdx = i + (j * rMax_0) + (k * rMax_0 * rMax_1);
758  functor(viskores::Id3(i, j, k), flatIdx);
759  });
760  CheckForErrors(); // synchronizes
761  }
762 
763  template <typename Hints, typename Functor>
764  VISKORES_CONT static void Schedule(Hints, Functor functor, viskores::Id numInstances)
765  {
767 
768  viskores::exec::kokkos::internal::TaskBasic1D<Functor, viskores::internal::NullType, Hints>
769  kernel(functor);
770  ScheduleTask(kernel, numInstances);
771  }
772 
773  template <typename FunctorType>
774  VISKORES_CONT static inline void Schedule(FunctorType&& functor, viskores::Id numInstances)
775  {
776  Schedule(viskores::cont::internal::HintList<>{}, functor, numInstances);
777  }
778 
779  template <typename Hints, typename Functor>
780  VISKORES_CONT static void Schedule(Hints, Functor functor, const viskores::Id3& rangeMax)
781  {
783 
784  viskores::exec::kokkos::internal::TaskBasic3D<Functor, viskores::internal::NullType, Hints>
785  kernel(functor);
786  ScheduleTask(kernel, rangeMax);
787  }
788 
789  template <typename FunctorType>
790  VISKORES_CONT static inline void Schedule(FunctorType&& functor, viskores::Id3 rangeMax)
791  {
792  Schedule(viskores::cont::internal::HintList<>{}, functor, rangeMax);
793  }
794 
795  //----------------------------------------------------------------------------
796 private:
797  template <typename T>
800  std::true_type)
801  {
802  // In Kokkos 3.7, we have noticed some errors when sorting with zero-length arrays (which
803  // should do nothing). There is no check, and the bin size computation gets messed up.
804  if (values.GetNumberOfValues() <= 1)
805  {
806  return;
807  }
808 
809  viskores::cont::Token token;
810  auto portal = values.PrepareForInPlace(viskores::cont::DeviceAdapterTagKokkos{}, token);
811  kokkos::internal::KokkosViewExec<T> view(portal.GetArray(), portal.GetNumberOfValues());
812 
813  // We use per-thread execution spaces so that the threads can execute independently without
814  // requiring global synchronizations.
815  // Currently, there is no way to specify the execution space for sort and therefore it
816  // executes in the default execution space.
817  // Therefore, we need explicit syncs here.
818  viskores::cont::kokkos::internal::GetExecutionSpaceInstance().fence();
819  Kokkos::sort(view);
820  viskores::cont::kokkos::internal::GetExecutionSpaceInstance().fence();
821  }
822 
823  template <typename T>
825  viskores::SortLess comp,
826  std::false_type)
827  {
828  Superclass::Sort(values, comp);
829  }
830 
831 public:
832  using Superclass::Sort;
833 
834  template <typename T>
836  {
837  SortImpl(values, comp, typename std::is_scalar<T>::type{});
838  }
839 
840 protected:
841  // Kokkos currently (11/10/2022) does not support a sort_by_key operator
842  // so instead we are using thrust if and only if HIP or CUDA are the backends for Kokkos
843 #if defined(VISKORES_USE_KOKKOS_THRUST)
844 
845  template <typename T, typename U, typename BinaryCompare>
846  VISKORES_CONT static std::enable_if_t<(std::is_same<BinaryCompare, viskores::SortLess>::value ||
847  std::is_same<BinaryCompare, viskores::SortGreater>::value)>
848  SortByKeyImpl(viskores::cont::ArrayHandle<T>& keys,
850  BinaryCompare,
851  std::true_type,
852  std::true_type)
853  {
854  viskores::cont::Token token;
855  auto keys_portal = keys.PrepareForInPlace(viskores::cont::DeviceAdapterTagKokkos{}, token);
856  auto values_portal = values.PrepareForInPlace(viskores::cont::DeviceAdapterTagKokkos{}, token);
857 
858  kokkos::internal::KokkosViewExec<T> keys_view(keys_portal.GetArray(),
859  keys_portal.GetNumberOfValues());
860  kokkos::internal::KokkosViewExec<U> values_view(values_portal.GetArray(),
861  values_portal.GetNumberOfValues());
862 
863  thrust::device_ptr<T> keys_begin(keys_view.data());
864  thrust::device_ptr<T> keys_end(keys_view.data() + keys_view.size());
865  thrust::device_ptr<U> values_begin(values_view.data());
866 
867  if (std::is_same<BinaryCompare, viskores::SortLess>::value)
868  {
869  thrust::sort_by_key(keys_begin, keys_end, values_begin, thrust::less<T>());
870  }
871  else
872  {
873  thrust::sort_by_key(keys_begin, keys_end, values_begin, thrust::greater<T>());
874  }
875  }
876 
877 #endif
878 
879  template <typename T,
880  typename U,
881  class StorageT,
882  class StorageU,
883  class BinaryCompare,
884  typename ValidKeys,
885  typename ValidValues>
888  BinaryCompare binary_compare,
889  ValidKeys,
890  ValidValues)
891  {
892  // Default to general algorithm
893  Superclass::SortByKey(keys, values, binary_compare);
894  }
895 
896 public:
897  template <typename T, typename U, class StorageT, class StorageU>
900  {
901  // Make sure not to use the general algorithm here since
902  // it will use Sort algorithm instead of SortByKey
904  }
905 
906  template <typename T, typename U, class StorageT, class StorageU, class BinaryCompare>
909  BinaryCompare binary_compare)
910  {
911  // If T or U are not scalar types, or the BinaryCompare is not supported
912  // then the general algorithm is called, otherwise we will run thrust
913  SortByKeyImpl(keys,
914  values,
915  binary_compare,
916  typename std::is_scalar<T>::type{},
917  typename std::is_scalar<U>::type{});
918  }
919 
920  //----------------------------------------------------------------------------
921  // Reduce By Key
922 
923 #ifdef VISKORES_USE_KOKKOS_THRUST
924 
925 protected:
926  template <typename K, typename V, class BinaryFunctor>
927  VISKORES_CONT static void ReduceByKeyImpl(const viskores::cont::ArrayHandle<K>& keys,
928  const viskores::cont::ArrayHandle<V>& values,
929  viskores::cont::ArrayHandle<K>& keys_output,
930  viskores::cont::ArrayHandle<V>& values_output,
931  BinaryFunctor binary_functor)
932  {
934 
935  const viskores::Id numberOfKeys = keys.GetNumberOfValues();
936 
937  viskores::Id num_unique_keys;
938  {
939  viskores::cont::Token token;
940 
941  auto keys_portal = keys.PrepareForInput(viskores::cont::DeviceAdapterTagKokkos{}, token);
942  auto values_portal = values.PrepareForInput(viskores::cont::DeviceAdapterTagKokkos{}, token);
943 
944  auto keys_output_portal =
945  keys_output.PrepareForOutput(numberOfKeys, viskores::cont::DeviceAdapterTagKokkos{}, token);
946  auto values_output_portal = values_output.PrepareForOutput(
947  numberOfKeys, viskores::cont::DeviceAdapterTagKokkos{}, token);
948 
949  thrust::device_ptr<const K> keys_begin(keys_portal.GetArray());
950  thrust::device_ptr<const K> keys_end(keys_portal.GetArray() + numberOfKeys);
951  thrust::device_ptr<const V> values_begin(values_portal.GetArray());
952  thrust::device_ptr<K> keys_output_begin(keys_output_portal.GetArray());
953  thrust::device_ptr<V> values_output_begin(values_output_portal.GetArray());
954 
955  auto ends = thrust::reduce_by_key(keys_begin,
956  keys_end,
957  values_begin,
958  keys_output_begin,
959  values_output_begin,
960  thrust::equal_to<K>(),
961  binary_functor);
962 
963  num_unique_keys = ends.first - keys_output_begin;
964  }
965 
966  // Resize output (reduce allocation)
967  keys_output.Allocate(num_unique_keys, CopyFlag::On);
968  values_output.Allocate(num_unique_keys, CopyFlag::On);
969  }
970 
971 
972  template <typename K, typename V, class BinaryFunctor>
973  VISKORES_CONT static void ReduceByKeyImpl(
974  const viskores::cont::ArrayHandle<K>& keys,
976  viskores::cont::ArrayHandle<K>& keys_output,
977  viskores::cont::ArrayHandle<V>& values_output,
978  BinaryFunctor binary_functor)
979  {
981 
982  const viskores::Id numberOfKeys = keys.GetNumberOfValues();
983 
984  viskores::Id num_unique_keys;
985  {
986  viskores::cont::Token token;
987 
988  auto keys_portal = keys.PrepareForInput(viskores::cont::DeviceAdapterTagKokkos{}, token);
989  auto value = values.ReadPortal().Get(0);
990 
991  auto keys_output_portal =
992  keys_output.PrepareForOutput(numberOfKeys, viskores::cont::DeviceAdapterTagKokkos{}, token);
993  auto values_output_portal = values_output.PrepareForOutput(
994  numberOfKeys, viskores::cont::DeviceAdapterTagKokkos{}, token);
995 
996  thrust::device_ptr<const K> keys_begin(keys_portal.GetArray());
997  thrust::device_ptr<const K> keys_end(keys_portal.GetArray() + numberOfKeys);
998  thrust::constant_iterator<const V> values_begin(value);
999  thrust::device_ptr<K> keys_output_begin(keys_output_portal.GetArray());
1000  thrust::device_ptr<V> values_output_begin(values_output_portal.GetArray());
1001 
1002  auto ends = thrust::reduce_by_key(keys_begin,
1003  keys_end,
1004  values_begin,
1005  keys_output_begin,
1006  values_output_begin,
1007  thrust::equal_to<K>(),
1008  binary_functor);
1009 
1010  num_unique_keys = ends.first - keys_output_begin;
1011  }
1012 
1013  // Resize output (reduce allocation)
1014  keys_output.Allocate(num_unique_keys, CopyFlag::On);
1015  values_output.Allocate(num_unique_keys, CopyFlag::On);
1016  }
1017 
1018  template <typename T,
1019  typename U,
1020  class KIn,
1021  class VIn,
1022  class KOut,
1023  class VOut,
1024  class BinaryFunctor>
1025  VISKORES_CONT static void ReduceByKeyImpl(const viskores::cont::ArrayHandle<T, KIn>& keys,
1028  viskores::cont::ArrayHandle<U, VOut>& values_output,
1029  BinaryFunctor binary_functor)
1030  {
1032 
1033  Superclass::ReduceByKey(keys, values, keys_output, values_output, binary_functor);
1034  }
1035 
1036 public:
1037  template <typename T,
1038  typename U,
1039  class KIn,
1040  class VIn,
1041  class KOut,
1042  class VOut,
1043  class BinaryFunctor>
1047  viskores::cont::ArrayHandle<U, VOut>& values_output,
1048  BinaryFunctor binary_functor)
1049  {
1051 
1052  ReduceByKeyImpl(keys, values, keys_output, values_output, binary_functor);
1053  }
1054 
1055 #endif
1056 
1057  //--------------------------------------------------------------------------
1058 
1060  {
1061  viskores::cont::kokkos::internal::GetExecutionSpaceInstance().fence();
1062  }
1063 };
1064 
1065 //=============================================================================
1066 template <>
1068 {
1069 public:
1070  template <typename Hints, typename WorkletType, typename InvocationType>
1071  VISKORES_CONT static viskores::exec::kokkos::internal::
1072  TaskBasic1D<WorkletType, InvocationType, Hints>
1073  MakeTask(WorkletType& worklet, InvocationType& invocation, viskores::Id, Hints = Hints{})
1074  {
1075  return viskores::exec::kokkos::internal::TaskBasic1D<WorkletType, InvocationType, Hints>(
1076  worklet, invocation);
1077  }
1078 
1079  template <typename Hints, typename WorkletType, typename InvocationType>
1080  VISKORES_CONT static viskores::exec::kokkos::internal::
1081  TaskBasic3D<WorkletType, InvocationType, Hints>
1082  MakeTask(WorkletType& worklet, InvocationType& invocation, viskores::Id3, Hints = {})
1083  {
1084  return viskores::exec::kokkos::internal::TaskBasic3D<WorkletType, InvocationType, Hints>(
1085  worklet, invocation);
1086  }
1087 
1088  template <typename WorkletType, typename InvocationType, typename RangeType>
1089  VISKORES_CONT static auto MakeTask(WorkletType& worklet,
1090  InvocationType& invocation,
1091  const RangeType& range)
1092  {
1093  return MakeTask<viskores::cont::internal::HintList<>>(worklet, invocation, range);
1094  }
1095 };
1096 }
1097 } // namespace viskores::cont
1098 
1099 #undef VISKORES_VOLATILE
1100 
1101 #endif //viskores_cont_kokkos_internal_DeviceAdapterAlgorithmKokkos_h
viskores::cont::DeviceTaskTypes< viskores::cont::DeviceAdapterTagKokkos >::MakeTask
static viskores::exec::kokkos::internal::TaskBasic3D< WorkletType, InvocationType, Hints > MakeTask(WorkletType &worklet, InvocationType &invocation, viskores::Id3, Hints={})
Definition: DeviceAdapterAlgorithmKokkos.h:1082
viskores::cont::DeviceAdapterAlgorithm::CopyIf
static void CopyIf(const viskores::cont::ArrayHandle< T, CIn > &input, const viskores::cont::ArrayHandle< U, CStencil > &stencil, viskores::cont::ArrayHandle< T, COut > &output)
Conditionally copy elements in the input array to the output array.
viskores::cont::DeviceAdapterAlgorithm
Struct containing device adapter algorithms.
Definition: DeviceAdapterAlgorithm.h:49
viskores::Product
Binary Predicate that takes two arguments argument x, and y and returns product (multiplication) of t...
Definition: BinaryOperators.h:64
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusiveFunctor
KokkosReduceFunctor< BinaryOperator, ScanExclusiveOperator< T, StorageIn, StorageOut, BinaryOperator >, T > ScanExclusiveFunctor
Definition: DeviceAdapterAlgorithmKokkos.h:498
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusiveImpl
static T ScanInclusiveImpl(const viskores::cont::ArrayHandle< T, StorageIn > &input, viskores::cont::ArrayHandle< T, StorageOut > &output, BinaryOperator binaryOperator, std::true_type)
Definition: DeviceAdapterAlgorithmKokkos.h:626
viskores::cont::ArrayHandle::ReadPortal
ReadPortalType ReadPortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:447
viskores::exec::FunctorBase
Base class for all user worklets invoked in the execution environment from a call to viskores::cont::...
Definition: FunctorBase.h:38
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ReduceOperator::Portal
ArrayPortal Portal
Definition: DeviceAdapterAlgorithmKokkos.h:340
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusiveOperator::PortalIn
ArrayPortalIn PortalIn
Definition: DeviceAdapterAlgorithmKokkos.h:489
viskores::SortLess
Binary Predicate that takes two arguments argument x, and y and returns True if and only if x is less...
Definition: BinaryPredicates.h:53
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusive
static T ScanExclusive(const viskores::cont::ArrayHandle< T, CIn > &input, viskores::cont::ArrayHandle< T, COut > &output, BinaryOperator binaryOperator, const T &initialValue)
Definition: DeviceAdapterAlgorithmKokkos.h:527
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusiveOperator::operator()
KOKKOS_INLINE_FUNCTION void operator()(const BinaryOperator &op, const viskores::Id i, T &update, const bool final) const
Definition: DeviceAdapterAlgorithmKokkos.h:471
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusiveOperator::ArrayPortalIn
typename ArrayHandle< T, StorageIn >::ReadPortalType ArrayPortalIn
Definition: DeviceAdapterAlgorithmKokkos.h:453
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::SortByKey
static void SortByKey(viskores::cont::ArrayHandle< T, StorageT > &keys, viskores::cont::ArrayHandle< U, StorageU > &values, BinaryCompare binary_compare)
Definition: DeviceAdapterAlgorithmKokkos.h:907
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::BitFieldToUnorderedSet
static viskores::Id BitFieldToUnorderedSet(const viskores::cont::BitField &bits, viskores::cont::ArrayHandle< Id, IndicesStorage > &indices)
Definition: DeviceAdapterAlgorithmKokkos.h:208
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::KokkosReduceFunctor::Functor
FunctorOperator Functor
Definition: DeviceAdapterAlgorithmKokkos.h:317
viskores::cont::ArrayHandle::PrepareForInput
ReadPortalType PrepareForInput(viskores::cont::DeviceAdapterId device, viskores::cont::Token &token) const
Prepares this array to be used as an input to an operation in the execution environment.
Definition: ArrayHandle.h:615
viskores::cont::DeviceTaskTypes< viskores::cont::DeviceAdapterTagKokkos >::MakeTask
static viskores::exec::kokkos::internal::TaskBasic1D< WorkletType, InvocationType, Hints > MakeTask(WorkletType &worklet, InvocationType &invocation, viskores::Id, Hints=Hints{})
Definition: DeviceAdapterAlgorithmKokkos.h:1073
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::Schedule
static void Schedule(FunctorType &&functor, viskores::Id numInstances)
Definition: DeviceAdapterAlgorithmKokkos.h:774
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusive
static T ScanExclusive(const viskores::cont::ArrayHandle< T, CIn > &input, viskores::cont::ArrayHandle< T, COut > &output)
Definition: DeviceAdapterAlgorithmKokkos.h:560
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::SortByKeyImpl
static void SortByKeyImpl(viskores::cont::ArrayHandle< T, StorageT > &keys, viskores::cont::ArrayHandle< U, StorageU > &values, BinaryCompare binary_compare, ValidKeys, ValidValues)
Definition: DeviceAdapterAlgorithmKokkos.h:886
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::UseKokkosScan
UseKokkosReduce< BinaryOperator, ResultType > UseKokkosScan
Definition: DeviceAdapterAlgorithmKokkos.h:437
VISKORES_THIRDPARTY_POST_INCLUDE
#define VISKORES_THIRDPARTY_POST_INCLUDE
Definition: Configure.h:200
viskores::TypeTraits::ZeroInitialization
static T ZeroInitialization()
A static function that returns 0 (or the closest equivalent to it) for the given type.
Definition: TypeTraits.h:85
viskores::BitwiseAnd
Binary Predicate that takes two arguments argument x, and y and returns the bitwise operation x&y
Definition: BinaryOperators.h:153
DeviceAdapterAlgorithmGeneral.h
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::Reduce
static U Reduce(const viskores::cont::ArrayHandle< T, CIn > &input, U initialValue, BinaryOperator binaryOperator)
Definition: DeviceAdapterAlgorithmKokkos.h:392
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusiveOperator::ArrayPortalIn
typename ArrayHandle< T, StorageIn >::ReadPortalType ArrayPortalIn
Definition: DeviceAdapterAlgorithmKokkos.h:587
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::KokkosReduceFunctor::Operator
BinaryOperator Operator
Definition: DeviceAdapterAlgorithmKokkos.h:316
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ReduceOperator::operator()
KOKKOS_INLINE_FUNCTION void operator()(const BinaryOperator &op, viskores::Id i, ResultType &update) const
Definition: DeviceAdapterAlgorithmKokkos.h:334
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::KokkosReduceFunctor::join
KOKKOS_INLINE_FUNCTION void join(volatile value_type &dst, const volatile value_type &src) const
Definition: DeviceAdapterAlgorithmKokkos.h:290
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusiveOperator::ScanInclusiveOperator
KOKKOS_INLINE_FUNCTION ScanInclusiveOperator(const ArrayPortalIn &portalIn, const ArrayPortalOut &portalOut)
Definition: DeviceAdapterAlgorithmKokkos.h:595
viskores::cont::BitField::GetNumberOfBits
viskores::Id GetNumberOfBits() const
Return the number of bits stored by this BitField.
viskores::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:313
ArrayHandleConstant.h
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusiveOperator::ArrayPortalOut
typename ArrayHandle< T, StorageOut >::WritePortalType ArrayPortalOut
Definition: DeviceAdapterAlgorithmKokkos.h:454
viskores::cont::ArrayPortal
A class that points to and access and array of data.
Definition: ArrayPortal.h:70
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::SortByKey
static void SortByKey(viskores::cont::ArrayHandle< T, StorageT > &keys, viskores::cont::ArrayHandle< U, StorageU > &values)
Definition: DeviceAdapterAlgorithmKokkos.h:898
viskores::IdComponent
viskores::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:202
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ReduceImpl
static ResultType ReduceImpl(const ArrayHandle &input, BinaryOperator binaryOperator, ResultType initialValue, std::true_type)
Definition: DeviceAdapterAlgorithmKokkos.h:349
DeviceAdapterTagKokkos.h
viskores::cont::DeviceAdapterAlgorithm::VIn
static T VIn
Definition: DeviceAdapterAlgorithm.h:360
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::Schedule
static void Schedule(FunctorType &&functor, viskores::Id3 rangeMax)
Definition: DeviceAdapterAlgorithmKokkos.h:790
VISKORES_EXEC_CONT
#define VISKORES_EXEC_CONT
Definition: ExportMacros.h:60
viskores::cont::DeviceAdapterAlgorithm::U
static T U
Definition: DeviceAdapterAlgorithm.h:358
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::Synchronize
static void Synchronize()
Definition: DeviceAdapterAlgorithmKokkos.h:1059
DeviceAdapterAlgorithm.h
viskores::cont::DeviceAdapterAlgorithm::VOut
static T VOut
Definition: DeviceAdapterAlgorithm.h:361
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::KokkosReduceFunctor::operator()
KOKKOS_INLINE_FUNCTION void operator()(viskores::Id i, ResultType &update, const bool final) const
Definition: DeviceAdapterAlgorithmKokkos.h:310
viskores::cont::DeviceAdapterTagKokkos
Tag for a device adapter that uses the Kokkos library to run algorithms in parallel.
Definition: DeviceAdapterTagKokkos.h:39
viskores::cont::DeviceAdapterAlgorithm::ScanExclusive
static T ScanExclusive(const viskores::cont::ArrayHandle< T, CIn > &input, viskores::cont::ArrayHandle< T, COut > &output)
Compute an exclusive prefix sum operation on the input ArrayHandle.
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ReduceImpl
static ResultType ReduceImpl(const ArrayHandle &input, BinaryOperator binaryOperator, ResultType initialValue, std::false_type)
Definition: DeviceAdapterAlgorithmKokkos.h:264
viskores::cont::DeviceAdapterAlgorithm::Reduce
static U Reduce(const viskores::cont::ArrayHandle< T, CIn > &input, U initialValue)
Compute a accumulated sum operation on the input ArrayHandle.
viskores::Multiply
Definition: Types.h:308
viskores::Add
Definition: Types.h:268
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::SortImpl
static void SortImpl(viskores::cont::ArrayHandle< T > &values, viskores::SortLess, std::true_type)
Definition: DeviceAdapterAlgorithmKokkos.h:798
viskores::cont::BitField::PrepareForInput
ReadPortalType PrepareForInput(viskores::cont::DeviceAdapterId device, viskores::cont::Token &token) const
Prepares this BitField to be used as an input to an operation in the execution environment.
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::Copy
static void Copy(const viskores::cont::ArrayHandle< T > &input, viskores::cont::ArrayHandle< T > &output)
Definition: DeviceAdapterAlgorithmKokkos.h:240
viskores::Maximum
Binary Predicate that takes two arguments argument x, and y and returns the x if x > y otherwise retu...
Definition: BinaryOperators.h:93
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::CountSetBits
static viskores::Id CountSetBits(const viskores::cont::BitField &bits)
Definition: DeviceAdapterAlgorithmKokkos.h:224
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScheduleTask
static void ScheduleTask(viskores::exec::kokkos::internal::TaskBasic1D< WType, IType, Hints > &functor, viskores::Id numInstances)
Definition: DeviceAdapterAlgorithmKokkos.h:692
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::KokkosReduceFunctor::init
KOKKOS_INLINE_FUNCTION void init(value_type &dst) const
Definition: DeviceAdapterAlgorithmKokkos.h:296
viskores::TypeTraits
The TypeTraits class provides helpful compile-time information about the basic types used in Viskores...
Definition: TypeTraits.h:69
viskores::Id
viskores::Int64 Id
Base type to use to index arrays.
Definition: Types.h:235
viskores::cont::ArrayHandle::ReleaseResources
void ReleaseResources() const
Releases all resources in both the control and execution environments.
Definition: ArrayHandle.h:600
viskores::BitwiseOr
Binary Predicate that takes two arguments argument x, and y and returns the bitwise operation x|y
Definition: BinaryOperators.h:176
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusiveOperator::ScanExclusiveOperator
KOKKOS_INLINE_FUNCTION ScanExclusiveOperator()
Definition: DeviceAdapterAlgorithmKokkos.h:458
viskores::cont::DeviceAdapterAlgorithm::SortByKey
static void SortByKey(viskores::cont::ArrayHandle< T, StorageT > &keys, viskores::cont::ArrayHandle< U, StorageU > &values)
Unstable ascending sort of keys and values.
VISKORES_CONT
#define VISKORES_CONT
Definition: ExportMacros.h:65
viskores::cont::BitField
Definition: BitField.h:507
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusiveImpl
static T ScanExclusiveImpl(const viskores::cont::ArrayHandle< T, StorageIn > &input, viskores::cont::ArrayHandle< T, StorageOut > &output, BinaryOperator binaryOperator, const T &initialValue, std::false_type)
Definition: DeviceAdapterAlgorithmKokkos.h:440
viskores
Groups connected points that have the same field value.
Definition: Atomic.h:27
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusiveImpl
static T ScanExclusiveImpl(const viskores::cont::ArrayHandle< T, StorageIn > &input, viskores::cont::ArrayHandle< T, StorageOut > &output, BinaryOperator binaryOperator, const T &initialValue, std::true_type)
Definition: DeviceAdapterAlgorithmKokkos.h:501
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusiveOperator::PortalIn
ArrayPortalIn PortalIn
Definition: DeviceAdapterAlgorithmKokkos.h:615
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusiveOperator::ScanInclusiveOperator
KOKKOS_INLINE_FUNCTION ScanInclusiveOperator()
Definition: DeviceAdapterAlgorithmKokkos.h:592
viskores::cont::ArrayHandle::PrepareForInPlace
WritePortalType PrepareForInPlace(viskores::cont::DeviceAdapterId device, viskores::cont::Token &token) const
Prepares this array to be used in an in-place operation (both as input and output) in the execution e...
Definition: ArrayHandle.h:634
viskores::CopyFlag::On
@ On
ArrayHandleIndex.h
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ReduceOperator::ReduceOperator
KOKKOS_INLINE_FUNCTION ReduceOperator(const ArrayPortal &portal)
Definition: DeviceAdapterAlgorithmKokkos.h:328
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::Schedule
static void Schedule(Hints, Functor functor, viskores::Id numInstances)
Definition: DeviceAdapterAlgorithmKokkos.h:764
viskores::CountSetBits
viskores::Int32 CountSetBits(viskores::UInt32 word)
Count the total number of bits set in word.
Definition: Math.h:2948
viskores::cont::DeviceAdapterAlgorithm::ScanInclusive
static T ScanInclusive(const viskores::cont::ArrayHandle< T, CIn > &input, viskores::cont::ArrayHandle< T, COut > &output)
Compute an inclusive prefix sum operation on the input ArrayHandle.
viskores::cont::ArrayHandle::Allocate
void Allocate(viskores::Id numberOfValues, viskores::CopyFlag preserve, viskores::cont::Token &token) const
Allocates an array large enough to hold the given number of values.
Definition: ArrayHandle.h:504
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::KokkosReduceFunctor::KokkosReduceFunctor
KOKKOS_INLINE_FUNCTION KokkosReduceFunctor(const BinaryOperator &op, Args... args)
Definition: DeviceAdapterAlgorithmKokkos.h:283
viskores::cont::ArrayHandle::GetNumberOfValues
viskores::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:482
viskores::cont::ArrayHandle::PrepareForOutput
WritePortalType PrepareForOutput(viskores::Id numberOfValues, viskores::cont::DeviceAdapterId device, viskores::cont::Token &token) const
Prepares (allocates) this array to be used as an output from an operation in the execution environmen...
Definition: ArrayHandle.h:654
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::Reduce
static U Reduce(const viskores::cont::ArrayHandle< T, CIn > &input, U initialValue)
Definition: DeviceAdapterAlgorithmKokkos.h:423
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusiveImpl
static T ScanInclusiveImpl(const viskores::cont::ArrayHandle< T, StorageIn > &input, viskores::cont::ArrayHandle< T, StorageOut > &output, BinaryOperator binaryOperator, std::false_type)
Definition: DeviceAdapterAlgorithmKokkos.h:575
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusiveOperator::operator()
KOKKOS_INLINE_FUNCTION void operator()(const BinaryOperator &op, const viskores::Id i, T &update, const bool final) const
Definition: DeviceAdapterAlgorithmKokkos.h:602
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::KokkosReduceFunctor::KokkosReduceFunctor
KOKKOS_INLINE_FUNCTION KokkosReduceFunctor()
Definition: DeviceAdapterAlgorithmKokkos.h:280
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusiveOperator::ArrayPortalOut
typename ArrayHandle< T, StorageOut >::WritePortalType ArrayPortalOut
Definition: DeviceAdapterAlgorithmKokkos.h:588
viskores::cont::DeviceAdapterAlgorithm::KIn
static T KIn
Definition: DeviceAdapterAlgorithm.h:359
ErrorExecution.h
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusive
static T ScanInclusive(const viskores::cont::ArrayHandle< T, CIn > &input, viskores::cont::ArrayHandle< T, COut > &output)
Definition: DeviceAdapterAlgorithmKokkos.h:682
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::SortImpl
static void SortImpl(viskores::cont::ArrayHandle< T > &values, viskores::SortLess comp, std::false_type)
Definition: DeviceAdapterAlgorithmKokkos.h:824
viskores::Sum
Binary Predicate that takes two arguments argument x, and y and returns sum (addition) of the two val...
Definition: BinaryOperators.h:41
KokkosTypes.h
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >
Definition: DeviceAdapterAlgorithmKokkos.h:192
viskores::cont::DeviceAdapterAlgorithm::ReduceByKey
static void ReduceByKey(const viskores::cont::ArrayHandle< T, CKeyIn > &keys, const viskores::cont::ArrayHandle< U, CValIn > &values, viskores::cont::ArrayHandle< T, CKeyOut > &keys_output, viskores::cont::ArrayHandle< U, CValOut > &values_output, BinaryFunctor binary_functor)
Compute a accumulated sum operation on the input key value pairs.
VISKORES_VOLATILE
#define VISKORES_VOLATILE
Definition: DeviceAdapterAlgorithmKokkos.h:47
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::KokkosReduceFunctor::value_type
ResultType value_type
Definition: DeviceAdapterAlgorithmKokkos.h:277
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusiveFunctor
KokkosReduceFunctor< BinaryOperator, ScanInclusiveOperator< T, StorageIn, StorageOut, BinaryOperator >, T > ScanInclusiveFunctor
Definition: DeviceAdapterAlgorithmKokkos.h:623
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusiveOperator::InitialValue
T InitialValue
Definition: DeviceAdapterAlgorithmKokkos.h:491
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::Superclass
viskores::cont::internal::DeviceAdapterAlgorithmGeneral< DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >, viskores::cont::DeviceAdapterTagKokkos > Superclass
Definition: DeviceAdapterAlgorithmKokkos.h:200
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusiveOperator::ScanExclusiveOperator
KOKKOS_INLINE_FUNCTION ScanExclusiveOperator(const ArrayPortalIn &portalIn, const ArrayPortalOut &portalOut, const T &initialValue)
Definition: DeviceAdapterAlgorithmKokkos.h:461
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusiveOperator::PortalOut
ArrayPortalOut PortalOut
Definition: DeviceAdapterAlgorithmKokkos.h:616
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanInclusive
static T ScanInclusive(const viskores::cont::ArrayHandle< T, CIn > &input, viskores::cont::ArrayHandle< T, COut > &output, BinaryOperator binaryOperator)
Definition: DeviceAdapterAlgorithmKokkos.h:651
VISKORES_LOG_SCOPE_FUNCTION
#define VISKORES_LOG_SCOPE_FUNCTION(level)
Definition: Logging.h:225
viskores::cont::LogLevel::Perf
@ Perf
General timing data and algorithm flow information, such as filter execution, worklet dispatches,...
viskores::cont::DeviceTaskTypes
Class providing a device-specific support for selecting the optimal Task type for a given worklet.
Definition: DeviceAdapterAlgorithm.h:757
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::Sort
static void Sort(viskores::cont::ArrayHandle< T > &values, viskores::SortLess comp)
Definition: DeviceAdapterAlgorithmKokkos.h:835
viskores::Minimum
Binary Predicate that takes two arguments argument x, and y and returns the x if x < y otherwise retu...
Definition: BinaryOperators.h:107
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ReduceOperator::ReduceOperator
KOKKOS_INLINE_FUNCTION ReduceOperator()
Definition: DeviceAdapterAlgorithmKokkos.h:325
viskores::cont::DeviceTaskTypes< viskores::cont::DeviceAdapterTagKokkos >::MakeTask
static auto MakeTask(WorkletType &worklet, InvocationType &invocation, const RangeType &range)
Definition: DeviceAdapterAlgorithmKokkos.h:1089
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ReduceFunctor
KokkosReduceFunctor< BinaryOperator, ReduceOperator< ArrayPortal, BinaryOperator, ResultType >, ResultType > ReduceFunctor
Definition: DeviceAdapterAlgorithmKokkos.h:346
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::KokkosReduceFunctor::size_type
viskores::Id size_type
Definition: DeviceAdapterAlgorithmKokkos.h:276
ArrayHandleImplicit.h
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScheduleTask
static void ScheduleTask(viskores::exec::kokkos::internal::TaskBasic3D< WType, IType, Hints > &functor, viskores::Id3 rangeMax)
Definition: DeviceAdapterAlgorithmKokkos.h:720
viskores::cont::make_ArrayHandleImplicit
viskores::cont::ArrayHandleImplicit< FunctorType > make_ArrayHandleImplicit(FunctorType functor, viskores::Id length)
make_ArrayHandleImplicit is convenience function to generate an ArrayHandleImplicit.
Definition: ArrayHandleImplicit.h:210
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::KokkosReduceFunctor::operator()
KOKKOS_INLINE_FUNCTION void operator()(viskores::Id i, ResultType &update) const
Definition: DeviceAdapterAlgorithmKokkos.h:303
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::Schedule
static void Schedule(Hints, Functor functor, const viskores::Id3 &rangeMax)
Definition: DeviceAdapterAlgorithmKokkos.h:780
viskores::cont::DeviceAdapterAlgorithm::Fill
static void Fill(viskores::cont::BitField &bits, bool value, viskores::Id numBits)
Fill the BitField with a specific pattern of bits.
VISKORES_THIRDPARTY_PRE_INCLUDE
#define VISKORES_THIRDPARTY_PRE_INCLUDE
Definition: Configure.h:199
viskores::Vec
A short fixed-length array.
Definition: Types.h:365
viskores::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:43
viskores::MinAndMax
Binary Predicate that takes two arguments argument x, and y and returns a viskores::Vec<T,...
Definition: BinaryOperators.h:120
VISKORES_EXEC
#define VISKORES_EXEC
Definition: ExportMacros.h:59
TaskBasic.h
viskores::cont::ArrayHandleIndex
An implicit array handle containing the its own indices.
Definition: ArrayHandleIndex.h:64
viskores::cont::DeviceAdapterAlgorithm< viskores::cont::DeviceAdapterTagKokkos >::ScanExclusiveOperator::PortalOut
ArrayPortalOut PortalOut
Definition: DeviceAdapterAlgorithmKokkos.h:490
viskores::cont::DeviceAdapterAlgorithm::Schedule
static void Schedule(Functor functor, viskores::Id numInstances)
Schedule many instances of a function to run on concurrent threads.
viskores_cont_export.h