Commit dad18e11 authored by Kenneth Moreland's avatar Kenneth Moreland

Improve 3D scheduling mechanism in DispatcherBase

Previously, DispatcherBase had an ivar to determine whether to use the
numInstances passed on the stack or to use a 3D range held in a
different ivar. This change allows either a 1D range or 3D range to be
passed on the stack, which I expect to be closer to how we we handle
this when 3D ranges are fully supported.

This also fixes a bug introduced with commit
fdac208a where the Use3DSchedule ivar
was not set correctly in UnitTestDispatcherBase.
parent 189a5305
......@@ -47,7 +47,7 @@ class DispatcherMapField :
public:
VTKM_CONT_EXPORT
DispatcherMapField(const WorkletType &worklet = WorkletType())
: Superclass(worklet) { this->Use3DSchedule=false; }
: Superclass(worklet) { }
template<typename Invocation>
VTKM_CONT_EXPORT
......
......@@ -169,9 +169,18 @@ struct DispatcherBaseTransportFunctor
{
vtkm::Id NumInstances;
VTKM_CONT_EXPORT
DispatcherBaseTransportFunctor(vtkm::Id numInstances)
: NumInstances(numInstances) { }
// TODO: We need to think harder about how scheduling on 3D arrays works.
// Chances are we need to allow the transport for each argument to manage
// 3D indices (for example, allocate a 3D array instead of a 1D array).
// But for now, just treat all transports as 1D arrays.
VTKM_CONT_EXPORT
DispatcherBaseTransportFunctor(vtkm::Id3 dimensions)
: NumInstances(dimensions[0]*dimensions[1]*dimensions[2]) { }
template<typename ControlParameter, vtkm::IdComponent Index>
struct InvokeTypes {
typedef typename ControlInterface::template ParameterType<Index>::type
......@@ -275,9 +284,6 @@ public:
// Implementation of the Invoke method is in this generated file.
#include <vtkm/worklet/internal/DispatcherBaseDetailInvoke.h>
bool Use3DSchedule;
vtkm::Id3 dims;
protected:
VTKM_CONT_EXPORT
DispatcherBase(const WorkletType &worklet) : Worklet(worklet) { }
......@@ -289,6 +295,13 @@ protected:
this->InvokeTransportParameters(invocation, numInstances);
}
template<typename Invocation>
VTKM_CONT_EXPORT
void BasicInvoke(const Invocation &invocation, vtkm::Id3 dimensions) const
{
this->InvokeTransportParameters(invocation, dimensions);
}
WorkletType Worklet;
private:
......@@ -296,10 +309,10 @@ private:
DispatcherBase(const MyType &);
void operator=(const MyType &);
template<typename Invocation>
template<typename Invocation, typename RangeType>
VTKM_CONT_EXPORT
void InvokeTransportParameters(const Invocation &invocation,
vtkm::Id numInstances) const
RangeType range) const
{
// The first step in invoking a worklet is to transport the arguments to
// the execution environment. The invocation object passed to this function
......@@ -319,17 +332,17 @@ private:
TransportFunctorType>::type ExecObjectParameters;
ExecObjectParameters execObjectParameters =
parameters.StaticTransformCont(TransportFunctorType(numInstances));
parameters.StaticTransformCont(TransportFunctorType(range));
// Replace the parameters in the invocation with the execution object and
// pass to next step of Invoke.
this->InvokeSchedule(invocation.ChangeParameters(execObjectParameters),
numInstances);
range);
}
template<typename Invocation>
template<typename Invocation, typename RangeType>
VTKM_CONT_EXPORT
void InvokeSchedule(const Invocation &invocation, vtkm::Id numInstances) const
void InvokeSchedule(const Invocation &invocation, RangeType range) const
{
// The WorkletInvokeFunctor class handles the magic of fetching values
// for each instance and calling the worklet's function. So just create
......@@ -341,14 +354,7 @@ private:
typedef vtkm::cont::DeviceAdapterAlgorithm<Device> Algorithm;
if(this->Use3DSchedule)
{
Algorithm::Schedule(workletFunctor, dims);
}
else
{
Algorithm::Schedule(workletFunctor, numInstances);
}
Algorithm::Schedule(workletFunctor, range);
}
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment