Refactor CellSetExplicit to remove NumIndices.

See #408 for details.
This commit is contained in:
Allison Vacanti 2019-08-30 13:04:17 -04:00
parent b2daec0e35
commit 3886b7dfb8
36 changed files with 1019 additions and 1112 deletions

@ -646,11 +646,11 @@ class BenchmarkFilters
}
}
template <typename T1, typename T2, typename T3, typename T4>
VTKM_CONT void operator()(const vtkm::cont::CellSetExplicit<T1, T2, T3, T4>& cellSet) const
template <typename T1, typename T2, typename T3>
VTKM_CONT void operator()(const vtkm::cont::CellSetExplicit<T1, T2, T3>& cellSet) const
{
{ // Why does CastAndCall insist on making the cellset const?
using CellSetT = vtkm::cont::CellSetExplicit<T1, T2, T3, T4>;
using CellSetT = vtkm::cont::CellSetExplicit<T1, T2, T3>;
CellSetT& mcellSet = const_cast<CellSetT&>(cellSet);
mcellSet.ResetConnectivity(vtkm::TopologyElementTagPoint{},
vtkm::TopologyElementTagCell{});

@ -0,0 +1,70 @@
# `CellSetExplicit` Refactoring
The `CellSetExplicit` class has been refactored to remove the `NumIndices`
array. This information is now derived from the `Offsets` array, which has
been changed to contain `[numCells + 1]` entries.
```
Old Layout:
-----------
NumIndices: [ 2, 4, 3, 3, 2 ]
IndexOffset: [ 0, 2, 6, 9, 12 ]
Connectivity: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
New Layout:
-----------
Offsets: [ 0, 2, 6, 9, 12, 14 ]
Connectivity: [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
```
This will reduce the memory overhead of the cellset by roughly `[numCells * 4]`
bytes.
The `IndexOffset` array / typedefs / methods have been renamed to `Offsets` for
brevity and consistency (similar members were plural, e.g. `Shapes`).
The `NumIndices` array can be recovered from the `Offsets` array by using an
`ArrayHandleDecorator`. This is done automatically by the
`CellSetExplicit::GetNumIndicesArray` method.
The `CellSetExplicit::Fill` signature has changed to remove `numIndices` as a
parameter and to require the `offsets` array as a non-optional argument. To
assist in porting old code, an `offsets` array can be generated from
`numIndices` using the new `vtkm::cont::ConvertNumIndicesToOffsets` methods,
defined in `CellSetExplicit.h`.
```
vtkm::Id numPoints = ...;
auto cellShapes = ...;
auto numIndices = ...;
auto connectivity = ...;
vtkm::cont::CellSetExplicit<> cellSet = ...;
// Old:
cellSet.Fill(numPoints, cellShapes, numIndices, connectivity);
// New:
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices);
cellSet.Fill(numPoints, cellShapes, connectivity, offsets);
```
Since the `offsets` array now contains an additional offset at the end, it
cannot be used directly with `ArrayHandleGroupVecVariable` with the cellset's
`connectivity` array to create an array handle containing cell definitions.
This now requires an `ArrayHandleView` to trim the last value off of the array:
```
vtkm::cont::CellSetExplicit<> cellSet = ...;
auto offsets = cellSet.GetOffsetsArray(vtkm::TopologyElementTagCell{},
vtkm::TopologyElementTagPoint{});
auto conn = cellSet.GetConnectivityArray(vtkm::TopologyElementTagCell{},
vtkm::TopologyElementTagPoint{});
// Old:
auto cells = vtkm::cont::make_ArrayHandleGroupVecVariable(conn, offsets);
// New:
const vtkm::Id numCells = offsets.GetNumberOfValues - 1;
auto offsetsTrim = vtkm::cont::make_ArrayHandleView(offsets, 0, numCells);
auto cells = vtkm::cont::make_ArrayHandleGroupVecVariable(conn, offsetsTrim);
```

@ -29,7 +29,7 @@ template <vtkm::IdComponent>
class CellSetStructured;
template <typename T>
class CellSetSingleType;
template <typename T, typename S, typename U, typename V>
template <typename T, typename S, typename U>
class CellSetExplicit;
template <typename T, typename S>
class CellSetPermutation;
@ -88,10 +88,8 @@ void CastAndCall(const vtkm::cont::CellSetSingleType<ConnectivityStorageTag>& ce
/// A specialization of CastAndCall for basic CellSetExplicit types,
/// Since the type is already known no deduction is needed.
/// This specialization is used to simplify numerous worklet algorithms
template <typename T, typename S, typename U, typename V, typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::CellSetExplicit<T, S, U, V>& cellset,
Functor&& f,
Args&&... args)
template <typename T, typename S, typename U, typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::CellSetExplicit<T, S, U>& cellset, Functor&& f, Args&&... args)
{
f(cellset, std::forward<Args>(args)...);
}

@ -19,7 +19,6 @@ namespace cont
template class VTKM_CONT_EXPORT CellSetExplicit<>; // default
template class VTKM_CONT_EXPORT
CellSetExplicit<typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag,
typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag,
VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>;
}

@ -12,8 +12,11 @@
#include <vtkm/CellShape.h>
#include <vtkm/TopologyElementTag.h>
#include <vtkm/cont/ArrayGetValues.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleDecorator.h>
#include <vtkm/cont/CellSet.h>
#include <vtkm/cont/internal/ConnectivityExplicitInternals.h>
#include <vtkm/exec/ConnectivityExplicit.h>
@ -34,14 +37,35 @@ struct CellSetExplicitConnectivityChooser
using ConnectivityType = vtkm::cont::internal::ConnectivityExplicitInternals<>;
};
// Used with ArrayHandleDecorator to recover the NumIndices array from the
// offsets.
struct NumIndicesDecorator
{
template <typename OffsetsPortal>
struct Functor
{
OffsetsPortal Offsets;
VTKM_EXEC_CONT
vtkm::IdComponent operator()(vtkm::Id cellId) const
{
return static_cast<vtkm::IdComponent>(this->Offsets.Get(cellId + 1) -
this->Offsets.Get(cellId));
}
};
template <typename OffsetsPortal>
static VTKM_CONT Functor<typename std::decay<OffsetsPortal>::type> CreateFunctor(
OffsetsPortal&& portal)
{
return { std::forward<OffsetsPortal>(portal) };
}
};
} // namespace detail
#ifndef VTKM_DEFAULT_SHAPE_STORAGE_TAG
#define VTKM_DEFAULT_SHAPE_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
#endif
#ifndef VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG
#define VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
#ifndef VTKM_DEFAULT_SHAPES_STORAGE_TAG
#define VTKM_DEFAULT_SHAPES_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
#endif
#ifndef VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG
@ -52,51 +76,89 @@ struct CellSetExplicitConnectivityChooser
#define VTKM_DEFAULT_OFFSETS_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
#endif
template <typename ShapeStorageTag = VTKM_DEFAULT_SHAPE_STORAGE_TAG,
typename NumIndicesStorageTag = VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG,
template <typename S1, typename S2>
void ConvertNumIndicesToOffsets(const vtkm::cont::ArrayHandle<vtkm::Id, S1>& numIndices,
vtkm::cont::ArrayHandle<vtkm::Id, S2>& offsets)
{
vtkm::cont::Algorithm::ScanExtended(numIndices, offsets);
}
template <typename T, typename S1, typename S2>
void ConvertNumIndicesToOffsets(const vtkm::cont::ArrayHandle<T, S1>& numIndices,
vtkm::cont::ArrayHandle<vtkm::Id, S2>& offsets)
{
const auto castCounts = vtkm::cont::make_ArrayHandleCast<vtkm::Id>(numIndices);
ConvertNumIndicesToOffsets(castCounts, offsets);
}
template <typename T, typename S1, typename S2>
void ConvertNumIndicesToOffsets(const vtkm::cont::ArrayHandle<T, S1>& numIndices,
vtkm::cont::ArrayHandle<vtkm::Id, S2>& offsets,
vtkm::Id& connectivitySize /* outparam */)
{
ConvertNumIndicesToOffsets(numIndices, offsets);
connectivitySize = vtkm::cont::ArrayGetValue(offsets.GetNumberOfValues() - 1, offsets);
}
template <typename T, typename S>
vtkm::cont::ArrayHandle<vtkm::Id> ConvertNumIndicesToOffsets(
const vtkm::cont::ArrayHandle<T, S>& numIndices)
{
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
ConvertNumIndicesToOffsets(numIndices, offsets);
return offsets;
}
template <typename T, typename S>
vtkm::cont::ArrayHandle<vtkm::Id> ConvertNumIndicesToOffsets(
const vtkm::cont::ArrayHandle<T, S>& numIndices,
vtkm::Id& connectivityLength /* outparam */)
{
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
ConvertNumIndicesToOffsets(numIndices, offsets, connectivityLength);
return offsets;
}
template <typename ShapesStorageTag = VTKM_DEFAULT_SHAPES_STORAGE_TAG,
typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
typename OffsetsStorageTag = VTKM_DEFAULT_OFFSETS_STORAGE_TAG>
class VTKM_ALWAYS_EXPORT CellSetExplicit : public CellSet
{
using Thisclass = CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>;
using Thisclass = CellSetExplicit<ShapesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>;
template <typename VisitTopology, typename IncidentTopology>
struct ConnectivityChooser
{
using ConnectivityType =
typename detail::CellSetExplicitConnectivityChooser<Thisclass,
VisitTopology,
IncidentTopology>::ConnectivityType;
private:
using Chooser = typename detail::CellSetExplicitConnectivityChooser<Thisclass,
VisitTopology,
IncidentTopology>;
using ShapeArrayType = typename ConnectivityType::ShapeArrayType;
using NumIndicesArrayType = typename ConnectivityType::NumIndicesArrayType;
public:
using ConnectivityType = typename Chooser::ConnectivityType;
using ShapesArrayType = typename ConnectivityType::ShapesArrayType;
using ConnectivityArrayType = typename ConnectivityType::ConnectivityArrayType;
using IndexOffsetArrayType = typename ConnectivityType::IndexOffsetArrayType;
using OffsetsArrayType = typename ConnectivityType::OffsetsArrayType;
using NumIndicesArrayType =
vtkm::cont::ArrayHandleDecorator<detail::NumIndicesDecorator, OffsetsArrayType>;
};
using VisitCellsWithPointsInternalsType =
typename ConnectivityChooser<vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint>::ConnectivityType;
using ConnTypes =
ConnectivityChooser<vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint>;
using RConnTypes =
ConnectivityChooser<vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell>;
using VisitPointsWithCellsInternalsType =
typename ConnectivityChooser<vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell>::ConnectivityType;
using CellPointIdsType = typename ConnTypes::ConnectivityType;
using PointCellIdsType = typename RConnTypes::ConnectivityType;
public:
using SchedulingRangeType = vtkm::Id;
//point to cell is used when iterating cells and asking for point properties
using VisitCellsWithPointsConnectivityType =
ConnectivityChooser<vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint>;
using ShapeArrayType = typename VisitCellsWithPointsConnectivityType::ShapeArrayType;
using NumIndicesArrayType = typename VisitCellsWithPointsConnectivityType::NumIndicesArrayType;
using ConnectivityArrayType =
typename VisitCellsWithPointsConnectivityType::ConnectivityArrayType;
using IndexOffsetArrayType = typename VisitCellsWithPointsConnectivityType::IndexOffsetArrayType;
using ShapesArrayType = typename CellPointIdsType::ShapesArrayType;
using ConnectivityArrayType = typename CellPointIdsType::ConnectivityArrayType;
using OffsetsArrayType = typename CellPointIdsType::OffsetsArrayType;
using NumIndicesArrayType = typename ConnTypes::NumIndicesArrayType;
VTKM_CONT CellSetExplicit();
VTKM_CONT CellSetExplicit(const Thisclass& src);
@ -105,28 +167,29 @@ public:
VTKM_CONT Thisclass& operator=(const Thisclass& src);
VTKM_CONT Thisclass& operator=(Thisclass&& src) noexcept;
virtual ~CellSetExplicit();
VTKM_CONT virtual ~CellSetExplicit();
vtkm::Id GetNumberOfCells() const override;
vtkm::Id GetNumberOfPoints() const override;
vtkm::Id GetNumberOfFaces() const override;
vtkm::Id GetNumberOfEdges() const override;
void PrintSummary(std::ostream& out) const override;
void ReleaseResourcesExecution() override;
VTKM_CONT vtkm::Id GetNumberOfCells() const override;
VTKM_CONT vtkm::Id GetNumberOfPoints() const override;
VTKM_CONT vtkm::Id GetNumberOfFaces() const override;
VTKM_CONT vtkm::Id GetNumberOfEdges() const override;
VTKM_CONT void PrintSummary(std::ostream& out) const override;
std::shared_ptr<CellSet> NewInstance() const override;
void DeepCopy(const CellSet* src) override;
VTKM_CONT void ReleaseResourcesExecution() override;
VTKM_CONT std::shared_ptr<CellSet> NewInstance() const override;
VTKM_CONT 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 override;
void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const override;
VTKM_CONT vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id cellid) const override;
VTKM_CONT void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const override;
VTKM_CONT vtkm::UInt8 GetCellShape(vtkm::Id cellIndex) const override;
VTKM_CONT vtkm::UInt8 GetCellShape(vtkm::Id cellid) const override;
template <vtkm::IdComponent ItemTupleLength>
VTKM_CONT void GetIndices(vtkm::Id index, vtkm::Vec<vtkm::Id, ItemTupleLength>& ids) const;
template <vtkm::IdComponent NumIndices>
VTKM_CONT void GetIndices(vtkm::Id index, vtkm::Vec<vtkm::Id, NumIndices>& ids) const;
VTKM_CONT void GetIndices(vtkm::Id index, vtkm::cont::ArrayHandle<vtkm::Id>& ids) const;
@ -143,74 +206,69 @@ public:
/// the way you can fill the memory from another system without copying
VTKM_CONT
void Fill(vtkm::Id numPoints,
const vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeStorageTag>& cellTypes,
const vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag>& numIndices,
const vtkm::cont::ArrayHandle<vtkm::UInt8, ShapesStorageTag>& cellTypes,
const vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityStorageTag>& connectivity,
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>& offsets =
vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>());
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>& offsets);
template <typename DeviceAdapter, typename VisitTopology, typename IncidentTopology>
template <typename Device, typename VisitTopology, typename IncidentTopology>
struct ExecutionTypes
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapter);
private:
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
VTKM_IS_TOPOLOGY_ELEMENT_TAG(VisitTopology);
VTKM_IS_TOPOLOGY_ELEMENT_TAG(IncidentTopology);
using ConnectivityTypes = ConnectivityChooser<VisitTopology, IncidentTopology>;
using Chooser = ConnectivityChooser<VisitTopology, IncidentTopology>;
using ShapePortalType = typename ConnectivityTypes::ShapeArrayType::template ExecutionTypes<
DeviceAdapter>::PortalConst;
using IndicePortalType =
typename ConnectivityTypes::NumIndicesArrayType::template ExecutionTypes<
DeviceAdapter>::PortalConst;
using ConnectivityPortalType =
typename ConnectivityTypes::ConnectivityArrayType::template ExecutionTypes<
DeviceAdapter>::PortalConst;
using IndexOffsetPortalType =
typename ConnectivityTypes::IndexOffsetArrayType::template ExecutionTypes<
DeviceAdapter>::PortalConst;
using ShapesAT = typename Chooser::ShapesArrayType;
using ConnAT = typename Chooser::ConnectivityArrayType;
using OffsetsAT = typename Chooser::OffsetsArrayType;
using ExecObjectType = vtkm::exec::ConnectivityExplicit<ShapePortalType,
IndicePortalType,
ConnectivityPortalType,
IndexOffsetPortalType>;
using ShapesET = typename ShapesAT::template ExecutionTypes<Device>;
using ConnET = typename ConnAT::template ExecutionTypes<Device>;
using OffsetsET = typename OffsetsAT::template ExecutionTypes<Device>;
public:
using ShapesPortalType = typename ShapesET::PortalConst;
using ConnectivityPortalType = typename ConnET::PortalConst;
using OffsetsPortalType = typename OffsetsET::PortalConst;
using ExecObjectType =
vtkm::exec::ConnectivityExplicit<ShapesPortalType, ConnectivityPortalType, OffsetsPortalType>;
};
template <typename Device, typename VisitTopology, typename IncidentTopology>
typename ExecutionTypes<Device, VisitTopology, IncidentTopology>::ExecObjectType
VTKM_CONT typename ExecutionTypes<Device, VisitTopology, IncidentTopology>::ExecObjectType
PrepareForInput(Device, VisitTopology, IncidentTopology) const;
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT const typename ConnectivityChooser<VisitTopology, IncidentTopology>::ShapeArrayType&
VTKM_CONT const typename ConnectivityChooser<VisitTopology, IncidentTopology>::ShapesArrayType&
GetShapesArray(VisitTopology, IncidentTopology) const;
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT const typename ConnectivityChooser<VisitTopology,
IncidentTopology>::NumIndicesArrayType&
GetNumIndicesArray(VisitTopology, IncidentTopology) const;
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT const typename ConnectivityChooser<VisitTopology,
IncidentTopology>::ConnectivityArrayType&
GetConnectivityArray(VisitTopology, IncidentTopology) const;
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT const typename ConnectivityChooser<VisitTopology,
IncidentTopology>::IndexOffsetArrayType&
GetIndexOffsetArray(VisitTopology, IncidentTopology) const;
VTKM_CONT const typename ConnectivityChooser<VisitTopology, IncidentTopology>::OffsetsArrayType&
GetOffsetsArray(VisitTopology, IncidentTopology) const;
// Can be used to check if e.g. CellToPoint table is built.
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT bool HasConnectivity(VisitTopology from, IncidentTopology to) const
VTKM_CONT typename ConnectivityChooser<VisitTopology, IncidentTopology>::NumIndicesArrayType
GetNumIndicesArray(VisitTopology, IncidentTopology) const;
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT bool HasConnectivity(VisitTopology visit, IncidentTopology incident) const
{
return this->HasConnectivityImpl(from, to);
return this->HasConnectivityImpl(visit, incident);
}
// Can be used to reset a connectivity table, mostly useful for benchmarking.
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT void ResetConnectivity(VisitTopology from, IncidentTopology to)
VTKM_CONT void ResetConnectivity(VisitTopology visit, IncidentTopology incident)
{
this->ResetConnectivityImpl(from, to);
this->ResetConnectivityImpl(visit, incident);
}
protected:
@ -225,20 +283,20 @@ protected:
VTKM_CONT bool HasConnectivityImpl(vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint) const
{
return this->Data->VisitCellsWithPoints.ElementsValid;
return this->Data->CellPointIds.ElementsValid;
}
VTKM_CONT bool HasConnectivityImpl(vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell) const
{
return this->Data->VisitPointsWithCells.ElementsValid;
return this->Data->PointCellIds.ElementsValid;
}
VTKM_CONT void ResetConnectivityImpl(vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint)
{
// Reset entire cell set
this->Data->VisitCellsWithPoints = VisitCellsWithPointsInternalsType{};
this->Data->VisitPointsWithCells = VisitPointsWithCellsInternalsType{};
this->Data->CellPointIds = CellPointIdsType{};
this->Data->PointCellIds = PointCellIdsType{};
this->Data->ConnectivityAdded = -1;
this->Data->NumberOfCellsAdded = -1;
this->Data->NumberOfPoints = 0;
@ -246,15 +304,15 @@ protected:
VTKM_CONT void ResetConnectivityImpl(vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell)
{
this->Data->VisitPointsWithCells = VisitPointsWithCellsInternalsType{};
this->Data->PointCellIds = PointCellIdsType{};
}
// Store internals in a shared pointer so shallow copies stay consistent.
// See #2268.
struct Internals
{
VisitCellsWithPointsInternalsType VisitCellsWithPoints;
VisitPointsWithCellsInternalsType VisitPointsWithCells;
CellPointIdsType CellPointIds;
PointCellIdsType PointCellIds;
// These are used in the AddCell and related methods to incrementally add
// cells. They need to be protected as subclasses of CellSetExplicit
@ -275,42 +333,45 @@ protected:
std::shared_ptr<Internals> Data;
private:
const VisitCellsWithPointsInternalsType& GetConnectivity(vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint) const
VTKM_CONT
const CellPointIdsType& GetConnectivity(vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint) const
{
return this->Data->VisitCellsWithPoints;
return this->Data->CellPointIds;
}
const VisitCellsWithPointsInternalsType& GetConnectivity(vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint)
VTKM_CONT
const CellPointIdsType& GetConnectivity(vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint)
{
return this->Data->VisitCellsWithPoints;
return this->Data->CellPointIds;
}
const VisitPointsWithCellsInternalsType& GetConnectivity(vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell) const
VTKM_CONT
const PointCellIdsType& GetConnectivity(vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell) const
{
return this->Data->VisitPointsWithCells;
return this->Data->PointCellIds;
}
const VisitPointsWithCellsInternalsType& GetConnectivity(vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell)
VTKM_CONT
const PointCellIdsType& GetConnectivity(vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell)
{
return this->Data->VisitPointsWithCells;
return this->Data->PointCellIds;
}
};
namespace detail
{
template <typename Storage1, typename Storage2, typename Storage3, typename Storage4>
struct CellSetExplicitConnectivityChooser<
vtkm::cont::CellSetExplicit<Storage1, Storage2, Storage3, Storage4>,
vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint>
template <typename Storage1, typename Storage2, typename Storage3>
struct CellSetExplicitConnectivityChooser<vtkm::cont::CellSetExplicit<Storage1, Storage2, Storage3>,
vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint>
{
using ConnectivityType =
vtkm::cont::internal::ConnectivityExplicitInternals<Storage1, Storage2, Storage3, Storage4>;
vtkm::cont::internal::ConnectivityExplicitInternals<Storage1, Storage2, Storage3>;
};
template <typename CellSetType>
@ -332,7 +393,6 @@ struct CellSetExplicitConnectivityChooser<CellSetType,
extern template class VTKM_CONT_TEMPLATE_EXPORT CellSetExplicit<>; // default
extern template class VTKM_CONT_TEMPLATE_EXPORT CellSetExplicit<
typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag,
typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag,
VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>; // CellSetSingleType base
#endif
@ -348,17 +408,15 @@ namespace vtkm
namespace cont
{
template <typename ShapeST, typename CountST, typename ConnectivityST, typename OffsetST>
struct SerializableTypeString<
vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>>
template <typename SST, typename CST, typename OST>
struct SerializableTypeString<vtkm::cont::CellSetExplicit<SST, CST, OST>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "CS_Explicit<" +
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeST>>::Get() + "_ST," +
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::IdComponent, CountST>>::Get() + "_ST," +
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST>>::Get() + "_ST," +
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, OffsetST>>::Get() + "_ST>";
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::UInt8, SST>>::Get() + "_ST," +
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, CST>>::Get() + "_ST," +
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, OST>>::Get() + "_ST>";
return name;
}
@ -369,11 +427,11 @@ struct SerializableTypeString<
namespace mangled_diy_namespace
{
template <typename ShapeST, typename CountST, typename ConnectivityST, typename OffsetST>
struct Serialization<vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>>
template <typename SST, typename CST, typename OST>
struct Serialization<vtkm::cont::CellSetExplicit<SST, CST, OST>>
{
private:
using Type = vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>;
using Type = vtkm::cont::CellSetExplicit<SST, CST, OST>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& cs)
@ -381,29 +439,25 @@ public:
vtkmdiy::save(bb, cs.GetNumberOfPoints());
vtkmdiy::save(
bb, cs.GetShapesArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
vtkmdiy::save(
bb, cs.GetNumIndicesArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
vtkmdiy::save(
bb, cs.GetConnectivityArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
vtkmdiy::save(
bb, cs.GetIndexOffsetArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
bb, cs.GetOffsetsArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{}));
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& cs)
{
vtkm::Id numberOfPoints = 0;
vtkmdiy::load(bb, numberOfPoints);
vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeST> shapes;
vtkm::cont::ArrayHandle<vtkm::UInt8, SST> shapes;
vtkmdiy::load(bb, shapes);
vtkm::cont::ArrayHandle<vtkm::IdComponent, CountST> counts;
vtkmdiy::load(bb, counts);
vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST> connectivity;
vtkm::cont::ArrayHandle<vtkm::Id, CST> connectivity;
vtkmdiy::load(bb, connectivity);
vtkm::cont::ArrayHandle<vtkm::Id, OffsetST> offsets;
vtkm::cont::ArrayHandle<vtkm::Id, OST> offsets;
vtkmdiy::load(bb, offsets);
cs = Type{};
cs.Fill(numberOfPoints, shapes, counts, connectivity, offsets);
cs.Fill(numberOfPoints, shapes, connectivity, offsets);
}
};

@ -10,302 +10,267 @@
#ifndef vtk_m_cont_CellSetExplicit_hxx
#define vtk_m_cont_CellSetExplicit_hxx
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayGetValues.h>
#include <vtkm/cont/ArrayHandleDecorator.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/RuntimeDeviceTracker.h>
#include <vtkm/cont/TryExecute.h>
// This file uses a lot of very verbose identifiers and the clang formatted
// code quickly becomes unreadable. Stick with manual formatting for now.
//
// clang-format off
namespace vtkm
{
namespace cont
{
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::CellSetExplicit()
template <typename SST, typename CST, typename OST>
VTKM_CONT
CellSetExplicit<SST, CST, OST>::CellSetExplicit()
: CellSet()
, Data(std::make_shared<Internals>())
{
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::CellSetExplicit(const Thisclass& src)
template <typename SST, typename CST, typename OST>
VTKM_CONT
CellSetExplicit<SST, CST, OST>::CellSetExplicit(const Thisclass& src)
: CellSet(src)
, Data(src.Data)
{
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::CellSetExplicit(Thisclass &&src) noexcept
: CellSet(std::forward<CellSet>(src)),
Data(std::move(src.Data))
template <typename SST, typename CST, typename OST>
VTKM_CONT
CellSetExplicit<SST, CST, OST>::CellSetExplicit(Thisclass &&src) noexcept
: CellSet(std::forward<CellSet>(src))
, Data(std::move(src.Data))
{
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT auto
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
operator=(const Thisclass& src) -> Thisclass&
template <typename SST, typename CST, typename OST>
VTKM_CONT
auto CellSetExplicit<SST, CST, OST>::operator=(const Thisclass& src)
-> Thisclass&
{
this->CellSet::operator=(src);
this->Data = src.Data;
return *this;
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT auto
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
operator=(Thisclass&& src) noexcept -> Thisclass&
template <typename SST, typename CST, typename OST>
VTKM_CONT
auto CellSetExplicit<SST, CST, OST>::operator=(Thisclass&& src) noexcept
-> Thisclass&
{
this->CellSet::operator=(std::forward<CellSet>(src));
this->Data = std::move(src.Data);
return *this;
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
~CellSetExplicit()
// explicitly define instead of '=default' to workaround an intel compiler bug
// (see #179)
template <typename SST, typename CST, typename OST>
VTKM_CONT
CellSetExplicit<SST, CST, OST>::~CellSetExplicit()
{
// explicitly define instead of '=default' to workaround an intel compiler bug
// (see #179)
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
void CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::PrintSummary(std::ostream& out) const
template <typename SST, typename CST, typename OST>
VTKM_CONT
void CellSetExplicit<SST, CST, OST>::PrintSummary(std::ostream& out) const
{
out << " ExplicitCellSet: " << std::endl;
out << " VisitCellsWithPoints: " << std::endl;
this->Data->VisitCellsWithPoints.PrintSummary(out);
out << " VisitPointsWithCells: " << std::endl;
this->Data->VisitPointsWithCells.PrintSummary(out);
out << " ExplicitCellSet:" << std::endl;
out << " CellPointIds:" << std::endl;
this->Data->CellPointIds.PrintSummary(out);
out << " PointCellIds:" << std::endl;
this->Data->PointCellIds.PrintSummary(out);
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetStorageTag>
void CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetStorageTag>::ReleaseResourcesExecution()
template <typename SST, typename CST, typename OST>
VTKM_CONT
void CellSetExplicit<SST, CST, OST>::ReleaseResourcesExecution()
{
this->Data->VisitCellsWithPoints.ReleaseResourcesExecution();
this->Data->VisitPointsWithCells.ReleaseResourcesExecution();
this->Data->CellPointIds.ReleaseResourcesExecution();
this->Data->PointCellIds.ReleaseResourcesExecution();
}
//----------------------------------------------------------------------------
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
vtkm::Id CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetNumberOfCells() const
template <typename SST, typename CST, typename OST>
VTKM_CONT
vtkm::Id CellSetExplicit<SST, CST, OST>::GetNumberOfCells() const
{
return this->Data->VisitCellsWithPoints.GetNumberOfElements();
return this->Data->CellPointIds.GetNumberOfElements();
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
vtkm::Id CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetNumberOfPoints() const
template <typename SST, typename CST, typename OST>
VTKM_CONT
vtkm::Id CellSetExplicit<SST, CST, OST>::GetNumberOfPoints() const
{
return this->Data->NumberOfPoints;
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
vtkm::Id CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetNumberOfFaces() const
template <typename SST, typename CST, typename OST>
VTKM_CONT
vtkm::Id CellSetExplicit<SST, CST, OST>::GetNumberOfFaces() const
{
return -1;
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
vtkm::Id CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetNumberOfEdges() const
template <typename SST, typename CST, typename OST>
VTKM_CONT
vtkm::Id CellSetExplicit<SST, CST, OST>::GetNumberOfEdges() const
{
return -1;
}
//----------------------------------------------------------------------------
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
void CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const
template <typename SST, typename CST, typename OST>
VTKM_CONT
void CellSetExplicit<SST, CST, OST>::GetCellPointIds(vtkm::Id cellId,
vtkm::Id* ptids) const
{
auto arrayWrapper = vtkm::cont::make_ArrayHandle(ptids, this->GetNumberOfPointsInCell(id));
this->GetIndices(id, arrayWrapper);
const auto offPortal = this->Data->CellPointIds.Offsets.GetPortalConstControl();
const vtkm::Id start = offPortal.Get(cellId);
const vtkm::Id end = offPortal.Get(cellId + 1);
const vtkm::IdComponent numIndices = static_cast<vtkm::IdComponent>(end - start);
auto connPortal = this->Data->CellPointIds.Connectivity.GetPortalConstControl();
for (vtkm::IdComponent i = 0; i < numIndices; i++)
{
ptids[i] = connPortal.Get(start + i);
}
}
//----------------------------------------------------------------------------
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT vtkm::Id
CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetSchedulingRange(vtkm::TopologyElementTagCell) const
template <typename SST, typename CST, typename OST>
VTKM_CONT
vtkm::Id CellSetExplicit<SST, CST, OST>
::GetSchedulingRange(vtkm::TopologyElementTagCell) const
{
return this->GetNumberOfCells();
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT vtkm::Id
CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetSchedulingRange(vtkm::TopologyElementTagPoint) const
template <typename SST, typename CST, typename OST>
VTKM_CONT
vtkm::Id CellSetExplicit<SST, CST, OST>
::GetSchedulingRange(vtkm::TopologyElementTagPoint) const
{
return this->GetNumberOfPoints();
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT vtkm::IdComponent
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
GetNumberOfPointsInCell(vtkm::Id cellIndex) const
template <typename SST, typename CST, typename OST>
VTKM_CONT
vtkm::IdComponent CellSetExplicit<SST, CST, OST>
::GetNumberOfPointsInCell(vtkm::Id cellid) const
{
return this->Data->VisitCellsWithPoints.NumIndices.GetPortalConstControl().Get(cellIndex);
const auto portal = this->Data->CellPointIds.Offsets.GetPortalConstControl();
return static_cast<vtkm::IdComponent>(portal.Get(cellid + 1) -
portal.Get(cellid));
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT vtkm::UInt8 CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetCellShape(vtkm::Id cellIndex) const
template <typename SST, typename CST, typename OST>
VTKM_CONT
vtkm::UInt8 CellSetExplicit<SST, CST, OST>
::GetCellShape(vtkm::Id cellid) const
{
return this->Data->VisitCellsWithPoints.Shapes.GetPortalConstControl().Get(cellIndex);
return this->Data->CellPointIds.Shapes.GetPortalConstControl().Get(cellid);
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
template <vtkm::IdComponent ItemTupleLength>
VTKM_CONT void
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
GetIndices(vtkm::Id index, vtkm::Vec<vtkm::Id, ItemTupleLength>& ids) const
template <typename SST, typename CST, typename OST>
template <vtkm::IdComponent NumVecIndices>
VTKM_CONT
void CellSetExplicit<SST, CST, OST>
::GetIndices(vtkm::Id cellId, vtkm::Vec<vtkm::Id, NumVecIndices>& ids) const
{
this->Data->VisitCellsWithPoints.BuildIndexOffsets(vtkm::cont::DeviceAdapterTagAny{});
vtkm::IdComponent numIndices = this->GetNumberOfPointsInCell(index);
vtkm::Id start = this->Data->VisitCellsWithPoints.IndexOffsets.GetPortalConstControl().Get(index);
for (vtkm::IdComponent i = 0; i < numIndices && i < ItemTupleLength; i++)
const auto offPortal = this->Data->CellPointIds.Offsets.GetPortalConstControl();
const vtkm::Id start = offPortal.Get(cellId);
const vtkm::Id end = offPortal.Get(cellId + 1);
const auto numCellIndices = static_cast<vtkm::IdComponent>(end - start);
const auto connPortal = this->Data->CellPointIds.Connectivity.GetPortalConstControl();
VTKM_LOG_IF_S(vtkm::cont::LogLevel::Warn,
numCellIndices != NumVecIndices,
"GetIndices given a " << NumVecIndices
<< "-vec to fetch a cell with " << numCellIndices << "points. "
"Truncating result.");
const vtkm::IdComponent numIndices = vtkm::Min(NumVecIndices, numCellIndices);
for (vtkm::IdComponent i = 0; i < numIndices; i++)
{
ids[i] = this->Data->VisitCellsWithPoints.Connectivity.GetPortalConstControl().Get(start + i);
ids[i] = connPortal.Get(start + i);
}
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT void
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
GetIndices(vtkm::Id index, vtkm::cont::ArrayHandle<vtkm::Id>& ids) const
template <typename SST, typename CST, typename OST>
VTKM_CONT
void CellSetExplicit<SST, CST, OST>
::GetIndices(vtkm::Id cellId, vtkm::cont::ArrayHandle<vtkm::Id>& ids) const
{
this->Data->VisitCellsWithPoints.BuildIndexOffsets(vtkm::cont::DeviceAdapterTagAny{});
vtkm::IdComponent numIndices = this->GetNumberOfPointsInCell(index);
const auto offPortal = this->Data->CellPointIds.Offsets.GetPortalConstControl();
const vtkm::Id start = offPortal.Get(cellId);
const vtkm::Id end = offPortal.Get(cellId + 1);
const vtkm::IdComponent numIndices = static_cast<vtkm::IdComponent>(end - start);
ids.Allocate(numIndices);
vtkm::Id start = this->Data->VisitCellsWithPoints.IndexOffsets.GetPortalConstControl().Get(index);
vtkm::cont::ArrayHandle<vtkm::Id>::PortalControl idPortal = ids.GetPortalControl();
auto PtCellPortal = this->Data->VisitCellsWithPoints.Connectivity.GetPortalConstControl();
auto connPortal = this->Data->CellPointIds.Connectivity.GetPortalConstControl();
for (vtkm::IdComponent i = 0; i < numIndices && i < numIndices; i++)
auto outIdPortal = ids.GetPortalControl();
for (vtkm::IdComponent i = 0; i < numIndices; i++)
{
idPortal.Set(i, PtCellPortal.Get(start + i));
outIdPortal.Set(i, connPortal.Get(start + i));
}
}
//----------------------------------------------------------------------------
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT void CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::PrepareToAddCells(vtkm::Id numCells,
vtkm::Id connectivityMaxLen)
namespace internal
{
this->Data->VisitCellsWithPoints.Shapes.Allocate(numCells);
this->Data->VisitCellsWithPoints.NumIndices.Allocate(numCells);
this->Data->VisitCellsWithPoints.Connectivity.Allocate(connectivityMaxLen);
this->Data->VisitCellsWithPoints.IndexOffsets.Allocate(numCells);
// Sets the first value of the array to zero if the handle is writable,
// otherwise do nothing:
template <typename ArrayType>
typename std::enable_if<vtkm::cont::internal::IsWritableArrayHandle<ArrayType>::value>::type
SetFirstToZeroIfWritable(ArrayType&& array)
{
using ValueType = typename std::decay<ArrayType>::type::ValueType;
using Traits = vtkm::TypeTraits<ValueType>;
array.GetPortalControl().Set(0, Traits::ZeroInitialization());
}
template <typename ArrayType>
typename std::enable_if<!vtkm::cont::internal::IsWritableArrayHandle<ArrayType>::value>::type
SetFirstToZeroIfWritable(ArrayType&&)
{ /* no-op */ }
} // end namespace internal
template <typename SST, typename CST, typename OST>
VTKM_CONT
void CellSetExplicit<SST, CST, OST>
::PrepareToAddCells(vtkm::Id numCells,
vtkm::Id connectivityMaxLen)
{
this->Data->CellPointIds.Shapes.Allocate(numCells);
this->Data->CellPointIds.Connectivity.Allocate(connectivityMaxLen);
this->Data->CellPointIds.Offsets.Allocate(numCells + 1);
internal::SetFirstToZeroIfWritable(this->Data->CellPointIds.Offsets);
this->Data->NumberOfCellsAdded = 0;
this->Data->ConnectivityAdded = 0;
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
template <typename SST, typename CST, typename OST>
template <typename IdVecType>
VTKM_CONT void
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
AddCell(vtkm::UInt8 cellType, vtkm::IdComponent numVertices, const IdVecType& ids)
VTKM_CONT
void CellSetExplicit<SST, CST, OST>::AddCell(vtkm::UInt8 cellType,
vtkm::IdComponent numVertices,
const IdVecType& ids)
{
using Traits = vtkm::VecTraits<IdVecType>;
VTKM_STATIC_ASSERT_MSG((std::is_same<typename Traits::ComponentType, vtkm::Id>::value),
@ -313,48 +278,45 @@ CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, O
if (Traits::GetNumberOfComponents(ids) < numVertices)
{
throw vtkm::cont::ErrorBadValue("Not enough indices given to CellSetSingleType::AddCell.");
throw vtkm::cont::ErrorBadValue("Not enough indices given to CellSetExplicit::AddCell.");
}
if (this->Data->NumberOfCellsAdded >= this->Data->VisitCellsWithPoints.Shapes.GetNumberOfValues())
if (this->Data->NumberOfCellsAdded >= this->Data->CellPointIds.Shapes.GetNumberOfValues())
{
throw vtkm::cont::ErrorBadValue("Added more cells then expected.");
}
if (this->Data->ConnectivityAdded + numVertices >
this->Data->VisitCellsWithPoints.Connectivity.GetNumberOfValues())
this->Data->CellPointIds.Connectivity.GetNumberOfValues())
{
throw vtkm::cont::ErrorBadValue(
"Connectivity increased passed estimated maximum connectivity.");
"Connectivity increased past estimated maximum connectivity.");
}
this->Data->VisitCellsWithPoints.Shapes.GetPortalControl().Set(this->Data->NumberOfCellsAdded,
cellType);
this->Data->VisitCellsWithPoints.NumIndices.GetPortalControl().Set(this->Data->NumberOfCellsAdded,
numVertices);
auto shapes = this->Data->CellPointIds.Shapes.GetPortalControl();
auto conn = this->Data->CellPointIds.Connectivity.GetPortalControl();
auto offsets = this->Data->CellPointIds.Offsets.GetPortalControl();
shapes.Set(this->Data->NumberOfCellsAdded, cellType);
for (vtkm::IdComponent iVec = 0; iVec < numVertices; ++iVec)
{
this->Data->VisitCellsWithPoints.Connectivity.GetPortalControl().Set(
this->Data->ConnectivityAdded + iVec, Traits::GetComponent(ids, iVec));
conn.Set(this->Data->ConnectivityAdded + iVec,
Traits::GetComponent(ids, iVec));
}
this->Data->VisitCellsWithPoints.IndexOffsets.GetPortalControl().Set(
this->Data->NumberOfCellsAdded, this->Data->ConnectivityAdded);
this->Data->NumberOfCellsAdded++;
this->Data->ConnectivityAdded += numVertices;
// Set the end offset for the added cell:
offsets.Set(this->Data->NumberOfCellsAdded, this->Data->ConnectivityAdded);
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT void CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::CompleteAddingCells(vtkm::Id numPoints)
template <typename SST, typename CST, typename OST>
VTKM_CONT
void CellSetExplicit<SST, CST, OST>::CompleteAddingCells(vtkm::Id numPoints)
{
this->Data->NumberOfPoints = numPoints;
this->Data->VisitCellsWithPoints.Connectivity.Shrink(this->Data->ConnectivityAdded);
this->Data->VisitCellsWithPoints.ElementsValid = true;
this->Data->VisitCellsWithPoints.IndexOffsetsValid = true;
this->Data->CellPointIds.Connectivity.Shrink(this->Data->ConnectivityAdded);
this->Data->CellPointIds.ElementsValid = true;
if (this->Data->NumberOfCellsAdded != this->GetNumberOfCells())
{
@ -367,159 +329,132 @@ VTKM_CONT void CellSetExplicit<ShapeStorageTag,
//----------------------------------------------------------------------------
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT void
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
Fill(vtkm::Id numPoints,
const vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeStorageTag>& cellTypes,
const vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag>& numIndices,
const vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityStorageTag>& connectivity,
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>& offsets)
template <typename SST, typename CST, typename OST>
VTKM_CONT
void CellSetExplicit<SST, CST, OST>
::Fill(vtkm::Id numPoints,
const vtkm::cont::ArrayHandle<vtkm::UInt8, SST>& shapes,
const vtkm::cont::ArrayHandle<vtkm::Id, CST>& connectivity,
const vtkm::cont::ArrayHandle<vtkm::Id, OST>& offsets)
{
// Validate inputs:
// Even for an empty cellset, offsets must contain a single 0:
VTKM_ASSERT(offsets.GetNumberOfValues() > 0);
// Must be [numCells + 1] offsets and [numCells] shapes
VTKM_ASSERT(offsets.GetNumberOfValues() == shapes.GetNumberOfValues() + 1);
// The last offset must be the size of the connectivity array.
VTKM_ASSERT(vtkm::cont::ArrayGetValue(offsets.GetNumberOfValues() - 1,
offsets) ==
connectivity.GetNumberOfValues());
this->Data->NumberOfPoints = numPoints;
this->Data->VisitCellsWithPoints.Shapes = cellTypes;
this->Data->VisitCellsWithPoints.NumIndices = numIndices;
this->Data->VisitCellsWithPoints.Connectivity = connectivity;
this->Data->CellPointIds.Shapes = shapes;
this->Data->CellPointIds.Connectivity = connectivity;
this->Data->CellPointIds.Offsets = offsets;
this->Data->VisitCellsWithPoints.ElementsValid = true;
if (offsets.GetNumberOfValues() == cellTypes.GetNumberOfValues())
{
this->Data->VisitCellsWithPoints.IndexOffsets = offsets;
this->Data->VisitCellsWithPoints.IndexOffsetsValid = true;
}
else
{
this->Data->VisitCellsWithPoints.IndexOffsetsValid = false;
if (offsets.GetNumberOfValues() != 0)
{
throw vtkm::cont::ErrorBadValue("Explicit cell offsets array unexpected size. "
"Use an empty array to automatically generate.");
}
}
this->Data->CellPointIds.ElementsValid = true;
this->ResetConnectivity(TopologyElementTagPoint{}, TopologyElementTagCell{});
}
//----------------------------------------------------------------------------
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
template <typename SST, typename CST, typename OST>
template <typename Device, typename VisitTopology, typename IncidentTopology>
auto CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::PrepareForInput(Device,
VisitTopology,
IncidentTopology) const ->
typename ExecutionTypes<Device, VisitTopology, IncidentTopology>::ExecObjectType
VTKM_CONT
auto CellSetExplicit<SST, CST, OST>
::PrepareForInput(Device, VisitTopology, IncidentTopology) const
-> typename ExecutionTypes<Device,
VisitTopology,
IncidentTopology>::ExecObjectType
{
this->BuildConnectivity(Device{}, VisitTopology(), IncidentTopology());
this->BuildConnectivity(Device{}, VisitTopology{}, IncidentTopology{});
const auto& connectivity = this->GetConnectivity(VisitTopology(), IncidentTopology());
const auto& connectivity = this->GetConnectivity(VisitTopology{},
IncidentTopology{});
VTKM_ASSERT(connectivity.ElementsValid);
using ExecObjType =
typename ExecutionTypes<Device, VisitTopology, IncidentTopology>::ExecObjectType;
return ExecObjType(connectivity.Shapes.PrepareForInput(Device()),
connectivity.NumIndices.PrepareForInput(Device()),
connectivity.Connectivity.PrepareForInput(Device()),
connectivity.IndexOffsets.PrepareForInput(Device()));
using ExecObjType = typename ExecutionTypes<Device,
VisitTopology,
IncidentTopology>::ExecObjectType;
return ExecObjType(connectivity.Shapes.PrepareForInput(Device{}),
connectivity.Connectivity.PrepareForInput(Device{}),
connectivity.Offsets.PrepareForInput(Device{}));
}
//----------------------------------------------------------------------------
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
template <typename SST, typename CST, typename OST>
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT auto CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetShapesArray(VisitTopology,
IncidentTopology) const -> const
typename ConnectivityChooser<VisitTopology, IncidentTopology>::ShapeArrayType&
VTKM_CONT auto CellSetExplicit<SST, CST, OST>
::GetShapesArray(VisitTopology, IncidentTopology) const
-> const typename ConnectivityChooser<VisitTopology,
IncidentTopology>::ShapesArrayType&
{
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{}, VisitTopology(), IncidentTopology());
return this->GetConnectivity(VisitTopology(), IncidentTopology()).Shapes;
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{},
VisitTopology{},
IncidentTopology{});
return this->GetConnectivity(VisitTopology{}, IncidentTopology{}).Shapes;
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
template <typename SST, typename CST, typename OST>
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT auto CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetNumIndicesArray(VisitTopology,
IncidentTopology) const
-> const typename ConnectivityChooser<VisitTopology, IncidentTopology>::NumIndicesArrayType&
VTKM_CONT
auto CellSetExplicit<SST, CST, OST>
::GetConnectivityArray(VisitTopology, IncidentTopology) const
-> const typename ConnectivityChooser<VisitTopology,
IncidentTopology>::ConnectivityArrayType&
{
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{}, VisitTopology(), IncidentTopology());
return this->GetConnectivity(VisitTopology(), IncidentTopology()).NumIndices;
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{},
VisitTopology{},
IncidentTopology{});
return this->GetConnectivity(VisitTopology{},
IncidentTopology{}).Connectivity;
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
template <typename SST, typename CST, typename OST>
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT auto CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetConnectivityArray(VisitTopology,
IncidentTopology) const
-> const typename ConnectivityChooser<VisitTopology, IncidentTopology>::ConnectivityArrayType&
VTKM_CONT
auto CellSetExplicit<SST, CST, OST>
::GetOffsetsArray(VisitTopology, IncidentTopology) const
-> const typename ConnectivityChooser<VisitTopology,
IncidentTopology>::OffsetsArrayType&
{
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{}, VisitTopology(), IncidentTopology());
return this->GetConnectivity(VisitTopology(), IncidentTopology()).Connectivity;
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{},
VisitTopology{},
IncidentTopology{});
return this->GetConnectivity(VisitTopology{},
IncidentTopology{}).Offsets;
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
template <typename SST, typename CST, typename OST>
template <typename VisitTopology, typename IncidentTopology>
VTKM_CONT auto CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::GetIndexOffsetArray(VisitTopology,
IncidentTopology) const
-> const typename ConnectivityChooser<VisitTopology, IncidentTopology>::IndexOffsetArrayType&
VTKM_CONT
auto CellSetExplicit<SST, CST, OST>
::GetNumIndicesArray(VisitTopology visited, IncidentTopology incident) const
-> typename ConnectivityChooser<VisitTopology,
IncidentTopology>::NumIndicesArrayType
{
this->BuildConnectivity(vtkm::cont::DeviceAdapterTagAny{}, VisitTopology(), IncidentTopology());
return this->GetConnectivity(VisitTopology(), IncidentTopology()).IndexOffsets;
auto offsets = this->GetOffsetsArray(visited, incident);
const vtkm::Id numVals = offsets.GetNumberOfValues() - 1;
return vtkm::cont::make_ArrayHandleDecorator(numVals,
detail::NumIndicesDecorator{},
std::move(offsets));
}
//----------------------------------------------------------------------------
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
std::shared_ptr<CellSet> CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>::NewInstance() const
template <typename SST, typename CST, typename OST>
VTKM_CONT
std::shared_ptr<CellSet> CellSetExplicit<SST, CST, OST>::NewInstance() 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)
template <typename SST, typename CST, typename OST>
VTKM_CONT
void CellSetExplicit<SST, CST, OST>::DeepCopy(const CellSet* src)
{
const auto* other = dynamic_cast<const CellSetExplicit*>(src);
if (!other)
@ -527,14 +462,18 @@ void CellSetExplicit<ShapeStorageTag,
throw vtkm::cont::ErrorBadType("CellSetExplicit::DeepCopy types don't match");
}
// TODO: implement actual deep-copy of the arrays
auto ct = vtkm::TopologyElementTagCell{};
auto pt = vtkm::TopologyElementTagPoint{};
this->Fill(other->GetNumberOfPoints(),
other->GetShapesArray(ct, pt),
other->GetNumIndicesArray(ct, pt),
other->GetConnectivityArray(ct, pt),
other->GetIndexOffsetArray(ct, pt));
ShapesArrayType shapes;
ConnectivityArrayType conn;
OffsetsArrayType offsets;
const auto ct = vtkm::TopologyElementTagCell{};
const auto pt = vtkm::TopologyElementTagPoint{};
vtkm::cont::ArrayCopy(other->GetShapesArray(ct, pt), shapes);
vtkm::cont::ArrayCopy(other->GetConnectivityArray(ct, pt), conn);
vtkm::cont::ArrayCopy(other->GetOffsetsArray(ct, pt), offsets);
this->Fill(other->GetNumberOfPoints(), shapes, conn, offsets);
}
//----------------------------------------------------------------------------
@ -542,33 +481,14 @@ void CellSetExplicit<ShapeStorageTag,
namespace detail
{
template <typename VisitCellsWithPointsConnectivity>
struct BuildVisitCellsWithPointsConnectivityFunctor
template <typename CellPointIdsT, typename PointCellIdsT>
struct BuildPointCellIdsFunctor
{
explicit BuildVisitCellsWithPointsConnectivityFunctor(VisitCellsWithPointsConnectivity& obj)
: VisitCellsWithPoints(&obj)
{
}
template <typename Device>
bool operator()(Device) const
{
this->VisitCellsWithPoints->BuildIndexOffsets(Device());
return true;
}
VisitCellsWithPointsConnectivity* VisitCellsWithPoints;
};
template <typename VisitCellsWithPointsConnectivity, typename VisitPointsWithCellsConnectivity>
struct BuildVisitPointsWithCellsConnectivityFunctor
{
BuildVisitPointsWithCellsConnectivityFunctor(
VisitCellsWithPointsConnectivity& visitCellsWithPoints,
VisitPointsWithCellsConnectivity& visitPointsWithCells,
vtkm::Id numberOfPoints)
: VisitCellsWithPoints(&visitCellsWithPoints)
, VisitPointsWithCells(&visitPointsWithCells)
BuildPointCellIdsFunctor(CellPointIdsT &cellPointIds,
PointCellIdsT &pointCellIds,
vtkm::Id numberOfPoints)
: CellPointIds(cellPointIds)
, PointCellIds(pointCellIds)
, NumberOfPoints(numberOfPoints)
{
}
@ -576,81 +496,57 @@ struct BuildVisitPointsWithCellsConnectivityFunctor
template <typename Device>
bool operator()(Device) const
{
this->VisitCellsWithPoints->BuildIndexOffsets(Device());
internal::ComputeVisitPointsWithCellsConnectivity(
*this->VisitPointsWithCells, *this->VisitCellsWithPoints, this->NumberOfPoints, Device());
this->VisitPointsWithCells->BuildIndexOffsets(Device());
internal::ComputeRConnTable(this->PointCellIds,
this->CellPointIds,
this->NumberOfPoints,
Device{});
return true;
}
VisitCellsWithPointsConnectivity* VisitCellsWithPoints;
VisitPointsWithCellsConnectivity* VisitPointsWithCells;
CellPointIdsT &CellPointIds;
PointCellIdsT &PointCellIds;
vtkm::Id NumberOfPoints;
};
} // detail
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT void
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
BuildConnectivity(vtkm::cont::DeviceAdapterId device,
template <typename SST, typename CST, typename OST>
VTKM_CONT
void CellSetExplicit<SST, CST, OST>
::BuildConnectivity(vtkm::cont::DeviceAdapterId,
vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint) const
{
using VisitCellsWithPointsConnectivity =
typename ConnectivityChooser<vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint>::ConnectivityType;
VTKM_ASSERT(this->Data->VisitCellsWithPoints.ElementsValid);
if (!this->Data->VisitCellsWithPoints.IndexOffsetsValid)
{
auto self = const_cast<Thisclass*>(this);
auto functor =
detail::BuildVisitCellsWithPointsConnectivityFunctor<VisitCellsWithPointsConnectivity>(
self->Data->VisitCellsWithPoints);
if (!vtkm::cont::TryExecuteOnDevice(device, functor))
{
throw vtkm::cont::ErrorExecution("Failed to run BuildConnectivity.");
}
}
VTKM_ASSERT(this->Data->CellPointIds.ElementsValid);
// no-op
}
template <typename ShapeStorageTag,
typename NumIndicesStorageTag,
typename ConnectivityStorageTag,
typename OffsetsStorageTag>
VTKM_CONT void
CellSetExplicit<ShapeStorageTag, NumIndicesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>::
BuildConnectivity(vtkm::cont::DeviceAdapterId device,
template <typename SST, typename CST, typename OST>
VTKM_CONT
void CellSetExplicit<SST, CST, OST>
::BuildConnectivity(vtkm::cont::DeviceAdapterId device,
vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell) const
{
using VisitCellsWithPointsConnectivity =
typename ConnectivityChooser<vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint>::ConnectivityType;
using VisitPointsWithCellsConnectivity =
typename ConnectivityChooser<vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell>::ConnectivityType;
if (!this->Data->VisitPointsWithCells.ElementsValid ||
!this->Data->VisitPointsWithCells.IndexOffsetsValid)
if (!this->Data->PointCellIds.ElementsValid)
{
auto self = const_cast<Thisclass*>(this);
auto functor =
detail::BuildVisitPointsWithCellsConnectivityFunctor<VisitCellsWithPointsConnectivity,
VisitPointsWithCellsConnectivity>(
self->Data->VisitCellsWithPoints,
self->Data->VisitPointsWithCells,
this->Data->NumberOfPoints);
using Func = detail::BuildPointCellIdsFunctor<CellPointIdsType, PointCellIdsType>;
auto functor = Func(self->Data->CellPointIds,
self->Data->PointCellIds,
self->Data->NumberOfPoints);
if (!vtkm::cont::TryExecuteOnDevice(device, functor))
{
throw vtkm::cont::ErrorExecution("Failed to run BuildConnectivity.");
throw vtkm::cont::ErrorExecution("Failed to run CellSetExplicit reverse "
"connectivity builder.");
}
}
}
}
} // vtkm::cont
// clang-format on
#endif

@ -42,15 +42,12 @@ struct VTKM_ALWAYS_EXPORT CellSetListTagStructured3D
};
template <typename ShapeStorageTag = VTKM_DEFAULT_SHAPE_STORAGE_TAG,
typename NumIndicesStorageTag = VTKM_DEFAULT_NUM_INDICES_STORAGE_TAG,
template <typename ShapesStorageTag = VTKM_DEFAULT_SHAPES_STORAGE_TAG,
typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
typename OffsetsStorageTag = VTKM_DEFAULT_OFFSETS_STORAGE_TAG>
struct VTKM_ALWAYS_EXPORT CellSetListTagExplicit
: vtkm::ListTagBase<vtkm::cont::CellSetExplicit<ShapeStorageTag,
NumIndicesStorageTag,
ConnectivityStorageTag,
OffsetsStorageTag>>
: vtkm::ListTagBase<
vtkm::cont::CellSetExplicit<ShapesStorageTag, ConnectivityStorageTag, OffsetsStorageTag>>
{
};

@ -12,13 +12,15 @@
#include <vtkm/CellShape.h>
#include <vtkm/CellTraits.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/CellSet.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/cont/internal/ConnectivityExplicitInternals.h>
#include <vtkm/internal/ConnectivityStructuredInternals.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
#include <vtkm/worklet/WorkletMapTopology.h>
#include <vtkm/exec/ConnectivityPermuted.h>
@ -35,7 +37,12 @@ namespace cont
namespace internal
{
class CellSetPermutationVisitCellsWithPointsHelpers
// To generate the reverse connectivity table with the
// ReverseConnectivityBuilder, we need a compact connectivity array that
// contains only the cell definitions from the permuted dataset, and an offsets
// array. These helpers are used to generate these arrays so that they can be
// converted in the reverse conn table.
class RConnTableHelpers
{
public:
struct WriteNumIndices : public vtkm::worklet::WorkletVisitCellsWithPoints
@ -70,102 +77,137 @@ public:
public:
template <typename CellSetPermutationType, typename Device>
static vtkm::cont::ArrayHandle<vtkm::IdComponent> GetNumIndicesArray(
static VTKM_CONT vtkm::cont::ArrayHandle<vtkm::IdComponent> GetNumIndicesArray(
const CellSetPermutationType& cs,
Device)
{
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
vtkm::worklet::DispatcherMapTopology<WriteNumIndices> dispatcher;
dispatcher.SetDevice(Device());
dispatcher.Invoke(cs, numIndices);
vtkm::cont::Invoker{ Device{} }(WriteNumIndices{}, cs, numIndices);
return numIndices;
}
template <typename NumIndicesStorageType, typename Device>
static vtkm::cont::ArrayHandle<vtkm::Id> GetIndexOffsetsArray(
static VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Id> GetOffsetsArray(
const vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageType>& numIndices,
vtkm::Id& connectivityLength,
vtkm::Id& connectivityLength /* outparam */,
Device)
{
return vtkm::cont::ConvertNumComponentsToOffsets(numIndices, connectivityLength);
return vtkm::cont::ConvertNumIndicesToOffsets(numIndices, connectivityLength);
}
template <typename CellSetPermutationType, typename IndexOffsetsStorageType, typename Device>
template <typename CellSetPermutationType, typename OffsetsStorageType, typename Device>
static vtkm::cont::ArrayHandle<vtkm::Id> GetConnectivityArray(
const CellSetPermutationType& cs,
const vtkm::cont::ArrayHandle<vtkm::Id, IndexOffsetsStorageType>& indexOffsets,
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageType>& offsets,
vtkm::Id connectivityLength,
Device)
{
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
connectivity.Allocate(connectivityLength);
vtkm::worklet::DispatcherMapTopology<WriteConnectivity> dispatcher;
dispatcher.SetDevice(Device());
dispatcher.Invoke(cs, vtkm::cont::make_ArrayHandleGroupVecVariable(connectivity, indexOffsets));
const auto offsetsTrim =
vtkm::cont::make_ArrayHandleView(offsets, 0, offsets.GetNumberOfValues() - 1);
auto connWrap = vtkm::cont::make_ArrayHandleGroupVecVariable(connectivity, offsetsTrim);
vtkm::cont::Invoker{ Device{} }(WriteConnectivity{}, cs, connWrap);
return connectivity;
}
};
// This holds the temporary input arrays for the ReverseConnectivityBuilder
// algorithm.
template <typename ConnectivityStorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename OffsetsStorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename NumIndicesStorageTag = VTKM_DEFAULT_STORAGE_TAG>
struct RConnBuilderInputData
{
using ConnectivityArrayType = vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityStorageTag>;
using OffsetsArrayType = vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>;
using NumIndicesArrayType = vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag>;
ConnectivityArrayType Connectivity;
OffsetsArrayType Offsets; // Includes the past-the-end offset.
NumIndicesArrayType NumIndices;
};
// default for CellSetPermutations of any cell type
template <typename CellSetPermutationType>
class CellSetPermutationVisitCellsWithPoints
class RConnBuilderInput
{
public:
using ConnectivityArrays = vtkm::cont::internal::ConnectivityExplicitInternals<>;
using ConnectivityArrays = vtkm::cont::internal::RConnBuilderInputData<>;
template <typename Device>
static ConnectivityArrays Get(const CellSetPermutationType& cellset, Device)
{
using Helper = RConnTableHelpers;
ConnectivityArrays conn;
vtkm::Id connectivityLength = 0;
conn.NumIndices =
CellSetPermutationVisitCellsWithPointsHelpers::GetNumIndicesArray(cellset, Device{});
conn.IndexOffsets = CellSetPermutationVisitCellsWithPointsHelpers::GetIndexOffsetsArray(
conn.NumIndices, connectivityLength, Device{});
conn.Connectivity = CellSetPermutationVisitCellsWithPointsHelpers::GetConnectivityArray(
cellset, conn.IndexOffsets, connectivityLength, Device{});
conn.NumIndices = Helper::GetNumIndicesArray(cellset, Device{});
conn.Offsets = Helper::GetOffsetsArray(conn.NumIndices, connectivityLength, Device{});
conn.Connectivity =
Helper::GetConnectivityArray(cellset, conn.Offsets, connectivityLength, Device{});
return conn;
}
};
// Specialization for CellSetExplicit/CellSetSingleType
template <typename S1, typename S2, typename S3, typename S4, typename PermutationArrayHandleType>
class CellSetPermutationVisitCellsWithPoints<
CellSetPermutation<CellSetExplicit<S1, S2, S3, S4>, PermutationArrayHandleType>>
template <typename InShapesST,
typename InConnST,
typename InOffsetsST,
typename PermutationArrayHandleType>
class RConnBuilderInput<CellSetPermutation<CellSetExplicit<InShapesST, InConnST, InOffsetsST>,
PermutationArrayHandleType>>
{
private:
using CellSetPermutationType =
CellSetPermutation<CellSetExplicit<S1, S2, S3, S4>, PermutationArrayHandleType>;
using BaseCellSetType = CellSetExplicit<InShapesST, InConnST, InOffsetsST>;
using CellSetPermutationType = CellSetPermutation<BaseCellSetType, PermutationArrayHandleType>;
using InShapesArrayType = typename BaseCellSetType::ShapesArrayType;
using InNumIndicesArrayType = typename BaseCellSetType::NumIndicesArrayType;
using ShapesStorageTag = StorageTagPermutation<PermutationArrayHandleType, InShapesArrayType>;
using ConnectivityStorageTag = vtkm::cont::ArrayHandle<vtkm::Id>::StorageTag;
using OffsetsStorageTag = vtkm::cont::ArrayHandle<vtkm::Id>::StorageTag;
using NumIndicesStorageTag =
StorageTagPermutation<PermutationArrayHandleType, InNumIndicesArrayType>;
using NumIndicesArrayType =
vtkm::cont::ArrayHandlePermutation<PermutationArrayHandleType,
vtkm::cont::ArrayHandle<vtkm::IdComponent, S2>>;
public:
using ConnectivityArrays = vtkm::cont::internal::ConnectivityExplicitInternals<
VTKM_DEFAULT_STORAGE_TAG, // shapes array is not used
typename NumIndicesArrayType::StorageTag>;
using ConnectivityArrays = vtkm::cont::internal::RConnBuilderInputData<ConnectivityStorageTag,
OffsetsStorageTag,
NumIndicesStorageTag>;
template <typename Device>
static ConnectivityArrays Get(const CellSetPermutationType& cellset, Device)
{
ConnectivityArrays conn;
vtkm::Id connectivityLength = 0;
using Helper = RConnTableHelpers;
conn.NumIndices =
NumIndicesArrayType(cellset.GetValidCellIds(),
cellset.GetFullCellSet().GetNumIndicesArray(
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint()));
conn.IndexOffsets = CellSetPermutationVisitCellsWithPointsHelpers::GetIndexOffsetsArray(
conn.NumIndices, connectivityLength, Device{});
conn.Connectivity = CellSetPermutationVisitCellsWithPointsHelpers::GetConnectivityArray(
cellset, conn.IndexOffsets, connectivityLength, Device{});
static constexpr vtkm::TopologyElementTagCell cell;
static constexpr vtkm::TopologyElementTagPoint point;
auto fullCellSet = cellset.GetFullCellSet();
vtkm::Id connectivityLength = 0;
ConnectivityArrays conn;
fullCellSet.GetOffsetsArray(cell, point);
// We can use the implicitly generated NumIndices array to save a bit of
// memory:
conn.NumIndices = vtkm::cont::make_ArrayHandlePermutation(
cellset.GetValidCellIds(), fullCellSet.GetNumIndicesArray(cell, point));
// Need to generate the offsets from scratch so that they're ordered for the
// lower-bounds binary searches in ReverseConnectivityBuilder.
conn.Offsets = Helper::GetOffsetsArray(conn.NumIndices, connectivityLength, Device{});
// Need to create a copy of this containing *only* the permuted cell defs,
// in order, since the ReverseConnectivityBuilder will process every entry
// in the connectivity array and we don't want the removed cells to be
// included.
conn.Connectivity =
Helper::GetConnectivityArray(cellset, conn.Offsets, connectivityLength, Device{});
return conn;
}
@ -173,7 +215,7 @@ public:
// Specialization for CellSetStructured
template <vtkm::IdComponent DIMENSION, typename PermutationArrayHandleType>
class CellSetPermutationVisitCellsWithPoints<
class RConnBuilderInput<
CellSetPermutation<CellSetStructured<DIMENSION>, PermutationArrayHandleType>>
{
private:
@ -181,11 +223,10 @@ private:
CellSetPermutation<CellSetStructured<DIMENSION>, PermutationArrayHandleType>;
public:
using ConnectivityArrays = vtkm::cont::internal::ConnectivityExplicitInternals<
VTKM_DEFAULT_STORAGE_TAG, // shapes array is not used
typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag,
using ConnectivityArrays = vtkm::cont::internal::RConnBuilderInputData<
VTKM_DEFAULT_STORAGE_TAG,
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>;
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag,
typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag>;
template <typename Device>
static ConnectivityArrays Get(const CellSetPermutationType& cellset, Device)
@ -197,9 +238,9 @@ public:
ConnectivityArrays conn;
conn.NumIndices = make_ArrayHandleConstant(numPointsInCell, numberOfCells);
conn.IndexOffsets = ArrayHandleCounting<vtkm::Id>(0, numPointsInCell, numberOfCells);
conn.Connectivity = CellSetPermutationVisitCellsWithPointsHelpers::GetConnectivityArray(
cellset, conn.IndexOffsets, connectivityLength, Device{});
conn.Offsets = ArrayHandleCounting<vtkm::Id>(0, numPointsInCell, numberOfCells + 1);
conn.Connectivity =
RConnTableHelpers::GetConnectivityArray(cellset, conn.Offsets, connectivityLength, Device{});
return conn;
}
@ -312,11 +353,11 @@ public:
const auto* other = dynamic_cast<const CellSetPermutation*>(src);
if (!other)
{
throw vtkm::cont::ErrorBadType("CellSetPermutaion::DeepCopy types don't match");
throw vtkm::cont::ErrorBadType("CellSetPermutation::DeepCopy types don't match");
}
this->FullCellSet.DeepCopy(&(other->GetFullCellSet()));
this->ValidCellIds = other->GetValidCellIds();
vtkm::cont::ArrayCopy(other->GetValidCellIds(), this->ValidCellIds);
}
//This is the way you can fill the memory from another system without copying
@ -361,17 +402,16 @@ public:
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
using ConnectiviyPortalType =
using ConnectivityPortalType =
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<Device>::PortalConst;
using NumIndicesPortalType = typename vtkm::cont::ArrayHandle<
vtkm::IdComponent>::template ExecutionTypes<Device>::PortalConst;
using IndexOffsetPortalType =
using OffsetPortalType =
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<Device>::PortalConst;
using ExecObjectType =
vtkm::exec::ConnectivityPermutedVisitPointsWithCells<ConnectiviyPortalType,
NumIndicesPortalType,
IndexOffsetPortalType>;
vtkm::exec::ConnectivityPermutedVisitPointsWithCells<ConnectivityPortalType,
OffsetPortalType>;
};
template <typename Device>
@ -397,19 +437,16 @@ public:
{
if (!this->VisitPointsWithCells.ElementsValid)
{
auto pointToCell =
internal::CellSetPermutationVisitCellsWithPoints<CellSetPermutation>::Get(*this, device);
internal::ComputeVisitPointsWithCellsConnectivity(
this->VisitPointsWithCells, pointToCell, this->GetNumberOfPoints(), device);
this->VisitPointsWithCells.BuildIndexOffsets(device);
auto connTable = internal::RConnBuilderInput<CellSetPermutation>::Get(*this, device);
internal::ComputeRConnTable(
this->VisitPointsWithCells, connTable, this->GetNumberOfPoints(), device);
}
using ConnectivityType = typename ExecutionTypes<Device,
vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell>::ExecObjectType;
return ConnectivityType(this->VisitPointsWithCells.Connectivity.PrepareForInput(device),
this->VisitPointsWithCells.NumIndices.PrepareForInput(device),
this->VisitPointsWithCells.IndexOffsets.PrepareForInput(device));
this->VisitPointsWithCells.Offsets.PrepareForInput(device));
}
VTKM_CONT

@ -30,19 +30,16 @@ namespace cont
template <typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG>
class VTKM_ALWAYS_EXPORT CellSetSingleType
: public vtkm::cont::CellSetExplicit<
typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag, //ShapeStorageTag
typename vtkm::cont::ArrayHandleConstant<
vtkm::IdComponent>::StorageTag, //NumIndicesStorageTag
typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag, //ShapesStorageTag
ConnectivityStorageTag,
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag //IndexOffsetStorageTag
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag //OffsetsStorageTag
>
{
using Thisclass = vtkm::cont::CellSetSingleType<ConnectivityStorageTag>;
using Superclass = vtkm::cont::CellSetExplicit<
typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag,
typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag,
ConnectivityStorageTag,
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>;
using Superclass =
vtkm::cont::CellSetExplicit<typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag,
ConnectivityStorageTag,
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>;
public:
VTKM_CONT
@ -98,7 +95,7 @@ public:
{
this->CellShapeAsId = vtkm::CELL_SHAPE_EMPTY;
this->Data->VisitCellsWithPoints.Connectivity.Allocate(connectivityMaxLen);
this->Data->CellPointIds.Connectivity.Allocate(connectivityMaxLen);
this->Data->NumberOfCellsAdded = 0;
this->Data->ConnectivityAdded = 0;
@ -119,10 +116,10 @@ public:
}
if (this->Data->ConnectivityAdded + numVertices >
this->Data->VisitCellsWithPoints.Connectivity.GetNumberOfValues())
this->Data->CellPointIds.Connectivity.GetNumberOfValues())
{
throw vtkm::cont::ErrorBadValue(
"Connectivity increased passed estimated maximum connectivity.");
"Connectivity increased past estimated maximum connectivity.");
}
if (this->CellShapeAsId == vtkm::CELL_SHAPE_EMPTY)
@ -147,10 +144,10 @@ public:
"Inconsistent number of points in cells for CellSetSingleType.");
}
}
auto conn = this->Data->CellPointIds.Connectivity.GetPortalControl();
for (vtkm::IdComponent iVert = 0; iVert < numVertices; ++iVert)
{
this->Data->VisitCellsWithPoints.Connectivity.GetPortalControl().Set(
this->Data->ConnectivityAdded + iVert, Traits::GetComponent(ids, iVert));
conn.Set(this->Data->ConnectivityAdded + iVert, Traits::GetComponent(ids, iVert));
}
this->Data->NumberOfCellsAdded++;
this->Data->ConnectivityAdded += numVertices;
@ -161,19 +158,16 @@ public:
void CompleteAddingCells(vtkm::Id numPoints)
{
this->Data->NumberOfPoints = numPoints;
this->VisitCellsWithPoints.Connectivity.Shrink(this->ConnectivityAdded);
this->CellPointIds.Connectivity.Shrink(this->ConnectivityAdded);
vtkm::Id numCells = this->NumberOfCellsAdded;
this->VisitCellsWithPoints.Shapes =
this->CellPointIds.Shapes =
vtkm::cont::make_ArrayHandleConstant(this->GetCellShape(0), numCells);
this->VisitCellsWithPoints.NumIndices =
vtkm::cont::make_ArrayHandleConstant(this->NumberOfPointsPerCell, numCells);
this->VisitCellsWithPoints.IndexOffsets = vtkm::cont::make_ArrayHandleCounting(
this->CellPointIds.IndexOffsets = vtkm::cont::make_ArrayHandleCounting(
vtkm::Id(0), static_cast<vtkm::Id>(this->NumberOfPointsPerCell), numCells);
this->VisitCellsWithPoints.ElementsValid = true;
this->VisitCellsWithPoints.IndexOffsetsValid = true;
this->CellPointIds.ElementsValid = true;
if (this->ExpectedNumberOfCellsAdded != this->GetNumberOfCells())
{
@ -195,18 +189,18 @@ public:
this->Data->NumberOfPoints = numPoints;
this->CellShapeAsId = shapeId;
this->CheckNumberOfPointsPerCell(numberOfPointsPerCell);
const vtkm::Id numCells = connectivity.GetNumberOfValues() / numberOfPointsPerCell;
VTKM_ASSERT((connectivity.GetNumberOfValues() % numberOfPointsPerCell) == 0);
this->Data->VisitCellsWithPoints.Shapes =
vtkm::cont::make_ArrayHandleConstant(shapeId, numCells);
this->Data->VisitCellsWithPoints.NumIndices =
vtkm::cont::make_ArrayHandleConstant(numberOfPointsPerCell, numCells);
this->Data->VisitCellsWithPoints.IndexOffsets = vtkm::cont::make_ArrayHandleCounting(
vtkm::Id(0), static_cast<vtkm::Id>(numberOfPointsPerCell), numCells);
this->Data->VisitCellsWithPoints.Connectivity = connectivity;
this->Data->VisitCellsWithPoints.ElementsValid = true;
this->Data->VisitCellsWithPoints.IndexOffsetsValid = true;
this->Data->CellPointIds.Shapes = vtkm::cont::make_ArrayHandleConstant(shapeId, numCells);
this->Data->CellPointIds.Offsets = vtkm::cont::make_ArrayHandleCounting(
vtkm::Id(0), static_cast<vtkm::Id>(numberOfPointsPerCell), numCells + 1);
this->Data->CellPointIds.Connectivity = connectivity;
this->Data->CellPointIds.ElementsValid = true;
this->ResetConnectivity(TopologyElementTagPoint{}, TopologyElementTagCell{});
}
@ -242,11 +236,11 @@ public:
virtual void PrintSummary(std::ostream& out) const override
{
out << " CellSetSingleType ShapeType " << this->CellShapeAsId << std::endl;
out << " VisitCellsWithPoints: " << std::endl;
this->Data->VisitCellsWithPoints.PrintSummary(out);
out << " VisitPointsWithCells: " << std::endl;
this->Data->VisitPointsWithCells.PrintSummary(out);
out << " CellSetSingleType: Type=" << this->CellShapeAsId << std::endl;
out << " CellPointIds:" << std::endl;
this->Data->CellPointIds.PrintSummary(out);
out << " PointCellIds:" << std::endl;
this->Data->PointCellIds.PrintSummary(out);
}
private:

@ -10,6 +10,8 @@
#ifndef vtk_m_cont_DataSetBuilderExplicit_h
#define vtk_m_cont_DataSetBuilderExplicit_h
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleCompositeVector.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/cont/CoordinateSystem.h>
@ -21,17 +23,9 @@ namespace cont
{
//Coordinates builder??
//Need a singlecellset handler.
class VTKM_CONT_EXPORT DataSetBuilderExplicit
{
template <typename T>
VTKM_CONT static void CopyInto(const std::vector<T>& input, vtkm::cont::ArrayHandle<T>& output)
{
output.Allocate(static_cast<vtkm::Id>(input.size()));
std::copy(input.begin(), input.end(), ArrayPortalToIteratorBegin(output.GetPortalControl()));
}
public:
VTKM_CONT
DataSetBuilderExplicit() {}
@ -84,8 +78,10 @@ public:
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
const std::string& coordsNm = "coords")
{
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices);
return DataSetBuilderExplicit::BuildDataSet(
xVals, yVals, zVals, shapes, numIndices, connectivity, coordsNm);
xVals, yVals, zVals, shapes, offsets, connectivity, coordsNm);
}
template <typename T>
@ -103,7 +99,8 @@ public:
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
const std::string& coordsNm = "coords")
{
return DataSetBuilderExplicit::BuildDataSet(coords, shapes, numIndices, connectivity, coordsNm);
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices);
return DataSetBuilderExplicit::BuildDataSet(coords, shapes, offsets, connectivity, coordsNm);
}
template <typename T, typename CellShapeTag>
@ -127,20 +124,19 @@ public:
private:
template <typename T>
static vtkm::cont::DataSet BuildDataSet(
const vtkm::cont::ArrayHandle<T>& X,
const vtkm::cont::ArrayHandle<T>& Y,
const vtkm::cont::ArrayHandle<T>& Z,
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
const std::string& coordsNm);
static vtkm::cont::DataSet BuildDataSet(const vtkm::cont::ArrayHandle<T>& X,
const vtkm::cont::ArrayHandle<T>& Y,
const vtkm::cont::ArrayHandle<T>& Z,
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
const vtkm::cont::ArrayHandle<vtkm::Id>& offsets,
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
const std::string& coordsNm);
template <typename T>
VTKM_CONT static vtkm::cont::DataSet BuildDataSet(
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>>& coords,
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
const vtkm::cont::ArrayHandle<vtkm::Id>& offsets,
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
const std::string& coordsNm);
@ -165,19 +161,18 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
{
VTKM_ASSERT(xVals.size() == yVals.size() && yVals.size() == zVals.size() && xVals.size() > 0);
vtkm::cont::ArrayHandle<T> Xc, Yc, Zc;
DataSetBuilderExplicit::CopyInto(xVals, Xc);
DataSetBuilderExplicit::CopyInto(yVals, Yc);
DataSetBuilderExplicit::CopyInto(zVals, Zc);
auto xArray = vtkm::cont::make_ArrayHandle(xVals, vtkm::CopyFlag::On);
auto yArray = vtkm::cont::make_ArrayHandle(yVals, vtkm::CopyFlag::On);
auto zArray = vtkm::cont::make_ArrayHandle(zVals, vtkm::CopyFlag::On);
vtkm::cont::ArrayHandle<vtkm::UInt8> Sc;
vtkm::cont::ArrayHandle<vtkm::IdComponent> Nc;
vtkm::cont::ArrayHandle<vtkm::Id> Cc;
DataSetBuilderExplicit::CopyInto(shapes, Sc);
DataSetBuilderExplicit::CopyInto(numIndices, Nc);
DataSetBuilderExplicit::CopyInto(connectivity, Cc);
auto shapesArray = vtkm::cont::make_ArrayHandle(shapes, vtkm::CopyFlag::On);
auto connArray = vtkm::cont::make_ArrayHandle(connectivity, vtkm::CopyFlag::On);
return DataSetBuilderExplicit::BuildDataSet(Xc, Yc, Zc, Sc, Nc, Cc, coordsNm);
auto offsetsArray = vtkm::cont::ConvertNumIndicesToOffsets(
vtkm::cont::make_ArrayHandle(numIndices, vtkm::CopyFlag::Off));
return DataSetBuilderExplicit::BuildDataSet(
xArray, yArray, zArray, shapesArray, offsetsArray, connArray, coordsNm);
}
template <typename T>
@ -186,13 +181,13 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
const vtkm::cont::ArrayHandle<T>& Y,
const vtkm::cont::ArrayHandle<T>& Z,
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
const vtkm::cont::ArrayHandle<vtkm::Id>& offsets,
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
const std::string& coordsNm)
{
VTKM_ASSERT(X.GetNumberOfValues() == Y.GetNumberOfValues() &&
Y.GetNumberOfValues() == Z.GetNumberOfValues() && X.GetNumberOfValues() > 0 &&
shapes.GetNumberOfValues() == numIndices.GetNumberOfValues());
shapes.GetNumberOfValues() + 1 == offsets.GetNumberOfValues());
vtkm::cont::DataSet dataSet;
dataSet.AddCoordinateSystem(
@ -200,7 +195,7 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
vtkm::Id nPts = X.GetNumberOfValues();
vtkm::cont::CellSetExplicit<> cellSet;
cellSet.Fill(nPts, shapes, numIndices, connectivity);
cellSet.Fill(nPts, shapes, connectivity, offsets);
dataSet.SetCellSet(cellSet);
return dataSet;
@ -214,24 +209,22 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
const std::vector<vtkm::Id>& connectivity,
const std::string& coordsNm)
{
vtkm::cont::ArrayHandle<Vec<T, 3>> coordsArray;
DataSetBuilderExplicit::CopyInto(coords, coordsArray);
auto coordsArray = vtkm::cont::make_ArrayHandle(coords, vtkm::CopyFlag::On);
auto shapesArray = vtkm::cont::make_ArrayHandle(shapes, vtkm::CopyFlag::On);
auto connArray = vtkm::cont::make_ArrayHandle(connectivity, vtkm::CopyFlag::On);
vtkm::cont::ArrayHandle<vtkm::UInt8> Sc;
vtkm::cont::ArrayHandle<vtkm::IdComponent> Nc;
vtkm::cont::ArrayHandle<vtkm::Id> Cc;
DataSetBuilderExplicit::CopyInto(shapes, Sc);
DataSetBuilderExplicit::CopyInto(numIndices, Nc);
DataSetBuilderExplicit::CopyInto(connectivity, Cc);
auto offsetsArray = vtkm::cont::ConvertNumIndicesToOffsets(
vtkm::cont::make_ArrayHandle(numIndices, vtkm::CopyFlag::Off));
return DataSetBuilderExplicit::Create(coordsArray, Sc, Nc, Cc, coordsNm);
return DataSetBuilderExplicit::BuildDataSet(
coordsArray, shapesArray, offsetsArray, connArray, coordsNm);
}
template <typename T>
inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
const vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>>& coords,
const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes,
const vtkm::cont::ArrayHandle<vtkm::IdComponent>& numIndices,
const vtkm::cont::ArrayHandle<vtkm::Id>& offsets,
const vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
const std::string& coordsNm)
{
@ -241,7 +234,7 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::BuildDataSet(
vtkm::Id nPts = static_cast<vtkm::Id>(coords.GetNumberOfValues());
vtkm::cont::CellSetExplicit<> cellSet;
cellSet.Fill(nPts, shapes, numIndices, connectivity);
cellSet.Fill(nPts, shapes, connectivity, offsets);
dataSet.SetCellSet(cellSet);
return dataSet;
@ -255,13 +248,11 @@ inline VTKM_CONT vtkm::cont::DataSet DataSetBuilderExplicit::Create(
const std::vector<vtkm::Id>& connectivity,
const std::string& coordsNm)
{
vtkm::cont::ArrayHandle<Vec<T, 3>> coordsArray;
DataSetBuilderExplicit::CopyInto(coords, coordsArray);
auto coordsArray = vtkm::cont::make_ArrayHandle(coords, vtkm::CopyFlag::On);
auto connArray = vtkm::cont::make_ArrayHandle(connectivity, vtkm::CopyFlag::On);
vtkm::cont::ArrayHandle<vtkm::Id> Cc;
DataSetBuilderExplicit::CopyInto(connectivity, Cc);
return DataSetBuilderExplicit::Create(coordsArray, tag, numberOfPointsPerCell, Cc, coordsNm);
return DataSetBuilderExplicit::Create(
coordsArray, tag, numberOfPointsPerCell, connArray, coordsNm);
}
template <typename T, typename CellShapeTag>

@ -12,6 +12,7 @@
#include <vtkm/CellShape.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayGetValues.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleConstant.h>
@ -26,67 +27,24 @@ namespace cont
namespace internal
{
template <typename NumIndicesArrayType, typename IndexOffsetArrayType>
void buildIndexOffsets(const NumIndicesArrayType& numIndices,
IndexOffsetArrayType& offsets,
vtkm::cont::DeviceAdapterId device,
std::true_type)
{
//We first need to make sure that NumIndices and IndexOffsetArrayType
//have the same type so we can call scane exclusive
using CastedNumIndicesType = vtkm::cont::ArrayHandleCast<vtkm::Id, NumIndicesArrayType>;
// Although technically we are making changes to this object, the changes
// are logically consistent with the previous state, so we consider it
// valid under const.
vtkm::cont::Algorithm::ScanExclusive(device, CastedNumIndicesType(numIndices), offsets);
}
template <typename NumIndicesArrayType, typename IndexOffsetArrayType>
void buildIndexOffsets(const NumIndicesArrayType&,
IndexOffsetArrayType&,
vtkm::cont::DeviceAdapterId,
std::false_type)
{
//this is a no-op as the storage for the offsets is an implicit handle
//and should already be built. This signature exists so that
//the compiler doesn't try to generate un-used code that will
//try and run Algorithm::ScanExclusive on an implicit array which will
//cause a compile time failure.
}
template <typename ArrayHandleIndices, typename ArrayHandleOffsets>
void buildIndexOffsets(const ArrayHandleIndices& numIndices,
ArrayHandleOffsets offsets,
vtkm::cont::DeviceAdapterId deviceId)
{
using IsWritable = vtkm::cont::internal::IsWritableArrayHandle<ArrayHandleOffsets>;
buildIndexOffsets(numIndices, offsets, deviceId, typename IsWritable::type());
}
template <typename ShapeStorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename NumIndicesStorageTag = VTKM_DEFAULT_STORAGE_TAG,
template <typename ShapesStorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename ConnectivityStorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename IndexOffsetStorageTag = VTKM_DEFAULT_STORAGE_TAG>
typename OffsetsStorageTag = VTKM_DEFAULT_STORAGE_TAG>
struct ConnectivityExplicitInternals
{
using ShapeArrayType = vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeStorageTag>;
using NumIndicesArrayType = vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag>;
using ShapesArrayType = vtkm::cont::ArrayHandle<vtkm::UInt8, ShapesStorageTag>;
using ConnectivityArrayType = vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityStorageTag>;
using IndexOffsetArrayType = vtkm::cont::ArrayHandle<vtkm::Id, IndexOffsetStorageTag>;
using OffsetsArrayType = vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>;
ShapeArrayType Shapes;
NumIndicesArrayType NumIndices;
ShapesArrayType Shapes;
ConnectivityArrayType Connectivity;
mutable IndexOffsetArrayType IndexOffsets;
OffsetsArrayType Offsets;
bool ElementsValid;
mutable bool IndexOffsetsValid;
VTKM_CONT
ConnectivityExplicitInternals()
: ElementsValid(false)
, IndexOffsetsValid(false)
{
}
@ -102,26 +60,8 @@ struct ConnectivityExplicitInternals
void ReleaseResourcesExecution()
{
this->Shapes.ReleaseResourcesExecution();
this->NumIndices.ReleaseResourcesExecution();
this->Connectivity.ReleaseResourcesExecution();
this->IndexOffsets.ReleaseResourcesExecution();
}
VTKM_CONT void BuildIndexOffsets(vtkm::cont::DeviceAdapterId deviceId) const
{
if (deviceId == vtkm::cont::DeviceAdapterTagUndefined())
{
throw vtkm::cont::ErrorBadValue("Cannot build indices using DeviceAdapterTagUndefined");
}
VTKM_ASSERT(this->ElementsValid);
if (!this->IndexOffsetsValid)
{
buildIndexOffsets(this->NumIndices, this->IndexOffsets, deviceId);
this->IndexOffsetsValid = true;
}
this->Offsets.ReleaseResourcesExecution();
}
VTKM_CONT
@ -131,19 +71,10 @@ struct ConnectivityExplicitInternals
{
out << " Shapes: ";
vtkm::cont::printSummary_ArrayHandle(this->Shapes, out);
out << " NumIndices: ";
vtkm::cont::printSummary_ArrayHandle(this->NumIndices, out);
out << " Connectivity: ";
vtkm::cont::printSummary_ArrayHandle(this->Connectivity, out);
if (this->IndexOffsetsValid)
{
out << " IndexOffsets: ";
vtkm::cont::printSummary_ArrayHandle(this->IndexOffsets, out);
}
else
{
out << " IndexOffsets: Not Allocated" << std::endl;
}
out << " Offsets: ";
vtkm::cont::printSummary_ArrayHandle(this->Offsets, out);
}
else
{
@ -225,95 +156,73 @@ struct ConnIdxToCellIdCalcSingleType
vtkm::Id operator()(vtkm::Id inIdx) const { return inIdx / this->CellSize; }
};
template <typename VisitCellsWithPoints, typename VisitPointsWithCells, typename Device>
void ComputeVisitPointsWithCellsConnectivity(VisitPointsWithCells& cell2Point,
const VisitCellsWithPoints& point2Cell,
vtkm::Id numberOfPoints,
Device)
template <typename ConnTableT, typename RConnTableT, typename Device>
void ComputeRConnTable(RConnTableT& rConnTable,
const ConnTableT& connTable,
vtkm::Id numberOfPoints,
Device)
{
if (cell2Point.ElementsValid)
if (rConnTable.ElementsValid)
{
return;
}
auto& conn = point2Cell.Connectivity;
auto& rConn = cell2Point.Connectivity;
auto& rNumIndices = cell2Point.NumIndices;
auto& rIndexOffsets = cell2Point.IndexOffsets;
vtkm::Id rConnSize = conn.GetNumberOfValues();
const auto& conn = connTable.Connectivity;
auto& rConn = rConnTable.Connectivity;
auto& rOffsets = rConnTable.Offsets;
const vtkm::Id rConnSize = conn.GetNumberOfValues();
auto offInPortal = point2Cell.IndexOffsets.PrepareForInput(Device{});
const auto offInPortal = connTable.Offsets.PrepareForInput(Device{});
PassThrough idxCalc{};
ConnIdxToCellIdCalc<decltype(offInPortal)> cellIdCalc{ offInPortal };
vtkm::cont::internal::ReverseConnectivityBuilder builder;
builder.Run(conn,
rConn,
rNumIndices,
rIndexOffsets,
idxCalc,
cellIdCalc,
numberOfPoints,
rConnSize,
Device());
builder.Run(conn, rConn, rOffsets, idxCalc, cellIdCalc, numberOfPoints, rConnSize, Device());
// Set the VisitPointsWithCells information
cell2Point.Shapes = vtkm::cont::make_ArrayHandleConstant(
rConnTable.Shapes = vtkm::cont::make_ArrayHandleConstant(
static_cast<vtkm::UInt8>(CELL_SHAPE_VERTEX), numberOfPoints);
cell2Point.ElementsValid = true;
cell2Point.IndexOffsetsValid = true;
rConnTable.ElementsValid = true;
}
// Specialize for CellSetSingleType:
template <typename ShapeStorageTag,
typename ConnectivityStorageTag,
typename IndexOffsetStorageTag,
typename VisitPointsWithCells,
typename Device>
void ComputeVisitPointsWithCellsConnectivity(
VisitPointsWithCells& cell2Point,
const ConnectivityExplicitInternals<
ShapeStorageTag,
vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag, // nIndices
ConnectivityStorageTag,
IndexOffsetStorageTag>& point2Cell,
vtkm::Id numberOfPoints,
Device)
template <typename RConnTableT, typename ConnectivityStorageTag, typename Device>
void ComputeRConnTable(RConnTableT& rConnTable,
const ConnectivityExplicitInternals< // SingleType specialization types:
typename vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag,
ConnectivityStorageTag,
typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>& connTable,
vtkm::Id numberOfPoints,
Device)
{
if (cell2Point.ElementsValid)
if (rConnTable.ElementsValid)
{
return;
}
auto& conn = point2Cell.Connectivity;
auto& rConn = cell2Point.Connectivity;
auto& rNumIndices = cell2Point.NumIndices;
auto& rIndexOffsets = cell2Point.IndexOffsets;
vtkm::Id rConnSize = conn.GetNumberOfValues();
const auto& conn = connTable.Connectivity;
auto& rConn = rConnTable.Connectivity;
auto& rOffsets = rConnTable.Offsets;
const vtkm::Id rConnSize = conn.GetNumberOfValues();
auto sizesInPortal = point2Cell.NumIndices.GetPortalConstControl();
vtkm::IdComponent cellSize = sizesInPortal.GetNumberOfValues() > 0 ? sizesInPortal.Get(0) : 0;
const vtkm::IdComponent cellSize = [&]() -> vtkm::IdComponent {
if (connTable.Offsets.GetNumberOfValues() >= 2)
{
const auto firstTwo = vtkm::cont::ArrayGetValues({ 0, 1 }, connTable.Offsets);
return static_cast<vtkm::IdComponent>(firstTwo[1] - firstTwo[0]);
}
return 0;
}();
PassThrough idxCalc{};
ConnIdxToCellIdCalcSingleType cellIdCalc{ cellSize };
vtkm::cont::internal::ReverseConnectivityBuilder builder;
builder.Run(conn,
rConn,
rNumIndices,
rIndexOffsets,
idxCalc,
cellIdCalc,
numberOfPoints,
rConnSize,
Device());
builder.Run(conn, rConn, rOffsets, idxCalc, cellIdCalc, numberOfPoints, rConnSize, Device());
// Set the VisitPointsWithCells information
cell2Point.Shapes = vtkm::cont::make_ArrayHandleConstant(
rConnTable.Shapes = vtkm::cont::make_ArrayHandleConstant(
static_cast<vtkm::UInt8>(CELL_SHAPE_VERTEX), numberOfPoints);
cell2Point.ElementsValid = true;
cell2Point.IndexOffsetsValid = true;
rConnTable.ElementsValid = true;
}
}
}

@ -131,15 +131,13 @@ public:
VTKM_CONT
template <typename ConnArray,
typename RConnArray,
typename RNumArray,
typename RIndexArray,
typename ROffsetsArray,
typename RConnToConnIdxCalc,
typename ConnIdxToCellIdxCalc,
typename Device>
inline void Run(const ConnArray& conn,
RConnArray& rConn,
RNumArray& rNumIndices,
RIndexArray& rIndexOffsets,
ROffsetsArray& rOffsets,
const RConnToConnIdxCalc& rConnToConnCalc,
const ConnIdxToCellIdxCalc& cellIdCalc,
vtkm::Id numberOfPoints,
@ -152,12 +150,13 @@ public:
auto zeros = vtkm::cont::make_ArrayHandleConstant(vtkm::IdComponent{ 0 }, numberOfPoints);
// Compute RConn offsets by atomically building a histogram and doing an
// exclusive scan.
// extended scan.
//
// Example:
// (in) Conn: | 3 0 1 2 | 3 0 1 3 | 3 0 3 4 | 3 3 4 5 |
// (out) RNumIndices: 3 2 1 3 2 1
// (out) RIdxOffsets: 0 3 5 6 9 11
// (out) RIdxOffsets: 0 3 5 6 9 11 12
vtkm::cont::ArrayHandle<vtkm::IdComponent> rNumIndices;
{ // allocate and zero the numIndices array:
Algo::Copy(zeros, rNumIndices);
}
@ -165,17 +164,15 @@ public:
{ // Build histogram:
vtkm::cont::AtomicArray<vtkm::IdComponent> atomicCounter{ rNumIndices };
auto ac = atomicCounter.PrepareForExecution(Device());
rcb::BuildHistogram<decltype(ac), decltype(connPortal), RConnToConnIdxCalc> histoGen{
ac, connPortal, rConnToConnCalc
};
using BuildHisto =
rcb::BuildHistogram<decltype(ac), decltype(connPortal), RConnToConnIdxCalc>;
BuildHisto histoGen{ ac, connPortal, rConnToConnCalc };
Algo::Schedule(histoGen, rConnSize);
}
{ // Compute offsets:
auto rNumIndicesAsId =
vtkm::cont::make_ArrayHandleCast<typename RIndexArray::ValueType>(rNumIndices);
Algo::ScanExclusive(rNumIndicesAsId, rIndexOffsets);
Algo::ScanExtended(vtkm::cont::make_ArrayHandleCast<vtkm::Id>(rNumIndices), rOffsets);
}
{ // Reset the numIndices array to 0's:
@ -198,16 +195,16 @@ public:
{
vtkm::cont::AtomicArray<vtkm::IdComponent> atomicCounter{ rNumIndices };
auto ac = atomicCounter.PrepareForExecution(Device());
auto rOffsetPortal = rIndexOffsets.PrepareForInput(Device());
auto rOffsetPortal = rOffsets.PrepareForInput(Device());
auto rConnPortal = rConn.PrepareForOutput(rConnSize, Device());
rcb::GenerateRConn<decltype(ac),
decltype(connPortal),
decltype(rOffsetPortal),
decltype(rConnPortal),
RConnToConnIdxCalc,
ConnIdxToCellIdxCalc>
rConnGen{ ac, connPortal, rOffsetPortal, rConnPortal, rConnToConnCalc, cellIdCalc };
using GenRConnT = rcb::GenerateRConn<decltype(ac),
decltype(connPortal),
decltype(rOffsetPortal),
decltype(rConnPortal),
RConnToConnIdxCalc,
ConnIdxToCellIdxCalc>;
GenRConnT rConnGen{ ac, connPortal, rOffsetPortal, rConnPortal, rConnToConnCalc, cellIdCalc };
Algo::Schedule(rConnGen, rConnSize);
}

@ -229,11 +229,10 @@ namespace detail
struct TestEqualCellSet
{
template <typename ShapeST, typename CountST, typename ConnectivityST, typename OffsetST>
void operator()(
const vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>& cs1,
const vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>& cs2,
TestEqualResult& result) const
template <typename ShapeST, typename ConnectivityST, typename OffsetST>
void operator()(const vtkm::cont::CellSetExplicit<ShapeST, ConnectivityST, OffsetST>& cs1,
const vtkm::cont::CellSetExplicit<ShapeST, ConnectivityST, OffsetST>& cs2,
TestEqualResult& result) const
{
vtkm::TopologyElementTagCell visitTopo{};
vtkm::TopologyElementTagPoint incidentTopo{};
@ -266,8 +265,8 @@ struct TestEqualCellSet
result.PushMessage("connectivity arrays don't match");
return;
}
result = test_equal_ArrayHandles(cs1.GetIndexOffsetArray(visitTopo, incidentTopo),
cs2.GetIndexOffsetArray(visitTopo, incidentTopo));
result = test_equal_ArrayHandles(cs1.GetOffsetsArray(visitTopo, incidentTopo),
cs2.GetOffsetsArray(visitTopo, incidentTopo));
if (!result)
{
result.PushMessage("offsets arrays don't match");

@ -100,14 +100,14 @@ private:
vtkm::cont::ArrayHandleConstant<vtkm::UInt8> shapes =
cellset.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices =
auto numIndices =
cellset.GetNumIndicesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
vtkm::cont::ArrayHandle<vtkm::Id> conn =
cellset.GetConnectivityArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
VTKM_TEST_ASSERT(TestArrayHandle(shapes, correctShapes, numPoints), "Got incorrect shapes");
VTKM_TEST_ASSERT(TestArrayHandle(numIndices, correctNumIndices, numPoints),
"Got incorrect shapes");
"Got incorrect numIndices");
// Some device adapters have unstable sorts, which may cause the order of
// the indices for each point to be different but still correct. Iterate

@ -105,26 +105,20 @@ private:
//verify that the point to cell connectivity types are correct
vtkm::cont::ArrayHandleConstant<vtkm::UInt8> shapesPointToCell =
cellset.GetShapesArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
vtkm::cont::ArrayHandleConstant<vtkm::IdComponent> numIndicesPointToCell =
cellset.GetNumIndicesArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
vtkm::cont::ArrayHandle<vtkm::Id> connPointToCell =
cellset.GetConnectivityArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
VTKM_TEST_ASSERT(shapesPointToCell.GetNumberOfValues() == 3, "Wrong number of shapes");
VTKM_TEST_ASSERT(numIndicesPointToCell.GetNumberOfValues() == 3, "Wrong number of indices");
VTKM_TEST_ASSERT(connPointToCell.GetNumberOfValues() == 9, "Wrong connectivity length");
//verify that the cell to point connectivity types are correct
//note the handle storage types differ compared to point to cell
vtkm::cont::ArrayHandleConstant<vtkm::UInt8> shapesCellToPoint =
cellset.GetShapesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndicesCellToPoint =
cellset.GetNumIndicesArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
vtkm::cont::ArrayHandle<vtkm::Id> connCellToPoint =
cellset.GetConnectivityArray(vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell());
VTKM_TEST_ASSERT(shapesCellToPoint.GetNumberOfValues() == 5, "Wrong number of shapes");
VTKM_TEST_ASSERT(numIndicesCellToPoint.GetNumberOfValues() == 5, "Wrong number of indices");
VTKM_TEST_ASSERT(connCellToPoint.GetNumberOfValues() == 9, "Wrong connectivity length");
//run a basic for-each topology algorithm on this

@ -75,8 +75,10 @@ vtkm::cont::CellSetExplicit<> MakeCellSetExplicit()
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
vtkm::cont::ArrayCopy(BaseLineConnectivity, connectivity);
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices);
vtkm::cont::CellSetExplicit<> cellset;
cellset.Fill(BaseLineNumberOfPoints, shapes, numIndices, connectivity);
cellset.Fill(BaseLineNumberOfPoints, shapes, connectivity, offsets);
return cellset;
}

@ -22,18 +22,18 @@ using PointTag = vtkm::TopologyElementTagPoint;
const vtkm::Id numberOfPoints = 11;
vtkm::UInt8 g_shapes[] = { static_cast<vtkm::UInt8>(vtkm::CELL_SHAPE_HEXAHEDRON),
static_cast<vtkm::UInt8>(vtkm::CELL_SHAPE_PYRAMID),
static_cast<vtkm::UInt8>(vtkm::CELL_SHAPE_TETRA),
static_cast<vtkm::UInt8>(vtkm::CELL_SHAPE_WEDGE) };
const vtkm::UInt8 g_shapes[] = { static_cast<vtkm::UInt8>(vtkm::CELL_SHAPE_HEXAHEDRON),
static_cast<vtkm::UInt8>(vtkm::CELL_SHAPE_PYRAMID),
static_cast<vtkm::UInt8>(vtkm::CELL_SHAPE_TETRA),
static_cast<vtkm::UInt8>(vtkm::CELL_SHAPE_WEDGE) };
const vtkm::UInt8 g_shapes2[] = { g_shapes[1], g_shapes[2] };
vtkm::IdComponent g_numIndices[] = { 8, 5, 4, 6 };
const vtkm::Id g_offsets[] = { 0, 8, 13, 17, 23 };
const vtkm::Id g_offsets2[] = { 0, 5, 9 };
vtkm::Id g_indexOffset[] = { 0, 8, 13, 17 };
vtkm::Id g_connectivity[] = {
0, 1, 5, 4, 3, 2, 6, 7, 1, 5, 6, 2, 8, 5, 8, 10, 6, 4, 7, 9, 5, 6, 10
};
const vtkm::Id g_connectivity[] = { 0, 1, 5, 4, 3, 2, 6, 7, 1, 5, 6, 2,
8, 5, 8, 10, 6, 4, 7, 9, 5, 6, 10 };
const vtkm::Id g_connectivity2[] = { 1, 5, 6, 2, 8, 5, 8, 10, 6 };
template <typename T, std::size_t Length>
vtkm::Id ArrayLength(const T (&)[Length])
@ -46,10 +46,9 @@ vtkm::cont::CellSetExplicit<> MakeTestCellSet1()
{
vtkm::cont::CellSetExplicit<> cs;
cs.Fill(numberOfPoints,
vtkm::cont::make_ArrayHandle(g_shapes, 4),
vtkm::cont::make_ArrayHandle(g_numIndices, 4),
vtkm::cont::make_ArrayHandle(g_shapes, ArrayLength(g_shapes)),
vtkm::cont::make_ArrayHandle(g_connectivity, ArrayLength(g_connectivity)),
vtkm::cont::make_ArrayHandle(g_indexOffset, 4));
vtkm::cont::make_ArrayHandle(g_offsets, ArrayLength(g_offsets)));
return cs;
}
@ -58,10 +57,9 @@ vtkm::cont::CellSetExplicit<> MakeTestCellSet2()
{
vtkm::cont::CellSetExplicit<> cs;
cs.Fill(numberOfPoints,
vtkm::cont::make_ArrayHandle(g_shapes + 1, 2),
vtkm::cont::make_ArrayHandle(g_numIndices + 1, 2),
vtkm::cont::make_ArrayHandle(g_connectivity + g_indexOffset[1],
g_indexOffset[3] - g_indexOffset[1]));
vtkm::cont::make_ArrayHandle(g_shapes2, ArrayLength(g_shapes2)),
vtkm::cont::make_ArrayHandle(g_connectivity2, ArrayLength(g_connectivity2)),
vtkm::cont::make_ArrayHandle(g_offsets2, ArrayLength(g_offsets2)));
return cs;
}
@ -107,7 +105,8 @@ void TestCellSetExplicit()
"result length not equal to number of cells");
for (vtkm::Id i = 0; i < result.GetNumberOfValues(); ++i)
{
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(i) == g_numIndices[i], "incorrect result");
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(i) == cellset.GetNumberOfPointsInCell(i),
"incorrect result");
}
std::cout << "\tTesting CellToPoint\n";
@ -131,9 +130,11 @@ void TestCellSetExplicit()
VTKM_TEST_ASSERT(result.GetNumberOfValues() == cellset.GetNumberOfCells(),
"result length not equal to number of cells");
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(0) == g_numIndices[1] &&
result.GetPortalConstControl().Get(1) == g_numIndices[2],
"incorrect result");
for (vtkm::Id i = 0; i < result.GetNumberOfValues(); ++i)
{
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(i) == cellset.GetNumberOfPointsInCell(i),
"incorrect result");
}
std::cout << "\tTesting CellToPoint\n";
vtkm::worklet::DispatcherMapTopology<WorkletCellToPoint>().Invoke(cellset, result);
@ -144,7 +145,8 @@ void TestCellSetExplicit()
vtkm::Id expected2[] = { 0, 1, 1, 0, 0, 2, 2, 0, 2, 0, 1 };
for (vtkm::Id i = 0; i < result.GetNumberOfValues(); ++i)
{
VTKM_TEST_ASSERT(result.GetPortalConstControl().Get(i) == expected2[i], "incorrect result");
VTKM_TEST_ASSERT(
result.GetPortalConstControl().Get(i) == expected2[i], "incorrect result at ", i);
}
std::cout << "----------------------------------------------------\n";
@ -152,7 +154,7 @@ void TestCellSetExplicit()
std::cout << "\tTesting resource releasing in CellSetExplicit\n";
cellset.ReleaseResourcesExecution();
VTKM_TEST_ASSERT(cellset.GetNumberOfCells() == ArrayLength(g_numIndices) / 2,
VTKM_TEST_ASSERT(cellset.GetNumberOfCells() == ArrayLength(g_shapes) / 2,
"release execution resources should not change the number of cells");
VTKM_TEST_ASSERT(cellset.GetNumberOfPoints() == ArrayLength(expected2),
"release execution resources should not change the number of points");

@ -20,10 +20,7 @@ namespace vtkm
namespace exec
{
template <typename ShapePortalType,
typename NumIndicesPortalType,
typename ConnectivityPortalType,
typename IndexOffsetPortalType>
template <typename ShapesPortalType, typename ConnectivityPortalType, typename OffsetsPortalType>
class ConnectivityExplicit
{
public:
@ -31,14 +28,12 @@ public:
ConnectivityExplicit() {}
ConnectivityExplicit(const ShapePortalType& shapePortal,
const NumIndicesPortalType& numIndicesPortal,
ConnectivityExplicit(const ShapesPortalType& shapesPortal,
const ConnectivityPortalType& connPortal,
const IndexOffsetPortalType& indexOffsetPortal)
: Shapes(shapePortal)
, NumIndices(numIndicesPortal)
const OffsetsPortalType& offsetsPortal)
: Shapes(shapesPortal)
, Connectivity(connPortal)
, IndexOffset(indexOffsetPortal)
, Offsets(offsetsPortal)
{
}
@ -51,7 +46,10 @@ public:
CellShapeTag GetCellShape(vtkm::Id index) const { return CellShapeTag(this->Shapes.Get(index)); }
VTKM_EXEC
vtkm::IdComponent GetNumberOfIndices(vtkm::Id index) const { return this->NumIndices.Get(index); }
vtkm::IdComponent GetNumberOfIndices(vtkm::Id index) const
{
return static_cast<vtkm::IdComponent>(this->Offsets.Get(index + 1) - this->Offsets.Get(index));
}
using IndicesType = vtkm::VecFromPortal<ConnectivityPortalType>;
@ -63,16 +61,17 @@ public:
VTKM_EXEC
IndicesType GetIndices(vtkm::Id index) const
{
vtkm::Id offset = this->IndexOffset.Get(index);
vtkm::IdComponent length = this->NumIndices.Get(index);
const vtkm::Id offset = this->Offsets.Get(index);
const vtkm::Id endOffset = this->Offsets.Get(index + 1);
const auto length = static_cast<vtkm::IdComponent>(endOffset - offset);
return IndicesType(this->Connectivity, length, offset);
}
private:
ShapePortalType Shapes;
NumIndicesPortalType NumIndices;
ShapesPortalType Shapes;
ConnectivityPortalType Connectivity;
IndexOffsetPortalType IndexOffset;
OffsetsPortalType Offsets;
};
} // namespace exec

@ -80,9 +80,7 @@ public:
OriginalConnectivity Connectivity;
};
template <typename ConnectivityPortalType,
typename NumIndicesPortalType,
typename IndexOffsetPortalType>
template <typename ConnectivityPortalType, typename OffsetPortalType>
class ConnectivityPermutedVisitPointsWithCells
{
public:
@ -93,32 +91,36 @@ public:
ConnectivityPermutedVisitPointsWithCells() = default;
ConnectivityPermutedVisitPointsWithCells(const ConnectivityPortalType& connectivity,
const NumIndicesPortalType& numIndices,
const IndexOffsetPortalType& indexOffset)
const OffsetPortalType& offsets)
: Connectivity(connectivity)
, NumIndices(numIndices)
, IndexOffset(indexOffset)
, Offsets(offsets)
{
}
VTKM_EXEC
SchedulingRangeType GetNumberOfElements() const { return this->NumIndices.GetNumberOfValues(); }
SchedulingRangeType GetNumberOfElements() const { return this->Offsets.GetNumberOfValues() - 1; }
VTKM_EXEC CellShapeTag GetCellShape(vtkm::Id) const { return CellShapeTag(); }
VTKM_EXEC
vtkm::IdComponent GetNumberOfIndices(vtkm::Id index) const { return this->NumIndices.Get(index); }
vtkm::IdComponent GetNumberOfIndices(vtkm::Id index) const
{
const vtkm::Id offBegin = this->Offsets.Get(index);
const vtkm::Id offEnd = this->Offsets.Get(index + 1);
return static_cast<vtkm::IdComponent>(offEnd - offBegin);
}
VTKM_EXEC IndicesType GetIndices(vtkm::Id index) const
{
const vtkm::Id offBegin = this->Offsets.Get(index);
const vtkm::Id offEnd = this->Offsets.Get(index + 1);
return IndicesType(
this->Connectivity, this->NumIndices.Get(index), this->IndexOffset.Get(index));
this->Connectivity, static_cast<vtkm::IdComponent>(offEnd - offBegin), offBegin);
}
private:
ConnectivityPortalType Connectivity;
NumIndicesPortalType NumIndices;
IndexOffsetPortalType IndexOffset;
OffsetPortalType Offsets;
};
}
} // namespace vtkm::exec

@ -44,22 +44,24 @@ inline VTKM_CONT vtkm::cont::DataSet CleanGrid::DoExecute(const vtkm::cont::Data
vtkm::cont::ArrayHandle<vtkm::UInt8> shapes;
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
vtkm::Id connectivitySize;
vtkm::cont::ConvertNumComponentsToOffsets(numIndices, offsets, connectivitySize);
vtkm::cont::ConvertNumIndicesToOffsets(numIndices, offsets, connectivitySize);
numIndices.ReleaseResourcesExecution();
vtkm::cont::ArrayHandle<vtkm::Id> connectivity;
connectivity.Allocate(connectivitySize);
auto offsetsTrim =
vtkm::cont::make_ArrayHandleView(offsets, 0, offsets.GetNumberOfValues() - 1);
this->Invoke(worklet::CellDeepCopy::PassCellStructure{},
deducedCellSet,
shapes,
vtkm::cont::make_ArrayHandleGroupVecVariable(connectivity, offsets));
vtkm::cont::make_ArrayHandleGroupVecVariable(connectivity, offsetsTrim));
shapes.ReleaseResourcesExecution();
offsets.ReleaseResourcesExecution();
connectivity.ReleaseResourcesExecution();
outputCellSet.Fill(
deducedCellSet.GetNumberOfPoints(), shapes, numIndices, connectivity, offsets);
outputCellSet.Fill(deducedCellSet.GetNumberOfPoints(), shapes, connectivity, offsets);
//Release the input grid from the execution space
deducedCellSet.ReleaseResourcesExecution();

@ -154,8 +154,9 @@ private:
}
else
{
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices);
vtkm::cont::CellSetExplicit<> cellSet;
cellSet.Fill(numPoints, shapes, numIndices, connectivity);
cellSet.Fill(numPoints, shapes, connectivity, offsets);
this->DataSet.SetCellSet(cellSet);
}

@ -80,8 +80,9 @@ private:
}
else
{
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices);
vtkm::cont::CellSetExplicit<> cellSet;
cellSet.Fill(numPoints, shapes, numIndices, connectivity);
cellSet.Fill(numPoints, shapes, connectivity, offsets);
this->DataSet.SetCellSet(cellSet);
}

@ -685,9 +685,10 @@ void MeshConnectivityBuilder::BuildConnectivity(
const vtkm::cont::ArrayHandle<vtkm::Id> conn = cellSetUnstructured.GetConnectivityArray(
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
const vtkm::cont::ArrayHandleCounting<vtkm::Id> shapeOffsets =
cellSetUnstructured.GetIndexOffsetArray(vtkm::TopologyElementTagCell(),
vtkm::TopologyElementTagPoint());
const vtkm::cont::ArrayHandleCounting<vtkm::Id> offsets = cellSetUnstructured.GetOffsetsArray(
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
const auto shapeOffsets =
vtkm::cont::make_ArrayHandleView(offsets, 0, offsets.GetNumberOfValues() - 1);
vtkm::cont::ArrayHandle<vtkm::Id> faceConnectivity;
vtkm::cont::ArrayHandle<vtkm::Id3> cellFaceId;
@ -746,8 +747,10 @@ void MeshConnectivityBuilder::BuildConnectivity(
const vtkm::cont::ArrayHandle<vtkm::Id> conn = cellSetUnstructured.GetConnectivityArray(
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
const vtkm::cont::ArrayHandle<vtkm::Id> shapeOffsets = cellSetUnstructured.GetIndexOffsetArray(
const vtkm::cont::ArrayHandle<vtkm::Id> offsets = cellSetUnstructured.GetOffsetsArray(
vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
const auto shapeOffsets =
vtkm::cont::make_ArrayHandleView(offsets, 0, offsets.GetNumberOfValues() - 1);
vtkm::cont::ArrayHandle<vtkm::Id> faceConnectivity;
vtkm::cont::ArrayHandle<vtkm::Id3> cellFaceId;

@ -71,7 +71,7 @@ UnstructuredContainer::UnstructuredContainer(const vtkm::cont::CellSetExplicit<>
CellConn =
Cellset.GetConnectivityArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
CellOffsets =
Cellset.GetIndexOffsetArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
Cellset.GetOffsetsArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
Shapes = Cellset.GetShapesArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
Intersector.SetData(Coords, Triangles);

@ -62,18 +62,15 @@ struct CellDeepCopy
template <typename InCellSetType,
typename ShapeStorage,
typename NumIndicesStorage,
typename ConnectivityStorage,
typename OffsetsStorage>
VTKM_CONT static void Run(const InCellSetType& inCellSet,
vtkm::cont::CellSetExplicit<ShapeStorage,
NumIndicesStorage,
ConnectivityStorage,
OffsetsStorage>& outCellSet)
VTKM_CONT static void Run(
const InCellSetType& inCellSet,
vtkm::cont::CellSetExplicit<ShapeStorage, ConnectivityStorage, OffsetsStorage>& outCellSet)
{
VTKM_IS_DYNAMIC_OR_STATIC_CELL_SET(InCellSetType);
vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorage> numIndices;
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndices;
vtkm::worklet::DispatcherMapTopology<CountCellPoints> countDispatcher;
countDispatcher.Invoke(inCellSet, numIndices);
@ -83,17 +80,18 @@ struct CellDeepCopy
vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorage> offsets;
vtkm::Id connectivitySize;
vtkm::cont::ConvertNumComponentsToOffsets(numIndices, offsets, connectivitySize);
vtkm::cont::ConvertNumIndicesToOffsets(numIndices, offsets, connectivitySize);
connectivity.Allocate(connectivitySize);
auto offsetsTrim =
vtkm::cont::make_ArrayHandleView(offsets, 0, offsets.GetNumberOfValues() - 1);
vtkm::worklet::DispatcherMapTopology<PassCellStructure> passDispatcher;
passDispatcher.Invoke(
inCellSet, shapes, vtkm::cont::make_ArrayHandleGroupVecVariable(connectivity, offsets));
inCellSet, shapes, vtkm::cont::make_ArrayHandleGroupVecVariable(connectivity, offsetsTrim));
vtkm::cont::
CellSetExplicit<ShapeStorage, NumIndicesStorage, ConnectivityStorage, OffsetsStorage>
newCellSet;
newCellSet.Fill(inCellSet.GetNumberOfPoints(), shapes, numIndices, connectivity, offsets);
vtkm::cont::CellSetExplicit<ShapeStorage, ConnectivityStorage, OffsetsStorage> newCellSet;
newCellSet.Fill(inCellSet.GetNumberOfPoints(), shapes, connectivity, offsets);
outCellSet = newCellSet;
}

@ -692,7 +692,10 @@ public:
vtkm::cont::CellSetExplicit<> output;
vtkm::Id numberOfPoints = scalars.GetNumberOfValues() +
this->EdgePointsInterpolation.GetNumberOfValues() + total.NumberOfInCellPoints;
output.Fill(numberOfPoints, shapes, numberOfIndices, connectivity);
vtkm::cont::ConvertNumIndicesToOffsets(numberOfIndices, offsets);
output.Fill(numberOfPoints, shapes, connectivity, offsets);
return output;
}

@ -27,6 +27,7 @@
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/ArrayHandleView.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/Field.h>
@ -668,16 +669,11 @@ public:
///
/// Faster Run() method for uniform and rectilinear grid types.
/// Uses grid extents to find cells on the boundaries of the grid.
template <typename ShapeStorage,
typename NumIndicesStorage,
typename ConnectivityStorage,
typename OffsetsStorage>
VTKM_CONT void Run(const vtkm::cont::CellSetStructured<3>& inCellSet,
const vtkm::cont::CoordinateSystem& coord,
vtkm::cont::CellSetExplicit<ShapeStorage,
NumIndicesStorage,
ConnectivityStorage,
OffsetsStorage>& outCellSet)
template <typename ShapeStorage, typename ConnectivityStorage, typename OffsetsStorage>
VTKM_CONT void Run(
const vtkm::cont::CellSetStructured<3>& inCellSet,
const vtkm::cont::CoordinateSystem& coord,
vtkm::cont::CellSetExplicit<ShapeStorage, ConnectivityStorage, OffsetsStorage>& outCellSet)
{
vtkm::Vec3f_64 MinPoint;
vtkm::Vec3f_64 MaxPoint;
@ -732,7 +728,7 @@ public:
vtkm::Id connectivitySize = 4 * numberOfExternalFaces;
vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityStorage> faceConnectivity;
vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeStorage> faceShapes;
vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorage> facePointCount;
vtkm::cont::ArrayHandle<vtkm::IdComponent> facePointCount;
// Must pre allocate because worklet invocation will not have enough
// information to.
faceConnectivity.Allocate(connectivitySize);
@ -748,23 +744,23 @@ public:
facePointCount,
vtkm::cont::make_ArrayHandleGroupVec<4>(faceConnectivity),
coordData);
outCellSet.Fill(inCellSet.GetNumberOfPoints(), faceShapes, facePointCount, faceConnectivity);
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(facePointCount);
outCellSet.Fill(inCellSet.GetNumberOfPoints(), faceShapes, faceConnectivity, offsets);
}
///////////////////////////////////////////////////
/// \brief ExternalFaces: Extract Faces on outside of geometry
template <typename InCellSetType,
typename ShapeStorage,
typename NumIndicesStorage,
typename ConnectivityStorage,
typename OffsetsStorage>
VTKM_CONT void Run(const InCellSetType& inCellSet,
vtkm::cont::CellSetExplicit<ShapeStorage,
NumIndicesStorage,
ConnectivityStorage,
OffsetsStorage>& outCellSet)
VTKM_CONT void Run(
const InCellSetType& inCellSet,
vtkm::cont::CellSetExplicit<ShapeStorage, ConnectivityStorage, OffsetsStorage>& outCellSet)
{
using PointCountArrayType = vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorage>;
using PointCountArrayType = vtkm::cont::ArrayHandle<vtkm::IdComponent>;
using ShapeArrayType = vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeStorage>;
using OffsetsArrayType = vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorage>;
using ConnectivityArrayType = vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityStorage>;
@ -802,7 +798,7 @@ public:
countPolyDataCellPointsDispatcher.Invoke(inCellSet, polyDataPointCount);
vtkm::cont::ConvertNumComponentsToOffsets(
vtkm::cont::ConvertNumIndicesToOffsets(
polyDataPointCount, polyDataOffsets, polyDataConnectivitySize);
vtkm::worklet::DispatcherMapTopology<PassPolyDataCells> passPolyDataCellsDispatcher(
@ -810,10 +806,13 @@ public:
polyDataConnectivity.Allocate(polyDataConnectivitySize);
auto pdOffsetsTrim = vtkm::cont::make_ArrayHandleView(
polyDataOffsets, 0, polyDataOffsets.GetNumberOfValues() - 1);
passPolyDataCellsDispatcher.Invoke(
inCellSet,
polyDataShapes,
vtkm::cont::make_ArrayHandleGroupVecVariable(polyDataConnectivity, polyDataOffsets),
vtkm::cont::make_ArrayHandleGroupVecVariable(polyDataConnectivity, pdOffsetsTrim),
polyDataCellIdMap);
}
}
@ -830,11 +829,8 @@ public:
else
{
// Pass only input poly data to output
outCellSet.Fill(inCellSet.GetNumberOfPoints(),
polyDataShapes,
polyDataPointCount,
polyDataConnectivity,
polyDataOffsets);
outCellSet.Fill(
inCellSet.GetNumberOfPoints(), polyDataShapes, polyDataConnectivity, polyDataOffsets);
this->CellIdMap = polyDataCellIdMap;
return;
}
@ -866,7 +862,7 @@ public:
OffsetsArrayType faceOffsets;
vtkm::Id connectivitySize;
vtkm::cont::ConvertNumComponentsToOffsets(facePointCount, faceOffsets, connectivitySize);
vtkm::cont::ConvertNumIndicesToOffsets(facePointCount, faceOffsets, connectivitySize);
ConnectivityArrayType faceConnectivity;
// Must pre allocate because worklet invocation will not have enough
@ -878,19 +874,22 @@ public:
vtkm::cont::ArrayHandle<vtkm::Id> faceToCellIdMap;
// Create a view that doesn't have the last offset:
auto faceOffsetsTrim =
vtkm::cont::make_ArrayHandleView(faceOffsets, 0, faceOffsets.GetNumberOfValues() - 1);
buildConnectivityDispatcher.Invoke(
faceKeys,
inCellSet,
originCells,
originFaces,
faceShapes,
vtkm::cont::make_ArrayHandleGroupVecVariable(faceConnectivity, faceOffsets),
vtkm::cont::make_ArrayHandleGroupVecVariable(faceConnectivity, faceOffsetsTrim),
faceToCellIdMap);
if (!polyDataConnectivitySize)
{
outCellSet.Fill(
inCellSet.GetNumberOfPoints(), faceShapes, facePointCount, faceConnectivity, faceOffsets);
outCellSet.Fill(inCellSet.GetNumberOfPoints(), faceShapes, faceConnectivity, faceOffsets);
this->CellIdMap = faceToCellIdMap;
}
else
@ -912,13 +911,11 @@ public:
vtkm::cont::ArrayCopy(connectivityArray, joinedConnectivity);
// Adjust poly data offsets array with face connectivity size before join
using TransformBiasArrayType =
vtkm::cont::ArrayHandleTransform<OffsetsArrayType, BiasFunctor<vtkm::Id>>;
TransformBiasArrayType adjustedPolyDataOffsets =
vtkm::cont::make_ArrayHandleTransform<OffsetsArrayType>(
polyDataOffsets, BiasFunctor<vtkm::Id>(faceConnectivity.GetNumberOfValues()));
vtkm::cont::ArrayHandleConcatenate<OffsetsArrayType, TransformBiasArrayType> offsetsArray(
faceOffsets, adjustedPolyDataOffsets);
auto adjustedPolyDataOffsets = vtkm::cont::make_ArrayHandleTransform(
polyDataOffsets, BiasFunctor<vtkm::Id>(faceConnectivity.GetNumberOfValues()));
auto offsetsArray =
vtkm::cont::make_ArrayHandleConcatenate(faceOffsetsTrim, adjustedPolyDataOffsets);
OffsetsArrayType joinedOffsets;
vtkm::cont::ArrayCopy(offsetsArray, joinedOffsets);
@ -928,11 +925,8 @@ public:
vtkm::cont::ArrayHandle<vtkm::Id> joinedCellIdMap;
vtkm::cont::ArrayCopy(cellIdMapArray, joinedCellIdMap);
outCellSet.Fill(inCellSet.GetNumberOfPoints(),
joinedShapesArray,
joinedPointCountArray,
joinedConnectivity,
joinedOffsets);
outCellSet.Fill(
inCellSet.GetNumberOfPoints(), joinedShapesArray, joinedConnectivity, joinedOffsets);
this->CellIdMap = joinedCellIdMap;
}
}

@ -443,18 +443,11 @@ public:
points = vtkm::cont::ArrayHandleVirtualCoordinates(concretePoints);
}
template <typename ShapeStorage,
typename NumIndicesStorage,
typename ConnectivityStorage,
typename OffsetsStorage>
VTKM_CONT vtkm::cont::CellSetExplicit<ShapeStorage,
NumIndicesStorage,
VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
OffsetsStorage>
MapCellSet(const vtkm::cont::CellSetExplicit<ShapeStorage,
NumIndicesStorage,
ConnectivityStorage,
OffsetsStorage>& inCellSet) const
template <typename ShapeStorage, typename ConnectivityStorage, typename OffsetsStorage>
VTKM_CONT
vtkm::cont::CellSetExplicit<ShapeStorage, VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG, OffsetsStorage>
MapCellSet(const vtkm::cont::CellSetExplicit<ShapeStorage, ConnectivityStorage, OffsetsStorage>&
inCellSet) const
{
return vtkm::worklet::RemoveUnusedPoints::MapCellSet(
inCellSet, this->PointInputToOutputMap, this->MergeKeys.GetInputRange());

@ -71,14 +71,9 @@ public:
VTKM_CONT
RemoveUnusedPoints() {}
template <typename ShapeStorage,
typename NumIndicesStorage,
typename ConnectivityStorage,
typename OffsetsStorage>
VTKM_CONT RemoveUnusedPoints(const vtkm::cont::CellSetExplicit<ShapeStorage,
NumIndicesStorage,
ConnectivityStorage,
OffsetsStorage>& inCellSet)
template <typename ShapeStorage, typename ConnectivityStorage, typename OffsetsStorage>
VTKM_CONT RemoveUnusedPoints(
const vtkm::cont::CellSetExplicit<ShapeStorage, ConnectivityStorage, OffsetsStorage>& inCellSet)
{
this->FindPointsStart();
this->FindPoints(inCellSet);
@ -93,14 +88,9 @@ public:
/// points are those that are not found in any cell sets passed to this
/// method.
///
template <typename ShapeStorage,
typename NumIndicesStorage,
typename ConnectivityStorage,
typename OffsetsStorage>
VTKM_CONT void FindPoints(const vtkm::cont::CellSetExplicit<ShapeStorage,
NumIndicesStorage,
ConnectivityStorage,
OffsetsStorage>& inCellSet)
template <typename ShapeStorage, typename ConnectivityStorage, typename OffsetsStorage>
VTKM_CONT void FindPoints(
const vtkm::cont::CellSetExplicit<ShapeStorage, ConnectivityStorage, OffsetsStorage>& inCellSet)
{
if (this->MaskArray.GetNumberOfValues() < 1)
{
@ -133,18 +123,11 @@ public:
/// returns a new cell set with cell points transformed to use the indices of
/// the new reduced point arrays.
///
template <typename ShapeStorage,
typename NumIndicesStorage,
typename ConnectivityStorage,
typename OffsetsStorage>
VTKM_CONT vtkm::cont::CellSetExplicit<ShapeStorage,
NumIndicesStorage,
VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
OffsetsStorage>
MapCellSet(const vtkm::cont::CellSetExplicit<ShapeStorage,
NumIndicesStorage,
ConnectivityStorage,
OffsetsStorage>& inCellSet) const
template <typename ShapeStorage, typename ConnectivityStorage, typename OffsetsStorage>
VTKM_CONT
vtkm::cont::CellSetExplicit<ShapeStorage, VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG, OffsetsStorage>
MapCellSet(const vtkm::cont::CellSetExplicit<ShapeStorage, ConnectivityStorage, OffsetsStorage>&
inCellSet) const
{
VTKM_ASSERT(this->PointScatter);
@ -166,20 +149,16 @@ public:
/// of \c MapCellSet.
///
template <typename ShapeStorage,
typename NumIndicesStorage,
typename ConnectivityStorage,
typename OffsetsStorage,
typename MapStorage>
VTKM_CONT static vtkm::cont::CellSetExplicit<ShapeStorage,
NumIndicesStorage,
VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
OffsetsStorage>
MapCellSet(const vtkm::cont::CellSetExplicit<ShapeStorage,
NumIndicesStorage,
ConnectivityStorage,
OffsetsStorage>& inCellSet,
const vtkm::cont::ArrayHandle<vtkm::Id, MapStorage>& inputToOutputPointMap,
vtkm::Id numberOfPoints)
MapCellSet(
const vtkm::cont::CellSetExplicit<ShapeStorage, ConnectivityStorage, OffsetsStorage>& inCellSet,
const vtkm::cont::ArrayHandle<vtkm::Id, MapStorage>& inputToOutputPointMap,
vtkm::Id numberOfPoints)
{
using VisitTopology = vtkm::TopologyElementTagCell;
using IncidentTopology = vtkm::TopologyElementTagPoint;
@ -193,14 +172,11 @@ public:
inputToOutputPointMap,
newConnectivityArray);
vtkm::cont::
CellSetExplicit<ShapeStorage, NumIndicesStorage, NewConnectivityStorage, OffsetsStorage>
outCellSet;
vtkm::cont::CellSetExplicit<ShapeStorage, NewConnectivityStorage, OffsetsStorage> outCellSet;
outCellSet.Fill(numberOfPoints,
inCellSet.GetShapesArray(VisitTopology(), IncidentTopology()),
inCellSet.GetNumIndicesArray(VisitTopology(), IncidentTopology()),
newConnectivityArray,
inCellSet.GetIndexOffsetArray(VisitTopology(), IncidentTopology()));
inCellSet.GetOffsetsArray(VisitTopology(), IncidentTopology()));
return outCellSet;
}

@ -482,8 +482,8 @@ public:
auto connectivityArrayHandle = newCellset.GetConnectivityArray(vtkm::TopologyElementTagCell(),
vtkm::TopologyElementTagPoint());
auto connectivityArrayHandleP = connectivityArrayHandle.GetPortalControl();
auto offsetArrayHandle = newCellset.GetIndexOffsetArray(vtkm::TopologyElementTagCell(),
vtkm::TopologyElementTagPoint());
auto offsetArrayHandle =
newCellset.GetOffsetsArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
auto offsetArrayHandleP = offsetArrayHandle.GetPortalControl();
for (vtkm::Id i = 0; i < cellTopologyUpdateTuples.GetNumberOfValues(); i++)
{

@ -379,8 +379,8 @@ public:
makeStreamLines, fieldArray, seedIdArray, seedPosArray, numIndices, validPoint, streamArray);
// Size of connectivity based on size of returned streamlines
vtkm::cont::ArrayHandle<vtkm::IdComponent> numIndicesOut;
vtkm::IdComponent connectivityLen = Algorithm::ScanExclusive(numIndices, numIndicesOut);
vtkm::Id connectivityLen;
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices, connectivityLen);
// Connectivity is sequential
vtkm::cont::ArrayHandleCounting<vtkm::Id> connCount(0, 1, connectivityLen);
@ -395,7 +395,7 @@ public:
vtkm::cont::DataSet OutDataSet;
vtkm::cont::CellSetExplicit<> outCellSet;
outCellSet.Fill(coordinates.GetNumberOfValues(), cellTypes, numIndices, connectivity);
outCellSet.Fill(coordinates.GetNumberOfValues(), cellTypes, connectivity, offsets);
OutDataSet.SetCellSet(outCellSet);
OutDataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates));

@ -28,6 +28,7 @@
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleGroupVec.h>
#include <vtkm/cont/ArrayHandleGroupVecVariable.h>
#include <vtkm/cont/ArrayHandleView.h>
#include <vtkm/cont/ArrayRangeCompute.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/CellSetSingleType.h>
@ -237,26 +238,28 @@ public:
{ // Multiple cell types:
vtkm::cont::ArrayHandle<vtkm::Id> offsets;
vtkm::Id connSize;
vtkm::cont::ConvertNumComponentsToOffsets(numIndices, offsets, connSize);
vtkm::cont::ConvertNumIndicesToOffsets(numIndices, offsets, connSize);
numIndices.ReleaseResourcesExecution();
vtkm::cont::ArrayHandle<vtkm::Id> conn;
conn.Allocate(connSize);
auto connGroupVec = vtkm::cont::make_ArrayHandleGroupVecVariable(conn, offsets);
// Trim the last value off for the group vec array:
auto offsetsTrim =
vtkm::cont::make_ArrayHandleView(offsets, 0, offsets.GetNumberOfValues() - 1);
auto connGroupVec = vtkm::cont::make_ArrayHandleGroupVecVariable(conn, offsetsTrim);
WorkletWindToCellNormalsGeneric worklet;
invoker(worklet, cellSet, coords, cellNormals, connGroupVec);
vtkm::cont::CellSetExplicit<> outCells;
outCells.Fill(cellSet.GetNumberOfPoints(), cellShapes, numIndices, conn, offsets);
outCells.Fill(cellSet.GetNumberOfPoints(), cellShapes, conn, offsets);
this->Result = outCells;
}
}
// Specialization for CellSetExplicit
template <typename S,
typename N,
typename C,
typename O,
typename PointComponentType,
@ -264,7 +267,7 @@ public:
typename CellNormalComponentType,
typename CellNormalStorageType>
VTKM_CONT void operator()(
const vtkm::cont::CellSetExplicit<S, N, C, O>& cellSet,
const vtkm::cont::CellSetExplicit<S, C, O>& cellSet,
const vtkm::cont::ArrayHandle<vtkm::Vec<PointComponentType, 3>, PointStorageType>& coords,
const vtkm::cont::ArrayHandle<vtkm::Vec<CellNormalComponentType, 3>, CellNormalStorageType>&
cellNormals,
@ -286,19 +289,19 @@ public:
vtkm::cont::Algorithm::Copy(connIn, conn);
}
const auto& offsets = cellSet.GetIndexOffsetArray(vtkm::TopologyElementTagCell{},
vtkm::TopologyElementTagPoint{});
auto cells = vtkm::cont::make_ArrayHandleGroupVecVariable(conn, offsets);
const auto& offsets =
cellSet.GetOffsetsArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{});
auto offsetsTrim =
vtkm::cont::make_ArrayHandleView(offsets, 0, offsets.GetNumberOfValues() - 1);
auto cells = vtkm::cont::make_ArrayHandleGroupVecVariable(conn, offsetsTrim);
WindToCellNormals dispatcher;
dispatcher.Invoke(cellNormals, cells, coords);
const auto& shapes =
cellSet.GetShapesArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{});
const auto& numIndices =
cellSet.GetNumIndicesArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{});
vtkm::cont::CellSetExplicit<S, N, vtkm::cont::StorageTagBasic, O> newCells;
newCells.Fill(cellSet.GetNumberOfPoints(), shapes, numIndices, conn, offsets);
vtkm::cont::CellSetExplicit<S, vtkm::cont::StorageTagBasic, O> newCells;
newCells.Fill(cellSet.GetNumberOfPoints(), shapes, conn, offsets);
this->Result = newCells;
}
@ -332,9 +335,11 @@ public:
vtkm::cont::Algorithm::Copy(connIn, conn);
}
const auto& offsets = cellSet.GetIndexOffsetArray(vtkm::TopologyElementTagCell{},
vtkm::TopologyElementTagPoint{});
auto cells = vtkm::cont::make_ArrayHandleGroupVecVariable(conn, offsets);
const auto& offsets =
cellSet.GetOffsetsArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{});
auto offsetsTrim =
vtkm::cont::make_ArrayHandleView(offsets, 0, offsets.GetNumberOfValues() - 1);
auto cells = vtkm::cont::make_ArrayHandleGroupVecVariable(conn, offsetsTrim);
WindToCellNormals dispatcher;
dispatcher.Invoke(cellNormals, cells, coords);

@ -143,12 +143,10 @@ template <typename DeviceAdapter>
class ExplicitCellInterpolationHelper : public vtkm::exec::CellInterpolationHelper
{
using ShapeType = vtkm::cont::ArrayHandle<vtkm::UInt8>;
using NumIdxType = vtkm::cont::ArrayHandle<vtkm::IdComponent>;
using OffsetType = vtkm::cont::ArrayHandle<vtkm::Id>;
using ConnType = vtkm::cont::ArrayHandle<vtkm::Id>;
using ShapePortalType = typename ShapeType::template ExecutionTypes<DeviceAdapter>::PortalConst;
using NumIdxPortalType = typename NumIdxType::template ExecutionTypes<DeviceAdapter>::PortalConst;
using OffsetPortalType = typename OffsetType::template ExecutionTypes<DeviceAdapter>::PortalConst;
using ConnPortalType = typename ConnType::template ExecutionTypes<DeviceAdapter>::PortalConst;
@ -157,11 +155,9 @@ public:
VTKM_CONT
ExplicitCellInterpolationHelper(const ShapeType& shape,
const NumIdxType& numIdx,
const OffsetType& offset,
const ConnType& connectivity)
: Shape(shape.PrepareForInput(DeviceAdapter()))
, NumIdx(numIdx.PrepareForInput(DeviceAdapter()))
, Offset(offset.PrepareForInput(DeviceAdapter()))
, Connectivity(connectivity.PrepareForInput(DeviceAdapter()))
{
@ -173,17 +169,16 @@ public:
vtkm::IdComponent& numVerts,
vtkm::VecVariable<vtkm::Id, 8>& indices) const override
{
cellShape = Shape.Get(cellId);
numVerts = NumIdx.Get(cellId);
vtkm::Id offset = Offset.Get(cellId);
cellShape = this->Shape.Get(cellId);
const vtkm::Id offset = this->Offset.Get(cellId);
numVerts = static_cast<vtkm::IdComponent>(this->Offset.Get(cellId + 1) - offset);
for (vtkm::IdComponent i = 0; i < numVerts; i++)
indices.Append(Connectivity.Get(offset + i));
indices.Append(this->Connectivity.Get(offset + i));
}
private:
ShapePortalType Shape;
NumIdxPortalType NumIdx;
OffsetPortalType Offset;
ConnPortalType Connectivity;
};
@ -341,10 +336,8 @@ public:
vtkm::cont::CellSetExplicit<> CellSet = cellSet.Cast<vtkm::cont::CellSetExplicit<>>();
Shape =
CellSet.GetShapesArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
NumIdx =
CellSet.GetNumIndicesArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
Offset = CellSet.GetIndexOffsetArray(vtkm::TopologyElementTagCell(),
vtkm::TopologyElementTagPoint());
Offset =
CellSet.GetOffsetsArray(vtkm::TopologyElementTagCell(), vtkm::TopologyElementTagPoint());
Connectivity = CellSet.GetConnectivityArray(vtkm::TopologyElementTagCell(),
vtkm::TopologyElementTagPoint());
}
@ -360,10 +353,8 @@ public:
HandleType& execInterpolator) const
{
using ExecutionType = vtkm::exec::ExplicitCellInterpolationHelper<DeviceAdapter>;
ExecutionType* execObject = new ExecutionType(contInterpolator.Shape,
contInterpolator.NumIdx,
contInterpolator.Offset,
contInterpolator.Connectivity);
ExecutionType* execObject = new ExecutionType(
contInterpolator.Shape, contInterpolator.Offset, contInterpolator.Connectivity);
execInterpolator.Reset(execObject);
return true;
}
@ -384,7 +375,6 @@ public:
private:
vtkm::cont::ArrayHandle<vtkm::UInt8> Shape;
vtkm::cont::ArrayHandle<vtkm::IdComponent> NumIdx;
vtkm::cont::ArrayHandle<vtkm::Id> Offset;
vtkm::cont::ArrayHandle<vtkm::Id> Connectivity;
mutable HandleType ExecHandle;

@ -238,11 +238,10 @@ private:
numSeeds);
vtkm::cont::ArrayCopy(polyLineShape, cellTypes);
vtkm::cont::ArrayHandle<vtkm::IdComponent> cellCounts;
vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandleCast(stepsTakenNow, vtkm::IdComponent()),
cellCounts);
auto numIndices = vtkm::cont::make_ArrayHandleCast(stepsTakenNow, vtkm::IdComponent());
auto offsets = vtkm::cont::ConvertNumIndicesToOffsets(numIndices);
polyLines.Fill(positions.GetNumberOfValues(), cellTypes, cellCounts, connectivity);
polyLines.Fill(positions.GetNumberOfValues(), cellTypes, connectivity, offsets);
}
IntegratorType integrator;

@ -72,9 +72,9 @@ void CheckOutput(const vtkm::cont::CellSetExplicit<>& copiedCells)
"Bad number of points in cell");
// Only checking 3 points. All cells should have at least 3
vtkm::Id3 cellPoints;
vtkm::Id3 cellPoints{ 0 };
copiedCells.GetIndices(cellIndex, cellPoints);
vtkm::Id3 oCellPoints;
vtkm::Id3 oCellPoints{ 0 };
originalCells.GetIndices(oCellIndex, oCellPoints);
VTKM_TEST_ASSERT(cellPoints == oCellPoints, "Point indices not copied correctly");
}

@ -57,8 +57,10 @@ void Validate(vtkm::cont::DataSet dataSet)
const auto conn =
cellSet.GetConnectivityArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{});
const auto offsets =
cellSet.GetIndexOffsetArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{});
const auto cellArray = vtkm::cont::make_ArrayHandleGroupVecVariable(conn, offsets);
cellSet.GetOffsetsArray(vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{});
const auto offsetsTrim =
vtkm::cont::make_ArrayHandleView(offsets, 0, offsets.GetNumberOfValues() - 1);
const auto cellArray = vtkm::cont::make_ArrayHandleGroupVecVariable(conn, offsetsTrim);
const auto cellNormalsVar = dataSet.GetCellField("normals").GetData();
const auto cellNormalsArray = cellNormalsVar.Cast<vtkm::cont::ArrayHandle<MyNormalT>>();