mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Merge topic 'specialize-worklet-for-device'
4e34feecb Add ability to specialize worklet for device Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Sujin Philip <sujin.philip@kitware.com> Merge-request: !1608
This commit is contained in:
commit
04254dbd25
147
docs/changelog/specialize-worklet-for-device.md
Normal file
147
docs/changelog/specialize-worklet-for-device.md
Normal file
@ -0,0 +1,147 @@
|
||||
# Add ability to specialize a worklet for a device
|
||||
|
||||
This change adds an execution signature tag named `Device` that passes
|
||||
a `DeviceAdapterTag` to the worklet's parenthesis operator. This allows the
|
||||
worklet to specialize its operation. This features is available in all
|
||||
worklets.
|
||||
|
||||
The following example shows a worklet that specializes itself for the CUDA
|
||||
device.
|
||||
|
||||
```cpp
|
||||
struct DeviceSpecificWorklet : vtkm::worklet::WorkletMapField
|
||||
{
|
||||
using ControlSignature = void(FieldIn, FieldOut);
|
||||
using ExecutionSignature = _2(_1, Device);
|
||||
|
||||
// Specialization for the Cuda device.
|
||||
template <typename T>
|
||||
T operator()(T x, vtkm::cont::DeviceAdapterTagCuda) const
|
||||
{
|
||||
// Special cuda implementation
|
||||
}
|
||||
|
||||
// General implementation
|
||||
template <typename T, typename Device>
|
||||
T operator()(T x, Device) const
|
||||
{
|
||||
// General implementation
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Effect on compile time and binary size
|
||||
|
||||
This change necessitated adding a template parameter for the device that
|
||||
followed at least from the schedule all the way down. This has the
|
||||
potential for duplicating several of the support methods (like
|
||||
`DoWorkletInvokeFunctor`) that would otherwise have the same type. This is
|
||||
especially true between the devices that run on the CPU as they should all
|
||||
be sharing the same portals from `ArrayHandle`s. So the question is whether
|
||||
it causes compile to take longer or cause a significant increase in
|
||||
binaries.
|
||||
|
||||
To informally test, I first ran a clean debug compile on my Windows machine
|
||||
with the serial and tbb devices. The build itself took **3 minutes, 50
|
||||
seconds**. Here is a list of the binary sizes in the bin directory:
|
||||
|
||||
```
|
||||
kmorel2 0> du -sh *.exe *.dll
|
||||
200K BenchmarkArrayTransfer_SERIAL.exe
|
||||
204K BenchmarkArrayTransfer_TBB.exe
|
||||
424K BenchmarkAtomicArray_SERIAL.exe
|
||||
424K BenchmarkAtomicArray_TBB.exe
|
||||
440K BenchmarkCopySpeeds_SERIAL.exe
|
||||
580K BenchmarkCopySpeeds_TBB.exe
|
||||
4.1M BenchmarkDeviceAdapter_SERIAL.exe
|
||||
5.3M BenchmarkDeviceAdapter_TBB.exe
|
||||
7.9M BenchmarkFieldAlgorithms_SERIAL.exe
|
||||
7.9M BenchmarkFieldAlgorithms_TBB.exe
|
||||
22M BenchmarkFilters_SERIAL.exe
|
||||
22M BenchmarkFilters_TBB.exe
|
||||
276K BenchmarkRayTracing_SERIAL.exe
|
||||
276K BenchmarkRayTracing_TBB.exe
|
||||
4.4M BenchmarkTopologyAlgorithms_SERIAL.exe
|
||||
4.4M BenchmarkTopologyAlgorithms_TBB.exe
|
||||
712K Rendering_SERIAL.exe
|
||||
712K Rendering_TBB.exe
|
||||
708K UnitTests_vtkm_cont_arg_testing.exe
|
||||
1.7M UnitTests_vtkm_cont_internal_testing.exe
|
||||
13M UnitTests_vtkm_cont_serial_testing.exe
|
||||
14M UnitTests_vtkm_cont_tbb_testing.exe
|
||||
18M UnitTests_vtkm_cont_testing.exe
|
||||
13M UnitTests_vtkm_cont_testing_mpi.exe
|
||||
736K UnitTests_vtkm_exec_arg_testing.exe
|
||||
136K UnitTests_vtkm_exec_internal_testing.exe
|
||||
196K UnitTests_vtkm_exec_serial_internal_testing.exe
|
||||
196K UnitTests_vtkm_exec_tbb_internal_testing.exe
|
||||
2.0M UnitTests_vtkm_exec_testing.exe
|
||||
83M UnitTests_vtkm_filter_testing.exe
|
||||
476K UnitTests_vtkm_internal_testing.exe
|
||||
148K UnitTests_vtkm_interop_internal_testing.exe
|
||||
1.3M UnitTests_vtkm_interop_testing.exe
|
||||
2.9M UnitTests_vtkm_io_reader_testing.exe
|
||||
548K UnitTests_vtkm_io_writer_testing.exe
|
||||
792K UnitTests_vtkm_rendering_testing.exe
|
||||
3.7M UnitTests_vtkm_testing.exe
|
||||
320K UnitTests_vtkm_worklet_internal_testing.exe
|
||||
65M UnitTests_vtkm_worklet_testing.exe
|
||||
11M vtkm_cont-1.3.dll
|
||||
2.1M vtkm_interop-1.3.dll
|
||||
21M vtkm_rendering-1.3.dll
|
||||
3.9M vtkm_worklet-1.3.dll
|
||||
```
|
||||
|
||||
After making the singular change to the `Invocation` object to add the
|
||||
`DeviceAdapterTag` as a template parameter (which should cause any extra
|
||||
compile instances) the compile took **4 minuts and 5 seconds**. Here is the
|
||||
new list of binaries.
|
||||
|
||||
```
|
||||
kmorel2 0> du -sh *.exe *.dll
|
||||
200K BenchmarkArrayTransfer_SERIAL.exe
|
||||
204K BenchmarkArrayTransfer_TBB.exe
|
||||
424K BenchmarkAtomicArray_SERIAL.exe
|
||||
424K BenchmarkAtomicArray_TBB.exe
|
||||
440K BenchmarkCopySpeeds_SERIAL.exe
|
||||
580K BenchmarkCopySpeeds_TBB.exe
|
||||
4.1M BenchmarkDeviceAdapter_SERIAL.exe
|
||||
5.3M BenchmarkDeviceAdapter_TBB.exe
|
||||
7.9M BenchmarkFieldAlgorithms_SERIAL.exe
|
||||
7.9M BenchmarkFieldAlgorithms_TBB.exe
|
||||
22M BenchmarkFilters_SERIAL.exe
|
||||
22M BenchmarkFilters_TBB.exe
|
||||
276K BenchmarkRayTracing_SERIAL.exe
|
||||
276K BenchmarkRayTracing_TBB.exe
|
||||
4.4M BenchmarkTopologyAlgorithms_SERIAL.exe
|
||||
4.4M BenchmarkTopologyAlgorithms_TBB.exe
|
||||
712K Rendering_SERIAL.exe
|
||||
712K Rendering_TBB.exe
|
||||
708K UnitTests_vtkm_cont_arg_testing.exe
|
||||
1.7M UnitTests_vtkm_cont_internal_testing.exe
|
||||
13M UnitTests_vtkm_cont_serial_testing.exe
|
||||
14M UnitTests_vtkm_cont_tbb_testing.exe
|
||||
19M UnitTests_vtkm_cont_testing.exe
|
||||
13M UnitTests_vtkm_cont_testing_mpi.exe
|
||||
736K UnitTests_vtkm_exec_arg_testing.exe
|
||||
136K UnitTests_vtkm_exec_internal_testing.exe
|
||||
196K UnitTests_vtkm_exec_serial_internal_testing.exe
|
||||
196K UnitTests_vtkm_exec_tbb_internal_testing.exe
|
||||
2.0M UnitTests_vtkm_exec_testing.exe
|
||||
86M UnitTests_vtkm_filter_testing.exe
|
||||
476K UnitTests_vtkm_internal_testing.exe
|
||||
148K UnitTests_vtkm_interop_internal_testing.exe
|
||||
1.3M UnitTests_vtkm_interop_testing.exe
|
||||
2.9M UnitTests_vtkm_io_reader_testing.exe
|
||||
548K UnitTests_vtkm_io_writer_testing.exe
|
||||
792K UnitTests_vtkm_rendering_testing.exe
|
||||
3.7M UnitTests_vtkm_testing.exe
|
||||
320K UnitTests_vtkm_worklet_internal_testing.exe
|
||||
68M UnitTests_vtkm_worklet_testing.exe
|
||||
11M vtkm_cont-1.3.dll
|
||||
2.1M vtkm_interop-1.3.dll
|
||||
21M vtkm_rendering-1.3.dll
|
||||
3.9M vtkm_worklet-1.3.dll
|
||||
```
|
||||
|
||||
So far the increase is quite negligible.
|
@ -737,8 +737,14 @@ struct Serialization<vtkm::cont::ArrayHandle<T>>
|
||||
|
||||
} // diy
|
||||
|
||||
#ifndef vtk_m_cont_ArrayHandle_hxx
|
||||
#include <vtkm/cont/ArrayHandle.hxx>
|
||||
#endif
|
||||
|
||||
#ifndef vtk_m_cont_internal_ArrayHandleBasicImpl_h
|
||||
#include <vtkm/cont/internal/ArrayHandleBasicImpl.h>
|
||||
#endif
|
||||
|
||||
#include <vtkm/cont/internal/ArrayExportMacros.h>
|
||||
|
||||
#ifndef vtkm_cont_ArrayHandle_cxx
|
||||
|
@ -17,6 +17,10 @@
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
#ifndef vtk_m_cont_ArrayHandle_hxx
|
||||
#define vtk_m_cont_ArrayHandle_hxx
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -425,3 +429,5 @@ VTKM_CONT void Serialization<vtkm::cont::ArrayHandle<T>>::load(BinaryBuffer& bb,
|
||||
}
|
||||
}
|
||||
} // diy
|
||||
|
||||
#endif //vtk_m_cont_ArrayHandle_hxx
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#define vtkm_cont_internal_ArrayHandleImpl_cxx
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/internal/ArrayHandleBasicImpl.h>
|
||||
|
||||
namespace vtkm
|
||||
|
@ -18,11 +18,11 @@
|
||||
// this software.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
|
||||
#ifndef vtk_m_cont_internal_ArrayHandleBasicImpl_h
|
||||
#define vtk_m_cont_internal_ArrayHandleBasicImpl_h
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
|
||||
#include <vtkm/cont/StorageBasic.h>
|
||||
|
||||
#include <type_traits>
|
||||
@ -57,19 +57,21 @@ struct ExecutionPortalFactoryBasic
|
||||
#ifndef VTKM_DOXYGEN_ONLY
|
||||
;
|
||||
#else // VTKM_DOXYGEN_ONLY
|
||||
{
|
||||
/// The portal type.
|
||||
using PortalType = SomePortalType;
|
||||
|
||||
/// The cont portal type.
|
||||
using ConstPortalType = SomePortalType;
|
||||
/// The cont portal type.
|
||||
using ConstPortalType = SomePortalType;
|
||||
|
||||
/// Create a portal to access the execution data from @a start to @a end.
|
||||
VTKM_CONT
|
||||
static PortalType CreatePortal(ValueType* start, ValueType* end);
|
||||
/// Create a portal to access the execution data from @a start to @a end.
|
||||
VTKM_CONT
|
||||
static PortalType CreatePortal(ValueType* start, ValueType* end);
|
||||
|
||||
/// Create a const portal to access the execution data from @a start to @a end.
|
||||
VTKM_CONT
|
||||
static PortalConstType CreatePortalConst(const ValueType* start, const ValueType* end);
|
||||
/// Create a const portal to access the execution data from @a start to @a end.
|
||||
VTKM_CONT
|
||||
static PortalConstType CreatePortalConst(const ValueType* start, const ValueType* end);
|
||||
};
|
||||
#endif // VTKM_DOXYGEN_ONLY
|
||||
|
||||
/// Typeless interface for interacting with a execution memory buffer when using basic storage.
|
||||
@ -233,6 +235,7 @@ public:
|
||||
template <typename DeviceTag>
|
||||
struct ExecutionTypes
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceTag);
|
||||
using Portal = typename PortalFactory<DeviceTag>::PortalType;
|
||||
using PortalConst = typename PortalFactory<DeviceTag>::PortalConstType;
|
||||
};
|
||||
@ -302,6 +305,8 @@ extern template class VTKM_CONT_TEMPLATE_EXPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef vtk_m_cont_internal_ArrayHandleBasicImpl_hxx
|
||||
#include <vtkm/cont/internal/ArrayHandleBasicImpl.hxx>
|
||||
#endif
|
||||
|
||||
#endif // vtk_m_cont_internal_ArrayHandleBasicImpl_h
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -51,6 +51,7 @@ $# Ignore the following comment. It is meant for the generated file.
|
||||
#include <vtkm/internal/Invocation.h>
|
||||
|
||||
#include <vtkm/exec/arg/Fetch.h>
|
||||
#include <vtkm/exec/arg/FetchTagExecObject.h>
|
||||
|
||||
$# This needs to match the max_parameters in FunctionInterfaceDetailPre.h.in
|
||||
$py(max_parameters=20)\
|
||||
@ -115,6 +116,11 @@ namespace internal
|
||||
namespace detail
|
||||
{
|
||||
|
||||
struct DummyDeviceControlSignatureTag
|
||||
{
|
||||
using FetchTag = vtkm::exec::arg::FetchTagExecObject;
|
||||
};
|
||||
|
||||
/// A helper class that takes an \c Invocation object and an index to a
|
||||
/// parameter in the ExecutionSignature and finds the \c Fetch type valid for
|
||||
/// that parameter.
|
||||
@ -133,15 +139,38 @@ struct InvocationToFetch
|
||||
using AspectTag = typename ExecutionSignatureTag::AspectTag;
|
||||
|
||||
// Find the fetch tag from the control signature tag pointed to by
|
||||
// ParameterIndex.
|
||||
// ParameterIndex. Note that ControlParameterIndex of 0 is reserved
|
||||
// for getting the device adapter tag.
|
||||
using ControlInterface = typename Invocation::ControlInterface;
|
||||
using ControlSignatureTag = typename ControlInterface::template ParameterType<ControlParameterIndex>::type;
|
||||
using ControlSignatureTag =
|
||||
typename std::conditional<
|
||||
ControlParameterIndex == 0,
|
||||
DummyDeviceControlSignatureTag,
|
||||
typename ControlInterface::template ParameterType<ControlParameterIndex>::type>::type;
|
||||
using FetchTag = typename ControlSignatureTag::FetchTag;
|
||||
|
||||
using ExecObjectType =
|
||||
typename Invocation::ParameterInterface::template ParameterType<ControlParameterIndex>::type;
|
||||
typename std::conditional<
|
||||
ControlParameterIndex == 0,
|
||||
typename Invocation::DeviceAdapterTag,
|
||||
typename Invocation::ParameterInterface::template ParameterType<ControlParameterIndex>::type>::type;
|
||||
|
||||
using type = vtkm::exec::arg::Fetch<FetchTag, AspectTag, ThreadIndicesType, ExecObjectType>;
|
||||
|
||||
VTKM_EXEC static ExecObjectType GetParameterImpl(const Invocation&, std::true_type)
|
||||
{
|
||||
return typename Invocation::DeviceAdapterTag();
|
||||
}
|
||||
|
||||
VTKM_EXEC static ExecObjectType GetParameterImpl(const Invocation& invocation, std::false_type)
|
||||
{
|
||||
return invocation.Parameters.template GetParameter<ControlParameterIndex>();
|
||||
}
|
||||
|
||||
VTKM_EXEC static ExecObjectType GetParameter(const Invocation& invocation)
|
||||
{
|
||||
return GetParameterImpl(invocation, std::integral_constant<bool, ControlParameterIndex == 0>());
|
||||
}
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
@ -154,6 +183,7 @@ template <typename WorkletType,
|
||||
typename OutputToInputMapType,
|
||||
typename VisitArrayType,
|
||||
typename ThreadToOutputMapType,
|
||||
typename DeviceAdapterTag,
|
||||
typename ThreadIndicesType,
|
||||
$template_params(num_params)>
|
||||
VTKM_EXEC void DoWorkletInvokeFunctor(
|
||||
@ -163,7 +193,9 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
|
||||
vtkm::internal::FunctionInterface<$signature(num_params)>,
|
||||
InputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
VisitArrayType, ThreadToOutputMapType>& invocation,
|
||||
VisitArrayType,
|
||||
ThreadToOutputMapType,
|
||||
DeviceAdapterTag>& invocation,
|
||||
const ThreadIndicesType& threadIndices)
|
||||
{
|
||||
using Invocation = vtkm::internal::Invocation<ParameterInterface,
|
||||
@ -171,15 +203,16 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
|
||||
vtkm::internal::FunctionInterface<$signature(num_params)>,
|
||||
InputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
VisitArrayType>;
|
||||
VisitArrayType,
|
||||
ThreadToOutputMapType,
|
||||
DeviceAdapterTag>;
|
||||
$for(param_index in range(1, num_params+1))\
|
||||
|
||||
using FetchInfo$(param_index) = InvocationToFetch<ThreadIndicesType, Invocation, $(param_index)>;
|
||||
using FetchType$(param_index) = typename FetchInfo$(param_index)::type;
|
||||
FetchType$(param_index) fetch$(param_index);
|
||||
typename FetchType$(param_index)::ValueType $pname(param_index) =
|
||||
fetch$(param_index).Load(threadIndices,
|
||||
invocation.Parameters.template GetParameter<FetchInfo$(param_index)::ControlParameterIndex>());
|
||||
fetch$(param_index).Load(threadIndices, FetchInfo$(param_index)::GetParameter(invocation));
|
||||
$endfor\
|
||||
|
||||
using FetchInfo0 = InvocationToFetch<ThreadIndicesType, Invocation, 0>;
|
||||
@ -197,15 +230,10 @@ $endfor\
|
||||
auto $pname(0) = typename ReturnFetchType::ValueType(worklet($arg_list(num_params)));
|
||||
|
||||
$for(param_index in range(1, num_params+1))\
|
||||
fetch$(param_index).Store(threadIndices,
|
||||
invocation.Parameters.template GetParameter<FetchInfo$(param_index)::ControlParameterIndex>(),
|
||||
$pname(param_index));
|
||||
fetch$(param_index).Store(threadIndices, FetchInfo$(param_index)::GetParameter(invocation), $pname(param_index));
|
||||
$endfor\
|
||||
|
||||
returnFetch.Store(
|
||||
threadIndices,
|
||||
invocation.Parameters.template GetParameter<FetchInfo0::ControlParameterIndex>(),
|
||||
$pname(0));
|
||||
returnFetch.Store(threadIndices, FetchInfo0::GetParameter(invocation), $pname(0));
|
||||
}
|
||||
|
||||
template <typename WorkletType,
|
||||
@ -213,7 +241,9 @@ template <typename WorkletType,
|
||||
typename ControlInterface,
|
||||
vtkm::IdComponent InputDomainIndex,
|
||||
typename OutputToInputMapType,
|
||||
typename VisitArrayType, typename ThreadToOutputMapType,
|
||||
typename VisitArrayType,
|
||||
typename ThreadToOutputMapType,
|
||||
typename DeviceAdapterTag,
|
||||
typename ThreadIndicesType,
|
||||
$template_params(num_params, start=1)>
|
||||
VTKM_EXEC void DoWorkletInvokeFunctor(
|
||||
@ -223,7 +253,9 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
|
||||
vtkm::internal::FunctionInterface<$signature(num_params, return_type='void')>,
|
||||
InputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
VisitArrayType, ThreadToOutputMapType>& invocation,
|
||||
VisitArrayType,
|
||||
ThreadToOutputMapType,
|
||||
DeviceAdapterTag>& invocation,
|
||||
const ThreadIndicesType& threadIndices)
|
||||
{
|
||||
using Invocation =
|
||||
@ -232,15 +264,16 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
|
||||
vtkm::internal::FunctionInterface<$signature(num_params, return_type='void')>,
|
||||
InputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
VisitArrayType>;
|
||||
VisitArrayType,
|
||||
ThreadToOutputMapType,
|
||||
DeviceAdapterTag>;
|
||||
$for(param_index in range(1, num_params+1))\
|
||||
|
||||
using FetchInfo$(param_index) = InvocationToFetch<ThreadIndicesType, Invocation, $(param_index)>;
|
||||
using FetchType$(param_index) = typename FetchInfo$(param_index)::type;
|
||||
FetchType$(param_index) fetch$(param_index);
|
||||
typename FetchType$(param_index)::ValueType $pname(param_index) =
|
||||
fetch$(param_index).Load(threadIndices,
|
||||
invocation.Parameters.template GetParameter<FetchInfo$(param_index)::ControlParameterIndex>());
|
||||
fetch$(param_index).Load(threadIndices, FetchInfo$(param_index)::GetParameter(invocation));
|
||||
$endfor\
|
||||
|
||||
// If you got a compile error on the following line, it probably means that
|
||||
@ -255,9 +288,7 @@ $endfor\
|
||||
worklet($arg_list(num_params));
|
||||
|
||||
$for(param_index in range(1, num_params+1))\
|
||||
fetch$(param_index).Store(threadIndices,
|
||||
invocation.Parameters.template GetParameter<FetchInfo$(param_index)::ControlParameterIndex>(),
|
||||
$pname(param_index));
|
||||
fetch$(param_index).Store(threadIndices, FetchInfo$(param_index)::GetParameter(invocation), $pname(param_index));
|
||||
$endfor\
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,8 @@ template <typename ParameterInterface_,
|
||||
vtkm::IdComponent InputDomainIndex_,
|
||||
typename OutputToInputMapType_ = vtkm::internal::NullType,
|
||||
typename VisitArrayType_ = vtkm::internal::NullType,
|
||||
typename ThreadToOutputMapType_ = vtkm::internal::NullType>
|
||||
typename ThreadToOutputMapType_ = vtkm::internal::NullType,
|
||||
typename DeviceAdapterTag_ = vtkm::internal::NullType>
|
||||
struct Invocation
|
||||
{
|
||||
/// \brief The types of the parameters
|
||||
@ -99,6 +100,13 @@ struct Invocation
|
||||
///
|
||||
using ThreadToOutputMapType = ThreadToOutputMapType_;
|
||||
|
||||
/// \brief The tag for the device adapter on which the worklet is run.
|
||||
///
|
||||
/// When the worklet is dispatched on a particular device, this type in the
|
||||
/// Invocation is set to the tag associated with that device.
|
||||
///
|
||||
using DeviceAdapterTag = DeviceAdapterTag_;
|
||||
|
||||
/// \brief Default Invocation constructors that holds the given parameters
|
||||
/// by reference.
|
||||
VTKM_CONT
|
||||
@ -125,7 +133,8 @@ struct Invocation
|
||||
InputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
VisitArrayType,
|
||||
ThreadToOutputMapType>;
|
||||
ThreadToOutputMapType,
|
||||
DeviceAdapterTag>;
|
||||
};
|
||||
|
||||
/// Returns a new \c Invocation that is the same as this one except that the
|
||||
@ -151,7 +160,8 @@ struct Invocation
|
||||
InputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
VisitArrayType,
|
||||
ThreadToOutputMapType>;
|
||||
ThreadToOutputMapType,
|
||||
DeviceAdapterTag>;
|
||||
};
|
||||
|
||||
/// Returns a new \c Invocation that is the same as this one except that the
|
||||
@ -177,7 +187,8 @@ struct Invocation
|
||||
InputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
VisitArrayType,
|
||||
ThreadToOutputMapType>;
|
||||
ThreadToOutputMapType,
|
||||
DeviceAdapterTag>;
|
||||
};
|
||||
|
||||
/// Returns a new \c Invocation that is the same as this one except that the
|
||||
@ -203,7 +214,8 @@ struct Invocation
|
||||
NewInputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
VisitArrayType,
|
||||
ThreadToOutputMapType>;
|
||||
ThreadToOutputMapType,
|
||||
DeviceAdapterTag>;
|
||||
};
|
||||
|
||||
/// Returns a new \c Invocation that is the same as this one except that the
|
||||
@ -229,7 +241,8 @@ struct Invocation
|
||||
InputDomainIndex,
|
||||
NewOutputToInputMapType,
|
||||
VisitArrayType,
|
||||
ThreadToOutputMapType>;
|
||||
ThreadToOutputMapType,
|
||||
DeviceAdapterTag>;
|
||||
};
|
||||
|
||||
/// Returns a new \c Invocation that is the same as this one except that the
|
||||
@ -255,7 +268,8 @@ struct Invocation
|
||||
InputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
NewVisitArrayType,
|
||||
ThreadToOutputMapType>;
|
||||
ThreadToOutputMapType,
|
||||
DeviceAdapterTag>;
|
||||
};
|
||||
|
||||
/// Returns a new \c Invocation that is the same as this one except that the
|
||||
@ -281,7 +295,8 @@ struct Invocation
|
||||
InputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
VisitArrayType,
|
||||
NewThreadToOutputMapType>;
|
||||
NewThreadToOutputMapType,
|
||||
DeviceAdapterTag>;
|
||||
};
|
||||
|
||||
/// Returns a new \c Invocation that is the same as this one except that the
|
||||
@ -295,6 +310,33 @@ struct Invocation
|
||||
this->Parameters, this->OutputToInputMap, this->VisitArray, newThreadToOutputMap);
|
||||
}
|
||||
|
||||
/// Defines a new \c Invocation type that is the same as this type except
|
||||
/// with the \c DeviceAdapterTag replaced.
|
||||
///
|
||||
template <typename NewDeviceAdapterTag>
|
||||
struct ChangeDeviceAdapterTagType
|
||||
{
|
||||
using type = Invocation<ParameterInterface,
|
||||
ControlInterface,
|
||||
ExecutionInterface,
|
||||
InputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
VisitArrayType,
|
||||
ThreadToOutputMapType,
|
||||
NewDeviceAdapterTag>;
|
||||
};
|
||||
|
||||
/// Returns a new \c Invocation that is the same as this one except that the
|
||||
/// \c DeviceAdapterTag is replaced with that provided.
|
||||
///
|
||||
template <typename NewDeviceAdapterTag>
|
||||
VTKM_CONT typename ChangeDeviceAdapterTagType<NewDeviceAdapterTag>::type ChangeDeviceAdapterTag(
|
||||
NewDeviceAdapterTag) const
|
||||
{
|
||||
return typename ChangeDeviceAdapterTagType<NewDeviceAdapterTag>::type(
|
||||
this->Parameters, this->OutputToInputMap, this->VisitArray, this->ThreadToOutputMap);
|
||||
}
|
||||
|
||||
/// A convenience alias for the input domain type.
|
||||
///
|
||||
using InputDomainType =
|
||||
@ -333,7 +375,8 @@ private:
|
||||
InputDomainIndex,
|
||||
OutputToInputMapType,
|
||||
VisitArrayType,
|
||||
ThreadToOutputMapType>&) = delete;
|
||||
ThreadToOutputMapType,
|
||||
DeviceAdapterTag>&) = delete;
|
||||
};
|
||||
|
||||
/// Convenience function for creating an Invocation object.
|
||||
|
@ -128,14 +128,14 @@ public:
|
||||
}
|
||||
}; //class createLeafs
|
||||
|
||||
template <typename Device>
|
||||
template <typename DeviceAdapterTag>
|
||||
class LinearBVHBuilder::GatherVecCast : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
using Vec4IdArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
|
||||
using Vec4IntArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Int32, 4>>;
|
||||
using PortalConst = typename Vec4IdArrayHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using Portal = typename Vec4IntArrayHandle::ExecutionTypes<Device>::Portal;
|
||||
using PortalConst = typename Vec4IdArrayHandle::ExecutionTypes<DeviceAdapterTag>::PortalConst;
|
||||
using Portal = typename Vec4IntArrayHandle::ExecutionTypes<DeviceAdapterTag>::Portal;
|
||||
|
||||
private:
|
||||
PortalConst InputPortal;
|
||||
@ -146,9 +146,9 @@ public:
|
||||
GatherVecCast(const Vec4IdArrayHandle& inputPortal,
|
||||
Vec4IntArrayHandle& outputPortal,
|
||||
const vtkm::Id& size)
|
||||
: InputPortal(inputPortal.PrepareForInput(Device()))
|
||||
: InputPortal(inputPortal.PrepareForInput(DeviceAdapterTag()))
|
||||
{
|
||||
this->OutputPortal = outputPortal.PrepareForOutput(size, Device());
|
||||
this->OutputPortal = outputPortal.PrepareForOutput(size, DeviceAdapterTag());
|
||||
}
|
||||
using ControlSignature = void(FieldIn);
|
||||
using ExecutionSignature = void(WorkIndex, _1);
|
||||
|
@ -307,12 +307,12 @@ public:
|
||||
} //namespace
|
||||
|
||||
|
||||
template <typename Device, typename LocatorType>
|
||||
template <typename DeviceAdapterTag, typename LocatorType>
|
||||
class Sampler : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
using ColorArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>;
|
||||
using ColorArrayPortal = typename ColorArrayHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using ColorArrayPortal = typename ColorArrayHandle::ExecutionTypes<DeviceAdapterTag>::PortalConst;
|
||||
ColorArrayPortal ColorMap;
|
||||
vtkm::Id ColorMapSize;
|
||||
vtkm::Float32 MinScalar;
|
||||
@ -327,7 +327,7 @@ public:
|
||||
const vtkm::Float32& maxScalar,
|
||||
const vtkm::Float32& sampleDistance,
|
||||
const LocatorType& locator)
|
||||
: ColorMap(colorMap.PrepareForInput(Device()))
|
||||
: ColorMap(colorMap.PrepareForInput(DeviceAdapterTag()))
|
||||
, MinScalar(minScalar)
|
||||
, SampleDistance(sampleDistance)
|
||||
, InverseDeltaScalar(minScalar)
|
||||
@ -500,12 +500,12 @@ public:
|
||||
}
|
||||
}; //Sampler
|
||||
|
||||
template <typename Device, typename LocatorType>
|
||||
template <typename DeviceAdapterTag, typename LocatorType>
|
||||
class SamplerCellAssoc : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
private:
|
||||
using ColorArrayHandle = typename vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>;
|
||||
using ColorArrayPortal = typename ColorArrayHandle::ExecutionTypes<Device>::PortalConst;
|
||||
using ColorArrayPortal = typename ColorArrayHandle::ExecutionTypes<DeviceAdapterTag>::PortalConst;
|
||||
ColorArrayPortal ColorMap;
|
||||
vtkm::Id ColorMapSize;
|
||||
vtkm::Float32 MinScalar;
|
||||
@ -520,7 +520,7 @@ public:
|
||||
const vtkm::Float32& maxScalar,
|
||||
const vtkm::Float32& sampleDistance,
|
||||
const LocatorType& locator)
|
||||
: ColorMap(colorMap.PrepareForInput(Device()))
|
||||
: ColorMap(colorMap.PrepareForInput(DeviceAdapterTag()))
|
||||
, MinScalar(minScalar)
|
||||
, SampleDistance(sampleDistance)
|
||||
, InverseDeltaScalar(minScalar)
|
||||
|
@ -820,11 +820,15 @@ private:
|
||||
}
|
||||
|
||||
template <typename Invocation, typename RangeType, typename DeviceAdapter>
|
||||
VTKM_CONT void InvokeSchedule(const Invocation& invocation, RangeType range, DeviceAdapter) const
|
||||
VTKM_CONT void InvokeSchedule(const Invocation& invocation,
|
||||
RangeType range,
|
||||
DeviceAdapter device) const
|
||||
{
|
||||
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
|
||||
using TaskTypes = typename vtkm::cont::DeviceTaskTypes<DeviceAdapter>;
|
||||
|
||||
auto invocationForDevice = invocation.ChangeDeviceAdapterTag(device);
|
||||
|
||||
// The TaskType class handles the magic of fetching values
|
||||
// for each instance and calling the worklet's function.
|
||||
// The TaskType will evaluate to one of the following classes:
|
||||
@ -832,7 +836,7 @@ private:
|
||||
// vtkm::exec::internal::TaskSingular
|
||||
// vtkm::exec::internal::TaskTiling1D
|
||||
// vtkm::exec::internal::TaskTiling3D
|
||||
auto task = TaskTypes::MakeTask(this->Worklet, invocation, range);
|
||||
auto task = TaskTypes::MakeTask(this->Worklet, invocationForDevice, range);
|
||||
Algorithm::ScheduleTask(task, range);
|
||||
}
|
||||
};
|
||||
|
@ -113,6 +113,15 @@ public:
|
||||
///
|
||||
using VisitIndex = vtkm::exec::arg::VisitIndex;
|
||||
|
||||
/// \c ExecutionSignature tag for getting the device adapter tag.
|
||||
///
|
||||
struct Device : vtkm::exec::arg::ExecutionSignatureTagBase
|
||||
{
|
||||
// INDEX 0 (which is an invalid parameter index) is reserved to mean the device adapter tag.
|
||||
static constexpr vtkm::IdComponent INDEX = 0;
|
||||
using AspectTag = vtkm::exec::arg::AspectTagDefault;
|
||||
};
|
||||
|
||||
/// \c ControlSignature tag for execution object inputs.
|
||||
struct ExecObject : vtkm::cont::arg::ControlSignatureTagBase
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
//============================================================================
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ArrayHandleIndex.h>
|
||||
#include <vtkm/cont/ExecutionObjectBase.h>
|
||||
#include <vtkm/cont/VariantArrayHandle.h>
|
||||
#include <vtkm/cont/internal/DeviceAdapterTag.h>
|
||||
|
||||
@ -27,21 +28,34 @@
|
||||
|
||||
#include <vtkm/cont/testing/Testing.h>
|
||||
|
||||
struct SimpleExecObject : vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
template <typename Device>
|
||||
Device PrepareForExecution(Device) const
|
||||
{
|
||||
return Device();
|
||||
}
|
||||
};
|
||||
|
||||
struct TestExecObjectWorklet
|
||||
{
|
||||
template <typename T>
|
||||
class Worklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn, WholeArrayIn, WholeArrayOut, FieldOut);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4);
|
||||
using ControlSignature = void(FieldIn, WholeArrayIn, WholeArrayOut, FieldOut, ExecObject);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, Device);
|
||||
|
||||
template <typename InPortalType, typename OutPortalType>
|
||||
template <typename InPortalType, typename OutPortalType, typename DeviceTag>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& index,
|
||||
const InPortalType& execIn,
|
||||
OutPortalType& execOut,
|
||||
T& out) const
|
||||
T& out,
|
||||
DeviceTag,
|
||||
DeviceTag) const
|
||||
{
|
||||
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceTag);
|
||||
|
||||
if (!test_equal(execIn.Get(index), TestValue(index, T()) + T(100)))
|
||||
{
|
||||
this->RaiseError("Got wrong input value.");
|
||||
@ -79,7 +93,7 @@ struct DoTestWorklet
|
||||
|
||||
std::cout << "Create and run dispatcher." << std::endl;
|
||||
vtkm::worklet::DispatcherMapField<typename WorkletType::template Worklet<T>> dispatcher;
|
||||
dispatcher.Invoke(counting, inputHandle, outputHandle, outputFieldArray);
|
||||
dispatcher.Invoke(counting, inputHandle, outputHandle, outputFieldArray, SimpleExecObject());
|
||||
|
||||
std::cout << "Check result." << std::endl;
|
||||
CheckPortal(outputHandle.GetPortalConstControl());
|
||||
@ -92,7 +106,7 @@ struct DoTestWorklet
|
||||
outputHandle.Allocate(ARRAY_SIZE);
|
||||
|
||||
vtkm::cont::VariantArrayHandleBase<vtkm::ListTagBase<T>> outputFieldDynamic(outputFieldArray);
|
||||
dispatcher.Invoke(counting, inputHandle, outputHandle, outputFieldDynamic);
|
||||
dispatcher.Invoke(counting, inputHandle, outputHandle, outputFieldDynamic, SimpleExecObject());
|
||||
|
||||
std::cout << "Check dynamic array result." << std::endl;
|
||||
CheckPortal(outputHandle.GetPortalConstControl());
|
||||
|
Loading…
Reference in New Issue
Block a user