VertexClustering worklet is not templated on device adapter.

This should help reduce the amount of code generation, when building the
VertexClustering worklet for all device adapters.
This commit is contained in:
Robert Maynard 2016-01-14 15:42:27 -05:00
parent 02d10e38c4
commit 12ddcfdda7
2 changed files with 36 additions and 49 deletions

@ -93,7 +93,6 @@ private:
} // namespace internal } // namespace internal
template<typename DeviceAdapter>
struct VertexClustering struct VertexClustering
{ {
struct GridInfo struct GridInfo
@ -176,34 +175,22 @@ struct VertexClustering
class IndexingWorklet : public vtkm::worklet::WorkletMapField class IndexingWorklet : public vtkm::worklet::WorkletMapField
{ {
public: public:
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdArrayHandle; typedef void ControlSignature(FieldIn<IdType>,
private: WholeArrayOut<IdType>);
typedef typename IdArrayHandle::ExecutionTypes<DeviceAdapter>::Portal IdPortalType; typedef void ExecutionSignature(WorkIndex, _1, _2); // WorkIndex: use vtkm indexing
IdPortalType CidIndexRaw;
vtkm::Id Len;
public:
typedef void ControlSignature(FieldIn<IdType>);
typedef void ExecutionSignature(WorkIndex, _1); // WorkIndex: use vtkm indexing
VTKM_CONT_EXPORT
IndexingWorklet( IdArrayHandle &cidIndexArray, vtkm::Id n ) : Len(n)
{
this->CidIndexRaw = cidIndexArray.PrepareForOutput(n, DeviceAdapter() );
}
template<typename OutPortalType>
VTKM_EXEC_EXPORT VTKM_EXEC_EXPORT
void operator()(const vtkm::Id &counter, const vtkm::Id &cid) const void operator()(const vtkm::Id &counter,
const vtkm::Id &cid,
const OutPortalType &outPortal) const
{ {
VTKM_ASSERT_EXEC( cid < this->Len , *this ); outPortal.Set(cid, counter);
this->CidIndexRaw.Set(cid, counter);
} }
}; };
class Cid2PointIdWorklet : public vtkm::worklet::WorkletMapField class Cid2PointIdWorklet : public vtkm::worklet::WorkletMapField
{ {
typedef typename vtkm::cont::ArrayHandle<vtkm::Id> IdArrayHandle;
typedef typename IdArrayHandle::ExecutionTypes<DeviceAdapter>::PortalConst IdPortalType;
const IdPortalType CidIndexRaw;
vtkm::Id NPoints; vtkm::Id NPoints;
VTKM_EXEC_EXPORT VTKM_EXEC_EXPORT
@ -213,17 +200,21 @@ struct VertexClustering
} }
public: public:
typedef void ControlSignature(FieldIn<Id3Type>, FieldOut<Id3Type>); typedef void ControlSignature(FieldIn<Id3Type>,
typedef void ExecutionSignature(_1, _2); FieldOut<Id3Type>,
WholeArrayIn<IdType>);
typedef void ExecutionSignature(_1, _2, _3);
VTKM_CONT_EXPORT VTKM_CONT_EXPORT
Cid2PointIdWorklet( IdArrayHandle &cidIndexArray, vtkm::Id nPoints ) Cid2PointIdWorklet( vtkm::Id nPoints ):
: CidIndexRaw ( cidIndexArray.PrepareForInput(DeviceAdapter()) ),
NPoints(nPoints) NPoints(nPoints)
{} {}
template<typename InPortalType>
VTKM_EXEC_EXPORT VTKM_EXEC_EXPORT
void operator()(const vtkm::Id3 &cid3, vtkm::Id3 &pointId3) const void operator()(const vtkm::Id3 &cid3,
vtkm::Id3 &pointId3,
const InPortalType& inPortal) const
{ {
if (cid3[0]==cid3[1] || cid3[0]==cid3[2] || cid3[1]==cid3[2]) if (cid3[0]==cid3[1] || cid3[0]==cid3[2] || cid3[1]==cid3[2])
{ {
@ -231,10 +222,9 @@ struct VertexClustering
} }
else else
{ {
pointId3[0] = this->CidIndexRaw.Get( cid3[0] ); pointId3[0] = inPortal.Get( cid3[0] );
pointId3[1] = this->CidIndexRaw.Get( cid3[1] ); pointId3[1] = inPortal.Get( cid3[1] );
pointId3[2] = this->CidIndexRaw.Get( cid3[2] ); pointId3[2] = inPortal.Get( cid3[2] );
VTKM_ASSERT_EXEC( pointId3[0] < this->NPoints && pointId3[1] < this->NPoints && pointId3[2] < this->NPoints, *this );
// Sort triangle point ids so that the same triangle will have the same signature // Sort triangle point ids so that the same triangle will have the same signature
// Rotate these ids making the first one the smallest // Rotate these ids making the first one the smallest
@ -317,25 +307,17 @@ struct VertexClustering
} }
}; };
template <typename ValueType>
void SortAndUnique(vtkm::cont::ArrayHandle<ValueType> &pointId3Array)
{
///
/// Unique: Decimate replicated cells
///
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Sort(pointId3Array);
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Unique(pointId3Array);
}
public: public:
/////////////////////////////////////////////////// ///////////////////////////////////////////////////
/// \brief VertexClustering: Mesh simplification /// \brief VertexClustering: Mesh simplification
/// ///
template<typename DeviceAdapter>
vtkm::cont::DataSet Run(const vtkm::cont::DynamicCellSet &cellSet, vtkm::cont::DataSet Run(const vtkm::cont::DynamicCellSet &cellSet,
const vtkm::cont::CoordinateSystem &coordinates, const vtkm::cont::CoordinateSystem &coordinates,
vtkm::Id nDivisions) vtkm::Id nDivisions,
DeviceAdapter)
{ {
vtkm::Float64 bounds[6]; vtkm::Float64 bounds[6];
coordinates.GetBounds(bounds, DeviceAdapter()); coordinates.GetBounds(bounds, DeviceAdapter());
@ -415,10 +397,12 @@ public:
/// preparation: Get the indexes of the clustered points to prepare for new cell array /// preparation: Get the indexes of the clustered points to prepare for new cell array
vtkm::cont::ArrayHandle<vtkm::Id> cidIndexArray; vtkm::cont::ArrayHandle<vtkm::Id> cidIndexArray;
cidIndexArray.PrepareForOutput(gridInfo.dim[0]*gridInfo.dim[1]*gridInfo.dim[2],
DeviceAdapter());
vtkm::worklet::DispatcherMapField<IndexingWorklet, DeviceAdapter> ( vtkm::worklet::DispatcherMapField<
IndexingWorklet(cidIndexArray, gridInfo.dim[0]*gridInfo.dim[1]*gridInfo.dim[2])) IndexingWorklet,
.Invoke(pointCidArrayReduced); DeviceAdapter>().Invoke(pointCidArrayReduced, cidIndexArray);
pointCidArrayReduced.ReleaseResources(); pointCidArrayReduced.ReleaseResources();
@ -431,7 +415,7 @@ public:
vtkm::cont::ArrayHandle<vtkm::Id3> pointId3Array; vtkm::cont::ArrayHandle<vtkm::Id3> pointId3Array;
vtkm::worklet::DispatcherMapField<Cid2PointIdWorklet, DeviceAdapter>( vtkm::worklet::DispatcherMapField<Cid2PointIdWorklet, DeviceAdapter>(
Cid2PointIdWorklet( cidIndexArray, nPoints)).Invoke(cid3Array, pointId3Array); Cid2PointIdWorklet(nPoints)).Invoke(cid3Array, pointId3Array, cidIndexArray);
cid3Array.ReleaseResources(); cid3Array.ReleaseResources();
cidIndexArray.ReleaseResources(); cidIndexArray.ReleaseResources();
@ -452,7 +436,8 @@ public:
std::cout << "Time before sort and unique with hashing (s): " << timer.GetElapsedTime() << std::endl; std::cout << "Time before sort and unique with hashing (s): " << timer.GetElapsedTime() << std::endl;
#endif #endif
SortAndUnique(pointId3HashArray); vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Sort(pointId3HashArray);
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Unique(pointId3HashArray);
#ifdef __VTKM_VERTEX_CLUSTERING_BENCHMARK #ifdef __VTKM_VERTEX_CLUSTERING_BENCHMARK
std::cout << "Time after sort and unique with hashing (s): " << timer.GetElapsedTime() << std::endl; std::cout << "Time after sort and unique with hashing (s): " << timer.GetElapsedTime() << std::endl;
@ -470,7 +455,8 @@ public:
std::cout << "Time before sort and unique [no hashing] (s): " << timer.GetElapsedTime() << std::endl; std::cout << "Time before sort and unique [no hashing] (s): " << timer.GetElapsedTime() << std::endl;
#endif #endif
SortAndUnique(pointId3Array); vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Sort(pointId3Array);
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Unique(pointId3Array);
#ifdef __VTKM_VERTEX_CLUSTERING_BENCHMARK #ifdef __VTKM_VERTEX_CLUSTERING_BENCHMARK
std::cout << "Time after sort and unique [no hashing] (s): " << timer.GetElapsedTime() << std::endl; std::cout << "Time after sort and unique [no hashing] (s): " << timer.GetElapsedTime() << std::endl;

@ -37,10 +37,11 @@ void TestVertexClustering()
vtkm::cont::DataSet dataSet = maker.Make3DExplicitDataSetCowNose(bounds); vtkm::cont::DataSet dataSet = maker.Make3DExplicitDataSetCowNose(bounds);
// run // run
vtkm::worklet::VertexClustering<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> clustering; vtkm::worklet::VertexClustering clustering;
vtkm::cont::DataSet outDataSet = clustering.Run(dataSet.GetCellSet(), vtkm::cont::DataSet outDataSet = clustering.Run(dataSet.GetCellSet(),
dataSet.GetCoordinateSystem(), dataSet.GetCoordinateSystem(),
divisions); divisions,
VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
// test // test
const vtkm::Id output_pointIds = 9; const vtkm::Id output_pointIds = 9;