Merge topic 'cellset_explicit_user_defined_offsets'
dbed8827 Correct issues found in code review. 82b977da CellSetExplicit::CreateConnectivity now works with implicit NumIndices. 30f5d628 ConnectivityExplicit will not generate IndexOffsets when they are implicit. f04ea6d7 CellSetExplicit has userdefined offset storage. Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: Kenneth Moreland <kmorel@sandia.gov> Tested-by: buildbot <buildbot@kitware.com> Merge-request: !212
This commit is contained in:
commit
9c85c623f0
@ -21,10 +21,10 @@
|
||||
#define vtk_m_cont_CellSetExplicit_h
|
||||
|
||||
#include <vtkm/CellShape.h>
|
||||
#include <vtkm/TopologyElementTag.h>
|
||||
#include <vtkm/cont/CellSet.h>
|
||||
#include <vtkm/cont/internal/ConnectivityExplicitInternals.h>
|
||||
#include <vtkm/exec/ConnectivityExplicit.h>
|
||||
#include <vtkm/TopologyElementTag.h>
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
@ -56,17 +56,25 @@ struct CellSetExplicitConnectivityChooser
|
||||
#define VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
|
||||
#endif
|
||||
|
||||
#ifndef VTKM_DEFAULT_OFFSETS_STORAGE_TAG
|
||||
#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,
|
||||
typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG >
|
||||
typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG,
|
||||
typename OffsetsStorageTag = VTKM_DEFAULT_OFFSETS_STORAGE_TAG >
|
||||
class CellSetExplicit : public CellSet
|
||||
{
|
||||
template<typename FromTopology, typename ToTopology>
|
||||
struct ConnectivityChooser
|
||||
{
|
||||
typedef CellSetExplicit< ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag > CellSetExplicitType;
|
||||
typedef typename detail::CellSetExplicitConnectivityChooser<
|
||||
CellSetExplicit<
|
||||
ShapeStorageTag,NumIndicesStorageTag,ConnectivityStorageTag>,
|
||||
CellSetExplicitType,
|
||||
FromTopology,
|
||||
ToTopology>::ConnectivityType ConnectivityType;
|
||||
};
|
||||
@ -185,7 +193,8 @@ public:
|
||||
VTKM_CONT_EXPORT
|
||||
void FillViaCopy(const std::vector<vtkm::UInt8> &cellTypes,
|
||||
const std::vector<vtkm::IdComponent> &numIndices,
|
||||
const std::vector<vtkm::Id> &connectivity)
|
||||
const std::vector<vtkm::Id> &connectivity,
|
||||
const std::vector<vtkm::Id> &offsets = std::vector<vtkm::Id>() )
|
||||
{
|
||||
|
||||
this->PointToCell.Shapes.Allocate( static_cast<vtkm::UInt8>(cellTypes.size()) );
|
||||
@ -204,7 +213,25 @@ public:
|
||||
this->PointToCell.Connectivity.GetPortalControl()));
|
||||
|
||||
this->PointToCell.ElementsValid = true;
|
||||
this->PointToCell.IndexOffsetsValid = false;
|
||||
|
||||
if(offsets.size() == cellTypes.size())
|
||||
{
|
||||
this->PointToCell.IndexOffsets.Allocate( static_cast<vtkm::Id>(offsets.size()) );
|
||||
std::copy(offsets.begin(), offsets.end(),
|
||||
vtkm::cont::ArrayPortalToIteratorBegin(
|
||||
this->PointToCell.IndexOffsets.GetPortalControl()));
|
||||
this->PointToCell.IndexOffsetsValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->PointToCell.IndexOffsetsValid = false;
|
||||
if (offsets.size() != 0)
|
||||
{
|
||||
throw vtkm::cont::ErrorControlBadValue(
|
||||
"Explicit cell offsets array unexpected size. "
|
||||
"Use an empty array to automatically generate.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Second method to add cells -- all at once.
|
||||
@ -212,14 +239,31 @@ public:
|
||||
/// the way you can fill the memory from another system without copying
|
||||
void Fill(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, ConnectivityStorageTag> &connectivity,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag> &offsets
|
||||
= vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorageTag>() )
|
||||
{
|
||||
this->PointToCell.Shapes = cellTypes;
|
||||
this->PointToCell.NumIndices = numIndices;
|
||||
this->PointToCell.Connectivity = connectivity;
|
||||
|
||||
this->PointToCell.ElementsValid = true;
|
||||
this->PointToCell.IndexOffsetsValid = false;
|
||||
|
||||
if(offsets.GetNumberOfValues() == cellTypes.GetNumberOfValues())
|
||||
{
|
||||
this->PointToCell.IndexOffsets = offsets;
|
||||
this->PointToCell.IndexOffsetsValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->PointToCell.IndexOffsetsValid = false;
|
||||
if (offsets.GetNumberOfValues() != 0)
|
||||
{
|
||||
throw vtkm::cont::ErrorControlBadValue(
|
||||
"Explicit cell offsets array unexpected size. "
|
||||
"Use an empty array to automatically generate.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename DeviceAdapter, typename FromTopology, typename ToTopology>
|
||||
@ -271,8 +315,9 @@ public:
|
||||
void BuildConnectivity(FromTopology, ToTopology) const
|
||||
{
|
||||
typedef CellSetExplicit<ShapeStorageTag,
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag> CSE;
|
||||
NumIndicesStorageTag,
|
||||
ConnectivityStorageTag,
|
||||
OffsetsStorageTag> CSE;
|
||||
CSE *self = const_cast<CSE*>(this);
|
||||
|
||||
self->CreateConnectivity(FromTopology(), ToTopology());
|
||||
@ -305,10 +350,10 @@ public:
|
||||
vtkm::Id numPoints = GetNumberOfPoints();
|
||||
for (vtkm::Id cell = 0, cindex = 0; cell < numCells; ++cell)
|
||||
{
|
||||
vtkm::Id npts = this->PointToCell.NumIndices.GetPortalControl().Get(cell);
|
||||
vtkm::Id npts = this->PointToCell.NumIndices.GetPortalConstControl().Get(cell);
|
||||
for (int pt=0; pt<npts; ++pt)
|
||||
{
|
||||
vtkm::Id index = this->PointToCell.Connectivity.GetPortalControl().Get(cindex++);
|
||||
vtkm::Id index = this->PointToCell.Connectivity.GetPortalConstControl().Get(cindex++);
|
||||
if (index > maxNodeID)
|
||||
maxNodeID = index;
|
||||
cells_of_nodes.insert(std::pair<vtkm::Id,vtkm::Id>(index,cell));
|
||||
@ -339,7 +384,7 @@ public:
|
||||
this->CellToPoint.Connectivity.GetPortalControl().Set(connIndex,cellId);
|
||||
++connIndex;
|
||||
const vtkm::IdComponent oldCellCount =
|
||||
this->CellToPoint.NumIndices.GetPortalControl().Get(pointIndex-1);
|
||||
this->CellToPoint.NumIndices.GetPortalConstControl().Get(pointIndex-1);
|
||||
|
||||
this->CellToPoint.NumIndices.GetPortalControl().Set(pointIndex-1,
|
||||
oldCellCount+1);
|
||||
@ -398,7 +443,7 @@ public:
|
||||
return this->GetConnectivity(FromTopology(), ToTopology()).IndexOffsets;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
typename ConnectivityChooser<
|
||||
vtkm::TopologyElementTagPoint,vtkm::TopologyElementTagCell>::
|
||||
ConnectivityType PointToCell;
|
||||
@ -408,6 +453,7 @@ private:
|
||||
typename ConnectivityChooser<
|
||||
vtkm::TopologyElementTagCell,vtkm::TopologyElementTagPoint>::
|
||||
ConnectivityType CellToPoint;
|
||||
private:
|
||||
|
||||
// A set of overloaded methods to get the connectivity from a pair of
|
||||
// topology element types.
|
||||
@ -445,14 +491,14 @@ private:
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename Storage1, typename Storage2, typename Storage3>
|
||||
template<typename Storage1, typename Storage2, typename Storage3, typename Storage4>
|
||||
struct CellSetExplicitConnectivityChooser<
|
||||
vtkm::cont::CellSetExplicit<Storage1,Storage2,Storage3>,
|
||||
vtkm::cont::CellSetExplicit<Storage1,Storage2,Storage3,Storage4>,
|
||||
vtkm::TopologyElementTagPoint,
|
||||
vtkm::TopologyElementTagCell>
|
||||
{
|
||||
typedef vtkm::cont::internal::ConnectivityExplicitInternals<
|
||||
Storage1,Storage2,Storage3> ConnectivityType;
|
||||
Storage1,Storage2,Storage3,Storage4> ConnectivityType;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
@ -29,6 +29,41 @@ namespace vtkm {
|
||||
namespace cont {
|
||||
namespace internal {
|
||||
|
||||
template<typename NumIndicesStorageTag,
|
||||
typename IndexOffsetStorageTag,
|
||||
typename DeviceAdapterTag>
|
||||
void buildIndexOffsets(vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag> numIndices,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id, IndexOffsetStorageTag> offsets,
|
||||
DeviceAdapterTag)
|
||||
{
|
||||
typedef vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag> NumIndicesArrayType;
|
||||
//We first need to make sure that NumIndices and IndexOffsetArrayType
|
||||
//have the same type so we can call scane exclusive
|
||||
typedef vtkm::cont::ArrayHandleCast< vtkm::Id,
|
||||
NumIndicesArrayType > CastedNumIndicesType;
|
||||
|
||||
// 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.
|
||||
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag> Algorithm;
|
||||
Algorithm::ScanExclusive( CastedNumIndicesType(numIndices), offsets);
|
||||
}
|
||||
|
||||
template<typename NumIndicesStorageTag,
|
||||
typename ImplicitPortalTag,
|
||||
typename DeviceAdapterTag>
|
||||
void buildIndexOffsets(vtkm::cont::ArrayHandle<vtkm::IdComponent, NumIndicesStorageTag>,
|
||||
vtkm::cont::ArrayHandle<vtkm::Id,
|
||||
vtkm::cont::StorageTagImplicit< ImplicitPortalTag > >,
|
||||
DeviceAdapterTag)
|
||||
{
|
||||
//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 ShapeStorageTag = VTKM_DEFAULT_STORAGE_TAG,
|
||||
typename NumIndicesStorageTag = VTKM_DEFAULT_STORAGE_TAG,
|
||||
typename ConnectivityStorageTag = VTKM_DEFAULT_STORAGE_TAG,
|
||||
@ -43,10 +78,10 @@ struct ConnectivityExplicitInternals
|
||||
ShapeArrayType Shapes;
|
||||
NumIndicesArrayType NumIndices;
|
||||
ConnectivityArrayType Connectivity;
|
||||
IndexOffsetArrayType IndexOffsets;
|
||||
mutable IndexOffsetArrayType IndexOffsets;
|
||||
|
||||
bool ElementsValid;
|
||||
bool IndexOffsetsValid;
|
||||
mutable bool IndexOffsetsValid;
|
||||
|
||||
VTKM_CONT_EXPORT
|
||||
ConnectivityExplicitInternals()
|
||||
@ -70,24 +105,13 @@ struct ConnectivityExplicitInternals
|
||||
void BuildIndexOffsets(Device) const
|
||||
{
|
||||
VTKM_ASSERT_CONT(this->ElementsValid);
|
||||
if (!this->IndexOffsetsValid)
|
||||
{
|
||||
//We first need to make sure that NumIndices and IndexOffsetArrayType
|
||||
//have the same type so we can call scane exclusive
|
||||
typedef vtkm::cont::ArrayHandleCast< vtkm::Id,
|
||||
NumIndicesArrayType > CastedNumIndicesType;
|
||||
|
||||
// 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::DeviceAdapterAlgorithm<Device>::ScanExclusive(
|
||||
CastedNumIndicesType(this->NumIndices),
|
||||
const_cast<IndexOffsetArrayType&>(this->IndexOffsets));
|
||||
const_cast<bool&>(this->IndexOffsetsValid) = true;
|
||||
}
|
||||
else
|
||||
if(!this->IndexOffsetsValid)
|
||||
{
|
||||
// Index offsets already built. Nothing to do.
|
||||
buildIndexOffsets(this->NumIndices,
|
||||
this->IndexOffsets,
|
||||
Device());
|
||||
this->IndexOffsetsValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user