mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Merge topic 'fix-475-support-sg-3d-scheduling'
e2c32ffac add unit test for WorkletMapTopology 0e90c22e7 Worklet{MapTopology,PointNeighbor} custom sg/mask Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Robert Maynard <robert.maynard@kitware.com> Merge-request: !1980
This commit is contained in:
commit
35276434bd
@ -53,6 +53,7 @@ public:
|
|||||||
//this->CellShape = connectivity.GetCellShape(index);
|
//this->CellShape = connectivity.GetCellShape(index);
|
||||||
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||||
VTKM_EXEC
|
VTKM_EXEC
|
||||||
ThreadIndicesTopologyMap(const vtkm::Id3& threadIndex3D,
|
ThreadIndicesTopologyMap(const vtkm::Id3& threadIndex3D,
|
||||||
@ -60,9 +61,7 @@ public:
|
|||||||
const ConnectivityType& connectivity,
|
const ConnectivityType& connectivity,
|
||||||
vtkm::Id globalThreadIndexOffset = 0)
|
vtkm::Id globalThreadIndexOffset = 0)
|
||||||
{
|
{
|
||||||
// We currently only support multidimensional indices on one-to-one input-
|
// This constructor handles multidimensional indices on one-to-one input-to-output
|
||||||
// to-output mappings. (We don't have a use case otherwise.)
|
|
||||||
// That is why we treat teh threadIndex as also the inputIndex and outputIndex
|
|
||||||
auto logicalIndex = detail::Deflate(threadIndex3D, LogicalIndexType());
|
auto logicalIndex = detail::Deflate(threadIndex3D, LogicalIndexType());
|
||||||
|
|
||||||
this->ThreadIndex = threadIndex1D;
|
this->ThreadIndex = threadIndex1D;
|
||||||
@ -75,6 +74,29 @@ public:
|
|||||||
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||||
|
VTKM_EXEC
|
||||||
|
ThreadIndicesTopologyMap(const vtkm::Id3& threadIndex3D,
|
||||||
|
vtkm::Id threadIndex1D,
|
||||||
|
vtkm::Id inputIndex,
|
||||||
|
vtkm::IdComponent visitIndex,
|
||||||
|
vtkm::Id outputIndex,
|
||||||
|
const ConnectivityType& connectivity,
|
||||||
|
vtkm::Id globalThreadIndexOffset = 0)
|
||||||
|
{
|
||||||
|
// This constructor handles multidimensional indices on many-to-many input-to-output
|
||||||
|
auto logicalIndex = detail::Deflate(threadIndex3D, LogicalIndexType());
|
||||||
|
|
||||||
|
this->ThreadIndex = threadIndex1D;
|
||||||
|
this->InputIndex = inputIndex;
|
||||||
|
this->OutputIndex = outputIndex;
|
||||||
|
this->VisitIndex = visitIndex;
|
||||||
|
this->LogicalIndex = logicalIndex;
|
||||||
|
this->IndicesIncident = connectivity.GetIndices(logicalIndex);
|
||||||
|
//this->CellShape = connectivity.GetCellShape(index);
|
||||||
|
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief The logical index into the input domain.
|
/// \brief The logical index into the input domain.
|
||||||
///
|
///
|
||||||
/// This is similar to \c GetIndex3D except the Vec size matches the actual
|
/// This is similar to \c GetIndex3D except the Vec size matches the actual
|
||||||
@ -159,7 +181,6 @@ private:
|
|||||||
vtkm::Id OutputIndex;
|
vtkm::Id OutputIndex;
|
||||||
LogicalIndexType LogicalIndex;
|
LogicalIndexType LogicalIndex;
|
||||||
IndicesIncidentType IndicesIncident;
|
IndicesIncidentType IndicesIncident;
|
||||||
//CellShapeTag CellShape;
|
|
||||||
vtkm::Id GlobalThreadIndexOffset;
|
vtkm::Id GlobalThreadIndexOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,7 +213,6 @@ public:
|
|||||||
this->VisitIndex = 0;
|
this->VisitIndex = 0;
|
||||||
this->LogicalIndex = logicalIndex;
|
this->LogicalIndex = logicalIndex;
|
||||||
this->IndicesIncident = connectivity.GetIndices(logicalIndex);
|
this->IndicesIncident = connectivity.GetIndices(logicalIndex);
|
||||||
//this->CellShape = connectivity.GetCellShape(index);
|
|
||||||
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,9 +230,29 @@ public:
|
|||||||
this->VisitIndex = 0;
|
this->VisitIndex = 0;
|
||||||
this->LogicalIndex = logicalIndex;
|
this->LogicalIndex = logicalIndex;
|
||||||
this->IndicesIncident = connectivity.GetIndices(logicalIndex);
|
this->IndicesIncident = connectivity.GetIndices(logicalIndex);
|
||||||
//this->CellShape = connectivity.GetCellShape(index);
|
|
||||||
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThreadIndicesTopologyMap(const vtkm::Id3& threadIndex3D,
|
||||||
|
vtkm::Id threadIndex1D,
|
||||||
|
vtkm::Id inputIndex,
|
||||||
|
vtkm::IdComponent visitIndex,
|
||||||
|
vtkm::Id outputIndex,
|
||||||
|
const ConnectivityType& connectivity,
|
||||||
|
vtkm::Id globalThreadIndexOffset = 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
const LogicalIndexType logicalIndex = detail::Deflate(threadIndex3D, LogicalIndexType());
|
||||||
|
|
||||||
|
this->ThreadIndex = threadIndex1D;
|
||||||
|
this->InputIndex = inputIndex;
|
||||||
|
this->OutputIndex = outputIndex;
|
||||||
|
this->VisitIndex = visitIndex;
|
||||||
|
this->LogicalIndex = logicalIndex;
|
||||||
|
this->IndicesIncident = connectivity.GetIndices(logicalIndex);
|
||||||
|
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief The logical index into the input domain.
|
/// \brief The logical index into the input domain.
|
||||||
///
|
///
|
||||||
/// This is similar to \c GetIndex3D except the Vec size matches the actual
|
/// This is similar to \c GetIndex3D except the Vec size matches the actual
|
||||||
@ -297,7 +337,6 @@ private:
|
|||||||
vtkm::Id OutputIndex;
|
vtkm::Id OutputIndex;
|
||||||
LogicalIndexType LogicalIndex;
|
LogicalIndexType LogicalIndex;
|
||||||
IndicesIncidentType IndicesIncident;
|
IndicesIncidentType IndicesIncident;
|
||||||
//CellShapeTag CellShape;
|
|
||||||
vtkm::Id GlobalThreadIndexOffset;
|
vtkm::Id GlobalThreadIndexOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -72,6 +72,26 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <vtkm::IdComponent Dimension>
|
||||||
|
VTKM_EXEC ThreadIndicesPointNeighborhood(
|
||||||
|
const vtkm::Id3& threadIndex3D,
|
||||||
|
vtkm::Id threadIndex1D,
|
||||||
|
vtkm::Id inputIndex,
|
||||||
|
vtkm::IdComponent visitIndex,
|
||||||
|
vtkm::Id outputIndex,
|
||||||
|
const vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagPoint,
|
||||||
|
vtkm::TopologyElementTagCell,
|
||||||
|
Dimension>& connectivity,
|
||||||
|
vtkm::Id globalThreadIndexOffset = 0)
|
||||||
|
: State(threadIndex3D, detail::To3D(connectivity.GetPointDimensions()))
|
||||||
|
, ThreadIndex(threadIndex1D)
|
||||||
|
, InputIndex(inputIndex)
|
||||||
|
, OutputIndex(outputIndex)
|
||||||
|
, VisitIndex(visitIndex)
|
||||||
|
, GlobalThreadIndexOffset(globalThreadIndexOffset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <vtkm::IdComponent Dimension>
|
template <vtkm::IdComponent Dimension>
|
||||||
VTKM_EXEC ThreadIndicesPointNeighborhood(
|
VTKM_EXEC ThreadIndicesPointNeighborhood(
|
||||||
vtkm::Id threadIndex,
|
vtkm::Id threadIndex,
|
||||||
|
@ -179,9 +179,7 @@ public:
|
|||||||
const ConnectivityType& connectivity,
|
const ConnectivityType& connectivity,
|
||||||
const vtkm::Id globalThreadIndexOffset = 0)
|
const vtkm::Id globalThreadIndexOffset = 0)
|
||||||
{
|
{
|
||||||
// We currently only support multidimensional indices on one-to-one input-
|
// This constructor handles multidimensional indices on one-to-one input-to-output
|
||||||
// to-output mappings. (We don't have a use case otherwise.)
|
|
||||||
// That is why we treat teh threadIndex as also the inputIndex and outputIndex
|
|
||||||
auto logicalIndex = detail::Deflate(threadIndex3D, LogicalIndexType());
|
auto logicalIndex = detail::Deflate(threadIndex3D, LogicalIndexType());
|
||||||
this->ThreadIndex = threadIndex1D;
|
this->ThreadIndex = threadIndex1D;
|
||||||
this->InputIndex = threadIndex1D;
|
this->InputIndex = threadIndex1D;
|
||||||
@ -193,6 +191,26 @@ public:
|
|||||||
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC ThreadIndicesTopologyMap(const vtkm::Id3& threadIndex3D,
|
||||||
|
vtkm::Id threadIndex1D,
|
||||||
|
vtkm::Id inIndex,
|
||||||
|
vtkm::IdComponent visitIndex,
|
||||||
|
vtkm::Id outIndex,
|
||||||
|
const ConnectivityType& connectivity,
|
||||||
|
const vtkm::Id globalThreadIndexOffset = 0)
|
||||||
|
{
|
||||||
|
// This constructor handles multidimensional indices on many-to-many input-to-output
|
||||||
|
auto logicalIndex = detail::Deflate(threadIndex3D, LogicalIndexType());
|
||||||
|
this->ThreadIndex = threadIndex1D;
|
||||||
|
this->InputIndex = inIndex;
|
||||||
|
this->VisitIndex = visitIndex;
|
||||||
|
this->OutputIndex = outIndex;
|
||||||
|
this->LogicalIndex = logicalIndex;
|
||||||
|
this->IndicesIncident = connectivity.GetIndices(logicalIndex);
|
||||||
|
this->CellShape = connectivity.GetCellShape(threadIndex1D);
|
||||||
|
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief The index of the thread or work invocation.
|
/// \brief The index of the thread or work invocation.
|
||||||
///
|
///
|
||||||
/// This index refers to which instance of the worklet is being invoked. Every invocation of the
|
/// This index refers to which instance of the worklet is being invoked. Every invocation of the
|
||||||
|
@ -179,30 +179,68 @@ public:
|
|||||||
globalThreadIndexOffset);
|
globalThreadIndexOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// In the remaining methods and `constexpr` we determine at compilation time
|
||||||
|
/// which method definition will be actually used for GetThreadIndices.
|
||||||
|
///
|
||||||
|
/// We want to avoid further function calls when we use WorkletMapTopology in which
|
||||||
|
/// ScatterType is set as ScatterIdentity and MaskType as MaskNone.
|
||||||
|
/// Otherwise, we call the default method defined at the bottom of this class.
|
||||||
|
private:
|
||||||
|
static constexpr bool IsScatterIdentity =
|
||||||
|
std::is_same<ScatterType, vtkm::worklet::ScatterIdentity>::value;
|
||||||
|
static constexpr bool IsMaskNone = std::is_same<MaskType, vtkm::worklet::MaskNone>::value;
|
||||||
|
|
||||||
|
template <bool Cond, typename ReturnType>
|
||||||
|
using EnableFnWhen = typename std::enable_if<Cond, ReturnType>::type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Optimized for ScatterIdentity and MaskNone
|
||||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||||
template <typename OutToInArrayType,
|
template <typename OutToInArrayType,
|
||||||
typename VisitArrayType,
|
typename VisitArrayType,
|
||||||
typename ThreadToOutArrayType,
|
typename ThreadToOutArrayType,
|
||||||
typename InputDomainType>
|
typename InputDomainType,
|
||||||
VTKM_EXEC vtkm::exec::arg::ThreadIndicesTopologyMap<InputDomainType> GetThreadIndices(
|
bool S = IsScatterIdentity,
|
||||||
vtkm::Id threadIndex1D,
|
bool M = IsMaskNone>
|
||||||
const vtkm::Id3& threadIndex3D,
|
VTKM_EXEC EnableFnWhen<S && M, vtkm::exec::arg::ThreadIndicesTopologyMap<InputDomainType>>
|
||||||
const OutToInArrayType& vtkmNotUsed(outToIn),
|
GetThreadIndices(vtkm::Id threadIndex1D,
|
||||||
const VisitArrayType& vtkmNotUsed(visit),
|
const vtkm::Id3& threadIndex3D,
|
||||||
const ThreadToOutArrayType& vtkmNotUsed(threadToOut),
|
const OutToInArrayType& vtkmNotUsed(outToIn),
|
||||||
const InputDomainType& connectivity,
|
const VisitArrayType& vtkmNotUsed(visit),
|
||||||
vtkm::Id globalThreadIndexOffset = 0) const
|
const ThreadToOutArrayType& vtkmNotUsed(threadToOut),
|
||||||
|
const InputDomainType& connectivity,
|
||||||
|
vtkm::Id globalThreadIndexOffset = 0) const
|
||||||
{
|
{
|
||||||
using ScatterCheck = std::is_same<ScatterType, vtkm::worklet::ScatterIdentity>;
|
|
||||||
VTKM_STATIC_ASSERT_MSG(ScatterCheck::value,
|
|
||||||
"Scheduling on 3D topologies only works with default ScatterIdentity.");
|
|
||||||
using MaskCheck = std::is_same<MaskType, vtkm::worklet::MaskNone>;
|
|
||||||
VTKM_STATIC_ASSERT_MSG(MaskCheck::value,
|
|
||||||
"Scheduling on 3D topologies only works with default MaskNone.");
|
|
||||||
|
|
||||||
return vtkm::exec::arg::ThreadIndicesTopologyMap<InputDomainType>(
|
return vtkm::exec::arg::ThreadIndicesTopologyMap<InputDomainType>(
|
||||||
threadIndex3D, threadIndex1D, connectivity, globalThreadIndexOffset);
|
threadIndex3D, threadIndex1D, connectivity, globalThreadIndexOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Default version
|
||||||
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||||
|
template <typename OutToInArrayType,
|
||||||
|
typename VisitArrayType,
|
||||||
|
typename ThreadToOutArrayType,
|
||||||
|
typename InputDomainType,
|
||||||
|
bool S = IsScatterIdentity,
|
||||||
|
bool M = IsMaskNone>
|
||||||
|
VTKM_EXEC EnableFnWhen<!(S && M), vtkm::exec::arg::ThreadIndicesTopologyMap<InputDomainType>>
|
||||||
|
GetThreadIndices(vtkm::Id threadIndex1D,
|
||||||
|
const vtkm::Id3& threadIndex3D,
|
||||||
|
const OutToInArrayType& outToIn,
|
||||||
|
const VisitArrayType& visit,
|
||||||
|
const ThreadToOutArrayType& threadToOut,
|
||||||
|
const InputDomainType& connectivity,
|
||||||
|
vtkm::Id globalThreadIndexOffset = 0) const
|
||||||
|
{
|
||||||
|
const vtkm::Id outIndex = threadToOut.Get(threadIndex1D);
|
||||||
|
return vtkm::exec::arg::ThreadIndicesTopologyMap<InputDomainType>(threadIndex3D,
|
||||||
|
threadIndex1D,
|
||||||
|
outToIn.Get(outIndex),
|
||||||
|
visit.Get(outIndex),
|
||||||
|
outIndex,
|
||||||
|
connectivity,
|
||||||
|
globalThreadIndexOffset);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Base class for worklets that map from Points to Cells.
|
/// Base class for worklets that map from Points to Cells.
|
||||||
|
@ -197,12 +197,30 @@ public:
|
|||||||
globalThreadIndexOffset);
|
globalThreadIndexOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// In the remaining methods and `constexpr` we determine at compilation time
|
||||||
|
/// which method definition will be actually used for GetThreadIndices.
|
||||||
|
///
|
||||||
|
/// We want to avoid further function calls when we use WorkletMapTopology in which
|
||||||
|
/// ScatterType is set as ScatterIdentity and MaskType as MaskNone.
|
||||||
|
/// Otherwise, we call the default method defined at the bottom of this class.
|
||||||
|
private:
|
||||||
|
static constexpr bool IsScatterIdentity =
|
||||||
|
std::is_same<ScatterType, vtkm::worklet::ScatterIdentity>::value;
|
||||||
|
static constexpr bool IsMaskNone = std::is_same<MaskType, vtkm::worklet::MaskNone>::value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <bool Cond, typename ReturnType>
|
||||||
|
using EnableFnWhen = typename std::enable_if<Cond, ReturnType>::type;
|
||||||
|
|
||||||
VTKM_SUPPRESS_EXEC_WARNINGS
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||||
template <typename OutToInArrayType,
|
template <typename OutToInArrayType,
|
||||||
typename VisitArrayType,
|
typename VisitArrayType,
|
||||||
typename ThreadToOutArrayType,
|
typename ThreadToOutArrayType,
|
||||||
typename InputDomainType>
|
typename InputDomainType,
|
||||||
VTKM_EXEC vtkm::exec::arg::ThreadIndicesPointNeighborhood GetThreadIndices(
|
bool S = IsScatterIdentity,
|
||||||
|
bool M = IsMaskNone>
|
||||||
|
VTKM_EXEC EnableFnWhen<S && M, vtkm::exec::arg::ThreadIndicesPointNeighborhood> GetThreadIndices(
|
||||||
vtkm::Id threadIndex1D,
|
vtkm::Id threadIndex1D,
|
||||||
const vtkm::Id3& threadIndex3D,
|
const vtkm::Id3& threadIndex3D,
|
||||||
const OutToInArrayType& vtkmNotUsed(outToIn),
|
const OutToInArrayType& vtkmNotUsed(outToIn),
|
||||||
@ -211,16 +229,35 @@ public:
|
|||||||
const InputDomainType& connectivity,
|
const InputDomainType& connectivity,
|
||||||
vtkm::Id globalThreadIndexOffset = 0) const
|
vtkm::Id globalThreadIndexOffset = 0) const
|
||||||
{
|
{
|
||||||
using ScatterCheck = std::is_same<ScatterType, vtkm::worklet::ScatterIdentity>;
|
|
||||||
VTKM_STATIC_ASSERT_MSG(ScatterCheck::value,
|
|
||||||
"Scheduling on 3D topologies only works with default ScatterIdentity.");
|
|
||||||
using MaskCheck = std::is_same<MaskType, vtkm::worklet::MaskNone>;
|
|
||||||
VTKM_STATIC_ASSERT_MSG(MaskCheck::value,
|
|
||||||
"Scheduling on 3D topologies only works with default MaskNone.");
|
|
||||||
|
|
||||||
return vtkm::exec::arg::ThreadIndicesPointNeighborhood(
|
return vtkm::exec::arg::ThreadIndicesPointNeighborhood(
|
||||||
threadIndex3D, threadIndex1D, connectivity, globalThreadIndexOffset);
|
threadIndex3D, threadIndex1D, connectivity, globalThreadIndexOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VTKM_SUPPRESS_EXEC_WARNINGS
|
||||||
|
template <typename OutToInArrayType,
|
||||||
|
typename VisitArrayType,
|
||||||
|
typename ThreadToOutArrayType,
|
||||||
|
typename InputDomainType,
|
||||||
|
bool S = IsScatterIdentity,
|
||||||
|
bool M = IsMaskNone>
|
||||||
|
VTKM_EXEC EnableFnWhen<!(S && M), vtkm::exec::arg::ThreadIndicesPointNeighborhood>
|
||||||
|
GetThreadIndices(vtkm::Id threadIndex1D,
|
||||||
|
const vtkm::Id3& threadIndex3D,
|
||||||
|
const OutToInArrayType& outToIn,
|
||||||
|
const VisitArrayType& visit,
|
||||||
|
const ThreadToOutArrayType& threadToOut,
|
||||||
|
const InputDomainType& connectivity,
|
||||||
|
vtkm::Id globalThreadIndexOffset = 0) const
|
||||||
|
{
|
||||||
|
const vtkm::Id outIndex = threadToOut.Get(threadIndex1D);
|
||||||
|
return vtkm::exec::arg::ThreadIndicesPointNeighborhood(threadIndex3D,
|
||||||
|
threadIndex1D,
|
||||||
|
outToIn.Get(outIndex),
|
||||||
|
visit.Get(outIndex),
|
||||||
|
outIndex,
|
||||||
|
connectivity,
|
||||||
|
globalThreadIndexOffset);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ set(unit_tests
|
|||||||
UnitTestScatterPermutation.cxx
|
UnitTestScatterPermutation.cxx
|
||||||
UnitTestSplatKernels.cxx
|
UnitTestSplatKernels.cxx
|
||||||
UnitTestSplitSharpEdges.cxx
|
UnitTestSplitSharpEdges.cxx
|
||||||
|
UnitTestScatterAndMaskWithTopology.cxx
|
||||||
UnitTestStreamingSine.cxx
|
UnitTestStreamingSine.cxx
|
||||||
UnitTestStreamLineUniformGrid.cxx
|
UnitTestStreamLineUniformGrid.cxx
|
||||||
UnitTestStreamSurface.cxx
|
UnitTestStreamSurface.cxx
|
||||||
|
211
vtkm/worklet/testing/UnitTestScatterAndMaskWithTopology.cxx
Normal file
211
vtkm/worklet/testing/UnitTestScatterAndMaskWithTopology.cxx
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
//============================================================================
|
||||||
|
// Copyright (c) Kitware, Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
// See LICENSE.txt for details.
|
||||||
|
//
|
||||||
|
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||||
|
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||||
|
// PURPOSE. See the above copyright notice for more information.
|
||||||
|
//============================================================================
|
||||||
|
#include <vtkm/cont/ArrayCopy.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/testing/MakeTestDataSet.h>
|
||||||
|
#include <vtkm/worklet/DispatcherMapTopology.h>
|
||||||
|
#include <vtkm/worklet/ScatterCounting.h>
|
||||||
|
#include <vtkm/worklet/WorkletMapTopology.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
#include <vtkm/worklet/MaskSelect.h>
|
||||||
|
#include <vtkm/worklet/ScatterUniform.h>
|
||||||
|
|
||||||
|
namespace maptopology3d
|
||||||
|
{
|
||||||
|
|
||||||
|
class TestWorkletMapTopo : public vtkm::worklet::WorkletVisitPointsWithCells
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using ControlSignature = void(CellSetIn topology, FieldInVisit pointCoords);
|
||||||
|
using ExecutionSignature = void(_2, WorkIndex, InputIndex, OutputIndex, VisitIndex);
|
||||||
|
|
||||||
|
virtual VTKM_EXEC void operator()(const vtkm::Vec<int, 3>& vtkmNotUsed(coords),
|
||||||
|
const vtkm::Id& workIndex,
|
||||||
|
const vtkm::Id& inputIndex,
|
||||||
|
const vtkm::Id& outputIndex,
|
||||||
|
const vtkm::Id& visitIndex) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TestWorkletMapTopoIdentity : public TestWorkletMapTopo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using ScatterType = vtkm::worklet::ScatterIdentity;
|
||||||
|
|
||||||
|
VTKM_EXEC void operator()(const vtkm::Vec<int, 3>& vtkmNotUsed(coords),
|
||||||
|
const vtkm::Id& workIndex,
|
||||||
|
const vtkm::Id& inputIndex,
|
||||||
|
const vtkm::Id& outputIndex,
|
||||||
|
const vtkm::Id& visitIndex) const override
|
||||||
|
{
|
||||||
|
if (workIndex != inputIndex)
|
||||||
|
{
|
||||||
|
this->RaiseError("Got wrong input value.");
|
||||||
|
}
|
||||||
|
if (outputIndex != workIndex)
|
||||||
|
{
|
||||||
|
this->RaiseError("Got work and output index don't match.");
|
||||||
|
}
|
||||||
|
if (visitIndex != 0)
|
||||||
|
{
|
||||||
|
this->RaiseError("Got wrong visit value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TestWorkletMapTopoUniform : public TestWorkletMapTopo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using ScatterType = vtkm::worklet::ScatterUniform<2>;
|
||||||
|
|
||||||
|
VTKM_EXEC void operator()(const vtkm::Vec<int, 3>& vtkmNotUsed(coords),
|
||||||
|
const vtkm::Id& workIndex,
|
||||||
|
const vtkm::Id& inputIndex,
|
||||||
|
const vtkm::Id& outputIndex,
|
||||||
|
const vtkm::Id& visitIndex) const override
|
||||||
|
{
|
||||||
|
if ((workIndex / 2) != inputIndex)
|
||||||
|
{
|
||||||
|
this->RaiseError("Got wrong input value.");
|
||||||
|
}
|
||||||
|
if (outputIndex != workIndex)
|
||||||
|
{
|
||||||
|
this->RaiseError("Got work and output index don't match.");
|
||||||
|
}
|
||||||
|
if ((workIndex % 2) != visitIndex)
|
||||||
|
{
|
||||||
|
this->RaiseError("Got wrong visit value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TestWorkletMapTopoNone : public TestWorkletMapTopo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using MaskType = vtkm::worklet::MaskNone;
|
||||||
|
|
||||||
|
VTKM_EXEC void operator()(const vtkm::Vec<int, 3>& vtkmNotUsed(coords),
|
||||||
|
const vtkm::Id& workIndex,
|
||||||
|
const vtkm::Id& inputIndex,
|
||||||
|
const vtkm::Id& outputIndex,
|
||||||
|
const vtkm::Id& visitIndex) const override
|
||||||
|
{
|
||||||
|
if (workIndex != inputIndex)
|
||||||
|
{
|
||||||
|
this->RaiseError("Got wrong input value.");
|
||||||
|
}
|
||||||
|
if (outputIndex != workIndex)
|
||||||
|
{
|
||||||
|
this->RaiseError("Got work and output index don't match.");
|
||||||
|
}
|
||||||
|
if (visitIndex != 0)
|
||||||
|
{
|
||||||
|
this->RaiseError("Got wrong visit value.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TestWorkletMapTopoSelect : public TestWorkletMapTopo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using MaskType = vtkm::worklet::MaskSelect;
|
||||||
|
|
||||||
|
VTKM_EXEC void operator()(const vtkm::Vec<int, 3>& vtkmNotUsed(coords),
|
||||||
|
const vtkm::Id& vtkmNotUsed(workIndex),
|
||||||
|
const vtkm::Id& vtkmNotUsed(inputIndex),
|
||||||
|
const vtkm::Id& vtkmNotUsed(outputIndex),
|
||||||
|
const vtkm::Id& vtkmNotUsed(visitIndex)) const override
|
||||||
|
{
|
||||||
|
// This method should never be called
|
||||||
|
this->RaiseError("An element was selected, this test selects none.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename WorkletType>
|
||||||
|
struct DoTestWorklet
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
VTKM_CONT void operator()(T) const
|
||||||
|
{
|
||||||
|
vtkm::cont::testing::MakeTestDataSet testDataSet;
|
||||||
|
vtkm::cont::DataSet dataSet3D = testDataSet.Make3DUniformDataSet0();
|
||||||
|
|
||||||
|
vtkm::cont::CellSetStructured<3> cellSet =
|
||||||
|
dataSet3D.GetCellSet().Cast<vtkm::cont::CellSetStructured<3>>();
|
||||||
|
|
||||||
|
vtkm::cont::Invoker invoker;
|
||||||
|
invoker(WorkletType{}, cellSet, dataSet3D.GetCoordinateSystem());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct DoTestWorklet<TestWorkletMapTopoSelect>
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
VTKM_CONT void operator()(T) const
|
||||||
|
{
|
||||||
|
// 18 are the number of vertices at the DataSet created by Make3DUniformDataSet0
|
||||||
|
const vtkm::Id selectArraySize = 18;
|
||||||
|
const vtkm::IdComponent selectArray[selectArraySize] = { 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
auto selectArrayHandle = vtkm::cont::make_ArrayHandle(selectArray, selectArraySize);
|
||||||
|
|
||||||
|
vtkm::cont::testing::MakeTestDataSet testDataSet;
|
||||||
|
vtkm::cont::DataSet dataSet3D = testDataSet.Make3DUniformDataSet0();
|
||||||
|
|
||||||
|
vtkm::cont::CellSetStructured<3> cellSet =
|
||||||
|
dataSet3D.GetCellSet().Cast<vtkm::cont::CellSetStructured<3>>();
|
||||||
|
|
||||||
|
vtkm::cont::Invoker invoker;
|
||||||
|
invoker(TestWorkletMapTopoSelect{},
|
||||||
|
vtkm::worklet::MaskSelect(selectArrayHandle),
|
||||||
|
cellSet,
|
||||||
|
dataSet3D.GetCoordinateSystem());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void TestWorkletMapField3d(vtkm::cont::DeviceAdapterId id)
|
||||||
|
{
|
||||||
|
using HandleTypesToTest3D =
|
||||||
|
vtkm::List<vtkm::Id, vtkm::Vec2i_32, vtkm::FloatDefault, vtkm::Vec3f_64>;
|
||||||
|
|
||||||
|
std::cout << "Testing WorkletMapTopology with ScatterIdentity on device adapter: " << id.GetName()
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
vtkm::testing::Testing::TryTypes(maptopology3d::DoTestWorklet<TestWorkletMapTopoIdentity>(),
|
||||||
|
HandleTypesToTest3D());
|
||||||
|
|
||||||
|
std::cout << "Testing WorkletMapTopology with ScatterUniform on device adapter: " << id.GetName()
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
vtkm::testing::Testing::TryTypes(maptopology3d::DoTestWorklet<TestWorkletMapTopoUniform>(),
|
||||||
|
HandleTypesToTest3D());
|
||||||
|
|
||||||
|
std::cout << "Testing WorkletMapTopology with MaskNone on device adapter: " << id.GetName()
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
vtkm::testing::Testing::TryTypes(maptopology3d::DoTestWorklet<TestWorkletMapTopoNone>(),
|
||||||
|
HandleTypesToTest3D());
|
||||||
|
|
||||||
|
std::cout << "Testing WorkletMapTopology with MaskSelect on device adapter: " << id.GetName()
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
vtkm::testing::Testing::TryTypes(maptopology3d::DoTestWorklet<TestWorkletMapTopoSelect>(),
|
||||||
|
HandleTypesToTest3D());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // maptopology3d namespace
|
||||||
|
|
||||||
|
int UnitTestScatterAndMaskWithTopology(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
return vtkm::cont::testing::Testing::RunOnDevice(
|
||||||
|
maptopology3d::TestWorkletMapField3d, argc, argv);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user