VTK-m  2.0
DeviceAdapterAlgorithmGeneral.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 
11 #ifndef vtk_m_cont_internal_DeviceAdapterAlgorithmGeneral_h
12 #define vtk_m_cont_internal_DeviceAdapterAlgorithmGeneral_h
13 
14 #include <vtkm/cont/ArrayHandle.h>
20 #include <vtkm/cont/BitField.h>
21 #include <vtkm/cont/Logging.h>
23 
26 
27 #include <vtkm/BinaryPredicates.h>
28 #include <vtkm/TypeTraits.h>
29 
30 #include <vtkm/internal/Windows.h>
31 
32 #include <type_traits>
33 
34 namespace vtkm
35 {
36 namespace cont
37 {
38 namespace internal
39 {
40 
89 template <class DerivedAlgorithm, class DeviceAdapterTag>
90 struct DeviceAdapterAlgorithmGeneral
91 {
92  //--------------------------------------------------------------------------
93  // Get Execution Value
94  // This method is used internally to get a single element from the execution
95  // array. Normally you would just use ArrayGetValue, but that functionality
96  // relies on the device adapter algorithm and would create a circular
97  // dependency.
98 private:
99  template <typename T, class CIn>
100  VTKM_CONT static T GetExecutionValue(const vtkm::cont::ArrayHandle<T, CIn>& input, vtkm::Id index)
101  {
103 
104  {
105  vtkm::cont::Token token;
106 
107  auto inputPortal = input.PrepareForInput(DeviceAdapterTag(), token);
108  auto outputPortal = output.PrepareForOutput(1, DeviceAdapterTag(), token);
109 
110  CopyKernel<decltype(inputPortal), decltype(outputPortal)> kernel(
111  inputPortal, outputPortal, index);
112 
113  DerivedAlgorithm::Schedule(kernel, 1);
114  }
115 
116  return output.ReadPortal().Get(0);
117  }
118 
119 public:
120  //--------------------------------------------------------------------------
121  // BitFieldToUnorderedSet
122  template <typename IndicesStorage>
123  VTKM_CONT static vtkm::Id BitFieldToUnorderedSet(
124  const vtkm::cont::BitField& bits,
126  {
128 
129  vtkm::Id numBits = bits.GetNumberOfBits();
130 
131  vtkm::cont::Token token;
132 
133  auto bitsPortal = bits.PrepareForInput(DeviceAdapterTag{}, token);
134  auto indicesPortal = indices.PrepareForOutput(numBits, DeviceAdapterTag{}, token);
135 
136  std::atomic<vtkm::UInt64> popCount;
137  popCount.store(0, std::memory_order_seq_cst);
138 
139  using Functor = BitFieldToUnorderedSetFunctor<decltype(bitsPortal), decltype(indicesPortal)>;
140  Functor functor{ bitsPortal, indicesPortal, popCount };
141 
142  DerivedAlgorithm::Schedule(functor, functor.GetNumberOfInstances());
143  DerivedAlgorithm::Synchronize();
144 
145  token.DetachFromAll();
146 
147  numBits = static_cast<vtkm::Id>(popCount.load(std::memory_order_seq_cst));
148 
149  indices.Allocate(numBits, vtkm::CopyFlag::On);
150  return numBits;
151  }
152 
153  //--------------------------------------------------------------------------
154  // Copy
155  template <typename T, typename U, class CIn, class COut>
156  VTKM_CONT static void Copy(const vtkm::cont::ArrayHandle<T, CIn>& input,
158  {
160 
161  vtkm::cont::Token token;
162 
163  const vtkm::Id inSize = input.GetNumberOfValues();
164  auto inputPortal = input.PrepareForInput(DeviceAdapterTag(), token);
165  auto outputPortal = output.PrepareForOutput(inSize, DeviceAdapterTag(), token);
166 
167  CopyKernel<decltype(inputPortal), decltype(outputPortal)> kernel(inputPortal, outputPortal);
168  DerivedAlgorithm::Schedule(kernel, inSize);
169  }
170 
171  //--------------------------------------------------------------------------
172  // CopyIf
173  template <typename T, typename U, class CIn, class CStencil, class COut, class UnaryPredicate>
174  VTKM_CONT static void CopyIf(const vtkm::cont::ArrayHandle<T, CIn>& input,
177  UnaryPredicate unary_predicate)
178  {
180 
181  VTKM_ASSERT(input.GetNumberOfValues() == stencil.GetNumberOfValues());
182  vtkm::Id arrayLength = stencil.GetNumberOfValues();
183 
185  IndexArrayType indices;
186 
187  {
188  vtkm::cont::Token token;
189 
190  auto stencilPortal = stencil.PrepareForInput(DeviceAdapterTag(), token);
191  auto indexPortal = indices.PrepareForOutput(arrayLength, DeviceAdapterTag(), token);
192 
193  StencilToIndexFlagKernel<decltype(stencilPortal), decltype(indexPortal), UnaryPredicate>
194  indexKernel(stencilPortal, indexPortal, unary_predicate);
195 
196  DerivedAlgorithm::Schedule(indexKernel, arrayLength);
197  }
198 
199  vtkm::Id outArrayLength = DerivedAlgorithm::ScanExclusive(indices, indices);
200 
201  {
202  vtkm::cont::Token token;
203 
204  auto inputPortal = input.PrepareForInput(DeviceAdapterTag(), token);
205  auto stencilPortal = stencil.PrepareForInput(DeviceAdapterTag(), token);
206  auto indexPortal = indices.PrepareForOutput(arrayLength, DeviceAdapterTag(), token);
207  auto outputPortal = output.PrepareForOutput(outArrayLength, DeviceAdapterTag(), token);
208 
209  CopyIfKernel<decltype(inputPortal),
210  decltype(stencilPortal),
211  decltype(indexPortal),
212  decltype(outputPortal),
213  UnaryPredicate>
214  copyKernel(inputPortal, stencilPortal, indexPortal, outputPortal, unary_predicate);
215  DerivedAlgorithm::Schedule(copyKernel, arrayLength);
216  }
217  }
218 
219  template <typename T, typename U, class CIn, class CStencil, class COut>
220  VTKM_CONT static void CopyIf(const vtkm::cont::ArrayHandle<T, CIn>& input,
223  {
225 
226  ::vtkm::NotZeroInitialized unary_predicate;
227  DerivedAlgorithm::CopyIf(input, stencil, output, unary_predicate);
228  }
229 
230  //--------------------------------------------------------------------------
231  // CopySubRange
232  template <typename T, typename U, class CIn, class COut>
233  VTKM_CONT static bool CopySubRange(const vtkm::cont::ArrayHandle<T, CIn>& input,
234  vtkm::Id inputStartIndex,
235  vtkm::Id numberOfElementsToCopy,
237  vtkm::Id outputIndex = 0)
238  {
240 
241  const vtkm::Id inSize = input.GetNumberOfValues();
242 
243  // Check if the ranges overlap and fail if they do.
244  if (input == output &&
245  ((outputIndex >= inputStartIndex &&
246  outputIndex < inputStartIndex + numberOfElementsToCopy) ||
247  (inputStartIndex >= outputIndex &&
248  inputStartIndex < outputIndex + numberOfElementsToCopy)))
249  {
250  return false;
251  }
252 
253  if (inputStartIndex < 0 || numberOfElementsToCopy < 0 || outputIndex < 0 ||
254  inputStartIndex >= inSize)
255  { //invalid parameters
256  return false;
257  }
258 
259  //determine if the numberOfElementsToCopy needs to be reduced
260  if (inSize < (inputStartIndex + numberOfElementsToCopy))
261  { //adjust the size
262  numberOfElementsToCopy = (inSize - inputStartIndex);
263  }
264 
265  const vtkm::Id outSize = output.GetNumberOfValues();
266  const vtkm::Id copyOutEnd = outputIndex + numberOfElementsToCopy;
267  if (outSize < copyOutEnd)
268  { //output is not large enough
269  if (outSize == 0)
270  { //since output has nothing, just need to allocate to correct length
271  output.Allocate(copyOutEnd);
272  }
273  else
274  { //we currently have data in this array, so preserve it in the new
275  //resized array
277  temp.Allocate(copyOutEnd);
278  DerivedAlgorithm::CopySubRange(output, 0, outSize, temp);
279  output = temp;
280  }
281  }
282 
283  vtkm::cont::Token token;
284 
285  auto inputPortal = input.PrepareForInput(DeviceAdapterTag(), token);
286  auto outputPortal = output.PrepareForInPlace(DeviceAdapterTag(), token);
287 
288  CopyKernel<decltype(inputPortal), decltype(outputPortal)> kernel(
289  inputPortal, outputPortal, inputStartIndex, outputIndex);
290  DerivedAlgorithm::Schedule(kernel, numberOfElementsToCopy);
291  return true;
292  }
293 
294  //--------------------------------------------------------------------------
295  // Count Set Bits
297  {
299 
300  vtkm::cont::Token token;
301 
302  auto bitsPortal = bits.PrepareForInput(DeviceAdapterTag{}, token);
303 
304  std::atomic<vtkm::UInt64> popCount;
305  popCount.store(0, std::memory_order_relaxed);
306 
307  using Functor = CountSetBitsFunctor<decltype(bitsPortal)>;
308  Functor functor{ bitsPortal, popCount };
309 
310  DerivedAlgorithm::Schedule(functor, functor.GetNumberOfInstances());
311  DerivedAlgorithm::Synchronize();
312 
313  return static_cast<vtkm::Id>(popCount.load(std::memory_order_seq_cst));
314  }
315 
316  //--------------------------------------------------------------------------
317  // Fill Bit Field (bool, resize)
318  VTKM_CONT static void Fill(vtkm::cont::BitField& bits, bool value, vtkm::Id numBits)
319  {
321 
322  if (numBits == 0)
323  {
324  bits.Allocate(0);
325  return;
326  }
327 
328  vtkm::cont::Token token;
329 
330  auto portal = bits.PrepareForOutput(numBits, DeviceAdapterTag{}, token);
331 
332  using WordType =
333  typename vtkm::cont::BitField::template ExecutionTypes<DeviceAdapterTag>::WordTypePreferred;
334 
335  using Functor = FillBitFieldFunctor<decltype(portal), WordType>;
336  Functor functor{ portal, value ? ~WordType{ 0 } : WordType{ 0 } };
337 
338  const vtkm::Id numWords = portal.template GetNumberOfWords<WordType>();
339  DerivedAlgorithm::Schedule(functor, numWords);
340  }
341 
342  //--------------------------------------------------------------------------
343  // Fill Bit Field (bool)
344  VTKM_CONT static void Fill(vtkm::cont::BitField& bits, bool value)
345  {
347 
348  const vtkm::Id numBits = bits.GetNumberOfBits();
349  if (numBits == 0)
350  {
351  return;
352  }
353 
354  vtkm::cont::Token token;
355 
356  auto portal = bits.PrepareForOutput(numBits, DeviceAdapterTag{}, token);
357 
358  using WordType =
359  typename vtkm::cont::BitField::template ExecutionTypes<DeviceAdapterTag>::WordTypePreferred;
360 
361  using Functor = FillBitFieldFunctor<decltype(portal), WordType>;
362  Functor functor{ portal, value ? ~WordType{ 0 } : WordType{ 0 } };
363 
364  const vtkm::Id numWords = portal.template GetNumberOfWords<WordType>();
365  DerivedAlgorithm::Schedule(functor, numWords);
366  }
367 
368  //--------------------------------------------------------------------------
369  // Fill Bit Field (mask, resize)
370  template <typename WordType>
371  VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word, vtkm::Id numBits)
372  {
374 
376 
377  if (numBits == 0)
378  {
379  bits.Allocate(0);
380  return;
381  }
382 
383  vtkm::cont::Token token;
384 
385  auto portal = bits.PrepareForOutput(numBits, DeviceAdapterTag{}, token);
386 
387  // If less than 32 bits, repeat the word until we get a 32 bit pattern.
388  // Using this for the pattern prevents races while writing small numbers
389  // to adjacent memory locations.
390  auto repWord = RepeatTo32BitsIfNeeded(word);
391  using RepWordType = decltype(repWord);
392 
393  using Functor = FillBitFieldFunctor<decltype(portal), RepWordType>;
394  Functor functor{ portal, repWord };
395 
396  const vtkm::Id numWords = portal.template GetNumberOfWords<RepWordType>();
397  DerivedAlgorithm::Schedule(functor, numWords);
398  }
399 
400  //--------------------------------------------------------------------------
401  // Fill Bit Field (mask)
402  template <typename WordType>
403  VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word)
404  {
407 
408  const vtkm::Id numBits = bits.GetNumberOfBits();
409  if (numBits == 0)
410  {
411  return;
412  }
413 
414  vtkm::cont::Token token;
415 
416  auto portal = bits.PrepareForOutput(numBits, DeviceAdapterTag{}, token);
417 
418  // If less than 32 bits, repeat the word until we get a 32 bit pattern.
419  // Using this for the pattern prevents races while writing small numbers
420  // to adjacent memory locations.
421  auto repWord = RepeatTo32BitsIfNeeded(word);
422  using RepWordType = decltype(repWord);
423 
424  using Functor = FillBitFieldFunctor<decltype(portal), RepWordType>;
425  Functor functor{ portal, repWord };
426 
427  const vtkm::Id numWords = portal.template GetNumberOfWords<RepWordType>();
428  DerivedAlgorithm::Schedule(functor, numWords);
429  }
430 
431  //--------------------------------------------------------------------------
432  // Fill ArrayHandle
433  template <typename T, typename S>
434  VTKM_CONT static void Fill(vtkm::cont::ArrayHandle<T, S>& handle, const T& value)
435  {
437 
438  const vtkm::Id numValues = handle.GetNumberOfValues();
439  if (numValues == 0)
440  {
441  return;
442  }
443 
444  vtkm::cont::Token token;
445 
446  auto portal = handle.PrepareForOutput(numValues, DeviceAdapterTag{}, token);
447  FillArrayHandleFunctor<decltype(portal)> functor{ portal, value };
448  DerivedAlgorithm::Schedule(functor, numValues);
449  }
450 
451  //--------------------------------------------------------------------------
452  // Fill ArrayHandle (resize)
453  template <typename T, typename S>
454  VTKM_CONT static void Fill(vtkm::cont::ArrayHandle<T, S>& handle,
455  const T& value,
456  const vtkm::Id numValues)
457  {
459  if (numValues == 0)
460  {
461  handle.ReleaseResources();
462  return;
463  }
464 
465  vtkm::cont::Token token;
466 
467  auto portal = handle.PrepareForOutput(numValues, DeviceAdapterTag{}, token);
468  FillArrayHandleFunctor<decltype(portal)> functor{ portal, value };
469  DerivedAlgorithm::Schedule(functor, numValues);
470  }
471 
472  //--------------------------------------------------------------------------
473  // Lower Bounds
474  template <typename T, class CIn, class CVal, class COut>
475  VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
476  const vtkm::cont::ArrayHandle<T, CVal>& values,
478  {
480 
481  vtkm::Id arraySize = values.GetNumberOfValues();
482 
483  vtkm::cont::Token token;
484 
485  auto inputPortal = input.PrepareForInput(DeviceAdapterTag(), token);
486  auto valuesPortal = values.PrepareForInput(DeviceAdapterTag(), token);
487  auto outputPortal = output.PrepareForOutput(arraySize, DeviceAdapterTag(), token);
488 
489  LowerBoundsKernel<decltype(inputPortal), decltype(valuesPortal), decltype(outputPortal)> kernel(
490  inputPortal, valuesPortal, outputPortal);
491 
492  DerivedAlgorithm::Schedule(kernel, arraySize);
493  }
494 
495  template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
496  VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
497  const vtkm::cont::ArrayHandle<T, CVal>& values,
499  BinaryCompare binary_compare)
500  {
502 
503  vtkm::Id arraySize = values.GetNumberOfValues();
504 
505  vtkm::cont::Token token;
506 
507  auto inputPortal = input.PrepareForInput(DeviceAdapterTag(), token);
508  auto valuesPortal = values.PrepareForInput(DeviceAdapterTag(), token);
509  auto outputPortal = output.PrepareForOutput(arraySize, DeviceAdapterTag(), token);
510 
511  LowerBoundsComparisonKernel<decltype(inputPortal),
512  decltype(valuesPortal),
513  decltype(outputPortal),
514  BinaryCompare>
515  kernel(inputPortal, valuesPortal, outputPortal, binary_compare);
516 
517  DerivedAlgorithm::Schedule(kernel, arraySize);
518  }
519 
520  template <class CIn, class COut>
521  VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle<vtkm::Id, CIn>& input,
523  {
525 
526  DeviceAdapterAlgorithmGeneral<DerivedAlgorithm, DeviceAdapterTag>::LowerBounds(
527  input, values_output, values_output);
528  }
529 
530  //--------------------------------------------------------------------------
531  // Reduce
532 private:
533  template <typename T, typename BinaryFunctor>
534  class ReduceDecoratorImpl
535  {
536  public:
537  VTKM_CONT ReduceDecoratorImpl() = default;
538 
539  VTKM_CONT
540  ReduceDecoratorImpl(const T& initialValue, const BinaryFunctor& binaryFunctor)
541  : InitialValue(initialValue)
542  , ReduceOperator(binaryFunctor)
543  {
544  }
545 
546  template <typename Portal>
547  VTKM_CONT ReduceKernel<Portal, T, BinaryFunctor> CreateFunctor(const Portal& portal) const
548  {
549  return ReduceKernel<Portal, T, BinaryFunctor>(
550  portal, this->InitialValue, this->ReduceOperator);
551  }
552 
553  private:
554  T InitialValue;
555  BinaryFunctor ReduceOperator;
556  };
557 
558 public:
559  template <typename T, typename U, class CIn>
560  VTKM_CONT static U Reduce(const vtkm::cont::ArrayHandle<T, CIn>& input, U initialValue)
561  {
563 
564  return DerivedAlgorithm::Reduce(input, initialValue, vtkm::Add());
565  }
566 
567  template <typename T, typename U, class CIn, class BinaryFunctor>
568  VTKM_CONT static U Reduce(const vtkm::cont::ArrayHandle<T, CIn>& input,
569  U initialValue,
570  BinaryFunctor binary_functor)
571  {
573 
574  //Crazy Idea:
575  //We perform the reduction in two levels. The first level is performed by
576  //an `ArrayHandleDecorator` which reduces 16 input values and maps them to
577  //one value. The decorator array is then 1/16 the length of the input array,
578  //and we can use inclusive scan as the second level to compute the final
579  //result.
580  vtkm::Id length = (input.GetNumberOfValues() / 16);
581  length += (input.GetNumberOfValues() % 16 == 0) ? 0 : 1;
583  length, ReduceDecoratorImpl<U, BinaryFunctor>(initialValue, binary_functor), input);
584 
586  const U scanResult =
587  DerivedAlgorithm::ScanInclusive(reduced, inclusiveScanStorage, binary_functor);
588  return scanResult;
589  }
590 
591  //--------------------------------------------------------------------------
592  // Reduce By Key
593  template <typename T,
594  typename U,
595  class KIn,
596  class VIn,
597  class KOut,
598  class VOut,
599  class BinaryFunctor>
600  VTKM_CONT static void ReduceByKey(const vtkm::cont::ArrayHandle<T, KIn>& keys,
601  const vtkm::cont::ArrayHandle<U, VIn>& values,
603  vtkm::cont::ArrayHandle<U, VOut>& values_output,
604  BinaryFunctor binary_functor)
605  {
607 
608  using KeysOutputType = vtkm::cont::ArrayHandle<U, KOut>;
609 
610  VTKM_ASSERT(keys.GetNumberOfValues() == values.GetNumberOfValues());
611  const vtkm::Id numberOfKeys = keys.GetNumberOfValues();
612 
613  if (numberOfKeys <= 1)
614  { //we only have a single key/value so that is our output
615  DerivedAlgorithm::Copy(keys, keys_output);
616  DerivedAlgorithm::Copy(values, values_output);
617  return;
618  }
619 
620  //we need to determine based on the keys what is the keystate for
621  //each key. The states are start, middle, end of a series and the special
622  //state start and end of a series
624 
625  {
626  vtkm::cont::Token token;
627  auto inputPortal = keys.PrepareForInput(DeviceAdapterTag(), token);
628  auto keyStatePortal = keystate.PrepareForOutput(numberOfKeys, DeviceAdapterTag(), token);
629  ReduceStencilGeneration<decltype(inputPortal), decltype(keyStatePortal)> kernel(
630  inputPortal, keyStatePortal);
631  DerivedAlgorithm::Schedule(kernel, numberOfKeys);
632  }
633 
634  //next step is we need to reduce the values for each key. This is done
635  //by running an inclusive scan over the values array using the stencil.
636  //
637  // this inclusive scan will write out two values, the first being
638  // the value summed currently, the second being 0 or 1, with 1 being used
639  // when this is a value of a key we need to write ( END or START_AND_END)
640  {
642  vtkm::cont::ArrayHandle<U> reducedValues;
643 
644  auto scanInput = vtkm::cont::make_ArrayHandleZip(values, keystate);
645  auto scanOutput = vtkm::cont::make_ArrayHandleZip(reducedValues, stencil);
646 
647  DerivedAlgorithm::ScanInclusive(
648  scanInput, scanOutput, ReduceByKeyAdd<BinaryFunctor>(binary_functor));
649 
650  //at this point we are done with keystate, so free the memory
651  keystate.ReleaseResources();
652 
653  // all we need know is an efficient way of doing the write back to the
654  // reduced global memory. this is done by using CopyIf with the
655  // stencil and values we just created with the inclusive scan
656  DerivedAlgorithm::CopyIf(reducedValues, stencil, values_output, ReduceByKeyUnaryStencilOp());
657 
658  } //release all temporary memory
659 
660  // Don't bother with the keys_output if it's an ArrayHandleDiscard -- there
661  // will be a runtime exception in Unique() otherwise:
663  {
664  //find all the unique keys
665  DerivedAlgorithm::Copy(keys, keys_output);
666  DerivedAlgorithm::Unique(keys_output);
667  }
668  }
669 
670  //--------------------------------------------------------------------------
671  // Scan Exclusive
672  template <typename T, class CIn, class COut, class BinaryFunctor>
673  VTKM_CONT static T ScanExclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
675  BinaryFunctor binaryFunctor,
676  const T& initialValue)
677  {
679 
680  vtkm::Id numValues = input.GetNumberOfValues();
681  if (numValues <= 0)
682  {
683  output.ReleaseResources();
684  return initialValue;
685  }
686 
688  T result = DerivedAlgorithm::ScanInclusive(input, inclusiveScan, binaryFunctor);
689 
690  vtkm::cont::Token token;
691 
692  auto inputPortal = inclusiveScan.PrepareForInput(DeviceAdapterTag(), token);
693  auto outputPortal = output.PrepareForOutput(numValues, DeviceAdapterTag(), token);
694 
695  InclusiveToExclusiveKernel<decltype(inputPortal), decltype(outputPortal), BinaryFunctor>
696  inclusiveToExclusive(inputPortal, outputPortal, binaryFunctor, initialValue);
697 
698  DerivedAlgorithm::Schedule(inclusiveToExclusive, numValues);
699 
700  return binaryFunctor(initialValue, result);
701  }
702 
703  template <typename T, class CIn, class COut>
704  VTKM_CONT static T ScanExclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
706  {
708 
709  return DerivedAlgorithm::ScanExclusive(
711  }
712 
713  //--------------------------------------------------------------------------
714  // Scan Exclusive Extend
715  template <typename T, class CIn, class COut, class BinaryFunctor>
716  VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle<T, CIn>& input,
718  BinaryFunctor binaryFunctor,
719  const T& initialValue)
720  {
722 
723  vtkm::Id numValues = input.GetNumberOfValues();
724  if (numValues <= 0)
725  {
726  output.Allocate(1);
727  output.WritePortal().Set(0, initialValue);
728  return;
729  }
730 
732  T result = DerivedAlgorithm::ScanInclusive(input, inclusiveScan, binaryFunctor);
733 
734  vtkm::cont::Token token;
735 
736  auto inputPortal = inclusiveScan.PrepareForInput(DeviceAdapterTag(), token);
737  auto outputPortal = output.PrepareForOutput(numValues + 1, DeviceAdapterTag(), token);
738 
739  InclusiveToExtendedKernel<decltype(inputPortal), decltype(outputPortal), BinaryFunctor>
740  inclusiveToExtended(inputPortal,
741  outputPortal,
742  binaryFunctor,
743  initialValue,
744  binaryFunctor(initialValue, result));
745 
746  DerivedAlgorithm::Schedule(inclusiveToExtended, numValues + 1);
747  }
748 
749  template <typename T, class CIn, class COut>
750  VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle<T, CIn>& input,
752  {
754 
755  DerivedAlgorithm::ScanExtended(
757  }
758 
759  //--------------------------------------------------------------------------
760  // Scan Exclusive By Key
761  template <typename KeyT,
762  typename ValueT,
763  typename KIn,
764  typename VIn,
765  typename VOut,
766  class BinaryFunctor>
767  VTKM_CONT static void ScanExclusiveByKey(const vtkm::cont::ArrayHandle<KeyT, KIn>& keys,
770  const ValueT& initialValue,
771  BinaryFunctor binaryFunctor)
772  {
774 
775  VTKM_ASSERT(keys.GetNumberOfValues() == values.GetNumberOfValues());
776 
777  // 0. Special case for 0 and 1 element input
778  vtkm::Id numberOfKeys = keys.GetNumberOfValues();
779 
780  if (numberOfKeys == 0)
781  {
782  return;
783  }
784  else if (numberOfKeys == 1)
785  {
786  output.Allocate(1);
787  output.WritePortal().Set(0, initialValue);
788  return;
789  }
790 
791  // 1. Create head flags
792  //we need to determine based on the keys what is the keystate for
793  //each key. The states are start, middle, end of a series and the special
794  //state start and end of a series
796 
797  {
798  vtkm::cont::Token token;
799  auto inputPortal = keys.PrepareForInput(DeviceAdapterTag(), token);
800  auto keyStatePortal = keystate.PrepareForOutput(numberOfKeys, DeviceAdapterTag(), token);
801  ReduceStencilGeneration<decltype(inputPortal), decltype(keyStatePortal)> kernel(
802  inputPortal, keyStatePortal);
803  DerivedAlgorithm::Schedule(kernel, numberOfKeys);
804  }
805 
806  // 2. Shift input and initialize elements at head flags position to initValue
808  {
809  vtkm::cont::Token token;
810  auto inputPortal = values.PrepareForInput(DeviceAdapterTag(), token);
811  auto keyStatePortal = keystate.PrepareForInput(DeviceAdapterTag(), token);
812  auto tempPortal = temp.PrepareForOutput(numberOfKeys, DeviceAdapterTag(), token);
813 
814  ShiftCopyAndInit<ValueT,
815  decltype(inputPortal),
816  decltype(keyStatePortal),
817  decltype(tempPortal)>
818  kernel(inputPortal, keyStatePortal, tempPortal, initialValue);
819  DerivedAlgorithm::Schedule(kernel, numberOfKeys);
820  }
821  // 3. Perform a ScanInclusiveByKey
822  DerivedAlgorithm::ScanInclusiveByKey(keys, temp, output, binaryFunctor);
823  }
824 
825  template <typename KeyT, typename ValueT, class KIn, typename VIn, typename VOut>
826  VTKM_CONT static void ScanExclusiveByKey(const vtkm::cont::ArrayHandle<KeyT, KIn>& keys,
829  {
831 
832  DerivedAlgorithm::ScanExclusiveByKey(
833  keys, values, output, vtkm::TypeTraits<ValueT>::ZeroInitialization(), vtkm::Sum());
834  }
835 
836  //--------------------------------------------------------------------------
837  // Scan Inclusive
838  template <typename T, class CIn, class COut>
839  VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
841  {
843 
844  return DerivedAlgorithm::ScanInclusive(input, output, vtkm::Add());
845  }
846 
847 private:
848  template <typename T1, typename S1, typename T2, typename S2>
849  VTKM_CONT static bool ArrayHandlesAreSame(const vtkm::cont::ArrayHandle<T1, S1>&,
851  {
852  return false;
853  }
854 
855  template <typename T, typename S>
856  VTKM_CONT static bool ArrayHandlesAreSame(const vtkm::cont::ArrayHandle<T, S>& a1,
858  {
859  return a1 == a2;
860  }
861 
862 public:
863  template <typename T, class CIn, class COut, class BinaryFunctor>
864  VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
866  BinaryFunctor binary_functor)
867  {
869 
870  if (!ArrayHandlesAreSame(input, output))
871  {
872  DerivedAlgorithm::Copy(input, output);
873  }
874 
875  vtkm::Id numValues = output.GetNumberOfValues();
876  if (numValues < 1)
877  {
879  }
880 
881  {
882  vtkm::cont::Token token;
883 
884  auto portal = output.PrepareForInPlace(DeviceAdapterTag(), token);
885  using ScanKernelType = ScanKernel<decltype(portal), BinaryFunctor>;
886 
887 
888  vtkm::Id stride;
889  for (stride = 2; stride - 1 < numValues; stride *= 2)
890  {
891  ScanKernelType kernel(portal, binary_functor, stride, stride / 2 - 1);
892  DerivedAlgorithm::Schedule(kernel, numValues / stride);
893  }
894 
895  // Do reverse operation on odd indices. Start at stride we were just at.
896  for (stride /= 2; stride > 1; stride /= 2)
897  {
898  ScanKernelType kernel(portal, binary_functor, stride, stride - 1);
899  DerivedAlgorithm::Schedule(kernel, numValues / stride);
900  }
901  }
902 
903  return GetExecutionValue(output, numValues - 1);
904  }
905 
906  template <typename KeyT, typename ValueT, class KIn, class VIn, class VOut>
907  VTKM_CONT static void ScanInclusiveByKey(const vtkm::cont::ArrayHandle<KeyT, KIn>& keys,
910  {
912 
913  return DerivedAlgorithm::ScanInclusiveByKey(keys, values, values_output, vtkm::Add());
914  }
915 
916  template <typename KeyT, typename ValueT, class KIn, class VIn, class VOut, class BinaryFunctor>
917  VTKM_CONT static void ScanInclusiveByKey(const vtkm::cont::ArrayHandle<KeyT, KIn>& keys,
920  BinaryFunctor binary_functor)
921  {
923 
924  VTKM_ASSERT(keys.GetNumberOfValues() == values.GetNumberOfValues());
925  const vtkm::Id numberOfKeys = keys.GetNumberOfValues();
926 
927  if (numberOfKeys <= 1)
928  { //we only have a single key/value so that is our output
929  DerivedAlgorithm::Copy(values, values_output);
930  return;
931  }
932 
933  //we need to determine based on the keys what is the keystate for
934  //each key. The states are start, middle, end of a series and the special
935  //state start and end of a series
937 
938  {
939  vtkm::cont::Token token;
940  auto inputPortal = keys.PrepareForInput(DeviceAdapterTag(), token);
941  auto keyStatePortal = keystate.PrepareForOutput(numberOfKeys, DeviceAdapterTag(), token);
942  ReduceStencilGeneration<decltype(inputPortal), decltype(keyStatePortal)> kernel(
943  inputPortal, keyStatePortal);
944  DerivedAlgorithm::Schedule(kernel, numberOfKeys);
945  }
946 
947  //next step is we need to reduce the values for each key. This is done
948  //by running an inclusive scan over the values array using the stencil.
949  //
950  // this inclusive scan will write out two values, the first being
951  // the value summed currently, the second being 0 or 1, with 1 being used
952  // when this is a value of a key we need to write ( END or START_AND_END)
953  {
954  vtkm::cont::ArrayHandle<ValueT> reducedValues;
956  auto scanInput = vtkm::cont::make_ArrayHandleZip(values, keystate);
957  auto scanOutput = vtkm::cont::make_ArrayHandleZip(reducedValues, stencil);
958 
959  DerivedAlgorithm::ScanInclusive(
960  scanInput, scanOutput, ReduceByKeyAdd<BinaryFunctor>(binary_functor));
961  //at this point we are done with keystate, so free the memory
962  keystate.ReleaseResources();
963  DerivedAlgorithm::Copy(reducedValues, values_output);
964  }
965  }
966 
967  //--------------------------------------------------------------------------
968  // Sort
969  template <typename T, class Storage, class BinaryCompare>
970  VTKM_CONT static void Sort(vtkm::cont::ArrayHandle<T, Storage>& values,
971  BinaryCompare binary_compare)
972  {
974 
975  vtkm::Id numValues = values.GetNumberOfValues();
976  if (numValues < 2)
977  {
978  return;
979  }
980  vtkm::Id numThreads = 1;
981  while (numThreads < numValues)
982  {
983  numThreads *= 2;
984  }
985  numThreads /= 2;
986 
987  vtkm::cont::Token token;
988 
989  auto portal = values.PrepareForInPlace(DeviceAdapterTag(), token);
990  using MergeKernel = BitonicSortMergeKernel<decltype(portal), BinaryCompare>;
991  using CrossoverKernel = BitonicSortCrossoverKernel<decltype(portal), BinaryCompare>;
992 
993  for (vtkm::Id crossoverSize = 1; crossoverSize < numValues; crossoverSize *= 2)
994  {
995  DerivedAlgorithm::Schedule(CrossoverKernel(portal, binary_compare, crossoverSize),
996  numThreads);
997  for (vtkm::Id mergeSize = crossoverSize / 2; mergeSize > 0; mergeSize /= 2)
998  {
999  DerivedAlgorithm::Schedule(MergeKernel(portal, binary_compare, mergeSize), numThreads);
1000  }
1001  }
1002  }
1003 
1004  template <typename T, class Storage>
1005  VTKM_CONT static void Sort(vtkm::cont::ArrayHandle<T, Storage>& values)
1006  {
1008 
1009  DerivedAlgorithm::Sort(values, DefaultCompareFunctor());
1010  }
1011 
1012  //--------------------------------------------------------------------------
1013  // Sort by Key
1014 public:
1015  template <typename T, typename U, class StorageT, class StorageU>
1016  VTKM_CONT static void SortByKey(vtkm::cont::ArrayHandle<T, StorageT>& keys,
1018  {
1020 
1021  //combine the keys and values into a ZipArrayHandle
1022  //we than need to specify a custom compare function wrapper
1023  //that only checks for key side of the pair, using a custom compare functor.
1024  auto zipHandle = vtkm::cont::make_ArrayHandleZip(keys, values);
1025  DerivedAlgorithm::Sort(zipHandle, internal::KeyCompare<T, U>());
1026  }
1027 
1028  template <typename T, typename U, class StorageT, class StorageU, class BinaryCompare>
1029  VTKM_CONT static void SortByKey(vtkm::cont::ArrayHandle<T, StorageT>& keys,
1031  BinaryCompare binary_compare)
1032  {
1034 
1035  //combine the keys and values into a ZipArrayHandle
1036  //we than need to specify a custom compare function wrapper
1037  //that only checks for key side of the pair, using the custom compare
1038  //functor that the user passed in
1039  auto zipHandle = vtkm::cont::make_ArrayHandleZip(keys, values);
1040  DerivedAlgorithm::Sort(zipHandle, internal::KeyCompare<T, U, BinaryCompare>(binary_compare));
1041  }
1042 
1043  template <typename T,
1044  typename U,
1045  typename V,
1046  typename StorageT,
1047  typename StorageU,
1048  typename StorageV,
1049  typename BinaryFunctor>
1050  VTKM_CONT static void Transform(const vtkm::cont::ArrayHandle<T, StorageT>& input1,
1053  BinaryFunctor binaryFunctor)
1054  {
1056 
1057  vtkm::Id numValues = vtkm::Min(input1.GetNumberOfValues(), input2.GetNumberOfValues());
1058  if (numValues <= 0)
1059  {
1060  return;
1061  }
1062 
1063  vtkm::cont::Token token;
1064 
1065  auto input1Portal = input1.PrepareForInput(DeviceAdapterTag(), token);
1066  auto input2Portal = input2.PrepareForInput(DeviceAdapterTag(), token);
1067  auto outputPortal = output.PrepareForOutput(numValues, DeviceAdapterTag(), token);
1068 
1069  BinaryTransformKernel<decltype(input1Portal),
1070  decltype(input2Portal),
1071  decltype(outputPortal),
1072  BinaryFunctor>
1073  binaryKernel(input1Portal, input2Portal, outputPortal, binaryFunctor);
1074  DerivedAlgorithm::Schedule(binaryKernel, numValues);
1075  }
1076 
1077  //};
1078  //--------------------------------------------------------------------------
1079  // Unique
1080  template <typename T, class Storage>
1081  VTKM_CONT static void Unique(vtkm::cont::ArrayHandle<T, Storage>& values)
1082  {
1084 
1085  DerivedAlgorithm::Unique(values, vtkm::Equal());
1086  }
1087 
1088  template <typename T, class Storage, class BinaryCompare>
1089  VTKM_CONT static void Unique(vtkm::cont::ArrayHandle<T, Storage>& values,
1090  BinaryCompare binary_compare)
1091  {
1093 
1095  vtkm::Id inputSize = values.GetNumberOfValues();
1096 
1097  using WrappedBOpType = internal::WrappedBinaryOperator<bool, BinaryCompare>;
1098  WrappedBOpType wrappedCompare(binary_compare);
1099 
1100  {
1101  vtkm::cont::Token token;
1102  auto valuesPortal = values.PrepareForInput(DeviceAdapterTag(), token);
1103  auto stencilPortal = stencilArray.PrepareForOutput(inputSize, DeviceAdapterTag(), token);
1104  ClassifyUniqueComparisonKernel<decltype(valuesPortal),
1105  decltype(stencilPortal),
1106  WrappedBOpType>
1107  classifyKernel(valuesPortal, stencilPortal, wrappedCompare);
1108 
1109  DerivedAlgorithm::Schedule(classifyKernel, inputSize);
1110  }
1111 
1113 
1114  DerivedAlgorithm::CopyIf(values, stencilArray, outputArray);
1115 
1116  values.Allocate(outputArray.GetNumberOfValues());
1117  DerivedAlgorithm::Copy(outputArray, values);
1118  }
1119 
1120  //--------------------------------------------------------------------------
1121  // Upper bounds
1122  template <typename T, class CIn, class CVal, class COut>
1123  VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
1124  const vtkm::cont::ArrayHandle<T, CVal>& values,
1126  {
1128 
1129  vtkm::Id arraySize = values.GetNumberOfValues();
1130 
1131  vtkm::cont::Token token;
1132 
1133  auto inputPortal = input.PrepareForInput(DeviceAdapterTag(), token);
1134  auto valuesPortal = values.PrepareForInput(DeviceAdapterTag(), token);
1135  auto outputPortal = output.PrepareForOutput(arraySize, DeviceAdapterTag(), token);
1136 
1137  UpperBoundsKernel<decltype(inputPortal), decltype(valuesPortal), decltype(outputPortal)> kernel(
1138  inputPortal, valuesPortal, outputPortal);
1139  DerivedAlgorithm::Schedule(kernel, arraySize);
1140  }
1141 
1142  template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
1143  VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
1144  const vtkm::cont::ArrayHandle<T, CVal>& values,
1146  BinaryCompare binary_compare)
1147  {
1149 
1150  vtkm::Id arraySize = values.GetNumberOfValues();
1151 
1152  vtkm::cont::Token token;
1153 
1154  auto inputPortal = input.PrepareForInput(DeviceAdapterTag(), token);
1155  auto valuesPortal = values.PrepareForInput(DeviceAdapterTag(), token);
1156  auto outputPortal = output.PrepareForOutput(arraySize, DeviceAdapterTag(), token);
1157 
1158  UpperBoundsKernelComparisonKernel<decltype(inputPortal),
1159  decltype(valuesPortal),
1160  decltype(outputPortal),
1161  BinaryCompare>
1162  kernel(inputPortal, valuesPortal, outputPortal, binary_compare);
1163 
1164  DerivedAlgorithm::Schedule(kernel, arraySize);
1165  }
1166 
1167  template <class CIn, class COut>
1168  VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle<vtkm::Id, CIn>& input,
1170  {
1172 
1173  DeviceAdapterAlgorithmGeneral<DerivedAlgorithm, DeviceAdapterTag>::UpperBounds(
1174  input, values_output, values_output);
1175  }
1176 };
1177 
1178 } // namespace internal
1179 
1190 template <typename DeviceTag>
1191 class DeviceTaskTypes
1192 {
1193 public:
1194  template <typename WorkletType, typename InvocationType>
1195  static vtkm::exec::internal::TaskSingular<WorkletType, InvocationType> MakeTask(
1196  WorkletType& worklet,
1197  InvocationType& invocation,
1198  vtkm::Id,
1199  vtkm::Id globalIndexOffset = 0)
1200  {
1201  using Task = vtkm::exec::internal::TaskSingular<WorkletType, InvocationType>;
1202  return Task(worklet, invocation, globalIndexOffset);
1203  }
1204 
1205  template <typename WorkletType, typename InvocationType>
1206  static vtkm::exec::internal::TaskSingular<WorkletType, InvocationType> MakeTask(
1207  WorkletType& worklet,
1208  InvocationType& invocation,
1209  vtkm::Id3,
1210  vtkm::Id globalIndexOffset = 0)
1211  {
1212  using Task = vtkm::exec::internal::TaskSingular<WorkletType, InvocationType>;
1213  return Task(worklet, invocation, globalIndexOffset);
1214  }
1215 };
1216 }
1217 } // namespace vtkm::cont
1218 
1219 #endif //vtk_m_cont_internal_DeviceAdapterAlgorithmGeneral_h
vtkm::cont::ArrayHandle::GetNumberOfValues
VTKM_CONT vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:448
vtkm::cont::ArrayHandle
Manages an array-worth of data.
Definition: ArrayHandle.h:283
ArrayHandle.h
FunctorsGeneral.h
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::TypeTraits
The TypeTraits class provides helpful compile-time information about the basic types used in VTKm (an...
Definition: TypeTraits.h:61
vtkm::cont::BitField::PrepareForInput
VTKM_CONT ReadPortalType PrepareForInput(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token) const
Prepares this BitField to be used as an input to an operation in the execution environment.
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
vtkm::cont::ArrayHandle::Allocate
VTKM_CONT void Allocate(vtkm::Id numberOfValues, vtkm::CopyFlag preserve, vtkm::cont::Token &token) const
Allocates an array large enough to hold the given number of values.
Definition: ArrayHandle.h:465
vtkm::cont::ArrayHandle::PrepareForInput
VTKM_CONT ReadPortalType PrepareForInput(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token) const
Prepares this array to be used as an input to an operation in the execution environment.
Definition: ArrayHandle.h:574
vtkm::cont::BitField::Allocate
VTKM_CONT void Allocate(vtkm::Id numberOfBits, vtkm::CopyFlag preserve, vtkm::cont::Token &token) const
Allocate the requested number of bits.
vtkm::cont::Token::DetachFromAll
VTKM_CONT void DetachFromAll()
Detaches this Token from all resources to allow them to be used elsewhere or deleted.
BitField.h
TaskSingular.h
vtkm::cont::ArrayHandle::PrepareForInPlace
VTKM_CONT WritePortalType PrepareForInPlace(vtkm::cont::DeviceAdapterId device, vtkm::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:593
ArrayHandleView.h
vtkm::cont::make_ArrayHandleDecorator
VTKM_CONT ArrayHandleDecorator< typename std::decay< DecoratorImplT >::type, typename std::decay< ArrayTs >::type... > make_ArrayHandleDecorator(vtkm::Id numValues, DecoratorImplT &&f, ArrayTs &&... arrays)
Create an ArrayHandleDecorator with the specified number of values that uses the provided DecoratorIm...
Definition: ArrayHandleDecorator.h:677
ArrayHandleDecorator.h
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
ArrayHandleZip.h
vtkm::cont::BitField::PrepareForOutput
VTKM_CONT WritePortalType PrepareForOutput(vtkm::Id numBits, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token) const
Prepares (allocates) this BitField to be used as an output from an operation in the execution environ...
vtkm::Add
Definition: Types.h:222
vtkm::cont::Token
A token to hold the scope of an ArrayHandle or other object.
Definition: Token.h:35
TypeTraits.h
vtkm::Sum
Binary Predicate that takes two arguments argument x, and y and returns sum (addition) of the two val...
Definition: BinaryOperators.h:33
vtkm::Equal
Binary Predicate that takes two arguments argument x, and y and returns True if and only if x is equa...
Definition: BinaryPredicates.h:33
ArrayHandleIndex.h
ErrorMessageBuffer.h
vtkm::cont::make_ArrayHandleZip
VTKM_CONT vtkm::cont::ArrayHandleZip< FirstHandleType, SecondHandleType > make_ArrayHandleZip(const FirstHandleType &first, const SecondHandleType &second)
A convenience function for creating an ArrayHandleZip.
Definition: ArrayHandleZip.h:288
VTKM_STATIC_ASSERT_MSG
#define VTKM_STATIC_ASSERT_MSG(condition, message)
Definition: StaticAssert.h:18
vtkm::cont::DeviceTaskTypes::MakeTask
static vtkm::exec::internal::TaskSingular< WorkletType, InvocationType > MakeTask(WorkletType &worklet, InvocationType &invocation, vtkm::Id3, vtkm::Id globalIndexOffset=0)
Definition: DeviceAdapterAlgorithmGeneral.h:1206
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::cont::ArrayHandle::WritePortal
VTKM_CONT WritePortalType WritePortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:435
VTKM_LOG_SCOPE_FUNCTION
#define VTKM_LOG_SCOPE_FUNCTION(level)
Definition: Logging.h:266
vtkm::CopyFlag::On
@ On
vtkm::cont::BitField::IsValidWordType
detail::BitFieldTraits::IsValidWordType< WordType > IsValidWordType
Check whether a word type is valid for non-atomic operations.
Definition: BitField.h:525
vtkm::Vec< vtkm::Id, 3 >
vtkm::cont::BitField
Definition: BitField.h:497
vtkm::cont::IsArrayHandleDiscard
Helper to determine if an ArrayHandle type is an ArrayHandleDiscard.
Definition: ArrayHandleDiscard.h:177
vtkm::NotZeroInitialized
Predicate that takes a single argument x, and returns True if it isn't the identity of the Type T.
Definition: UnaryPredicates.h:32
vtkm::cont::ArrayHandle::ReadPortal
VTKM_CONT ReadPortalType ReadPortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:414
vtkm::cont::ArrayHandle::PrepareForOutput
VTKM_CONT WritePortalType PrepareForOutput(vtkm::Id numberOfValues, vtkm::cont::DeviceAdapterId device, vtkm::cont::Token &token) const
Prepares (allocates) this array to be used as an output from an operation in the execution environmen...
Definition: ArrayHandle.h:613
vtkm::cont::BitField::GetNumberOfBits
VTKM_CONT vtkm::Id GetNumberOfBits() const
Return the number of bits stored by this BitField.
BinaryPredicates.h
ArrayHandleDiscard.h
vtkm::cont::DeviceTaskTypes::MakeTask
static vtkm::exec::internal::TaskSingular< WorkletType, InvocationType > MakeTask(WorkletType &worklet, InvocationType &invocation, vtkm::Id, vtkm::Id globalIndexOffset=0)
Definition: DeviceAdapterAlgorithmGeneral.h:1195
Logging.h
Logging utilities.
vtkm::CountSetBits
VTKM_EXEC_CONT vtkm::Int32 CountSetBits(vtkm::UInt32 word)
Count the total number of bits set in word.
Definition: Math.h:2887
vtkm::cont::ArrayHandle::ReleaseResources
VTKM_CONT void ReleaseResources() const
Releases all resources in both the control and execution environments.
Definition: ArrayHandle.h:559
vtkm::TypeTraits::ZeroInitialization
static VTKM_EXEC_CONT T ZeroInitialization()
Definition: TypeTraits.h:75
Windows.h
vtkm::cont::LogLevel::Perf
@ Perf
General timing data and algorithm flow information, such as filter execution, worklet dispatches,...