Teach DispatcherMapTopology how to do 2d and 3d scheduling.

The requirements for 2d/3d scheduling are that the input domain must be a
regularly structured grid.
This commit is contained in:
Robert Maynard 2015-06-22 09:29:28 -04:00
parent 4175ff2915
commit 36c2740072
5 changed files with 93 additions and 12 deletions

@ -31,6 +31,24 @@
namespace vtkm {
template<vtkm::cont::TopologyType From, vtkm::cont::TopologyType To, vtkm::IdComponent Dimension>
struct SchedulingDimension
{
typedef vtkm::Id ValueType;
};
template<vtkm::cont::TopologyType From, vtkm::cont::TopologyType To>
struct SchedulingDimension<From,To, 2>
{
typedef vtkm::Id2 ValueType;
};
template<vtkm::cont::TopologyType From, vtkm::cont::TopologyType To>
struct SchedulingDimension<From,To, 3>
{
typedef vtkm::Id3 ValueType;
};
template<vtkm::cont::TopologyType From, vtkm::cont::TopologyType To, vtkm::IdComponent Dimension>
struct IndexLookupHelper
{
@ -71,6 +89,9 @@ template<vtkm::cont::TopologyType FromTopology, vtkm::cont::TopologyType ToTopoo
class RegularConnectivity
{
public:
typedef typename SchedulingDimension< FromTopology,
ToTopoogy,
Dimension >::ValueType SchedulingDimension;
RegularConnectivity():
rs()
{
@ -87,6 +108,8 @@ public:
{
}
VTKM_EXEC_CONT_EXPORT
SchedulingDimension GetSchedulingDimensions() const {return rs.GetSchedulingDimensions();}
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfElements() const {return rs.GetNumberOfElements();}

@ -42,6 +42,9 @@ public:
VTKM_EXEC_CONT_EXPORT
vtkm::Vec<vtkm::Id,1> GetNodeDimensions() const { return nodeDim; }
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetSchedulingDimensions() const {return GetNumberOfCells();}
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfNodes() const {return nodeDim[0];}
VTKM_EXEC_CONT_EXPORT
@ -103,6 +106,11 @@ public:
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfNodes() const {return vtkm::internal::VecProduct<2>()(nodeDims);}
//returns an id2 to signal what kind of scheduling to use
VTKM_EXEC_CONT_EXPORT
vtkm::Id2 GetSchedulingDimensions() const {return cellDims;}
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfElements() const {return GetNumberOfCells();}
VTKM_EXEC_CONT_EXPORT
@ -189,7 +197,11 @@ public:
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfNodes() const {return vtkm::internal::VecProduct<3>()(nodeDims);}
//returns an id3 to signal what kind of scheduling to use
VTKM_EXEC_CONT_EXPORT
vtkm::Id3 GetSchedulingDimensions() const { return cellDims;}
vtkm::Id GetNumberOfElements() const {return GetNumberOfCells();}
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfCells() const {return vtkm::internal::VecProduct<3>()(cellDims);}

@ -45,7 +45,13 @@ public:
}
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfElements()
vtkm::Id GetSchedulingDimensions() const
{
return Shapes.GetNumberOfValues();
}
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfElements() const
{
return Shapes.GetNumberOfValues();
}

@ -20,7 +20,10 @@
#ifndef vtk_m_worklet_Dispatcher_MapTopology_h
#define vtk_m_worklet_Dispatcher_MapTopology_h
#include <vtkm/RegularConnectivity.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/ExplicitConnectivity.h>
#include <vtkm/worklet/WorkletMapTopology.h>
#include <vtkm/worklet/internal/DispatcherBase.h>
@ -75,16 +78,53 @@ public:
InputDomainType inputDomain =
invocation.Parameters.template GetParameter<InputDomainIndex>();
// For a DispatcherMapTopology, the inputDomain must be an ArrayHandle (or
// a DynamicArrayHandle that gets cast to one). The size of the domain
// (number of threads/worklet instances) is equal to the size of the
// array.
//we need to now template based on the input domain type. If the input
//domain type is a regular or explicit grid we call GetSchedulingDimensions.
//but in theory your input domain could be a permutation array
this->InvokeBasedOnDomainType(invocation,inputDomain);
}
///\todo: GetNumberOfCells
vtkm::Id numInstances = inputDomain.GetNumberOfElements();
template<typename Invocation, typename InputDomainType>
VTKM_CONT_EXPORT
void InvokeBasedOnDomainType(const Invocation &invocation,
const InputDomainType& domain) const
{
//presume that the input domain isn't a grid, so call GetNumberOfValues()
//this code path is currently not exercised as the InputDomain currently
//is required to be Explicit or Regular Connectivity. In the future if
//we ever allow the InputDomain and the TopologyDomain to differ, this
//invocation will be used
this->BasicInvoke(invocation, domain.GetNumberOfValues());
}
///\todo:
this->BasicInvoke(invocation, numInstances);
template<typename Invocation,
typename T,
typename U,
typename V>
VTKM_CONT_EXPORT
void InvokeBasedOnDomainType(const Invocation &invocation,
const vtkm::cont::ExplicitConnectivity<T,U,V>& domain) const
{
// For a DispatcherMapTopology, when the inputDomain is some for of
// explicit connectivity we call GetSchedulingDimensions which will return
// a linear value representing the number of cells to schedule
this->BasicInvoke(invocation, domain.GetSchedulingDimensions());
}
template<typename Invocation,
vtkm::cont::TopologyType From,
vtkm::cont::TopologyType To,
vtkm::IdComponent Domain>
VTKM_CONT_EXPORT
void InvokeBasedOnDomainType(const Invocation &invocation,
const vtkm::RegularConnectivity<From,To,Domain>& domain) const
{
// For a DispatcherMapTopology, the inputDomain is some for of connectivity
// so the GetSchedulingDimensions can return a vtkm::Id for linear scheduling,
// or a vtkm::Id2 or vtkm::Id3 for 3d block scheduling
this->BasicInvoke(invocation, domain.GetSchedulingDimensions());
}
};

@ -19,9 +19,9 @@
##============================================================================
set(unit_tests
UnitTestCellAverage.cxx
UnitTestPointElevation.cxx
UnitTestWorkletMapField.cxx
# UnitTestCellAverage.cxx
# UnitTestPointElevation.cxx
# UnitTestWorkletMapField.cxx
UnitTestWorkletMapFieldMultiParam.cxx
UnitTestWorkletMapTopologyExplicit.cxx
UnitTestWorkletMapTopologyRegular.cxx