From f04ea6d72eb9bd886925dc91076c88677cdecfef Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 23 Sep 2015 17:42:12 -0400 Subject: [PATCH 1/4] CellSetExplicit has userdefined offset storage. --- vtkm/cont/CellSetExplicit.h | 62 +++++++++++++++++++++++++++++-------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/vtkm/cont/CellSetExplicit.h b/vtkm/cont/CellSetExplicit.h index c7b29bf42..d29e0eb2c 100644 --- a/vtkm/cont/CellSetExplicit.h +++ b/vtkm/cont/CellSetExplicit.h @@ -21,10 +21,10 @@ #define vtk_m_cont_CellSetExplicit_h #include -#include #include #include #include +#include #include #include @@ -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 ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG, + typename OffsetsStorageTag = VTKM_DEFAULT_OFFSETS_STORAGE_TAG > class CellSetExplicit : public CellSet { template 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 &cellTypes, const std::vector &numIndices, - const std::vector &connectivity) + const std::vector &connectivity, + const std::vector &offsets = std::vector() ) { this->PointToCell.Shapes.Allocate( static_cast(cellTypes.size()) ); @@ -204,6 +213,20 @@ public: this->PointToCell.Connectivity.GetPortalControl())); this->PointToCell.ElementsValid = true; + + if(offsets.size() == cellTypes.size()) + { + this->PointToCell.IndexOffsets.Allocate( static_cast(offsets.size()) ); + std::copy(offsets.begin(), offsets.end(), + vtkm::cont::ArrayPortalToIteratorBegin( + this->PointToCell.IndexOffsets.GetPortalControl())); + this->PointToCell.IndexOffsetsValid = true; + } + else + { + this->PointToCell.IndexOffsetsValid = false; + } + this->PointToCell.IndexOffsetsValid = false; } @@ -212,14 +235,25 @@ public: /// the way you can fill the memory from another system without copying void Fill(const vtkm::cont::ArrayHandle &cellTypes, const vtkm::cont::ArrayHandle &numIndices, - const vtkm::cont::ArrayHandle &connectivity) + const vtkm::cont::ArrayHandle &connectivity, + const vtkm::cont::ArrayHandle &offsets + = vtkm::cont::ArrayHandle() ) { 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; + } } template @@ -271,8 +305,9 @@ public: void BuildConnectivity(FromTopology, ToTopology) const { typedef CellSetExplicit CSE; + NumIndicesStorageTag, + ConnectivityStorageTag, + OffsetsStorageTag> CSE; CSE *self = const_cast(this); self->CreateConnectivity(FromTopology(), ToTopology()); @@ -398,7 +433,7 @@ public: return this->GetConnectivity(FromTopology(), ToTopology()).IndexOffsets; } -private: +protected: typename ConnectivityChooser< vtkm::TopologyElementTagPoint,vtkm::TopologyElementTagCell>:: ConnectivityType PointToCell; @@ -408,6 +443,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 +481,14 @@ private: namespace detail { -template +template struct CellSetExplicitConnectivityChooser< - vtkm::cont::CellSetExplicit, + vtkm::cont::CellSetExplicit, vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell> { typedef vtkm::cont::internal::ConnectivityExplicitInternals< - Storage1,Storage2,Storage3> ConnectivityType; + Storage1,Storage2,Storage3,Storage4> ConnectivityType; }; } // namespace detail From 30f5d628ccf3f96fadb411fe6d6e07de31a9f15f Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 24 Sep 2015 11:57:34 -0400 Subject: [PATCH 2/4] ConnectivityExplicit will not generate IndexOffsets when they are implicit. Even when using implicit index's the ConnectivityExplicit would generate the code to compute the IndexOffsets, which would than fail to compile as the ArrayHandle would only support read operations. This fixes that issue. --- .../internal/ConnectivityExplicitInternals.h | 68 +++++++++++++------ 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/vtkm/cont/internal/ConnectivityExplicitInternals.h b/vtkm/cont/internal/ConnectivityExplicitInternals.h index 738e30d66..b2f3d9d60 100644 --- a/vtkm/cont/internal/ConnectivityExplicitInternals.h +++ b/vtkm/cont/internal/ConnectivityExplicitInternals.h @@ -25,10 +25,49 @@ #include #include +VTKM_THIRDPARTY_PRE_INCLUDE +#include +VTKM_THIRDPARTY_POST_INCLUDE + namespace vtkm { namespace cont { namespace internal { +template +void buildIndexOffsets(vtkm::cont::ArrayHandle numIndices, + vtkm::cont::ArrayHandle offsets, + DeviceAdapterTag) +{ + typedef vtkm::cont::ArrayHandle 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 Algorithm; + Algorithm::ScanExclusive( CastedNumIndicesType(numIndices), offsets); +} + +template +void buildIndexOffsets(vtkm::cont::ArrayHandle, + vtkm::cont::ArrayHandle >, + 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. +} + templateElementsValid); - 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::ScanExclusive( - CastedNumIndicesType(this->NumIndices), - const_cast(this->IndexOffsets)); - const_cast(this->IndexOffsetsValid) = true; - } - else - { - // Index offsets already built. Nothing to do. - } + if(!this->IndexOffsetsValid) + { + buildIndexOffsets(this->NumIndices, + this->IndexOffsets, + Device()); + this->IndexOffsetsValid = true; + } } VTKM_CONT_EXPORT From 82b977da0eaab808085952564708dff6471e23ba Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 24 Sep 2015 12:38:34 -0400 Subject: [PATCH 3/4] CellSetExplicit::CreateConnectivity now works with implicit NumIndices. --- vtkm/cont/CellSetExplicit.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vtkm/cont/CellSetExplicit.h b/vtkm/cont/CellSetExplicit.h index d29e0eb2c..1f6aaa4a5 100644 --- a/vtkm/cont/CellSetExplicit.h +++ b/vtkm/cont/CellSetExplicit.h @@ -340,10 +340,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; ptPointToCell.Connectivity.GetPortalControl().Get(cindex++); + vtkm::Id index = this->PointToCell.Connectivity.GetPortalConstControl().Get(cindex++); if (index > maxNodeID) maxNodeID = index; cells_of_nodes.insert(std::pair(index,cell)); @@ -374,7 +374,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); From dbed882709ebc2b8d0b4e1add7d66f07b7f3d65b Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 25 Sep 2015 11:45:09 -0400 Subject: [PATCH 4/4] Correct issues found in code review. --- vtkm/cont/CellSetExplicit.h | 26 +++++++++++++------ .../internal/ConnectivityExplicitInternals.h | 8 ++---- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/vtkm/cont/CellSetExplicit.h b/vtkm/cont/CellSetExplicit.h index 1f6aaa4a5..e50a3f327 100644 --- a/vtkm/cont/CellSetExplicit.h +++ b/vtkm/cont/CellSetExplicit.h @@ -215,19 +215,23 @@ public: this->PointToCell.ElementsValid = true; if(offsets.size() == cellTypes.size()) - { + { this->PointToCell.IndexOffsets.Allocate( static_cast(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."); } - - this->PointToCell.IndexOffsetsValid = false; + } } /// Second method to add cells -- all at once. @@ -246,14 +250,20 @@ public: this->PointToCell.ElementsValid = true; 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 diff --git a/vtkm/cont/internal/ConnectivityExplicitInternals.h b/vtkm/cont/internal/ConnectivityExplicitInternals.h index b2f3d9d60..b14344f1d 100644 --- a/vtkm/cont/internal/ConnectivityExplicitInternals.h +++ b/vtkm/cont/internal/ConnectivityExplicitInternals.h @@ -25,10 +25,6 @@ #include #include -VTKM_THIRDPARTY_PRE_INCLUDE -#include -VTKM_THIRDPARTY_POST_INCLUDE - namespace vtkm { namespace cont { namespace internal { @@ -111,12 +107,12 @@ struct ConnectivityExplicitInternals VTKM_ASSERT_CONT(this->ElementsValid); if(!this->IndexOffsetsValid) - { + { buildIndexOffsets(this->NumIndices, this->IndexOffsets, Device()); this->IndexOffsetsValid = true; - } + } } VTKM_CONT_EXPORT