//============================================================================ // 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. // // Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS). // Copyright 2014 UT-Battelle, LLC. // Copyright 2014 Los Alamos National Security. // // Under the terms of Contract DE-NA0003525 with NTESS, // the U.S. Government retains certain rights in this software. // // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National // Laboratory (LANL), the U.S. Government retains certain rights in // this software. //============================================================================ #ifndef vtk_m_cont_Algorithm_h #define vtk_m_cont_Algorithm_h #include #include #include #include #include namespace vtkm { namespace cont { namespace detail { template inline auto DoPrepareArgForExec(T&& object, std::true_type) -> decltype(std::declval().PrepareForExecution(Device())) { VTKM_IS_EXECUTION_OBJECT(T); return object.PrepareForExecution(Device{}); } template inline T&& DoPrepareArgForExec(T&& object, 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) -> decltype(DoPrepareArgForExec(std::forward(object), vtkm::cont::internal::IsExecutionObjectBase{})) { return DoPrepareArgForExec(std::forward(object), vtkm::cont::internal::IsExecutionObjectBase{}); } struct CopyFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::Copy( PrepareArgForExec(std::forward(args))...); return true; } }; struct CopyIfFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::CopyIf( PrepareArgForExec(std::forward(args))...); return true; } }; struct CopySubRangeFunctor { bool valid; CopySubRangeFunctor() : valid(false) { } template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); valid = vtkm::cont::DeviceAdapterAlgorithm::CopySubRange( PrepareArgForExec(std::forward(args))...); return true; } }; struct LowerBoundsFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::LowerBounds( PrepareArgForExec(std::forward(args))...); 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); result = vtkm::cont::DeviceAdapterAlgorithm::Reduce( PrepareArgForExec(std::forward(args))...); return true; } }; struct ReduceByKeyFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::ReduceByKey( PrepareArgForExec(std::forward(args))...); 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); result = vtkm::cont::DeviceAdapterAlgorithm::ScanInclusive( PrepareArgForExec(std::forward(args))...); return true; } }; template struct StreamingScanExclusiveFunctor { T result; StreamingScanExclusiveFunctor() : result(T(0)) { } template VTKM_CONT bool operator()(Device, const vtkm::Id numBlocks, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); result = vtkm::cont::DeviceAdapterAlgorithm::StreamingScanExclusive(numBlocks, input, output); return true; } template VTKM_CONT bool operator()(Device, const vtkm::Id numBlocks, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output, BinaryFunctor binary_functor, const T& initialValue) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); result = vtkm::cont::DeviceAdapterAlgorithm::StreamingScanExclusive( numBlocks, input, output, binary_functor, initialValue); return true; } }; template struct StreamingReduceFunctor { U result; StreamingReduceFunctor() : result(U(0)) { } template VTKM_CONT bool operator()(Device, const vtkm::Id numBlocks, const vtkm::cont::ArrayHandle& input, U initialValue) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); result = vtkm::cont::DeviceAdapterAlgorithm::StreamingReduce(numBlocks, input, initialValue); return true; } template VTKM_CONT bool operator()(Device, const vtkm::Id numBlocks, const vtkm::cont::ArrayHandle& input, U InitialValue, BinaryFunctor binaryFunctor) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); result = vtkm::cont::DeviceAdapterAlgorithm::StreamingReduce( numBlocks, input, InitialValue, binaryFunctor); return true; } }; struct ScanInclusiveByKeyFunctor { ScanInclusiveByKeyFunctor() {} template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::ScanInclusiveByKey( PrepareArgForExec(std::forward(args))...); return true; } }; template struct ScanExclusiveFunctor { T result; ScanExclusiveFunctor() : result(T()) { } template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); result = vtkm::cont::DeviceAdapterAlgorithm::ScanExclusive( PrepareArgForExec(std::forward(args))...); return true; } }; struct ScanExclusiveByKeyFunctor { ScanExclusiveByKeyFunctor() {} template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::ScanExclusiveByKey( PrepareArgForExec(std::forward(args))...); return true; } }; struct ScheduleFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::Schedule( PrepareArgForExec(std::forward(args))...); return true; } }; struct SortFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::Sort( PrepareArgForExec(std::forward(args))...); return true; } }; struct SortByKeyFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::SortByKey( PrepareArgForExec(std::forward(args))...); 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::DeviceAdapterAlgorithm::Transform( PrepareArgForExec(std::forward(args))...); return true; } }; struct UniqueFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::Unique( PrepareArgForExec(std::forward(args))...); return true; } }; struct UpperBoundsFunctor { template VTKM_CONT bool operator()(Device, Args&&... args) const { VTKM_IS_DEVICE_ADAPTER_TAG(Device); vtkm::cont::DeviceAdapterAlgorithm::UpperBounds( PrepareArgForExec(std::forward(args))...); return true; } }; } // namespace detail struct Algorithm { 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( input.GetDeviceAdapterId(), detail::CopyFunctor(), input, output); if (isCopied) { return true; } } return vtkm::cont::TryExecuteOnDevice(devId, detail::CopyFunctor(), 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); } 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 StreamingScanExclusive(vtkm::cont::DeviceAdapterId devId, const vtkm::Id numBlocks, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { detail::StreamingScanExclusiveFunctor functor; vtkm::cont::TryExecuteOnDevice(devId, functor, numBlocks, input, output); return functor.result; } template VTKM_CONT static T StreamingScanExclusive(const vtkm::Id numBlocks, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output) { return StreamingScanExclusive(vtkm::cont::DeviceAdapterTagAny(), numBlocks, input, output); } template VTKM_CONT static T StreamingScanExclusive(const vtkm::Id numBlocks, const vtkm::cont::ArrayHandle& input, vtkm::cont::ArrayHandle& output, BinaryFunctor binary_functor, const T& initialValue) { detail::StreamingScanExclusiveFunctor functor; vtkm::cont::TryExecuteOnDevice(vtkm::cont::DeviceAdapterTagAny(), functor, numBlocks, input, output, binary_functor, initialValue); return functor.result; } template VTKM_CONT static U StreamingReduce(const vtkm::Id numBlocks, const vtkm::cont::ArrayHandle& input, U initialValue) { detail::StreamingReduceFunctor functor; vtkm::cont::TryExecuteOnDevice( vtkm::cont::DeviceAdapterTagAny(), functor, numBlocks, input, initialValue); return functor.result; } template VTKM_CONT static U StreamingReduce(const vtkm::Id numBlocks, const vtkm::cont::ArrayHandle& input, U initialValue, BinaryFunctor binaryFunctor) { detail::StreamingReduceFunctor functor; vtkm::cont::TryExecuteOnDevice( vtkm::cont::DeviceAdapterTagAny(), functor, numBlocks, input, initialValue, binaryFunctor); return functor.result; } 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 Schedule(vtkm::cont::DeviceAdapterId devId, Functor functor, vtkm::Id numInstances) { vtkm::cont::TryExecuteOnDevice(devId, detail::ScheduleFunctor(), 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(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