Merge topic 'improve-cellset-api'

a09bb9eca Add a new test for CellSet API
8868fb989 Improve CellSet API

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Kenneth Moreland <kmorel@sandia.gov>
Merge-request: !1589
This commit is contained in:
Sujin Philip 2019-03-22 16:52:21 +00:00 committed by Kitware Robot
commit 96f4a17e4f
8 changed files with 341 additions and 8 deletions

@ -68,6 +68,13 @@ public:
virtual vtkm::Id GetNumberOfPoints() const = 0;
virtual vtkm::UInt8 GetCellShape(vtkm::Id id) const = 0;
virtual vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id id) const = 0;
virtual void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const = 0;
virtual std::shared_ptr<CellSet> CreateNewInstance() const = 0;
virtual void DeepCopy(const CellSet* src) = 0;
virtual void PrintSummary(std::ostream&) const = 0;
virtual void ReleaseResourcesExecution() = 0;

@ -123,12 +123,16 @@ public:
void PrintSummary(std::ostream& out) const override;
void ReleaseResourcesExecution() override;
std::shared_ptr<CellSet> CreateNewInstance() const override;
void DeepCopy(const CellSet* src) override;
VTKM_CONT vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagCell) const;
VTKM_CONT vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagPoint) const;
VTKM_CONT vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id cellIndex) const;
VTKM_CONT vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id cellIndex) const override;
void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const override;
VTKM_CONT vtkm::UInt8 GetCellShape(vtkm::Id cellIndex) const;
VTKM_CONT vtkm::UInt8 GetCellShape(vtkm::Id cellIndex) const override;
template <vtkm::IdComponent ItemTupleLength>
VTKM_CONT void GetIndices(vtkm::Id index, vtkm::Vec<vtkm::Id, ItemTupleLength>& ids) const;

@ -182,6 +182,21 @@ vtkm::Id CellSetExplicit<ShapeStorageTag,
//----------------------------------------------------------------------------
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
void CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const
{
auto arrayWrapper = vtkm::cont::make_ArrayHandle(ptids, this->GetNumberOfPointsInCell(id));
this->GetIndices(id, arrayWrapper);
}
//----------------------------------------------------------------------------
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
@ -485,6 +500,45 @@ VTKM_CONT auto CellSetExplicit<ShapeStorageTag,
//----------------------------------------------------------------------------
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
std::shared_ptr<CellSet> CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::CreateNewInstance() const
{
return std::make_shared<CellSetExplicit>();
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
void CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::DeepCopy(const CellSet* src)
{
const auto* other = dynamic_cast<const CellSetExplicit*>(src);
if (!other)
{
throw vtkm::cont::ErrorBadType("CellSetExplicit::DeepCopy types don't match");
}
// TODO: implement actual deep-copy of the arrays
auto pt = vtkm::TopologyElementTagPoint{};
auto ct = vtkm::TopologyElementTagCell{};
this->Fill(other->GetNumberOfPoints(),
other->GetShapesArray(pt, ct),
other->GetNumIndicesArray(pt, ct),
other->GetConnectivityArray(pt, ct),
other->GetIndexOffsetArray(pt, ct));
}
//----------------------------------------------------------------------------
namespace detail
{

@ -213,14 +213,41 @@ public:
this->CellToPoint.ReleaseResourcesExecution();
}
VTKM_CONT
vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id cellIndex) const
vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id cellIndex) const override
{
return this->FullCellSet.GetNumberOfPointsInCell(
this->ValidCellIds.GetPortalConstControl().Get(cellIndex));
}
vtkm::UInt8 GetCellShape(vtkm::Id id) const override
{
return this->FullCellSet.GetCellShape(this->ValidCellIds.GetPortalConstControl().Get(id));
}
void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const override
{
return this->FullCellSet.GetCellPointIds(this->ValidCellIds.GetPortalConstControl().Get(id),
ptids);
}
std::shared_ptr<CellSet> CreateNewInstance() const override
{
return std::make_shared<CellSetPermutation>();
}
void DeepCopy(const CellSet* src) override
{
const auto* other = dynamic_cast<const CellSetPermutation*>(src);
if (!other)
{
throw vtkm::cont::ErrorBadType("CellSetPermutaion::DeepCopy types don't match");
}
this->FullCellSet.DeepCopy(&(other->GetFullCellSet()));
this->ValidCellIds = other->GetValidCellIds();
}
//This is the way you can fill the memory from another system without copying
VTKM_CONT
void Fill(const PermutationArrayHandleType& validCellIds, const OriginalCellSetType& cellset)
@ -366,6 +393,11 @@ public:
this->ValidCellIds = make_ArrayHandlePermutation(validCellIds, cellset.GetValidCellIds());
this->FullCellSet = cellset.GetFullCellSet();
}
std::shared_ptr<CellSet> CreateNewInstance() const
{
return std::make_shared<CellSetPermutation>();
}
};
template <typename OriginalCellSet, typename PermutationArrayHandleType>

@ -206,12 +206,32 @@ public:
vtkm::Id GetCellShapeAsId() const { return this->CellShapeAsId; }
VTKM_CONT
vtkm::UInt8 GetCellShape(vtkm::Id vtkmNotUsed(cellIndex)) const
vtkm::UInt8 GetCellShape(vtkm::Id vtkmNotUsed(cellIndex)) const override
{
return static_cast<vtkm::UInt8>(this->CellShapeAsId);
}
virtual void PrintSummary(std::ostream& out) const
VTKM_CONT
std::shared_ptr<CellSet> CreateNewInstance() const override
{
return std::make_shared<CellSetSingleType>();
}
VTKM_CONT
void DeepCopy(const CellSet* src) override
{
const auto* other = dynamic_cast<const CellSetSingleType*>(src);
if (!other)
{
throw vtkm::cont::ErrorBadType("CellSetSingleType::DeepCopy types don't match");
}
this->Superclass::DeepCopy(other);
this->CellShapeAsId = other->CellShapeAsId;
this->NumberOfPointsPerCell = other->NumberOfPointsPerCell;
}
virtual void PrintSummary(std::ostream& out) const override
{
out << " ExplicitSingleCellSet: " << this->Name << " Type " << this->CellShapeAsId
<< std::endl;

@ -87,12 +87,40 @@ public:
return this->Structure.GetGlobalPointIndexStart();
}
vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id vtkmNotUsed(cellIndex) = 0) const
vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id vtkmNotUsed(cellIndex) = 0) const override
{
return this->Structure.GetNumberOfPointsInCell();
}
vtkm::IdComponent GetCellShape() const { return this->Structure.GetCellShape(); }
vtkm::UInt8 GetCellShape(vtkm::Id vtkmNotUsed(cellIndex) = 0) const override
{
return static_cast<vtkm::UInt8>(this->Structure.GetCellShape());
}
void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const override
{
auto asVec = this->Structure.GetPointsOfCell(id);
for (vtkm::IdComponent i = 0; i < InternalsType::NUM_POINTS_IN_CELL; ++i)
{
ptids[i] = asVec[i];
}
}
std::shared_ptr<CellSet> CreateNewInstance() const override
{
return std::make_shared<CellSetStructured>();
}
void DeepCopy(const CellSet* src) override
{
const auto* other = dynamic_cast<const CellSetStructured*>(src);
if (!other)
{
throw vtkm::cont::ErrorBadType("CellSetStructured::DeepCopy types don't match");
}
this->Structure = other->Structure;
}
template <typename TopologyElement>
SchedulingRangeType GetSchedulingRange(TopologyElement) const;

@ -61,6 +61,7 @@ set(unit_tests
UnitTestVariantArrayHandle.cxx
UnitTestArrayPortalToIterators.cxx
UnitTestCellLocator.cxx
UnitTestCellSet.cxx
UnitTestCellSetExplicit.cxx
UnitTestCellSetPermutation.cxx
UnitTestContTesting.cxx

@ -0,0 +1,187 @@
//============================================================================
// 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.
//
// Copyright 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleImplicit.h>
#include <vtkm/cont/CellSet.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
constexpr vtkm::Id xdim = 3, ydim = 5, zdim = 7;
constexpr vtkm::Id3 BaseLinePointDimensions{ xdim, ydim, zdim };
constexpr vtkm::Id BaseLineNumberOfPoints = xdim * ydim * zdim;
constexpr vtkm::Id BaseLineNumberOfCells = (xdim - 1) * (ydim - 1) * (zdim - 1);
vtkm::cont::CellSetStructured<3> BaseLine{ "BaseLine" };
void InitializeBaseLine()
{
BaseLine.SetPointDimensions(BaseLinePointDimensions);
}
class BaseLineConnectivityFunctor
{
public:
explicit BaseLineConnectivityFunctor()
{
this->Structure.SetPointDimensions(BaseLinePointDimensions);
}
VTKM_EXEC_CONT
vtkm::Id operator()(vtkm::Id idx) const
{
auto i = idx / this->Structure.NUM_POINTS_IN_CELL;
auto c = static_cast<vtkm::IdComponent>(idx % this->Structure.NUM_POINTS_IN_CELL);
return this->Structure.GetPointsOfCell(i)[c];
}
private:
vtkm::internal::ConnectivityStructuredInternals<3> Structure;
};
using BaseLineConnectivityType = vtkm::cont::ArrayHandleImplicit<BaseLineConnectivityFunctor>;
BaseLineConnectivityType BaseLineConnectivity(BaseLineConnectivityFunctor{},
BaseLineNumberOfCells * 8);
auto PermutationArray = vtkm::cont::ArrayHandleCounting<vtkm::Id>(0, 2, BaseLineNumberOfCells / 2);
//-----------------------------------------------------------------------------
vtkm::cont::CellSetExplicit<> MakeCellSetExplicit()
{
vtkm::cont::ArrayHandle<vtkm::UInt8> shapes;
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleConstant<vtkm::UInt8>{ vtkm::CELL_SHAPE_HEXAHEDRON,
BaseLineNumberOfCells },
shapes);
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
vtkm::cont::ArrayCopy(
vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>{ 8, BaseLineNumberOfCells }, numIndices);
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
vtkm::cont::ArrayCopy(BaseLineConnectivity, connectivity);
vtkm::cont::CellSetExplicit<> cellset;
cellset.Fill(BaseLineNumberOfPoints, shapes, numIndices, connectivity);
return cellset;
}
vtkm::cont::CellSetSingleType<typename BaseLineConnectivityType::StorageTag> MakeCellSetSingleType()
{
vtkm::cont::CellSetSingleType<typename BaseLineConnectivityType::StorageTag> cellset;
cellset.Fill(BaseLineNumberOfPoints, vtkm::CELL_SHAPE_HEXAHEDRON, 8, BaseLineConnectivity);
return cellset;
}
vtkm::cont::CellSetStructured<3> MakeCellSetStructured()
{
vtkm::cont::CellSetStructured<3> cellset;
cellset.SetPointDimensions(BaseLinePointDimensions);
return cellset;
}
//-----------------------------------------------------------------------------
enum class IsPermutationCellSet
{
NO = 0,
YES = 1
};
void TestAgainstBaseLine(const vtkm::cont::CellSet& cellset,
IsPermutationCellSet flag = IsPermutationCellSet::NO)
{
vtkm::internal::ConnectivityStructuredInternals<3> baseLineStructure;
baseLineStructure.SetPointDimensions(BaseLinePointDimensions);
VTKM_TEST_ASSERT(cellset.GetNumberOfPoints() == BaseLineNumberOfPoints, "Wrong number of points");
vtkm::Id numCells = cellset.GetNumberOfCells();
vtkm::Id expectedNumCell = (flag == IsPermutationCellSet::NO)
? BaseLineNumberOfCells
: PermutationArray.GetNumberOfValues();
VTKM_TEST_ASSERT(numCells == expectedNumCell, "Wrong number of cells");
for (vtkm::Id i = 0; i < numCells; ++i)
{
VTKM_TEST_ASSERT(cellset.GetCellShape(i) == vtkm::CELL_SHAPE_HEXAHEDRON, "Wrong shape");
VTKM_TEST_ASSERT(cellset.GetNumberOfPointsInCell(i) == 8, "Wrong number of points-of-cell");
vtkm::Id baseLineCellId =
(flag == IsPermutationCellSet::YES) ? PermutationArray.GetPortalConstControl().Get(i) : i;
auto baseLinePointIds = baseLineStructure.GetPointsOfCell(baseLineCellId);
vtkm::Id pointIds[8];
cellset.GetCellPointIds(i, pointIds);
for (int j = 0; j < 8; ++j)
{
VTKM_TEST_ASSERT(pointIds[j] == baseLinePointIds[j], "Wrong points-of-cell point id");
}
}
}
void RunTests(const vtkm::cont::CellSet& cellset,
IsPermutationCellSet flag = IsPermutationCellSet::NO)
{
TestAgainstBaseLine(cellset, flag);
auto deepcopy = cellset.CreateNewInstance();
deepcopy->DeepCopy(&cellset);
TestAgainstBaseLine(*deepcopy, flag);
}
void TestCellSet()
{
InitializeBaseLine();
std::cout << "Testing CellSetExplicit\n";
auto csExplicit = MakeCellSetExplicit();
RunTests(csExplicit);
std::cout << "Testing CellSetPermutation of CellSetExplicit\n";
RunTests(vtkm::cont::make_CellSetPermutation(PermutationArray, csExplicit),
IsPermutationCellSet::YES);
std::cout << "Testing CellSetSingleType\n";
auto csSingle = MakeCellSetSingleType();
RunTests(csSingle);
std::cout << "Testing CellSetPermutation of CellSetSingleType\n";
RunTests(vtkm::cont::make_CellSetPermutation(PermutationArray, csSingle),
IsPermutationCellSet::YES);
std::cout << "Testing CellSetStructured\n";
auto csStructured = MakeCellSetStructured();
RunTests(csStructured);
std::cout << "Testing CellSetPermutation of CellSetStructured\n";
RunTests(vtkm::cont::make_CellSetPermutation(PermutationArray, csStructured),
IsPermutationCellSet::YES);
}
} // anonymous namespace
//-----------------------------------------------------------------------------
int UnitTestCellSet(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestCellSet, argc, argv);
}