mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Support ExecArg behavior in vtkm::cont::Algorithm methods
Most of the arguments given to device adapter algorithms are actually control-side arguments that get converted to execution objects internally (usually a `vtkm::cont::ArrayHandle`). However, some of the algorithms, take an argument that is passed directly to the execution environment, such as the predicate argument of `Sort`. If the argument is a plain-old-data (POD) type, which is common enough, then you can just pass the object straight through. However, if the object has any special elements that have to be transferred to the execution environment, such as internal arrays, passing this to the `vtkm::cont::Algorithm` functions becomes problematic. To cover this use case, all the `vtkm::cont::Algorithm` functions now support automatically transferring objects that support the `ExecObject` worklet convention. If any argument to any of the `vtkm::cont::Algorithm` functions inherits from `vtkm::cont::ExecutionObjectBase`, then the `PrepareForExecution` method is called with the device the algorithm is running on, which allows these device-specific objects to be used without the hassle of creating a `TryExecute`.
This commit is contained in:
parent
9238cedcab
commit
3b828608a4
24
docs/changelog/exec-objects-alg-args.md
Normal file
24
docs/changelog/exec-objects-alg-args.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Support ExecArg behavior in `vtkm::cont::Algorithm` methods
|
||||
|
||||
`vtkm::cont::Algorithm` is a wrapper around `DeviceAdapterAlgorithm` that
|
||||
internally uses `TryExecute`s to select an appropriate device. The
|
||||
intention is that you can run parallel algorithms (outside of worklets)
|
||||
without having to specify a particular device.
|
||||
|
||||
Most of the arguments given to device adapter algorithms are actually
|
||||
control-side arguments that get converted to execution objects internally
|
||||
(usually a `vtkm::cont::ArrayHandle`). However, some of the algorithms,
|
||||
take an argument that is passed directly to the execution environment, such
|
||||
as the predicate argument of `Sort`. If the argument is a plain-old-data
|
||||
(POD) type, which is common enough, then you can just pass the object
|
||||
straight through. However, if the object has any special elements that have
|
||||
to be transferred to the execution environment, such as internal arrays,
|
||||
passing this to the `vtkm::cont::Algorithm` functions becomes problematic.
|
||||
|
||||
To cover this use case, all the `vtkm::cont::Algorithm` functions now
|
||||
support automatically transferring objects that support the `ExecObject`
|
||||
worklet convention. If any argument to any of the `vtkm::cont::Algorithm`
|
||||
functions inherits from `vtkm::cont::ExecutionObjectBase`, then the
|
||||
`PrepareForExecution` method is called with the device the algorithm is
|
||||
running on, which allows these device-specific objects to be used without
|
||||
the hassle of creating a `TryExecute`.
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
|
||||
#include <vtkm/cont/ExecutionObjectBase.h>
|
||||
#include <vtkm/cont/TryExecute.h>
|
||||
#include <vtkm/cont/internal/ArrayManagerExecution.h>
|
||||
#include <vtkm/cont/internal/DeviceAdapterTag.h>
|
||||
@ -31,15 +32,55 @@ namespace vtkm
|
||||
namespace cont
|
||||
{
|
||||
|
||||
namespace
|
||||
namespace detail
|
||||
{
|
||||
template <typename T, typename Device, typename IsExecObject>
|
||||
struct PrepareArgForExecDetail;
|
||||
|
||||
template <typename T, typename Device>
|
||||
struct PrepareArgForExecDetail<T, Device, std::false_type>
|
||||
{
|
||||
using ExecType = T;
|
||||
|
||||
static VTKM_CONT ExecType DoPrepare(T&& object) { return std::forward<T>(object); }
|
||||
};
|
||||
|
||||
template <typename T, typename Device>
|
||||
struct PrepareArgForExecDetail<T, Device, std::true_type>
|
||||
{
|
||||
using ExecType = decltype(std::declval<T>().PrepareForExecution(Device()));
|
||||
|
||||
static VTKM_CONT ExecType DoPrepare(T&& object) { return object.PrepareForExecution(Device()); }
|
||||
};
|
||||
|
||||
template <typename T, typename Device>
|
||||
struct PrepareArgForExecHelper
|
||||
{
|
||||
using IsExecObject =
|
||||
typename std::is_base_of<vtkm::cont::ExecutionObjectBase, typename std::decay<T>::type>::type;
|
||||
|
||||
using ExecType = typename PrepareArgForExecDetail<T, Device, IsExecObject>::ExecType;
|
||||
|
||||
static VTKM_CONT ExecType DoPrepare(T&& object)
|
||||
{
|
||||
return PrepareArgForExecDetail<T, Device, IsExecObject>::DoPrepare(object);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Device, typename T>
|
||||
VTKM_CONT typename PrepareArgForExecHelper<T, Device>::ExecType PrepareArgForExec(T&& object)
|
||||
{
|
||||
return PrepareArgForExecHelper<T, Device>::DoPrepare(object);
|
||||
}
|
||||
|
||||
struct CopyFunctor
|
||||
{
|
||||
template <typename Device, typename... Args>
|
||||
VTKM_CONT bool operator()(Device, Args&&... args) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Copy(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Copy(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -51,7 +92,8 @@ struct CopyIfFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -64,7 +106,8 @@ struct CopySubRangeFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
valid = vtkm::cont::DeviceAdapterAlgorithm<Device>::CopySubRange(std::forward<Args>(args)...);
|
||||
valid = vtkm::cont::DeviceAdapterAlgorithm<Device>::CopySubRange(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -76,7 +119,8 @@ struct LowerBoundsFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::LowerBounds(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::LowerBounds(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -95,7 +139,8 @@ struct ReduceFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(std::forward<Args>(args)...);
|
||||
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -106,7 +151,8 @@ struct ReduceByKeyFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::ReduceByKey(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::ReduceByKey(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -124,7 +170,8 @@ struct ScanInclusiveResultFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanInclusive(std::forward<Args>(args)...);
|
||||
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanInclusive(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -159,7 +206,8 @@ struct ScanInclusiveByKeyFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanInclusiveByKey(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanInclusiveByKey(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -177,7 +225,8 @@ struct ScanExclusiveFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusive(std::forward<Args>(args)...);
|
||||
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusive(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -190,7 +239,8 @@ struct ScanExclusiveByKeyFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusiveByKey(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusiveByKey(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -201,7 +251,8 @@ struct ScheduleFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args)
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -212,7 +263,8 @@ struct SortFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Sort(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Sort(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -223,7 +275,8 @@ struct SortByKeyFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::SortByKey(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::SortByKey(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -245,7 +298,8 @@ struct TransformFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Transform(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Transform(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -256,7 +310,8 @@ struct UniqueFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Unique(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::Unique(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -267,11 +322,12 @@ struct UpperBoundsFunctor
|
||||
VTKM_CONT bool operator()(Device, Args&&... args) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::UpperBounds(std::forward<Args>(args)...);
|
||||
vtkm::cont::DeviceAdapterAlgorithm<Device>::UpperBounds(
|
||||
PrepareArgForExec<Device>(std::forward<Args>(args))...);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
} // anonymous namespace
|
||||
} // namespace detail
|
||||
|
||||
struct Algorithm
|
||||
{
|
||||
@ -280,7 +336,7 @@ struct Algorithm
|
||||
VTKM_CONT static void Copy(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<U, COut>& output)
|
||||
{
|
||||
vtkm::cont::TryExecute(CopyFunctor(), input, output);
|
||||
vtkm::cont::TryExecute(detail::CopyFunctor(), input, output);
|
||||
}
|
||||
|
||||
template <typename T, typename U, class CIn, class CStencil, class COut>
|
||||
@ -288,7 +344,7 @@ struct Algorithm
|
||||
const vtkm::cont::ArrayHandle<U, CStencil>& stencil,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output)
|
||||
{
|
||||
vtkm::cont::TryExecute(CopyIfFunctor(), input, stencil, output);
|
||||
vtkm::cont::TryExecute(detail::CopyIfFunctor(), input, stencil, output);
|
||||
}
|
||||
|
||||
template <typename T, typename U, class CIn, class CStencil, class COut, class UnaryPredicate>
|
||||
@ -297,7 +353,7 @@ struct Algorithm
|
||||
vtkm::cont::ArrayHandle<T, COut>& output,
|
||||
UnaryPredicate unary_predicate)
|
||||
{
|
||||
vtkm::cont::TryExecute(CopyIfFunctor(), input, stencil, output, unary_predicate);
|
||||
vtkm::cont::TryExecute(detail::CopyIfFunctor(), input, stencil, output, unary_predicate);
|
||||
}
|
||||
|
||||
template <typename T, typename U, class CIn, class COut>
|
||||
@ -307,7 +363,7 @@ struct Algorithm
|
||||
vtkm::cont::ArrayHandle<U, COut>& output,
|
||||
vtkm::Id outputIndex = 0)
|
||||
{
|
||||
CopySubRangeFunctor functor;
|
||||
detail::CopySubRangeFunctor functor;
|
||||
vtkm::cont::TryExecute(
|
||||
functor, input, inputStartIndex, numberOfElementsToCopy, output, outputIndex);
|
||||
return functor.valid;
|
||||
@ -318,7 +374,7 @@ struct Algorithm
|
||||
const vtkm::cont::ArrayHandle<T, CVal>& values,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output)
|
||||
{
|
||||
vtkm::cont::TryExecute(LowerBoundsFunctor(), input, values, output);
|
||||
vtkm::cont::TryExecute(detail::LowerBoundsFunctor(), input, values, output);
|
||||
}
|
||||
|
||||
template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
|
||||
@ -327,20 +383,20 @@ struct Algorithm
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output,
|
||||
BinaryCompare binary_compare)
|
||||
{
|
||||
vtkm::cont::TryExecute(LowerBoundsFunctor(), input, values, output, binary_compare);
|
||||
vtkm::cont::TryExecute(detail::LowerBoundsFunctor(), input, values, output, binary_compare);
|
||||
}
|
||||
|
||||
template <class CIn, class COut>
|
||||
VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle<vtkm::Id, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, COut>& values_output)
|
||||
{
|
||||
vtkm::cont::TryExecute(LowerBoundsFunctor(), input, values_output);
|
||||
vtkm::cont::TryExecute(detail::LowerBoundsFunctor(), input, values_output);
|
||||
}
|
||||
|
||||
template <typename T, typename U, class CIn>
|
||||
VTKM_CONT static U Reduce(const vtkm::cont::ArrayHandle<T, CIn>& input, U initialValue)
|
||||
{
|
||||
ReduceFunctor<U> functor;
|
||||
detail::ReduceFunctor<U> functor;
|
||||
vtkm::cont::TryExecute(functor, input, initialValue);
|
||||
return functor.result;
|
||||
}
|
||||
@ -350,7 +406,7 @@ struct Algorithm
|
||||
U initialValue,
|
||||
BinaryFunctor binary_functor)
|
||||
{
|
||||
ReduceFunctor<U> functor;
|
||||
detail::ReduceFunctor<U> functor;
|
||||
vtkm::cont::TryExecute(functor, input, initialValue, binary_functor);
|
||||
return functor.result;
|
||||
}
|
||||
@ -369,14 +425,14 @@ struct Algorithm
|
||||
BinaryFunctor binary_functor)
|
||||
{
|
||||
vtkm::cont::TryExecute(
|
||||
ReduceByKeyFunctor(), keys, values, keys_output, values_output, binary_functor);
|
||||
detail::ReduceByKeyFunctor(), keys, values, keys_output, values_output, binary_functor);
|
||||
}
|
||||
|
||||
template <typename T, class CIn, class COut>
|
||||
VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output)
|
||||
{
|
||||
ScanInclusiveResultFunctor<T> functor;
|
||||
detail::ScanInclusiveResultFunctor<T> functor;
|
||||
vtkm::cont::TryExecute(functor, input, output);
|
||||
return functor.result;
|
||||
}
|
||||
@ -386,7 +442,7 @@ struct Algorithm
|
||||
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output)
|
||||
{
|
||||
StreamingScanExclusiveFunctor<T> functor;
|
||||
detail::StreamingScanExclusiveFunctor<T> functor;
|
||||
vtkm::cont::TryExecute(functor, numBlocks, input, output);
|
||||
return functor.result;
|
||||
}
|
||||
@ -396,7 +452,7 @@ struct Algorithm
|
||||
vtkm::cont::ArrayHandle<T, COut>& output,
|
||||
BinaryFunctor binary_functor)
|
||||
{
|
||||
ScanInclusiveResultFunctor<T> functor;
|
||||
detail::ScanInclusiveResultFunctor<T> functor;
|
||||
vtkm::cont::TryExecute(functor, input, output, binary_functor);
|
||||
return functor.result;
|
||||
}
|
||||
@ -413,7 +469,7 @@ struct Algorithm
|
||||
BinaryFunctor binary_functor)
|
||||
{
|
||||
vtkm::cont::TryExecute(
|
||||
ScanInclusiveByKeyFunctor(), keys, values, values_output, binary_functor);
|
||||
detail::ScanInclusiveByKeyFunctor(), keys, values, values_output, binary_functor);
|
||||
}
|
||||
|
||||
template <typename T, typename U, typename KIn, typename VIn, typename VOut>
|
||||
@ -421,14 +477,14 @@ struct Algorithm
|
||||
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
||||
vtkm::cont::ArrayHandle<U, VOut>& values_output)
|
||||
{
|
||||
vtkm::cont::TryExecute(ScanInclusiveByKeyFunctor(), keys, values, values_output);
|
||||
vtkm::cont::TryExecute(detail::ScanInclusiveByKeyFunctor(), keys, values, values_output);
|
||||
}
|
||||
|
||||
template <typename T, class CIn, class COut>
|
||||
VTKM_CONT static T ScanExclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<T, COut>& output)
|
||||
{
|
||||
ScanExclusiveFunctor<T> functor;
|
||||
detail::ScanExclusiveFunctor<T> functor;
|
||||
vtkm::cont::TryExecute(functor, input, output);
|
||||
return functor.result;
|
||||
}
|
||||
@ -439,7 +495,7 @@ struct Algorithm
|
||||
BinaryFunctor binaryFunctor,
|
||||
const T& initialValue)
|
||||
{
|
||||
ScanExclusiveFunctor<T> functor;
|
||||
detail::ScanExclusiveFunctor<T> functor;
|
||||
vtkm::cont::TryExecute(functor, input, output, binaryFunctor, initialValue);
|
||||
return functor.result;
|
||||
}
|
||||
@ -452,7 +508,7 @@ struct Algorithm
|
||||
BinaryFunctor binaryFunctor)
|
||||
{
|
||||
vtkm::cont::TryExecute(
|
||||
ScanExclusiveByKeyFunctor(), keys, values, output, initialValue, binaryFunctor);
|
||||
detail::ScanExclusiveByKeyFunctor(), keys, values, output, initialValue, binaryFunctor);
|
||||
}
|
||||
|
||||
template <typename T, typename U, class KIn, typename VIn, typename VOut>
|
||||
@ -460,39 +516,39 @@ struct Algorithm
|
||||
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
||||
vtkm::cont::ArrayHandle<U, VOut>& output)
|
||||
{
|
||||
vtkm::cont::TryExecute(ScanExclusiveByKeyFunctor(), keys, values, output);
|
||||
vtkm::cont::TryExecute(detail::ScanExclusiveByKeyFunctor(), keys, values, output);
|
||||
}
|
||||
|
||||
template <class Functor>
|
||||
VTKM_CONT static void Schedule(Functor functor, vtkm::Id numInstances)
|
||||
{
|
||||
vtkm::cont::TryExecute(ScheduleFunctor(), functor, numInstances);
|
||||
vtkm::cont::TryExecute(detail::ScheduleFunctor(), functor, numInstances);
|
||||
}
|
||||
|
||||
template <class Functor>
|
||||
VTKM_CONT static void Schedule(Functor functor, vtkm::Id3 rangeMax)
|
||||
{
|
||||
vtkm::cont::TryExecute(ScheduleFunctor(), functor, rangeMax);
|
||||
vtkm::cont::TryExecute(detail::ScheduleFunctor(), functor, rangeMax);
|
||||
}
|
||||
|
||||
template <typename T, class Storage>
|
||||
VTKM_CONT static void Sort(vtkm::cont::ArrayHandle<T, Storage>& values)
|
||||
{
|
||||
vtkm::cont::TryExecute(SortFunctor(), values);
|
||||
vtkm::cont::TryExecute(detail::SortFunctor(), values);
|
||||
}
|
||||
|
||||
template <typename T, class Storage, class BinaryCompare>
|
||||
VTKM_CONT static void Sort(vtkm::cont::ArrayHandle<T, Storage>& values,
|
||||
BinaryCompare binary_compare)
|
||||
{
|
||||
vtkm::cont::TryExecute(SortFunctor(), values, binary_compare);
|
||||
vtkm::cont::TryExecute(detail::SortFunctor(), values, binary_compare);
|
||||
}
|
||||
|
||||
template <typename T, typename U, class StorageT, class StorageU>
|
||||
VTKM_CONT static void SortByKey(vtkm::cont::ArrayHandle<T, StorageT>& keys,
|
||||
vtkm::cont::ArrayHandle<U, StorageU>& values)
|
||||
{
|
||||
vtkm::cont::TryExecute(SortByKeyFunctor(), keys, values);
|
||||
vtkm::cont::TryExecute(detail::SortByKeyFunctor(), keys, values);
|
||||
}
|
||||
|
||||
template <typename T, typename U, class StorageT, class StorageU, class BinaryCompare>
|
||||
@ -500,10 +556,10 @@ struct Algorithm
|
||||
vtkm::cont::ArrayHandle<U, StorageU>& values,
|
||||
BinaryCompare binary_compare)
|
||||
{
|
||||
vtkm::cont::TryExecute(SortByKeyFunctor(), keys, values, binary_compare);
|
||||
vtkm::cont::TryExecute(detail::SortByKeyFunctor(), keys, values, binary_compare);
|
||||
}
|
||||
|
||||
VTKM_CONT static void Synchronize() { vtkm::cont::TryExecute(SynchronizeFunctor()); }
|
||||
VTKM_CONT static void Synchronize() { vtkm::cont::TryExecute(detail::SynchronizeFunctor()); }
|
||||
|
||||
template <typename T,
|
||||
typename U,
|
||||
@ -517,20 +573,20 @@ struct Algorithm
|
||||
vtkm::cont::ArrayHandle<V, StorageV>& output,
|
||||
BinaryFunctor binaryFunctor)
|
||||
{
|
||||
vtkm::cont::TryExecute(TransformFunctor(), input1, input2, output, binaryFunctor);
|
||||
vtkm::cont::TryExecute(detail::TransformFunctor(), input1, input2, output, binaryFunctor);
|
||||
}
|
||||
|
||||
template <typename T, class Storage>
|
||||
VTKM_CONT static void Unique(vtkm::cont::ArrayHandle<T, Storage>& values)
|
||||
{
|
||||
vtkm::cont::TryExecute(UniqueFunctor(), values);
|
||||
vtkm::cont::TryExecute(detail::UniqueFunctor(), values);
|
||||
}
|
||||
|
||||
template <typename T, class Storage, class BinaryCompare>
|
||||
VTKM_CONT static void Unique(vtkm::cont::ArrayHandle<T, Storage>& values,
|
||||
BinaryCompare binary_compare)
|
||||
{
|
||||
vtkm::cont::TryExecute(UniqueFunctor(), values, binary_compare);
|
||||
vtkm::cont::TryExecute(detail::UniqueFunctor(), values, binary_compare);
|
||||
}
|
||||
|
||||
template <typename T, class CIn, class CVal, class COut>
|
||||
@ -538,7 +594,7 @@ struct Algorithm
|
||||
const vtkm::cont::ArrayHandle<T, CVal>& values,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output)
|
||||
{
|
||||
vtkm::cont::TryExecute(UpperBoundsFunctor(), input, values, output);
|
||||
vtkm::cont::TryExecute(detail::UpperBoundsFunctor(), input, values, output);
|
||||
}
|
||||
|
||||
template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
|
||||
@ -547,14 +603,14 @@ struct Algorithm
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output,
|
||||
BinaryCompare binary_compare)
|
||||
{
|
||||
vtkm::cont::TryExecute(UpperBoundsFunctor(), input, values, output, binary_compare);
|
||||
vtkm::cont::TryExecute(detail::UpperBoundsFunctor(), input, values, output, binary_compare);
|
||||
}
|
||||
|
||||
template <class CIn, class COut>
|
||||
VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle<vtkm::Id, CIn>& input,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, COut>& values_output)
|
||||
{
|
||||
vtkm::cont::TryExecute(UpperBoundsFunctor(), input, values_output);
|
||||
vtkm::cont::TryExecute(detail::UpperBoundsFunctor(), input, values_output);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -136,6 +136,15 @@ struct CompFunctor
|
||||
}
|
||||
};
|
||||
|
||||
struct CompExecObject : vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
template <typename Device>
|
||||
VTKM_CONT CompFunctor PrepareForExecution(Device)
|
||||
{
|
||||
return CompFunctor();
|
||||
}
|
||||
};
|
||||
|
||||
void SortTest()
|
||||
{
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> input;
|
||||
@ -146,8 +155,10 @@ void SortTest()
|
||||
|
||||
vtkm::cont::Algorithm::Sort(input);
|
||||
vtkm::cont::Algorithm::Sort(input, CompFunctor());
|
||||
vtkm::cont::Algorithm::Sort(input, CompExecObject());
|
||||
vtkm::cont::Algorithm::SortByKey(keys, input);
|
||||
vtkm::cont::Algorithm::SortByKey(keys, input, CompFunctor());
|
||||
vtkm::cont::Algorithm::SortByKey(keys, input, CompExecObject());
|
||||
}
|
||||
|
||||
void SynchronizeTest()
|
||||
@ -163,6 +174,7 @@ void UniqueTest()
|
||||
|
||||
vtkm::cont::Algorithm::Unique(input);
|
||||
vtkm::cont::Algorithm::Unique(input, CompFunctor());
|
||||
vtkm::cont::Algorithm::Unique(input, CompExecObject());
|
||||
}
|
||||
|
||||
void TestAll()
|
||||
|
Loading…
Reference in New Issue
Block a user