Move the processing of scatter cell data to worklet from the filter.

This commit is contained in:
Patricia Kroll Fasel - 090207 2017-03-24 16:34:53 -06:00
parent 3a1a6aece3
commit 36b480993d
10 changed files with 176 additions and 113 deletions

@ -49,7 +49,7 @@ public:
const DeviceAdapter& tag);
private:
vtkm::cont::ArrayHandle<vtkm::IdComponent> OutCellsPerCell;
vtkm::worklet::Tetrahedralize Worklet;
};
}

@ -24,38 +24,11 @@
namespace vtkm {
namespace filter {
struct DistributeCellData : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn<> inIndices,
FieldOut<> outIndices);
typedef void ExecutionSignature(_1, _2);
typedef vtkm::worklet::ScatterCounting ScatterType;
VTKM_CONT
ScatterType GetScatter() const { return this->Scatter; }
template <typename CountArrayType, typename DeviceAdapter>
VTKM_CONT
DistributeCellData(const CountArrayType &countArray,
DeviceAdapter device) :
Scatter(countArray, device) { }
template <typename T>
VTKM_EXEC
void operator()(T inputIndex,
T &outputIndex) const
{
outputIndex = inputIndex;
}
private:
ScatterType Scatter;
};
//-----------------------------------------------------------------------------
inline VTKM_CONT
Tetrahedralize::Tetrahedralize():
vtkm::filter::FilterDataSet<Tetrahedralize>()
vtkm::filter::FilterDataSet<Tetrahedralize>(),
Worklet()
{
}
@ -65,29 +38,26 @@ template<typename DerivedPolicy,
inline VTKM_CONT
vtkm::filter::ResultDataSet Tetrahedralize::DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter& device)
{
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter> DeviceAlgorithm;
typedef vtkm::cont::CellSetStructured<3> CellSetStructuredType;
typedef vtkm::cont::CellSetExplicit<> CellSetExplicitType;
const vtkm::cont::DynamicCellSet& cells =
input.GetCellSet(this->GetActiveCellSetIndex());
vtkm::Id numberOfCells = cells.GetNumberOfCells();
vtkm::cont::CellSetSingleType<> outCellSet;
vtkm::worklet::Tetrahedralize<DeviceAdapter> worklet;
if (cells.IsType<CellSetStructuredType>())
{
DeviceAlgorithm::Copy(vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>(5, numberOfCells),
this->OutCellsPerCell);
outCellSet = worklet.Run(cells.Cast<CellSetStructuredType>());
outCellSet = this->Worklet.Run(cells.Cast<CellSetStructuredType>(),
device);
}
else
{
outCellSet = worklet.Run(cells.Cast<CellSetExplicitType>(), this->OutCellsPerCell);
outCellSet = this->Worklet.Run(cells.Cast<CellSetExplicitType>(),
device);
}
// create the output dataset
@ -108,7 +78,7 @@ bool Tetrahedralize::DoMapField(
vtkm::filter::ResultDataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter& device)
{
// point data is copied as is because it was not collapsed
@ -121,11 +91,8 @@ bool Tetrahedralize::DoMapField(
// cell data must be scattered to the cells created per input cell
if(fieldMeta.IsCellField())
{
vtkm::cont::ArrayHandle<T, StorageType> output;
DistributeCellData distribute(this->OutCellsPerCell, device);
vtkm::worklet::DispatcherMapField<DistributeCellData, DeviceAdapter> dispatcher(distribute);
dispatcher.Invoke(input, output);
vtkm::cont::ArrayHandle<T, StorageType> output =
this->Worklet.ProcessField(input, device);
result.GetDataSet().AddField(fieldMeta.AsField(output));
return true;

@ -49,7 +49,7 @@ public:
const DeviceAdapter& tag);
private:
vtkm::cont::ArrayHandle<vtkm::IdComponent> OutCellsPerCell;
vtkm::worklet::Triangulate Worklet;
};
}

@ -24,39 +24,11 @@
namespace vtkm {
namespace filter {
struct DistributeCellData : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn<> inIndices,
FieldOut<> outIndices);
typedef void ExecutionSignature(_1, _2);
typedef vtkm::worklet::ScatterCounting ScatterType;
VTKM_CONT
ScatterType GetScatter() const { return this->Scatter; }
template <typename CountArrayType, typename DeviceAdapter>
VTKM_CONT
DistributeCellData(const CountArrayType &countArray,
DeviceAdapter device) :
Scatter(countArray, device) { }
template <typename T>
VTKM_EXEC
void operator()(T inputIndex,
T &outputIndex) const
{
outputIndex = inputIndex;
}
private:
ScatterType Scatter;
};
//-----------------------------------------------------------------------------
inline VTKM_CONT
Triangulate::Triangulate():
vtkm::filter::FilterDataSet<Triangulate>(),
OutCellsPerCell()
Worklet()
{
}
@ -66,29 +38,26 @@ template<typename DerivedPolicy,
inline VTKM_CONT
vtkm::filter::ResultDataSet Triangulate::DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter& device)
{
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter> DeviceAlgorithm;
typedef vtkm::cont::CellSetStructured<2> CellSetStructuredType;
typedef vtkm::cont::CellSetExplicit<> CellSetExplicitType;
const vtkm::cont::DynamicCellSet& cells =
input.GetCellSet(this->GetActiveCellSetIndex());
vtkm::Id numberOfCells = cells.GetNumberOfCells();
vtkm::cont::CellSetSingleType<> outCellSet;
vtkm::worklet::Triangulate<DeviceAdapter> worklet;
if (cells.IsType<CellSetStructuredType>())
{
DeviceAlgorithm::Copy(vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>(2, numberOfCells),
this->OutCellsPerCell);
outCellSet = worklet.Run(cells.Cast<CellSetStructuredType>());
outCellSet = this->Worklet.Run(cells.Cast<CellSetStructuredType>(),
device);
}
else
{
outCellSet = worklet.Run(cells.Cast<CellSetExplicitType>(), this->OutCellsPerCell);
outCellSet = this->Worklet.Run(cells.Cast<CellSetExplicitType>(),
device);
}
// create the output dataset
@ -109,7 +78,7 @@ bool Triangulate::DoMapField(
vtkm::filter::ResultDataSet& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter& device)
{
// point data is copied as is because it was not collapsed
@ -122,14 +91,12 @@ bool Triangulate::DoMapField(
// cell data must be scattered to the cells created per input cell
if(fieldMeta.IsCellField())
{
vtkm::cont::ArrayHandle<T, StorageType> output;
DistributeCellData distribute(this->OutCellsPerCell, device);
vtkm::worklet::DispatcherMapField<DistributeCellData, DeviceAdapter> dispatcher(distribute);
dispatcher.Invoke(input, output);
vtkm::cont::ArrayHandle<T, StorageType> output =
this->Worklet.ProcessField(input, device);
result.GetDataSet().AddField(fieldMeta.AsField(output));
return true;
}
return false;

@ -26,24 +26,79 @@
namespace vtkm {
namespace worklet {
template <typename DeviceAdapter>
//
// Distribute multiple copies of cell data depending on cells create from original
//
struct DistributeCellData : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn<> inIndices,
FieldOut<> outIndices);
typedef void ExecutionSignature(_1, _2);
typedef vtkm::worklet::ScatterCounting ScatterType;
VTKM_CONT
ScatterType GetScatter() const { return this->Scatter; }
template <typename CountArrayType, typename DeviceAdapter>
VTKM_CONT
DistributeCellData(const CountArrayType &countArray,
DeviceAdapter device) :
Scatter(countArray, device) { }
template <typename T>
VTKM_EXEC
void operator()(T inputIndex,
T &outputIndex) const
{
outputIndex = inputIndex;
}
private:
ScatterType Scatter;
};
class Tetrahedralize
{
public:
Tetrahedralize() {}
Tetrahedralize() : OutCellsPerCell() {}
// Tetrahedralize explicit data set, save number of tetra cells per input
template <typename DeviceAdapter>
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetExplicit<> &cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent> &outCellsPerCell)
const DeviceAdapter&)
{
TetrahedralizeExplicit<DeviceAdapter> worklet;
return worklet.Run(cellSet, outCellsPerCell);
return worklet.Run(cellSet, this->OutCellsPerCell);
}
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<3> &cellSet)
// Tetrahedralize structured data set, save number of tetra cells per input
template <typename DeviceAdapter>
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<3> &cellSet,
const DeviceAdapter&)
{
TetrahedralizeStructured<DeviceAdapter> worklet;
return worklet.Run(cellSet);
return worklet.Run(cellSet, this->OutCellsPerCell);
}
// Using the saved input to output cells, expand cell data
template <typename T,
typename StorageType,
typename DeviceAdapter>
vtkm::cont::ArrayHandle<T, StorageType> ProcessField(
const vtkm::cont::ArrayHandle<T, StorageType> &input,
const DeviceAdapter& device)
{
vtkm::cont::ArrayHandle<T, StorageType> output;
DistributeCellData distribute(this->OutCellsPerCell, device);
vtkm::worklet::DispatcherMapField<DistributeCellData, DeviceAdapter> dispatcher(distribute);
dispatcher.Invoke(input, output);
return output;
}
private:
vtkm::cont::ArrayHandle<vtkm::IdComponent> OutCellsPerCell;
};
}

@ -26,24 +26,79 @@
namespace vtkm {
namespace worklet {
template <typename DeviceAdapter>
//
// Distribute multiple copies of cell data depending on cells create from original
//
struct DistributeCellData : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn<> inIndices,
FieldOut<> outIndices);
typedef void ExecutionSignature(_1, _2);
typedef vtkm::worklet::ScatterCounting ScatterType;
VTKM_CONT
ScatterType GetScatter() const { return this->Scatter; }
template <typename CountArrayType, typename DeviceAdapter>
VTKM_CONT
DistributeCellData(const CountArrayType &countArray,
DeviceAdapter device) :
Scatter(countArray, device) { }
template <typename T>
VTKM_EXEC
void operator()(T inputIndex,
T &outputIndex) const
{
outputIndex = inputIndex;
}
private:
ScatterType Scatter;
};
class Triangulate
{
public:
Triangulate() {}
Triangulate() : OutCellsPerCell() {}
// Triangulate explicit data set, save number of triangulated cells per input
template <typename DeviceAdapter>
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetExplicit<> &cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent> &outCellsPerCell)
const DeviceAdapter&)
{
TriangulateExplicit<DeviceAdapter> worklet;
return worklet.Run(cellSet, outCellsPerCell);
return worklet.Run(cellSet, this->OutCellsPerCell);
}
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<2> &cellSet)
// Triangulate structured data set, save number of triangulated cells per input
template <typename DeviceAdapter>
vtkm::cont::CellSetSingleType<> Run(const vtkm::cont::CellSetStructured<2> &cellSet,
const DeviceAdapter&)
{
TriangulateStructured<DeviceAdapter> worklet;
return worklet.Run(cellSet);
return worklet.Run(cellSet, this->OutCellsPerCell);
}
// Using the saved input to output cells, expand cell data
template <typename T,
typename StorageType,
typename DeviceAdapter>
vtkm::cont::ArrayHandle<T, StorageType> ProcessField(
const vtkm::cont::ArrayHandle<T, StorageType> &input,
const DeviceAdapter& device)
{
vtkm::cont::ArrayHandle<T, StorageType> output;
DistributeCellData distribute(this->OutCellsPerCell, device);
vtkm::worklet::DispatcherMapField<DistributeCellData, DeviceAdapter> dispatcher(distribute);
dispatcher.Invoke(input, output);
return output;
}
private:
vtkm::cont::ArrayHandle<vtkm::IdComponent> OutCellsPerCell;
};
}

@ -49,8 +49,9 @@ public:
dataSet.GetCellSet(0).CopyTo(cellSet);
// Convert uniform hexahedra to tetrahedra
vtkm::worklet::Tetrahedralize<DeviceAdapter> tetrahedralize;
OutCellSetType outCellSet = tetrahedralize.Run(cellSet);
vtkm::worklet::Tetrahedralize tetrahedralize;
OutCellSetType outCellSet = tetrahedralize.Run(cellSet,
DeviceAdapter());
// Create the output dataset with same coordinate system
vtkm::cont::DataSet outDataSet;
@ -78,8 +79,9 @@ public:
vtkm::cont::ArrayHandle<vtkm::IdComponent> outCellsPerCell;
// Convert explicit cells to tetrahedra
vtkm::worklet::Tetrahedralize<DeviceAdapter> tetrahedralize;
OutCellSetType outCellSet = tetrahedralize.Run(cellSet, outCellsPerCell);
vtkm::worklet::Tetrahedralize tetrahedralize;
OutCellSetType outCellSet = tetrahedralize.Run(cellSet,
DeviceAdapter());
// Create the output dataset explicit cell set with same coordinate system
vtkm::cont::DataSet outDataSet;

@ -44,8 +44,9 @@ public:
dataSet.GetCellSet(0).CopyTo(cellSet);
// Convert uniform quadrilaterals to triangles
vtkm::worklet::Triangulate<DeviceAdapter> triangulate;
OutCellSetType outCellSet = triangulate.Run(cellSet);
vtkm::worklet::Triangulate triangulate;
OutCellSetType outCellSet = triangulate.Run(cellSet,
DeviceAdapter());
// Create the output dataset and assign the input coordinate system
vtkm::cont::DataSet outDataSet;
@ -70,8 +71,9 @@ public:
vtkm::cont::ArrayHandle<vtkm::IdComponent> outCellsPerCell;
// Convert explicit cells to triangles
vtkm::worklet::Triangulate<DeviceAdapter> triangulate;
OutCellSetType outCellSet = triangulate.Run(cellSet, outCellsPerCell);
vtkm::worklet::Triangulate triangulate;
OutCellSetType outCellSet = triangulate.Run(cellSet,
DeviceAdapter());
// Create the output dataset explicit cell set with same coordinate system
vtkm::cont::DataSet outDataSet;

@ -114,16 +114,23 @@ public:
};
template <typename CellSetType>
vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet)
vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent> &outCellsPerCell)
{
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter> DeviceAlgorithm;
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
vtkm::worklet::DispatcherMapTopology<TetrahedralizeCell,DeviceAdapter> dispatcher;
dispatcher.Invoke(cellSet,
vtkm::cont::make_ArrayHandleGroupVec<4>(connectivity));
// Fill in array of output cells per input cell
DeviceAlgorithm::Copy(
vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>(5, cellSet.GetNumberOfCells()),
outCellsPerCell);
// Add cells to output cellset
outCellSet.Fill(cellSet.GetNumberOfPoints(),
vtkm::CellShapeTagTetra::Id,

@ -92,16 +92,24 @@ public:
};
template <typename CellSetType>
vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet)
{
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
vtkm::cont::CellSetSingleType<> Run(const CellSetType &cellSet,
vtkm::cont::ArrayHandle<vtkm::IdComponent> &outCellsPerCell)
{
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter> DeviceAlgorithm;
vtkm::cont::CellSetSingleType<> outCellSet(cellSet.GetName());
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
vtkm::worklet::DispatcherMapTopology<TriangulateCell,DeviceAdapter> dispatcher;
dispatcher.Invoke(cellSet,
vtkm::cont::make_ArrayHandleGroupVec<3>(connectivity));
// Fill in array of output cells per input cell
DeviceAlgorithm::Copy(
vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>(2, cellSet.GetNumberOfCells()),
outCellsPerCell);
// Add cells to output cellset
outCellSet.Fill(
cellSet.GetNumberOfPoints(),