//============================================================================ // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. //============================================================================ #ifndef vtk_m_cont_Algorithm_h #define vtk_m_cont_Algorithm_h #include #include #include #include #include #include #include namespace vtkm { namespace cont { /// @cond NONE namespace detail { template inline auto DoPrepareArgForExec(T&& object, vtkm::cont::Token& token, std::true_type) -> decltype( vtkm::cont::internal::CallPrepareForExecution(std::forward(object), Device{}, token)) { VTKM_IS_EXECUTION_OBJECT(T); return vtkm::cont::internal::CallPrepareForExecution(std::forward(object), Device{}, token); } template inline T&& DoPrepareArgForExec(T&& object, vtkm::cont::Token&, std::false_type) { static_assert(!vtkm::cont::internal::IsExecutionObjectBase::value, "Internal error: failed to detect execution object."); return std::forward(object); } template auto PrepareArgForExec(T&& object, vtkm::cont::Token& token) -> decltype(DoPrepareArgForExec(std::forward(object), token, vtkm::cont::internal::IsExecutionObjectBase{})) { return DoPrepareArgForExec( std::forward(object), token, vtkm::cont::internal::IsExecutionObjectBase{}); } struct BitFieldToUnorderedSetFunctor { vtkm::Id Result{ 0 }; template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; this->Result = vtkm::cont::DeviceAdapterAlgorithm::BitFieldToUnorderedSet( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct CopyFunctor { template VTKM_CONT bool InputArrayOnDevice(vtkm::cont::DeviceAdapterId device, const vtkm::cont::ArrayHandle& input, Args&&...) const { return input.IsOnDevice(device); } template VTKM_CONT bool operator()(Device device, bool useExistingDevice, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); if (!useExistingDevice || this->InputArrayOnDevice(device, std::forward(args)...)) { vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::Copy( PrepareArgForExec(std::forward(args), token)...); return true; } else { return false; } } }; struct CopyIfFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::CopyIf( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct CopySubRangeFunctor { bool valid; CopySubRangeFunctor() : valid(false) { } template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; valid = vtkm::cont::DeviceAdapterAlgorithm::CopySubRange( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct CountSetBitsFunctor { vtkm::Id PopCount{ 0 }; template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; this->PopCount = vtkm::cont::DeviceAdapterAlgorithm::CountSetBits( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct FillFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::Fill( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct LowerBoundsFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::LowerBounds( PrepareArgForExec(std::forward(args), token)...); return true; } }; template struct ReduceFunctor { U result; ReduceFunctor() : result(vtkm::TypeTraits::ZeroInitialization()) { } template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; result = vtkm::cont::DeviceAdapterAlgorithm::Reduce( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct ReduceByKeyFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::ReduceByKey( PrepareArgForExec(std::forward(args), token)...); return true; } }; template struct ScanInclusiveResultFunctor { U result; ScanInclusiveResultFunctor() : result(vtkm::TypeTraits::ZeroInitialization()) { } template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; result = vtkm::cont::DeviceAdapterAlgorithm::ScanInclusive( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct ScanInclusiveByKeyFunctor { ScanInclusiveByKeyFunctor() {} template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::ScanInclusiveByKey( PrepareArgForExec(std::forward(args), token)...); return true; } }; template struct ScanExclusiveFunctor { T result; ScanExclusiveFunctor() : result(T()) { } template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; result = vtkm::cont::DeviceAdapterAlgorithm::ScanExclusive( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct ScanExclusiveByKeyFunctor { ScanExclusiveByKeyFunctor() {} template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::ScanExclusiveByKey( PrepareArgForExec(std::forward(args), token)...); return true; } }; template struct ScanExtendedFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::ScanExtended( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct ScheduleFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::Schedule( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct SortFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::Sort( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct SortByKeyFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::SortByKey( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct SynchronizeFunctor { template VTKM_CONT bool operator()(Device) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::Synchronize(); return true; } }; struct TransformFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::Transform( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct UniqueFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::Unique( PrepareArgForExec(std::forward(args), token)...); return true; } }; struct UpperBoundsFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::Token token; vtkm::cont::DeviceAdapterAlgorithm::UpperBounds( PrepareArgForExec(std::forward(args), token)...); return true; } }; } // namespace detail /// @endcond struct Algorithm { template VTKM_CONT static vtkm::Id BitFieldToUnorderedSet( vtkm::cont::DeviceAdapterId devId, const vtkm::cont::BitField& bits, vtkm::cont::ArrayHandle& indices) { detail::BitFieldToUnorderedSetFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, bits, indices); return functor.Result; } template VTKM_CONT static vtkm::Id BitFieldToUnorderedSet( const vtkm::cont::BitField& bits, vtkm::cont::ArrayHandle& indices) { detail::BitFieldToUnorderedSetFunctor functor; vtkm::cont::TryExecute(functor, bits, indices); return functor.Result; } template VTKM_CONT static bool Copy(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { // If we can use any device, prefer to use source's already loaded device. if (devId == vtkm::cont::DeviceAdapterTagAny()) { bool isCopied = vtkm::cont::TryExecuteOnDevice(devId, detail::CopyFunctor(), true, input, output); if (isCopied) { return true; } } return vtkm::cont::TryExecuteOnDevice(devId, detail::CopyFunctor(), false, input, output); } template VTKM_CONT static void Copy(const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { Copy(vtkm::cont::DeviceAdapterTagAny(), input, output); } template VTKM_CONT static void CopyIf(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& stencil, vtkm::cont::ArrayHandle& output) { vtkm::cont::TryExecuteOnDevice(devId, detail::CopyIfFunctor(), input, stencil, output); } template VTKM_CONT static void CopyIf(const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& stencil, vtkm::cont::ArrayHandle& output) { CopyIf(vtkm::cont::DeviceAdapterTagAny(), input, stencil, output); } template VTKM_CONT static void CopyIf(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& stencil, vtkm::cont::ArrayHandle& output, UnaryPredicate unary_predicate) { vtkm::cont::TryExecuteOnDevice( devId, detail::CopyIfFunctor(), input, stencil, output, unary_predicate); } template VTKM_CONT static void CopyIf(const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& stencil, vtkm::cont::ArrayHandle& output, UnaryPredicate unary_predicate) { CopyIf(vtkm::cont::DeviceAdapterTagAny(), input, stencil, output, unary_predicate); } template VTKM_CONT static bool CopySubRange(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, vtkm::Id inputStartIndex, vtkm::Id numberOfElementsToCopy, vtkm::cont::ArrayHandle& output, vtkm::Id outputIndex = 0) { detail::CopySubRangeFunctor functor; vtkm::cont::TryExecuteOnDevice( devId, functor, input, inputStartIndex, numberOfElementsToCopy, output, outputIndex); return functor.valid; } template VTKM_CONT static bool CopySubRange(const vtkm::cont::ArrayHandle& input, vtkm::Id inputStartIndex, vtkm::Id numberOfElementsToCopy, vtkm::cont::ArrayHandle& output, vtkm::Id outputIndex = 0) { return CopySubRange(vtkm::cont::DeviceAdapterTagAny(), input, inputStartIndex, numberOfElementsToCopy, output, outputIndex); } VTKM_CONT static vtkm::Id CountSetBits(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::BitField& bits) { detail::CountSetBitsFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, bits); return functor.PopCount; } VTKM_CONT static vtkm::Id CountSetBits(const vtkm::cont::BitField& bits) { return CountSetBits(vtkm::cont::DeviceAdapterTagAny{}, bits); } VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId, vtkm::cont::BitField& bits, bool value, vtkm::Id numBits) { detail::FillFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, bits, value, numBits); } VTKM_CONT static void Fill(vtkm::cont::BitField& bits, bool value, vtkm::Id numBits) { Fill(vtkm::cont::DeviceAdapterTagAny{}, bits, value, numBits); } VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId, vtkm::cont::BitField& bits, bool value) { detail::FillFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, bits, value); } VTKM_CONT static void Fill(vtkm::cont::BitField& bits, bool value) { Fill(vtkm::cont::DeviceAdapterTagAny{}, bits, value); } template VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId, vtkm::cont::BitField& bits, WordType word, vtkm::Id numBits) { detail::FillFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, bits, word, numBits); } template VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word, vtkm::Id numBits) { Fill(vtkm::cont::DeviceAdapterTagAny{}, bits, word, numBits); } template VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId, vtkm::cont::BitField& bits, WordType word) { detail::FillFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, bits, word); } template VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word) { Fill(vtkm::cont::DeviceAdapterTagAny{}, bits, word); } template VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle& handle, const T& value) { detail::FillFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, handle, value); } template VTKM_CONT static void Fill(vtkm::cont::ArrayHandle& handle, const T& value) { Fill(vtkm::cont::DeviceAdapterTagAny{}, handle, value); } template VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle& handle, const T& value, const vtkm::Id numValues) { detail::FillFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, handle, value, numValues); } template VTKM_CONT static void Fill(vtkm::cont::ArrayHandle& handle, const T& value, const vtkm::Id numValues) { Fill(vtkm::cont::DeviceAdapterTagAny{}, handle, value, numValues); } template VTKM_CONT static void LowerBounds(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output) { vtkm::cont::TryExecuteOnDevice(devId, detail::LowerBoundsFunctor(), input, values, output); } template VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output) { LowerBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output); } template VTKM_CONT static void LowerBounds(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output, BinaryCompare binary_compare) { vtkm::cont::TryExecuteOnDevice( devId, detail::LowerBoundsFunctor(), input, values, output, binary_compare); } template VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output, BinaryCompare binary_compare) { LowerBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output, binary_compare); } template VTKM_CONT static void LowerBounds(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& values_output) { vtkm::cont::TryExecuteOnDevice(devId, detail::LowerBoundsFunctor(), input, values_output); } template VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& values_output) { LowerBounds(vtkm::cont::DeviceAdapterTagAny(), input, values_output); } template VTKM_CONT static U Reduce(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, U initialValue) { detail::ReduceFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, input, initialValue); return functor.result; } template VTKM_CONT static U Reduce(const vtkm::cont::ArrayHandle& input, U initialValue) { return Reduce(vtkm::cont::DeviceAdapterTagAny(), input, initialValue); } template VTKM_CONT static U Reduce(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, U initialValue, BinaryFunctor binary_functor) { detail::ReduceFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, input, initialValue, binary_functor); return functor.result; } template VTKM_CONT static U Reduce(const vtkm::cont::ArrayHandle& input, U initialValue, BinaryFunctor binary_functor) { return Reduce(vtkm::cont::DeviceAdapterTagAny(), input, initialValue, binary_functor); } template VTKM_CONT static void ReduceByKey(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& keys, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& keys_output, vtkm::cont::ArrayHandle& values_output, BinaryFunctor binary_functor) { vtkm::cont::TryExecuteOnDevice(devId, detail::ReduceByKeyFunctor(), keys, values, keys_output, values_output, binary_functor); } template VTKM_CONT static void ReduceByKey(const vtkm::cont::ArrayHandle& keys, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& keys_output, vtkm::cont::ArrayHandle& values_output, BinaryFunctor binary_functor) { ReduceByKey( vtkm::cont::DeviceAdapterTagAny(), keys, values, keys_output, values_output, binary_functor); } template VTKM_CONT static T ScanInclusive(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { detail::ScanInclusiveResultFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, input, output); return functor.result; } template VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { return ScanInclusive(vtkm::cont::DeviceAdapterTagAny(), input, output); } template VTKM_CONT static T ScanInclusive(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output, BinaryFunctor binary_functor) { detail::ScanInclusiveResultFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, input, output, binary_functor); return functor.result; } template VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output, BinaryFunctor binary_functor) { return ScanInclusive(vtkm::cont::DeviceAdapterTagAny(), input, output, binary_functor); } template VTKM_CONT static void ScanInclusiveByKey(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& keys, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& values_output, BinaryFunctor binary_functor) { vtkm::cont::TryExecuteOnDevice( devId, detail::ScanInclusiveByKeyFunctor(), keys, values, values_output, binary_functor); } template VTKM_CONT static void ScanInclusiveByKey(const vtkm::cont::ArrayHandle& keys, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& values_output, BinaryFunctor binary_functor) { ScanInclusiveByKey( vtkm::cont::DeviceAdapterTagAny(), keys, values, values_output, binary_functor); } template VTKM_CONT static void ScanInclusiveByKey(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& keys, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& values_output) { vtkm::cont::TryExecuteOnDevice( devId, detail::ScanInclusiveByKeyFunctor(), keys, values, values_output); } template VTKM_CONT static void ScanInclusiveByKey(const vtkm::cont::ArrayHandle& keys, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& values_output) { ScanInclusiveByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values, values_output); } template VTKM_CONT static T ScanExclusive(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { detail::ScanExclusiveFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, input, output); return functor.result; } template VTKM_CONT static T ScanExclusive(const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { return ScanExclusive(vtkm::cont::DeviceAdapterTagAny(), input, output); } template VTKM_CONT static T ScanExclusive(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output, BinaryFunctor binaryFunctor, const T& initialValue) { detail::ScanExclusiveFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, input, output, binaryFunctor, initialValue); return functor.result; } template VTKM_CONT static T ScanExclusive(const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output, BinaryFunctor binaryFunctor, const T& initialValue) { return ScanExclusive( vtkm::cont::DeviceAdapterTagAny(), input, output, binaryFunctor, initialValue); } template VTKM_CONT static void ScanExclusiveByKey(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& keys, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output, const U& initialValue, BinaryFunctor binaryFunctor) { vtkm::cont::TryExecuteOnDevice(devId, detail::ScanExclusiveByKeyFunctor(), keys, values, output, initialValue, binaryFunctor); } template VTKM_CONT static void ScanExclusiveByKey(const vtkm::cont::ArrayHandle& keys, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output, const U& initialValue, BinaryFunctor binaryFunctor) { ScanExclusiveByKey( vtkm::cont::DeviceAdapterTagAny(), keys, values, output, initialValue, binaryFunctor); } template VTKM_CONT static void ScanExclusiveByKey(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& keys, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output) { vtkm::cont::TryExecuteOnDevice( devId, detail::ScanExclusiveByKeyFunctor(), keys, values, output); } template VTKM_CONT static void ScanExclusiveByKey(const vtkm::cont::ArrayHandle& keys, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output) { ScanExclusiveByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values, output); } template VTKM_CONT static void ScanExtended(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { detail::ScanExtendedFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, input, output); } template VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { ScanExtended(vtkm::cont::DeviceAdapterTagAny(), input, output); } template VTKM_CONT static void ScanExtended(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output, BinaryFunctor binaryFunctor, const T& initialValue) { detail::ScanExtendedFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, input, output, binaryFunctor, initialValue); } template VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output, BinaryFunctor binaryFunctor, const T& initialValue) { ScanExtended(vtkm::cont::DeviceAdapterTagAny(), input, output, binaryFunctor, initialValue); } // Should this be deprecated in favor of `RuntimeDeviceTracker`? template VTKM_CONT static void Schedule(vtkm::cont::DeviceAdapterId devId, Functor functor, vtkm::Id numInstances) { vtkm::cont::TryExecuteOnDevice(devId, detail::ScheduleFunctor{}, functor, numInstances); } template VTKM_CONT static void Schedule(vtkm::cont::internal::HintList hints, Functor functor, vtkm::Id numInstances) { vtkm::cont::TryExecute(detail::ScheduleFunctor{}, hints, functor, numInstances); } template VTKM_CONT static void Schedule(Functor functor, vtkm::Id numInstances) { Schedule(vtkm::cont::DeviceAdapterTagAny{}, functor, numInstances); } template VTKM_CONT static void Schedule(vtkm::cont::DeviceAdapterId devId, Functor functor, vtkm::Id3 rangeMax) { vtkm::cont::TryExecuteOnDevice(devId, detail::ScheduleFunctor(), functor, rangeMax); } template VTKM_CONT static void Schedule(vtkm::cont::internal::HintList hints, Functor functor, vtkm::Id3 rangeMax) { vtkm::cont::TryExecute(detail::ScheduleFunctor{}, hints, functor, rangeMax); } template VTKM_CONT static void Schedule(Functor functor, vtkm::Id3 rangeMax) { Schedule(vtkm::cont::DeviceAdapterTagAny(), functor, rangeMax); } template VTKM_CONT static void Sort(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle& values) { vtkm::cont::TryExecuteOnDevice(devId, detail::SortFunctor(), values); } template VTKM_CONT static void Sort(vtkm::cont::ArrayHandle& values) { Sort(vtkm::cont::DeviceAdapterTagAny(), values); } template VTKM_CONT static void Sort(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle& values, BinaryCompare binary_compare) { vtkm::cont::TryExecuteOnDevice(devId, detail::SortFunctor(), values, binary_compare); } template VTKM_CONT static void Sort(vtkm::cont::ArrayHandle& values, BinaryCompare binary_compare) { Sort(vtkm::cont::DeviceAdapterTagAny(), values, binary_compare); } template VTKM_CONT static void SortByKey(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle& keys, vtkm::cont::ArrayHandle& values) { vtkm::cont::TryExecuteOnDevice(devId, detail::SortByKeyFunctor(), keys, values); } template VTKM_CONT static void SortByKey(vtkm::cont::ArrayHandle& keys, vtkm::cont::ArrayHandle& values) { SortByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values); } template VTKM_CONT static void SortByKey(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle& keys, vtkm::cont::ArrayHandle& values, BinaryCompare binary_compare) { vtkm::cont::TryExecuteOnDevice(devId, detail::SortByKeyFunctor(), keys, values, binary_compare); } template VTKM_CONT static void SortByKey(vtkm::cont::ArrayHandle& keys, vtkm::cont::ArrayHandle& values, BinaryCompare binary_compare) { SortByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values, binary_compare); } VTKM_CONT static void Synchronize(vtkm::cont::DeviceAdapterId devId) { vtkm::cont::TryExecuteOnDevice(devId, detail::SynchronizeFunctor()); } VTKM_CONT static void Synchronize() { Synchronize(vtkm::cont::DeviceAdapterTagAny()); } template VTKM_CONT static void Transform(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input1, const vtkm::cont::ArrayHandle& input2, vtkm::cont::ArrayHandle& output, BinaryFunctor binaryFunctor) { vtkm::cont::TryExecuteOnDevice( devId, detail::TransformFunctor(), input1, input2, output, binaryFunctor); } template VTKM_CONT static void Transform(const vtkm::cont::ArrayHandle& input1, const vtkm::cont::ArrayHandle& input2, vtkm::cont::ArrayHandle& output, BinaryFunctor binaryFunctor) { Transform(vtkm::cont::DeviceAdapterTagAny(), input1, input2, output, binaryFunctor); } template VTKM_CONT static void Unique(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle& values) { vtkm::cont::TryExecuteOnDevice(devId, detail::UniqueFunctor(), values); } template VTKM_CONT static void Unique(vtkm::cont::ArrayHandle& values) { Unique(vtkm::cont::DeviceAdapterTagAny(), values); } template VTKM_CONT static void Unique(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle& values, BinaryCompare binary_compare) { vtkm::cont::TryExecuteOnDevice(devId, detail::UniqueFunctor(), values, binary_compare); } template VTKM_CONT static void Unique(vtkm::cont::ArrayHandle& values, BinaryCompare binary_compare) { Unique(vtkm::cont::DeviceAdapterTagAny(), values, binary_compare); } template VTKM_CONT static void UpperBounds(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output) { vtkm::cont::TryExecuteOnDevice(devId, detail::UpperBoundsFunctor(), input, values, output); } template VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output) { UpperBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output); } template VTKM_CONT static void UpperBounds(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output, BinaryCompare binary_compare) { vtkm::cont::TryExecuteOnDevice( devId, detail::UpperBoundsFunctor(), input, values, output, binary_compare); } template VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle& input, const vtkm::cont::ArrayHandle& values, vtkm::cont::ArrayHandle& output, BinaryCompare binary_compare) { UpperBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output, binary_compare); } template VTKM_CONT static void UpperBounds(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& values_output) { vtkm::cont::TryExecuteOnDevice(devId, detail::UpperBoundsFunctor(), input, values_output); } template VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& values_output) { UpperBounds(vtkm::cont::DeviceAdapterTagAny(), input, values_output); } }; } } // namespace vtkm::cont #endif //vtk_m_cont_Algorithm_h