2017-11-29 15:44:37 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
2019-04-15 23:24:21 +00:00
|
|
|
//
|
2017-11-29 15:44:37 +00:00
|
|
|
// 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 <vtkm/Types.h>
|
|
|
|
|
2020-12-21 22:16:59 +00:00
|
|
|
#include <vtkm/cont/BitField.h>
|
2020-04-22 19:58:59 +00:00
|
|
|
#include <vtkm/cont/DeviceAdapter.h>
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
#include <vtkm/cont/ExecutionObjectBase.h>
|
2020-01-19 06:36:14 +00:00
|
|
|
#include <vtkm/cont/Token.h>
|
2017-11-29 15:44:37 +00:00
|
|
|
#include <vtkm/cont/TryExecute.h>
|
2024-02-06 18:33:33 +00:00
|
|
|
#include <vtkm/cont/internal/Hints.h>
|
2019-04-03 20:28:31 +00:00
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
|
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace cont
|
|
|
|
{
|
2020-06-01 15:36:07 +00:00
|
|
|
/// @cond NONE
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
namespace detail
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
2018-07-10 19:01:57 +00:00
|
|
|
template <typename Device, typename T>
|
2020-01-21 20:18:03 +00:00
|
|
|
inline auto DoPrepareArgForExec(T&& object, vtkm::cont::Token& token, std::true_type) -> decltype(
|
|
|
|
vtkm::cont::internal::CallPrepareForExecution(std::forward<T>(object), Device{}, token))
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
{
|
2018-09-08 17:07:06 +00:00
|
|
|
VTKM_IS_EXECUTION_OBJECT(T);
|
2020-01-21 20:18:03 +00:00
|
|
|
return vtkm::cont::internal::CallPrepareForExecution(std::forward<T>(object), Device{}, token);
|
2018-07-10 19:01:57 +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`.
2018-07-06 07:50:01 +00:00
|
|
|
|
2018-07-10 19:01:57 +00:00
|
|
|
template <typename Device, typename T>
|
2020-01-19 06:36:14 +00:00
|
|
|
inline T&& DoPrepareArgForExec(T&& object, vtkm::cont::Token&, std::false_type)
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
{
|
2018-09-08 17:07:06 +00:00
|
|
|
static_assert(!vtkm::cont::internal::IsExecutionObjectBase<T>::value,
|
|
|
|
"Internal error: failed to detect execution object.");
|
2018-07-10 19:01:57 +00:00
|
|
|
return std::forward<T>(object);
|
|
|
|
}
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
|
|
|
|
template <typename Device, typename T>
|
2020-01-19 06:36:14 +00:00
|
|
|
auto PrepareArgForExec(T&& object, vtkm::cont::Token& token)
|
2018-09-08 17:07:06 +00:00
|
|
|
-> decltype(DoPrepareArgForExec<Device>(std::forward<T>(object),
|
2020-01-19 06:36:14 +00:00
|
|
|
token,
|
2018-09-08 17:07:06 +00:00
|
|
|
vtkm::cont::internal::IsExecutionObjectBase<T>{}))
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
{
|
2020-01-19 06:36:14 +00:00
|
|
|
return DoPrepareArgForExec<Device>(
|
|
|
|
std::forward<T>(object), token, vtkm::cont::internal::IsExecutionObjectBase<T>{});
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
}
|
|
|
|
|
2019-03-05 21:47:09 +00:00
|
|
|
struct BitFieldToUnorderedSetFunctor
|
|
|
|
{
|
|
|
|
vtkm::Id Result{ 0 };
|
|
|
|
|
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args)
|
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
2019-03-05 21:47:09 +00:00
|
|
|
this->Result = vtkm::cont::DeviceAdapterAlgorithm<Device>::BitFieldToUnorderedSet(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2019-03-05 21:47:09 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
struct CopyFunctor
|
|
|
|
{
|
2021-07-19 19:21:07 +00:00
|
|
|
template <typename T, typename S, typename... Args>
|
|
|
|
VTKM_CONT bool InputArrayOnDevice(vtkm::cont::DeviceAdapterId device,
|
|
|
|
const vtkm::cont::ArrayHandle<T, S>& input,
|
|
|
|
Args&&...) const
|
|
|
|
{
|
|
|
|
return input.IsOnDevice(device);
|
|
|
|
}
|
|
|
|
|
2017-12-12 16:04:54 +00:00
|
|
|
template <typename Device, typename... Args>
|
2021-07-19 19:21:07 +00:00
|
|
|
VTKM_CONT bool operator()(Device device, bool useExistingDevice, Args&&... args) const
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2021-07-19 19:21:07 +00:00
|
|
|
if (!useExistingDevice || this->InputArrayOnDevice(device, std::forward<Args>(args)...))
|
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::Copy(
|
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CopyIfFunctor
|
|
|
|
{
|
|
|
|
|
2017-12-11 22:15:12 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args) const
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CopySubRangeFunctor
|
|
|
|
{
|
|
|
|
bool valid;
|
|
|
|
|
2018-10-16 22:32:46 +00:00
|
|
|
CopySubRangeFunctor()
|
|
|
|
: valid(false)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-12-12 16:04:54 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args)
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
valid = vtkm::cont::DeviceAdapterAlgorithm<Device>::CopySubRange(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-06-13 14:04:28 +00:00
|
|
|
struct CountSetBitsFunctor
|
|
|
|
{
|
|
|
|
vtkm::Id PopCount{ 0 };
|
|
|
|
|
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args)
|
|
|
|
{
|
2020-01-19 06:36:14 +00:00
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
|
|
|
vtkm::cont::Token token;
|
2019-06-13 14:04:28 +00:00
|
|
|
this->PopCount = vtkm::cont::DeviceAdapterAlgorithm<Device>::CountSetBits(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2019-06-13 14:04:28 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FillFunctor
|
|
|
|
{
|
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args)
|
|
|
|
{
|
2020-01-19 06:36:14 +00:00
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
|
|
|
vtkm::cont::Token token;
|
2019-06-13 14:04:28 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::Fill(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2019-06-13 14:04:28 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
struct LowerBoundsFunctor
|
|
|
|
{
|
|
|
|
|
2017-12-11 22:15:12 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args) const
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::LowerBounds(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-12-11 22:15:12 +00:00
|
|
|
template <typename U>
|
2017-11-29 15:44:37 +00:00
|
|
|
struct ReduceFunctor
|
|
|
|
{
|
|
|
|
U result;
|
2017-12-12 16:04:54 +00:00
|
|
|
|
|
|
|
ReduceFunctor()
|
2019-02-15 19:47:07 +00:00
|
|
|
: result(vtkm::TypeTraits<U>::ZeroInitialization())
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-12-12 16:04:54 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args)
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::Reduce(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ReduceByKeyFunctor
|
|
|
|
{
|
2017-12-12 16:04:54 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args) const
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::ReduceByKey(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-02-15 19:47:07 +00:00
|
|
|
template <typename U>
|
2017-12-11 22:15:12 +00:00
|
|
|
struct ScanInclusiveResultFunctor
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
2019-02-15 19:47:07 +00:00
|
|
|
U result;
|
|
|
|
|
2017-12-11 22:15:12 +00:00
|
|
|
ScanInclusiveResultFunctor()
|
2019-02-15 19:47:07 +00:00
|
|
|
: result(vtkm::TypeTraits<U>::ZeroInitialization())
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-12-11 22:15:12 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args)
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanInclusive(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ScanInclusiveByKeyFunctor
|
|
|
|
{
|
2017-12-11 22:15:12 +00:00
|
|
|
ScanInclusiveByKeyFunctor() {}
|
2017-11-29 15:44:37 +00:00
|
|
|
|
2017-12-11 22:15:12 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args) const
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanInclusiveByKey(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
2017-12-12 16:04:54 +00:00
|
|
|
struct ScanExclusiveFunctor
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
T result;
|
|
|
|
|
2018-10-16 22:32:46 +00:00
|
|
|
ScanExclusiveFunctor()
|
|
|
|
: result(T())
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-12-12 16:04:54 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args)
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
result = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusive(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ScanExclusiveByKeyFunctor
|
|
|
|
{
|
2017-12-11 22:15:12 +00:00
|
|
|
ScanExclusiveByKeyFunctor() {}
|
|
|
|
|
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args) const
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusiveByKey(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-09-03 15:53:14 +00:00
|
|
|
template <typename T>
|
|
|
|
struct ScanExtendedFunctor
|
|
|
|
{
|
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args)
|
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
2019-09-03 15:53:14 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExtended(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2019-09-03 15:53:14 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
struct ScheduleFunctor
|
|
|
|
{
|
2017-12-12 16:04:54 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args)
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SortFunctor
|
|
|
|
{
|
2017-12-11 22:15:12 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args) const
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::Sort(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SortByKeyFunctor
|
|
|
|
{
|
2017-12-12 16:04:54 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args) const
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::SortByKey(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SynchronizeFunctor
|
|
|
|
{
|
|
|
|
template <typename Device>
|
|
|
|
VTKM_CONT bool operator()(Device)
|
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::Synchronize();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-04-02 18:42:17 +00:00
|
|
|
struct TransformFunctor
|
|
|
|
{
|
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args) const
|
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::Transform(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2018-04-02 18:42:17 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
struct UniqueFunctor
|
|
|
|
{
|
2017-12-11 22:15:12 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args) const
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::Unique(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct UpperBoundsFunctor
|
|
|
|
{
|
2017-12-11 22:15:12 +00:00
|
|
|
template <typename Device, typename... Args>
|
|
|
|
VTKM_CONT bool operator()(Device, Args&&... args) const
|
2017-11-29 15:44:37 +00:00
|
|
|
{
|
|
|
|
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
|
2020-01-19 06:36:14 +00:00
|
|
|
vtkm::cont::Token token;
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
vtkm::cont::DeviceAdapterAlgorithm<Device>::UpperBounds(
|
2020-01-19 06:36:14 +00:00
|
|
|
PrepareArgForExec<Device>(std::forward<Args>(args), token)...);
|
2017-11-29 15:44:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
} // namespace detail
|
2020-06-01 15:36:07 +00:00
|
|
|
/// @endcond
|
2017-11-29 15:44:37 +00:00
|
|
|
|
|
|
|
struct Algorithm
|
|
|
|
{
|
|
|
|
|
2019-03-05 21:47:09 +00:00
|
|
|
template <typename IndicesStorage>
|
|
|
|
VTKM_CONT static vtkm::Id BitFieldToUnorderedSet(
|
|
|
|
vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::BitField& bits,
|
|
|
|
vtkm::cont::ArrayHandle<Id, IndicesStorage>& indices)
|
|
|
|
{
|
|
|
|
detail::BitFieldToUnorderedSetFunctor functor;
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, functor, bits, indices);
|
|
|
|
return functor.Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename IndicesStorage>
|
|
|
|
VTKM_CONT static vtkm::Id BitFieldToUnorderedSet(
|
|
|
|
const vtkm::cont::BitField& bits,
|
|
|
|
vtkm::cont::ArrayHandle<Id, IndicesStorage>& indices)
|
|
|
|
{
|
|
|
|
detail::BitFieldToUnorderedSetFunctor functor;
|
|
|
|
vtkm::cont::TryExecute(functor, bits, indices);
|
|
|
|
return functor.Result;
|
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
template <typename T, typename U, class CIn, class COut>
|
2019-04-01 21:25:44 +00:00
|
|
|
VTKM_CONT static bool Copy(vtkm::cont::DeviceAdapterId devId,
|
2018-07-25 21:39:24 +00:00
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
vtkm::cont::ArrayHandle<U, COut>& output)
|
|
|
|
{
|
2019-04-01 21:25:44 +00:00
|
|
|
// If we can use any device, prefer to use source's already loaded device.
|
|
|
|
if (devId == vtkm::cont::DeviceAdapterTagAny())
|
|
|
|
{
|
2021-07-19 19:21:07 +00:00
|
|
|
bool isCopied =
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::CopyFunctor(), true, input, output);
|
2019-04-01 21:25:44 +00:00
|
|
|
if (isCopied)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2021-07-19 19:21:07 +00:00
|
|
|
return vtkm::cont::TryExecuteOnDevice(devId, detail::CopyFunctor(), false, input, output);
|
2018-07-25 21:39:24 +00:00
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, typename U, class CIn, class COut>
|
|
|
|
VTKM_CONT static void Copy(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
vtkm::cont::ArrayHandle<U, COut>& output)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
Copy(vtkm::cont::DeviceAdapterTagAny(), input, output);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, typename U, class CIn, class CStencil, class COut>
|
|
|
|
VTKM_CONT static void CopyIf(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<U, CStencil>& stencil,
|
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::CopyIfFunctor(), input, stencil, output);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, typename U, class CIn, class CStencil, class COut>
|
|
|
|
VTKM_CONT static void CopyIf(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<U, CStencil>& stencil,
|
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
CopyIf(vtkm::cont::DeviceAdapterTagAny(), input, stencil, output);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, typename U, class CIn, class CStencil, class COut, class UnaryPredicate>
|
|
|
|
VTKM_CONT static void CopyIf(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<U, CStencil>& stencil,
|
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output,
|
|
|
|
UnaryPredicate unary_predicate)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(
|
|
|
|
devId, detail::CopyIfFunctor(), input, stencil, output, unary_predicate);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, typename U, class CIn, class CStencil, class COut, class UnaryPredicate>
|
|
|
|
VTKM_CONT static void CopyIf(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<U, CStencil>& stencil,
|
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output,
|
|
|
|
UnaryPredicate unary_predicate)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
CopyIf(vtkm::cont::DeviceAdapterTagAny(), input, stencil, output, unary_predicate);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, typename U, class CIn, class COut>
|
2018-07-25 21:39:24 +00:00
|
|
|
VTKM_CONT static bool CopySubRange(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
2017-11-29 15:44:37 +00:00
|
|
|
vtkm::Id inputStartIndex,
|
|
|
|
vtkm::Id numberOfElementsToCopy,
|
|
|
|
vtkm::cont::ArrayHandle<U, COut>& output,
|
|
|
|
vtkm::Id outputIndex = 0)
|
|
|
|
{
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
detail::CopySubRangeFunctor functor;
|
2018-07-25 21:39:24 +00:00
|
|
|
vtkm::cont::TryExecuteOnDevice(
|
|
|
|
devId, functor, input, inputStartIndex, numberOfElementsToCopy, output, outputIndex);
|
2017-11-29 15:44:37 +00:00
|
|
|
return functor.valid;
|
|
|
|
}
|
2018-07-25 21:39:24 +00:00
|
|
|
template <typename T, typename U, class CIn, class COut>
|
|
|
|
VTKM_CONT static bool CopySubRange(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
vtkm::Id inputStartIndex,
|
|
|
|
vtkm::Id numberOfElementsToCopy,
|
|
|
|
vtkm::cont::ArrayHandle<U, COut>& output,
|
|
|
|
vtkm::Id outputIndex = 0)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
return CopySubRange(vtkm::cont::DeviceAdapterTagAny(),
|
2018-07-25 21:39:24 +00:00
|
|
|
input,
|
|
|
|
inputStartIndex,
|
|
|
|
numberOfElementsToCopy,
|
|
|
|
output,
|
|
|
|
outputIndex);
|
|
|
|
}
|
|
|
|
|
2019-06-13 14:04:28 +00:00
|
|
|
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 <typename WordType>
|
|
|
|
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 <typename WordType>
|
|
|
|
VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word, vtkm::Id numBits)
|
|
|
|
{
|
|
|
|
Fill(vtkm::cont::DeviceAdapterTagAny{}, bits, word, numBits);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename WordType>
|
|
|
|
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 <typename WordType>
|
|
|
|
VTKM_CONT static void Fill(vtkm::cont::BitField& bits, WordType word)
|
|
|
|
{
|
2019-10-09 21:39:49 +00:00
|
|
|
Fill(vtkm::cont::DeviceAdapterTagAny{}, bits, word);
|
2019-06-13 14:04:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename S>
|
|
|
|
VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
vtkm::cont::ArrayHandle<T, S>& handle,
|
|
|
|
const T& value)
|
|
|
|
{
|
|
|
|
detail::FillFunctor functor;
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, functor, handle, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename S>
|
|
|
|
VTKM_CONT static void Fill(vtkm::cont::ArrayHandle<T, S>& handle, const T& value)
|
|
|
|
{
|
|
|
|
Fill(vtkm::cont::DeviceAdapterTagAny{}, handle, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename S>
|
|
|
|
VTKM_CONT static void Fill(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
vtkm::cont::ArrayHandle<T, S>& handle,
|
|
|
|
const T& value,
|
|
|
|
const vtkm::Id numValues)
|
|
|
|
{
|
|
|
|
detail::FillFunctor functor;
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, functor, handle, value, numValues);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, typename S>
|
|
|
|
VTKM_CONT static void Fill(vtkm::cont::ArrayHandle<T, S>& handle,
|
|
|
|
const T& value,
|
|
|
|
const vtkm::Id numValues)
|
|
|
|
{
|
|
|
|
Fill(vtkm::cont::DeviceAdapterTagAny{}, handle, value, numValues);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
template <typename T, class CIn, class CVal, class COut>
|
|
|
|
VTKM_CONT static void LowerBounds(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CVal>& values,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::LowerBoundsFunctor(), input, values, output);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, class CIn, class CVal, class COut>
|
|
|
|
VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CVal>& values,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
LowerBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
|
|
|
|
VTKM_CONT static void LowerBounds(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CVal>& values,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output,
|
|
|
|
BinaryCompare binary_compare)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(
|
|
|
|
devId, detail::LowerBoundsFunctor(), input, values, output, binary_compare);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
|
|
|
|
VTKM_CONT static void LowerBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CVal>& values,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output,
|
|
|
|
BinaryCompare binary_compare)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
LowerBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output, binary_compare);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <class CIn, class COut>
|
|
|
|
VTKM_CONT static void LowerBounds(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<vtkm::Id, CIn>& input,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id, COut>& values_output)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::LowerBoundsFunctor(), input, values_output);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
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)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
LowerBounds(vtkm::cont::DeviceAdapterTagAny(), input, values_output);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, typename U, class CIn>
|
2018-07-25 21:39:24 +00:00
|
|
|
VTKM_CONT static U Reduce(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
U initialValue)
|
2017-11-29 15:44:37 +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`.
2018-07-06 07:50:01 +00:00
|
|
|
detail::ReduceFunctor<U> functor;
|
2018-07-25 21:39:24 +00:00
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, functor, input, initialValue);
|
2017-12-12 16:04:54 +00:00
|
|
|
return functor.result;
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
2018-07-25 21:39:24 +00:00
|
|
|
template <typename T, typename U, class CIn>
|
|
|
|
VTKM_CONT static U Reduce(const vtkm::cont::ArrayHandle<T, CIn>& input, U initialValue)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
return Reduce(vtkm::cont::DeviceAdapterTagAny(), input, initialValue);
|
2018-07-25 21:39:24 +00:00
|
|
|
}
|
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
|
|
|
|
template <typename T, typename U, class CIn, class BinaryFunctor>
|
2018-07-25 21:39:24 +00:00
|
|
|
VTKM_CONT static U Reduce(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
2017-11-29 15:44:37 +00:00
|
|
|
U initialValue,
|
|
|
|
BinaryFunctor binary_functor)
|
|
|
|
{
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
detail::ReduceFunctor<U> functor;
|
2018-07-25 21:39:24 +00:00
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, functor, input, initialValue, binary_functor);
|
2017-11-29 15:44:37 +00:00
|
|
|
return functor.result;
|
|
|
|
}
|
2018-07-25 21:39:24 +00:00
|
|
|
template <typename T, typename U, class CIn, class BinaryFunctor>
|
|
|
|
VTKM_CONT static U Reduce(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
U initialValue,
|
|
|
|
BinaryFunctor binary_functor)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
return Reduce(vtkm::cont::DeviceAdapterTagAny(), input, initialValue, binary_functor);
|
2018-07-25 21:39:24 +00:00
|
|
|
}
|
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
template <typename T,
|
|
|
|
typename U,
|
|
|
|
class CKeyIn,
|
|
|
|
class CValIn,
|
|
|
|
class CKeyOut,
|
|
|
|
class CValOut,
|
|
|
|
class BinaryFunctor>
|
|
|
|
VTKM_CONT static void ReduceByKey(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CKeyIn>& keys,
|
|
|
|
const vtkm::cont::ArrayHandle<U, CValIn>& values,
|
|
|
|
vtkm::cont::ArrayHandle<T, CKeyOut>& keys_output,
|
|
|
|
vtkm::cont::ArrayHandle<U, CValOut>& values_output,
|
|
|
|
BinaryFunctor binary_functor)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId,
|
|
|
|
detail::ReduceByKeyFunctor(),
|
|
|
|
keys,
|
|
|
|
values,
|
|
|
|
keys_output,
|
|
|
|
values_output,
|
|
|
|
binary_functor);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T,
|
|
|
|
typename U,
|
|
|
|
class CKeyIn,
|
|
|
|
class CValIn,
|
|
|
|
class CKeyOut,
|
|
|
|
class CValOut,
|
|
|
|
class BinaryFunctor>
|
|
|
|
VTKM_CONT static void ReduceByKey(const vtkm::cont::ArrayHandle<T, CKeyIn>& keys,
|
|
|
|
const vtkm::cont::ArrayHandle<U, CValIn>& values,
|
|
|
|
vtkm::cont::ArrayHandle<T, CKeyOut>& keys_output,
|
|
|
|
vtkm::cont::ArrayHandle<U, CValOut>& values_output,
|
|
|
|
BinaryFunctor binary_functor)
|
|
|
|
{
|
2018-07-25 21:39:24 +00:00
|
|
|
ReduceByKey(
|
2018-08-29 16:20:44 +00:00
|
|
|
vtkm::cont::DeviceAdapterTagAny(), keys, values, keys_output, values_output, binary_functor);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, class CIn, class COut>
|
2018-07-25 21:39:24 +00:00
|
|
|
VTKM_CONT static T ScanInclusive(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
2017-11-29 15:44:37 +00:00
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output)
|
|
|
|
{
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
detail::ScanInclusiveResultFunctor<T> functor;
|
2018-07-25 21:39:24 +00:00
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, functor, input, output);
|
2017-11-29 15:44:37 +00:00
|
|
|
return functor.result;
|
|
|
|
}
|
2018-07-25 21:39:24 +00:00
|
|
|
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)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
return ScanInclusive(vtkm::cont::DeviceAdapterTagAny(), input, output);
|
2018-07-25 21:39:24 +00:00
|
|
|
}
|
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
|
|
|
|
template <typename T, class CIn, class COut, class BinaryFunctor>
|
2018-07-25 21:39:24 +00:00
|
|
|
VTKM_CONT static T ScanInclusive(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
2017-11-29 15:44:37 +00:00
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output,
|
|
|
|
BinaryFunctor binary_functor)
|
|
|
|
{
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
detail::ScanInclusiveResultFunctor<T> functor;
|
2018-07-25 21:39:24 +00:00
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, functor, input, output, binary_functor);
|
2017-11-29 15:44:37 +00:00
|
|
|
return functor.result;
|
|
|
|
}
|
2018-07-25 21:39:24 +00:00
|
|
|
template <typename T, class CIn, class COut, class BinaryFunctor>
|
|
|
|
VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output,
|
|
|
|
BinaryFunctor binary_functor)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
return ScanInclusive(vtkm::cont::DeviceAdapterTagAny(), input, output, binary_functor);
|
2018-07-25 21:39:24 +00:00
|
|
|
}
|
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
template <typename T,
|
|
|
|
typename U,
|
|
|
|
typename KIn,
|
|
|
|
typename VIn,
|
|
|
|
typename VOut,
|
|
|
|
typename BinaryFunctor>
|
|
|
|
VTKM_CONT static void ScanInclusiveByKey(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, KIn>& keys,
|
|
|
|
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
|
|
|
vtkm::cont::ArrayHandle<U, VOut>& values_output,
|
|
|
|
BinaryFunctor binary_functor)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(
|
|
|
|
devId, detail::ScanInclusiveByKeyFunctor(), keys, values, values_output, binary_functor);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T,
|
|
|
|
typename U,
|
|
|
|
typename KIn,
|
|
|
|
typename VIn,
|
|
|
|
typename VOut,
|
|
|
|
typename BinaryFunctor>
|
|
|
|
VTKM_CONT static void ScanInclusiveByKey(const vtkm::cont::ArrayHandle<T, KIn>& keys,
|
|
|
|
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
|
|
|
vtkm::cont::ArrayHandle<U, VOut>& values_output,
|
|
|
|
BinaryFunctor binary_functor)
|
|
|
|
{
|
2018-07-25 21:39:24 +00:00
|
|
|
ScanInclusiveByKey(
|
2018-08-29 16:20:44 +00:00
|
|
|
vtkm::cont::DeviceAdapterTagAny(), keys, values, values_output, binary_functor);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, typename U, typename KIn, typename VIn, typename VOut>
|
|
|
|
VTKM_CONT static void ScanInclusiveByKey(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, KIn>& keys,
|
|
|
|
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
|
|
|
vtkm::cont::ArrayHandle<U, VOut>& values_output)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(
|
|
|
|
devId, detail::ScanInclusiveByKeyFunctor(), keys, values, values_output);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, typename U, typename KIn, typename VIn, typename VOut>
|
|
|
|
VTKM_CONT static void ScanInclusiveByKey(const vtkm::cont::ArrayHandle<T, KIn>& keys,
|
|
|
|
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
|
|
|
vtkm::cont::ArrayHandle<U, VOut>& values_output)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
ScanInclusiveByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values, values_output);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, class CIn, class COut>
|
2018-07-25 21:39:24 +00:00
|
|
|
VTKM_CONT static T ScanExclusive(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
2017-11-29 15:44:37 +00:00
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output)
|
|
|
|
{
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
detail::ScanExclusiveFunctor<T> functor;
|
2018-07-25 21:39:24 +00:00
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, functor, input, output);
|
2017-12-12 16:04:54 +00:00
|
|
|
return functor.result;
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
2018-07-25 21:39:24 +00:00
|
|
|
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)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
return ScanExclusive(vtkm::cont::DeviceAdapterTagAny(), input, output);
|
2018-07-25 21:39:24 +00:00
|
|
|
}
|
|
|
|
|
2017-11-29 15:44:37 +00:00
|
|
|
|
|
|
|
template <typename T, class CIn, class COut, class BinaryFunctor>
|
2018-07-25 21:39:24 +00:00
|
|
|
VTKM_CONT static T ScanExclusive(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
2017-11-29 15:44:37 +00:00
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output,
|
|
|
|
BinaryFunctor binaryFunctor,
|
|
|
|
const T& initialValue)
|
|
|
|
{
|
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`.
2018-07-06 07:50:01 +00:00
|
|
|
detail::ScanExclusiveFunctor<T> functor;
|
2018-07-25 21:39:24 +00:00
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, functor, input, output, binaryFunctor, initialValue);
|
2017-11-29 15:44:37 +00:00
|
|
|
return functor.result;
|
|
|
|
}
|
2018-07-25 21:39:24 +00:00
|
|
|
template <typename T, class CIn, class COut, class BinaryFunctor>
|
|
|
|
VTKM_CONT static T ScanExclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output,
|
|
|
|
BinaryFunctor binaryFunctor,
|
|
|
|
const T& initialValue)
|
|
|
|
{
|
|
|
|
return ScanExclusive(
|
2018-08-29 16:20:44 +00:00
|
|
|
vtkm::cont::DeviceAdapterTagAny(), input, output, binaryFunctor, initialValue);
|
2018-07-25 21:39:24 +00:00
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, typename U, typename KIn, typename VIn, typename VOut, class BinaryFunctor>
|
|
|
|
VTKM_CONT static void ScanExclusiveByKey(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, KIn>& keys,
|
|
|
|
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
|
|
|
vtkm::cont::ArrayHandle<U, VOut>& output,
|
|
|
|
const U& initialValue,
|
|
|
|
BinaryFunctor binaryFunctor)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId,
|
|
|
|
detail::ScanExclusiveByKeyFunctor(),
|
|
|
|
keys,
|
|
|
|
values,
|
|
|
|
output,
|
|
|
|
initialValue,
|
|
|
|
binaryFunctor);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, typename U, typename KIn, typename VIn, typename VOut, class BinaryFunctor>
|
|
|
|
VTKM_CONT static void ScanExclusiveByKey(const vtkm::cont::ArrayHandle<T, KIn>& keys,
|
|
|
|
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
|
|
|
vtkm::cont::ArrayHandle<U, VOut>& output,
|
|
|
|
const U& initialValue,
|
|
|
|
BinaryFunctor binaryFunctor)
|
|
|
|
{
|
2018-07-25 21:39:24 +00:00
|
|
|
ScanExclusiveByKey(
|
2018-08-29 16:20:44 +00:00
|
|
|
vtkm::cont::DeviceAdapterTagAny(), keys, values, output, initialValue, binaryFunctor);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, typename U, class KIn, typename VIn, typename VOut>
|
|
|
|
VTKM_CONT static void ScanExclusiveByKey(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, KIn>& keys,
|
|
|
|
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
|
|
|
vtkm::cont::ArrayHandle<U, VOut>& output)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(
|
|
|
|
devId, detail::ScanExclusiveByKeyFunctor(), keys, values, output);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, typename U, class KIn, typename VIn, typename VOut>
|
|
|
|
VTKM_CONT static void ScanExclusiveByKey(const vtkm::cont::ArrayHandle<T, KIn>& keys,
|
|
|
|
const vtkm::cont::ArrayHandle<U, VIn>& values,
|
|
|
|
vtkm::cont::ArrayHandle<U, VOut>& output)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
ScanExclusiveByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values, output);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
2019-09-03 15:53:14 +00:00
|
|
|
template <typename T, class CIn, class COut>
|
|
|
|
VTKM_CONT static void ScanExtended(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output)
|
|
|
|
{
|
|
|
|
detail::ScanExtendedFunctor<T> functor;
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, functor, input, output);
|
|
|
|
}
|
|
|
|
template <typename T, class CIn, class COut>
|
|
|
|
VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output)
|
|
|
|
{
|
|
|
|
ScanExtended(vtkm::cont::DeviceAdapterTagAny(), input, output);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <typename T, class CIn, class COut, class BinaryFunctor>
|
|
|
|
VTKM_CONT static void ScanExtended(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output,
|
|
|
|
BinaryFunctor binaryFunctor,
|
|
|
|
const T& initialValue)
|
|
|
|
{
|
|
|
|
detail::ScanExtendedFunctor<T> functor;
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, functor, input, output, binaryFunctor, initialValue);
|
|
|
|
}
|
|
|
|
template <typename T, class CIn, class COut, class BinaryFunctor>
|
|
|
|
VTKM_CONT static void ScanExtended(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
vtkm::cont::ArrayHandle<T, COut>& output,
|
|
|
|
BinaryFunctor binaryFunctor,
|
|
|
|
const T& initialValue)
|
|
|
|
{
|
|
|
|
ScanExtended(vtkm::cont::DeviceAdapterTagAny(), input, output, binaryFunctor, initialValue);
|
|
|
|
}
|
|
|
|
|
2024-02-06 18:33:33 +00:00
|
|
|
// Should this be deprecated in favor of `RuntimeDeviceTracker`?
|
|
|
|
template <typename Functor>
|
2018-07-25 21:39:24 +00:00
|
|
|
VTKM_CONT static void Schedule(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
Functor functor,
|
|
|
|
vtkm::Id numInstances)
|
|
|
|
{
|
2024-02-06 18:33:33 +00:00
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::ScheduleFunctor{}, functor, numInstances);
|
|
|
|
}
|
|
|
|
template <typename... Hints, typename Functor>
|
|
|
|
VTKM_CONT static void Schedule(vtkm::cont::internal::HintList<Hints...> hints,
|
|
|
|
Functor functor,
|
|
|
|
vtkm::Id numInstances)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecute(detail::ScheduleFunctor{}, hints, functor, numInstances);
|
2018-07-25 21:39:24 +00:00
|
|
|
}
|
2024-02-06 18:33:33 +00:00
|
|
|
template <typename Functor>
|
2017-11-29 15:44:37 +00:00
|
|
|
VTKM_CONT static void Schedule(Functor functor, vtkm::Id numInstances)
|
|
|
|
{
|
2024-02-06 18:33:33 +00:00
|
|
|
Schedule(vtkm::cont::DeviceAdapterTagAny{}, functor, numInstances);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
2024-02-06 18:33:33 +00:00
|
|
|
template <typename Functor>
|
2018-07-25 21:39:24 +00:00
|
|
|
VTKM_CONT static void Schedule(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
Functor functor,
|
|
|
|
vtkm::Id3 rangeMax)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::ScheduleFunctor(), functor, rangeMax);
|
|
|
|
}
|
2024-02-06 18:33:33 +00:00
|
|
|
template <typename... Hints, typename Functor>
|
|
|
|
VTKM_CONT static void Schedule(vtkm::cont::internal::HintList<Hints...> hints,
|
|
|
|
Functor functor,
|
|
|
|
vtkm::Id3 rangeMax)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecute(detail::ScheduleFunctor{}, hints, functor, rangeMax);
|
|
|
|
}
|
|
|
|
template <typename Functor>
|
2017-11-29 15:44:37 +00:00
|
|
|
VTKM_CONT static void Schedule(Functor functor, vtkm::Id3 rangeMax)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
Schedule(vtkm::cont::DeviceAdapterTagAny(), functor, rangeMax);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, class Storage>
|
|
|
|
VTKM_CONT static void Sort(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
vtkm::cont::ArrayHandle<T, Storage>& values)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::SortFunctor(), values);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, class Storage>
|
|
|
|
VTKM_CONT static void Sort(vtkm::cont::ArrayHandle<T, Storage>& values)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
Sort(vtkm::cont::DeviceAdapterTagAny(), values);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, class Storage, class BinaryCompare>
|
|
|
|
VTKM_CONT static void Sort(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
vtkm::cont::ArrayHandle<T, Storage>& values,
|
|
|
|
BinaryCompare binary_compare)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::SortFunctor(), values, binary_compare);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, class Storage, class BinaryCompare>
|
|
|
|
VTKM_CONT static void Sort(vtkm::cont::ArrayHandle<T, Storage>& values,
|
|
|
|
BinaryCompare binary_compare)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
Sort(vtkm::cont::DeviceAdapterTagAny(), values, binary_compare);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, typename U, class StorageT, class StorageU>
|
|
|
|
VTKM_CONT static void SortByKey(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
vtkm::cont::ArrayHandle<T, StorageT>& keys,
|
|
|
|
vtkm::cont::ArrayHandle<U, StorageU>& values)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::SortByKeyFunctor(), keys, values);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
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)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
SortByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
template <typename T, typename U, class StorageT, class StorageU, class BinaryCompare>
|
|
|
|
VTKM_CONT static void SortByKey(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
vtkm::cont::ArrayHandle<T, StorageT>& keys,
|
|
|
|
vtkm::cont::ArrayHandle<U, StorageU>& values,
|
|
|
|
BinaryCompare binary_compare)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::SortByKeyFunctor(), keys, values, binary_compare);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, typename U, class StorageT, class StorageU, class BinaryCompare>
|
|
|
|
VTKM_CONT static void SortByKey(vtkm::cont::ArrayHandle<T, StorageT>& keys,
|
|
|
|
vtkm::cont::ArrayHandle<U, StorageU>& values,
|
|
|
|
BinaryCompare binary_compare)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
SortByKey(vtkm::cont::DeviceAdapterTagAny(), keys, values, binary_compare);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
VTKM_CONT static void Synchronize(vtkm::cont::DeviceAdapterId devId)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::SynchronizeFunctor());
|
|
|
|
}
|
2018-08-29 16:20:44 +00:00
|
|
|
VTKM_CONT static void Synchronize() { Synchronize(vtkm::cont::DeviceAdapterTagAny()); }
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
|
|
|
|
template <typename T,
|
|
|
|
typename U,
|
|
|
|
typename V,
|
|
|
|
typename StorageT,
|
|
|
|
typename StorageU,
|
|
|
|
typename StorageV,
|
|
|
|
typename BinaryFunctor>
|
|
|
|
VTKM_CONT static void Transform(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, StorageT>& input1,
|
|
|
|
const vtkm::cont::ArrayHandle<U, StorageU>& input2,
|
|
|
|
vtkm::cont::ArrayHandle<V, StorageV>& output,
|
|
|
|
BinaryFunctor binaryFunctor)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(
|
|
|
|
devId, detail::TransformFunctor(), input1, input2, output, binaryFunctor);
|
|
|
|
}
|
2018-04-02 18:42:17 +00:00
|
|
|
template <typename T,
|
|
|
|
typename U,
|
|
|
|
typename V,
|
|
|
|
typename StorageT,
|
|
|
|
typename StorageU,
|
|
|
|
typename StorageV,
|
|
|
|
typename BinaryFunctor>
|
|
|
|
VTKM_CONT static void Transform(const vtkm::cont::ArrayHandle<T, StorageT>& input1,
|
|
|
|
const vtkm::cont::ArrayHandle<U, StorageU>& input2,
|
|
|
|
vtkm::cont::ArrayHandle<V, StorageV>& output,
|
|
|
|
BinaryFunctor binaryFunctor)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
Transform(vtkm::cont::DeviceAdapterTagAny(), input1, input2, output, binaryFunctor);
|
2018-04-02 18:42:17 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, class Storage>
|
|
|
|
VTKM_CONT static void Unique(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
vtkm::cont::ArrayHandle<T, Storage>& values)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::UniqueFunctor(), values);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, class Storage>
|
|
|
|
VTKM_CONT static void Unique(vtkm::cont::ArrayHandle<T, Storage>& values)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
Unique(vtkm::cont::DeviceAdapterTagAny(), values);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, class Storage, class BinaryCompare>
|
|
|
|
VTKM_CONT static void Unique(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
vtkm::cont::ArrayHandle<T, Storage>& values,
|
|
|
|
BinaryCompare binary_compare)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::UniqueFunctor(), values, binary_compare);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, class Storage, class BinaryCompare>
|
|
|
|
VTKM_CONT static void Unique(vtkm::cont::ArrayHandle<T, Storage>& values,
|
|
|
|
BinaryCompare binary_compare)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
Unique(vtkm::cont::DeviceAdapterTagAny(), values, binary_compare);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, class CIn, class CVal, class COut>
|
|
|
|
VTKM_CONT static void UpperBounds(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CVal>& values,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::UpperBoundsFunctor(), input, values, output);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, class CIn, class CVal, class COut>
|
|
|
|
VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CVal>& values,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
UpperBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
|
|
|
|
VTKM_CONT static void UpperBounds(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CVal>& values,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output,
|
|
|
|
BinaryCompare binary_compare)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(
|
|
|
|
devId, detail::UpperBoundsFunctor(), input, values, output, binary_compare);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
template <typename T, class CIn, class CVal, class COut, class BinaryCompare>
|
|
|
|
VTKM_CONT static void UpperBounds(const vtkm::cont::ArrayHandle<T, CIn>& input,
|
|
|
|
const vtkm::cont::ArrayHandle<T, CVal>& values,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id, COut>& output,
|
|
|
|
BinaryCompare binary_compare)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
UpperBounds(vtkm::cont::DeviceAdapterTagAny(), input, values, output, binary_compare);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-25 21:39:24 +00:00
|
|
|
|
|
|
|
template <class CIn, class COut>
|
|
|
|
VTKM_CONT static void UpperBounds(vtkm::cont::DeviceAdapterId devId,
|
|
|
|
const vtkm::cont::ArrayHandle<vtkm::Id, CIn>& input,
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id, COut>& values_output)
|
|
|
|
{
|
|
|
|
vtkm::cont::TryExecuteOnDevice(devId, detail::UpperBoundsFunctor(), input, values_output);
|
|
|
|
}
|
2017-11-29 15:44:37 +00:00
|
|
|
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)
|
|
|
|
{
|
2018-08-29 16:20:44 +00:00
|
|
|
UpperBounds(vtkm::cont::DeviceAdapterTagAny(), input, values_output);
|
2017-11-29 15:44:37 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} // namespace vtkm::cont
|
|
|
|
|
|
|
|
#endif //vtk_m_cont_Algorithm_h
|