From fc79055f7687637e90efbdb07dc843d2683dc22e Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 24 Sep 2015 10:39:48 -0400 Subject: [PATCH 01/11] Add suppression pragmas to exec::Fetch classes --- vtkm/exec/arg/CellShape.h | 1 + vtkm/exec/arg/FetchTagArrayDirectIn.h | 1 + vtkm/exec/arg/FetchTagArrayDirectInOut.h | 2 ++ vtkm/exec/arg/FetchTagArrayDirectOut.h | 2 ++ vtkm/exec/arg/FetchTagArrayTopologyMapIn.h | 3 +++ vtkm/exec/arg/FetchTagExecObject.h | 1 + vtkm/exec/arg/FetchTagTopologyIn.h | 1 + vtkm/exec/arg/FromCount.h | 1 + vtkm/exec/arg/FromIndices.h | 1 + vtkm/exec/internal/WorkletInvokeFunctor.h | 1 + 10 files changed, 14 insertions(+) diff --git a/vtkm/exec/arg/CellShape.h b/vtkm/exec/arg/CellShape.h index 574f0273d..0f5202def 100644 --- a/vtkm/exec/arg/CellShape.h +++ b/vtkm/exec/arg/CellShape.h @@ -69,6 +69,7 @@ struct Fetch< typedef typename ConnectivityType::CellShapeTag ValueType; + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT ValueType Load(vtkm::Id index, const Invocation &invocation) const { diff --git a/vtkm/exec/arg/FetchTagArrayDirectIn.h b/vtkm/exec/arg/FetchTagArrayDirectIn.h index 79830b031..9f646de7d 100644 --- a/vtkm/exec/arg/FetchTagArrayDirectIn.h +++ b/vtkm/exec/arg/FetchTagArrayDirectIn.h @@ -48,6 +48,7 @@ struct Fetch< typedef typename ExecObjectType::ValueType ValueType; + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT ValueType Load(vtkm::Id index, const Invocation &invocation) const { diff --git a/vtkm/exec/arg/FetchTagArrayDirectInOut.h b/vtkm/exec/arg/FetchTagArrayDirectInOut.h index 4560ddefb..c20179734 100644 --- a/vtkm/exec/arg/FetchTagArrayDirectInOut.h +++ b/vtkm/exec/arg/FetchTagArrayDirectInOut.h @@ -49,6 +49,7 @@ struct Fetch< typedef typename ExecObjectType::ValueType ValueType; + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT ValueType Load(vtkm::Id index, const Invocation &invocation) const { @@ -56,6 +57,7 @@ struct Fetch< Get(index); } + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT void Store(vtkm::Id index, const Invocation &invocation, diff --git a/vtkm/exec/arg/FetchTagArrayDirectOut.h b/vtkm/exec/arg/FetchTagArrayDirectOut.h index 869dced33..7376bb21d 100644 --- a/vtkm/exec/arg/FetchTagArrayDirectOut.h +++ b/vtkm/exec/arg/FetchTagArrayDirectOut.h @@ -48,6 +48,7 @@ struct Fetch< typedef typename ExecObjectType::ValueType ValueType; + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT ValueType Load(vtkm::Id, const Invocation &) const { @@ -55,6 +56,7 @@ struct Fetch< return ValueType(); } + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT void Store(vtkm::Id index, const Invocation &invocation, diff --git a/vtkm/exec/arg/FetchTagArrayTopologyMapIn.h b/vtkm/exec/arg/FetchTagArrayTopologyMapIn.h index 727763a21..37bfa3c56 100644 --- a/vtkm/exec/arg/FetchTagArrayTopologyMapIn.h +++ b/vtkm/exec/arg/FetchTagArrayTopologyMapIn.h @@ -67,6 +67,7 @@ struct FetchArrayTopologyMapInImplementation typedef vtkm::exec::internal::VecFromPortalPermute< IndexVecType,PortalType> ValueType; + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT static ValueType Load(vtkm::Id index, const ConnectivityType &connectivity, @@ -132,6 +133,7 @@ struct FetchArrayTopologyMapInImplementation< typedef vtkm::VecRectilinearPointCoordinates ValueType; + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT static ValueType Load( vtkm::Id index, @@ -178,6 +180,7 @@ struct Fetch< typedef typename Implementation::ValueType ValueType; + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT ValueType Load(vtkm::Id index, const Invocation &invocation) const { diff --git a/vtkm/exec/arg/FetchTagExecObject.h b/vtkm/exec/arg/FetchTagExecObject.h index fa1259e92..28c6b4bc0 100644 --- a/vtkm/exec/arg/FetchTagExecObject.h +++ b/vtkm/exec/arg/FetchTagExecObject.h @@ -62,6 +62,7 @@ struct Fetch< typedef ExecObjectType ValueType; + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT ValueType Load(vtkm::Id vtkmNotUsed(index), const Invocation &invocation) const diff --git a/vtkm/exec/arg/FetchTagTopologyIn.h b/vtkm/exec/arg/FetchTagTopologyIn.h index ef9c97d9f..bae8402bc 100644 --- a/vtkm/exec/arg/FetchTagTopologyIn.h +++ b/vtkm/exec/arg/FetchTagTopologyIn.h @@ -48,6 +48,7 @@ struct Fetch< typedef vtkm::Id ValueType; + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT ValueType Load(vtkm::Id index, const Invocation &invocation) const { diff --git a/vtkm/exec/arg/FromCount.h b/vtkm/exec/arg/FromCount.h index de09dc396..43610a4b4 100644 --- a/vtkm/exec/arg/FromCount.h +++ b/vtkm/exec/arg/FromCount.h @@ -53,6 +53,7 @@ struct Fetch { typedef vtkm::IdComponent ValueType; + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT ValueType Load(vtkm::Id index, const Invocation &invocation) const { diff --git a/vtkm/exec/arg/FromIndices.h b/vtkm/exec/arg/FromIndices.h index ac6ad912a..47f750a91 100644 --- a/vtkm/exec/arg/FromIndices.h +++ b/vtkm/exec/arg/FromIndices.h @@ -68,6 +68,7 @@ struct Fetch< typedef typename ConnectivityType::IndicesType ValueType; + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT ValueType Load(vtkm::Id index, const Invocation &invocation) const { diff --git a/vtkm/exec/internal/WorkletInvokeFunctor.h b/vtkm/exec/internal/WorkletInvokeFunctor.h index 9720b9056..8844bfdc2 100644 --- a/vtkm/exec/internal/WorkletInvokeFunctor.h +++ b/vtkm/exec/internal/WorkletInvokeFunctor.h @@ -49,6 +49,7 @@ public: this->Worklet.SetErrorMessageBuffer(buffer); } + VTKM_SUPPRESS_EXEC_WARNINGS VTKM_EXEC_EXPORT void operator()(vtkm::Id index) const { From f04ea6d72eb9bd886925dc91076c88677cdecfef Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Wed, 23 Sep 2015 17:42:12 -0400 Subject: [PATCH 02/11] 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 03/11] 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 04/11] 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 fa0c695424d318eef594c939126265bd2e86d0fa Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 24 Sep 2015 16:48:03 -0600 Subject: [PATCH 05/11] Fix issue with test_equal of 0 numbers There was an error in the test_equal comparison that would return true when the second value was 0 (or close to 0) and the first value was not. This was a bug I introduced with commit b270438fea8a9fe4200322bfe6344ab2075c4d9a. I clearly misinterpreted how a conditional worked. --- vtkm/testing/Testing.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vtkm/testing/Testing.h b/vtkm/testing/Testing.h index 628bb119a..b90c44418 100644 --- a/vtkm/testing/Testing.h +++ b/vtkm/testing/Testing.h @@ -21,6 +21,7 @@ #define vtk_m_testing_Testing_h #include +#include #include #include #include @@ -346,7 +347,7 @@ bool test_equal(VectorType1 vector1, vtkm::Float64(Traits1::GetComponent(vector1, component)); vtkm::Float64 value2 = vtkm::Float64(Traits2::GetComponent(vector2, component)); - if ((fabs(value1) <= 2*tolerance) && (fabs(value2) <= 2*tolerance)) + if ((vtkm::Abs(value1) <= 2*tolerance) && (vtkm::Abs(value2) <= 2*tolerance)) { continue; } @@ -354,13 +355,15 @@ bool test_equal(VectorType1 vector1, // The following condition is redundant since the previous check // guarantees neither value will be zero, but the MSVC compiler // sometimes complains about it. - if (value2 != 0) + if (vtkm::Abs(value2) > tolerance) { ratio = value1 / value2; } else { - ratio = 1.0; + // If we are here, it means that value2 is close to 0 but value1 is not. + // These cannot be within tolerance, so just return false. + return false; } if ((ratio > vtkm::Float64(1.0) - tolerance) && (ratio < vtkm::Float64(1.0) + tolerance)) From fcfe63ef856cfdcb3b7e20a38f29b7b93f7bd8b1 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 24 Sep 2015 21:52:58 -0600 Subject: [PATCH 06/11] Fix unnecessary warning about divide by zero. Again. Hopefully I got it right this time. --- vtkm/testing/Testing.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtkm/testing/Testing.h b/vtkm/testing/Testing.h index b90c44418..2aa7c1c47 100644 --- a/vtkm/testing/Testing.h +++ b/vtkm/testing/Testing.h @@ -355,7 +355,7 @@ bool test_equal(VectorType1 vector1, // The following condition is redundant since the previous check // guarantees neither value will be zero, but the MSVC compiler // sometimes complains about it. - if (vtkm::Abs(value2) > tolerance) + if ((vtkm::Abs(value2) > tolerance) && (value2 != 0)) { ratio = value1 / value2; } From dbed882709ebc2b8d0b4e1add7d66f07b7f3d65b Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Fri, 25 Sep 2015 11:45:09 -0400 Subject: [PATCH 07/11] 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 From 5a3e7c779efdb43c0a769ebb02040c2ced2bb1d0 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 24 Sep 2015 13:58:19 -0400 Subject: [PATCH 08/11] CellSetExplicit CreateConnectivity works even when NumberOfPoints is zero. Previously if you created a cell set explicit and didn't set the number of points you would get a runtime error when you over-ran an array's bounds. Now we account for this use case and properly generate the Cell To Point Connectivity. --- vtkm/cont/CellSetExplicit.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/vtkm/cont/CellSetExplicit.h b/vtkm/cont/CellSetExplicit.h index e50a3f327..ef14bc847 100644 --- a/vtkm/cont/CellSetExplicit.h +++ b/vtkm/cont/CellSetExplicit.h @@ -342,12 +342,12 @@ public: return; } + std::multimap cells_of_nodes; vtkm::Id pairCount = 0; vtkm::Id maxNodeID = 0; vtkm::Id numCells = GetNumberOfCells(); - vtkm::Id numPoints = GetNumberOfPoints(); for (vtkm::Id cell = 0, cindex = 0; cell < numCells; ++cell) { vtkm::Id npts = this->PointToCell.NumIndices.GetPortalConstControl().Get(cell); @@ -355,12 +355,21 @@ public: { vtkm::Id index = this->PointToCell.Connectivity.GetPortalConstControl().Get(cindex++); if (index > maxNodeID) + { maxNodeID = index; + } cells_of_nodes.insert(std::pair(index,cell)); pairCount++; } } + if(GetNumberOfPoints() <= 0) + { + this->NumberOfPoints = maxNodeID + 1; + } + + vtkm::Id numPoints = GetNumberOfPoints(); + this->CellToPoint.Shapes.Allocate(numPoints); this->CellToPoint.NumIndices.Allocate(numPoints); this->CellToPoint.Connectivity.Allocate(pairCount); @@ -380,9 +389,11 @@ public: this->CellToPoint.NumIndices.GetPortalControl().Set(pointIndex,0); ++pointIndex; } + vtkm::Id cellId = iter->second; this->CellToPoint.Connectivity.GetPortalControl().Set(connIndex,cellId); ++connIndex; + const vtkm::IdComponent oldCellCount = this->CellToPoint.NumIndices.GetPortalConstControl().Get(pointIndex-1); From c58f8ef193df2dfc01b0ef6c1ad73c06293e652e Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 24 Sep 2015 15:02:33 -0400 Subject: [PATCH 09/11] CellSetExplicit Getters now properly deduce the correct handle type. Previously the CellSetExplicit presumed that the CellToPoint and PointToCell Storage tags matched, which they don't when using custom storage tags. --- vtkm/cont/CellSetExplicit.h | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/vtkm/cont/CellSetExplicit.h b/vtkm/cont/CellSetExplicit.h index ef14bc847..ded00c0fa 100644 --- a/vtkm/cont/CellSetExplicit.h +++ b/vtkm/cont/CellSetExplicit.h @@ -77,8 +77,15 @@ class CellSetExplicit : public CellSet CellSetExplicitType, FromTopology, ToTopology>::ConnectivityType ConnectivityType; + + typedef typename ConnectivityType::ShapeArrayType ShapeArrayType; + typedef typename ConnectivityType::NumIndicesArrayType NumIndicesArrayType; + typedef typename ConnectivityType::ConnectivityArrayType ConnectivityArrayType; + typedef typename ConnectivityType::IndexOffsetArrayType IndexOffsetArrayType; + }; + public: typedef vtkm::Id SchedulingRangeType; @@ -273,14 +280,12 @@ public: VTKM_IS_TOPOLOGY_ELEMENT_TAG(FromTopology); VTKM_IS_TOPOLOGY_ELEMENT_TAG(ToTopology); - typedef typename - ConnectivityChooser::ConnectivityType - ContObjectType; + typedef ConnectivityChooser ConnectivityTypes; - typedef typename ContObjectType::ShapeArrayType::template ExecutionTypes::PortalConst ShapePortalType; - typedef typename ContObjectType::NumIndicesArrayType::template ExecutionTypes::PortalConst IndicePortalType; - typedef typename ContObjectType::ConnectivityArrayType::template ExecutionTypes::PortalConst ConnectivityPortalType; - typedef typename ContObjectType::IndexOffsetArrayType::template ExecutionTypes::PortalConst IndexOffsetPortalType; + typedef typename ConnectivityTypes::ShapeArrayType::template ExecutionTypes::PortalConst ShapePortalType; + typedef typename ConnectivityTypes::NumIndicesArrayType::template ExecutionTypes::PortalConst IndicePortalType; + typedef typename ConnectivityTypes::ConnectivityArrayType::template ExecutionTypes::PortalConst ConnectivityPortalType; + typedef typename ConnectivityTypes::IndexOffsetArrayType::template ExecutionTypes::PortalConst IndexOffsetPortalType; typedef vtkm::exec::ConnectivityExplicit VTKM_CONT_EXPORT - const vtkm::cont::ArrayHandle & + const typename ConnectivityChooser::ShapeArrayType & GetShapesArray(FromTopology,ToTopology) const { return this->GetConnectivity(FromTopology(), ToTopology()).Shapes; @@ -432,7 +437,7 @@ public: template VTKM_CONT_EXPORT - const vtkm::cont::ArrayHandle & + const typename ConnectivityChooser::NumIndicesArrayType & GetNumIndicesArray(FromTopology,ToTopology) const { return this->GetConnectivity(FromTopology(), ToTopology()).NumIndices; @@ -440,7 +445,7 @@ public: template VTKM_CONT_EXPORT - const vtkm::cont::ArrayHandle & + const typename ConnectivityChooser::ConnectivityArrayType & GetConnectivityArray(FromTopology,ToTopology) const { return this->GetConnectivity(FromTopology(), ToTopology()).Connectivity; @@ -448,7 +453,7 @@ public: template VTKM_CONT_EXPORT - const vtkm::cont::ArrayHandle & + const typename ConnectivityChooser::IndexOffsetArrayType & GetIndexOffsetArray(FromTopology,ToTopology) const { return this->GetConnectivity(FromTopology(), ToTopology()).IndexOffsets; From 011849a2514ad0bb4bfdcf75c6e5ecdf292d3f7e Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 24 Sep 2015 08:39:27 -0400 Subject: [PATCH 10/11] Add CellSetSingleType --- vtkm/cont/CMakeLists.txt | 1 + vtkm/cont/CellSetListTag.h | 5 +- vtkm/cont/CellSetSingleType.h | 162 ++++++++++++++++++ vtkm/cont/testing/CMakeLists.txt | 1 + .../testing/UnitTestDataSetSingleType.cxx | 146 ++++++++++++++++ 5 files changed, 314 insertions(+), 1 deletion(-) create mode 100644 vtkm/cont/CellSetSingleType.h create mode 100644 vtkm/cont/testing/UnitTestDataSetSingleType.cxx diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index b41b16f10..961ca0483 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -37,6 +37,7 @@ set(headers Assert.h CellSet.h CellSetExplicit.h + CellSetSingleType.h CellSetListTag.h CellSetStructured.h CoordinateSystem.h diff --git a/vtkm/cont/CellSetListTag.h b/vtkm/cont/CellSetListTag.h index e6f67739e..927b88ee7 100644 --- a/vtkm/cont/CellSetListTag.h +++ b/vtkm/cont/CellSetListTag.h @@ -27,6 +27,7 @@ #include #include +#include #include namespace vtkm { @@ -58,7 +59,9 @@ struct CellSetListTagCommon : vtkm::ListTagBase< vtkm::cont::CellSetStructured<2>, vtkm::cont::CellSetStructured<3>, - vtkm::cont::CellSetExplicit<> > { }; + vtkm::cont::CellSetExplicit<>, + vtkm::cont::CellSetSingleType<> + > { }; } } // namespace vtkm::cont diff --git a/vtkm/cont/CellSetSingleType.h b/vtkm/cont/CellSetSingleType.h new file mode 100644 index 000000000..35f074257 --- /dev/null +++ b/vtkm/cont/CellSetSingleType.h @@ -0,0 +1,162 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +// +// Copyright 2015 Sandia Corporation. +// Copyright 2015 UT-Battelle, LLC. +// Copyright 2015 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ +#ifndef vtk_m_cont_CellSetSingleType_h +#define vtk_m_cont_CellSetSingleType_h + +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace vtkm { +namespace cont { + + +//Only works with fixed sized cell sets + +template< typename ConnectivityStorageTag = VTKM_DEFAULT_CONNECTIVITY_STORAGE_TAG > +class CellSetSingleType : + public vtkm::cont::CellSetExplicit< + typename vtkm::cont::ArrayHandleConstant::StorageTag, //ShapeStorageTag + typename vtkm::cont::ArrayHandleConstant::StorageTag, //NumIndicesStorageTag + ConnectivityStorageTag, + typename vtkm::cont::ArrayHandleCounting::StorageTag //IndexOffsetStorageTag + > +{ + typedef vtkm::cont::CellSetExplicit< + typename vtkm::cont::ArrayHandleConstant::StorageTag, + typename vtkm::cont::ArrayHandleConstant::StorageTag, + ConnectivityStorageTag, + typename vtkm::cont::ArrayHandleCounting::StorageTag > Superclass; + +public: + template + VTKM_CONT_EXPORT + CellSetSingleType(CellShapeTag, const std::string &name = std::string()) + : Superclass(0, name, vtkm::CellTraits::TOPOLOGICAL_DIMENSIONS), + CellTypeAsId(CellShapeTag::Id) + { + } + + VTKM_CONT_EXPORT + CellSetSingleType(const std::string &name = std::string()) + : Superclass(0, name, vtkm::CellTraits::TOPOLOGICAL_DIMENSIONS), + CellTypeAsId(CellShapeTagEmpty::Id) + { + } + + //This is the way you can fill the memory from another system without copying + VTKM_CONT_EXPORT + void Fill(const vtkm::cont::ArrayHandle &connectivity) + { + + vtkm::IdComponent numberOfPointsPerCell = this->DetermineNumberOfPoints(); + const vtkm::Id length = connectivity.GetNumberOfValues() / numberOfPointsPerCell; + const vtkm::UInt8 shapeTypeValue = static_cast(this->CellTypeAsId); + this->PointToCell.Shapes = + vtkm::cont::make_ArrayHandleConstant(shapeTypeValue, length); + this->PointToCell.NumIndices = + vtkm::cont::make_ArrayHandleConstant(numberOfPointsPerCell, + length); + this->PointToCell.IndexOffsets = + vtkm::cont::make_ArrayHandleCounting(vtkm::Id(0), + static_cast(numberOfPointsPerCell), + length ); + this->PointToCell.Connectivity = connectivity; + + this->PointToCell.ElementsValid = true; + this->PointToCell.IndexOffsetsValid = true; + } + + /// Second method to add cells -- all at once. + /// Copies the data from the vectors, so they can be released. + VTKM_CONT_EXPORT + void FillViaCopy(const std::vector &connectivity) + { + vtkm::IdComponent numberOfPointsPerCell = this->DetermineNumberOfPoints(); + const vtkm::Id connectSize = static_cast(connectivity.size()); + + const vtkm::Id length = connectSize / numberOfPointsPerCell; + const vtkm::UInt8 shapeTypeValue = static_cast(this->CellTypeAsId); + this->PointToCell.Shapes = + vtkm::cont::make_ArrayHandleConstant(shapeTypeValue, length); + this->PointToCell.NumIndices = + vtkm::cont::make_ArrayHandleConstant(numberOfPointsPerCell, + length); + this->PointToCell.IndexOffsets = + vtkm::cont::make_ArrayHandleCounting(vtkm::Id(0), + static_cast(numberOfPointsPerCell), + length ); + + + this->PointToCell.Connectivity.Allocate( connectSize ); + std::copy(connectivity.begin(), connectivity.end(), + vtkm::cont::ArrayPortalToIteratorBegin( + this->PointToCell.Connectivity.GetPortalControl())); + + this->PointToCell.ElementsValid = true; + this->PointToCell.IndexOffsetsValid = true; + } + +private: + template< typename CellShapeTag> + void DetermineNumberOfPoints(CellShapeTag, + vtkm::CellTraitsTagSizeFixed, + vtkm::IdComponent& numberOfPoints) const + { + numberOfPoints = vtkm::CellTraits::NUM_POINTS; + } + + template< typename CellShapeTag> + void DetermineNumberOfPoints(CellShapeTag, + vtkm::CellTraitsTagSizeVariable, + vtkm::IdComponent& numberOfPoints) const + { //variable length cells can't be used with this class + numberOfPoints = -1; + } + + + vtkm::IdComponent DetermineNumberOfPoints() const + { + vtkm::IdComponent numberOfPointsPerCell = -1; + switch (this->CellTypeAsId) + { + vtkmGenericCellShapeMacro( this->DetermineNumberOfPoints(CellShapeTag(), + vtkm::CellTraits::IsSizeFixed(), + numberOfPointsPerCell) ); + default: + throw vtkm::cont::ErrorControlBadValue( + "CellSetSingleType unable to determine the cell type"); + } + return numberOfPointsPerCell; + } + + vtkm::Id CellTypeAsId; +}; + +} +} // namespace vtkm::cont + +#endif //vtk_m_cont_CellSetSingleType_h diff --git a/vtkm/cont/testing/CMakeLists.txt b/vtkm/cont/testing/CMakeLists.txt index 681171f7a..d7136c878 100644 --- a/vtkm/cont/testing/CMakeLists.txt +++ b/vtkm/cont/testing/CMakeLists.txt @@ -44,6 +44,7 @@ set(unit_tests UnitTestComputeBoundsSerial.cxx UnitTestDataSetRegular.cxx UnitTestDataSetExplicit.cxx + UnitTestDataSetSingleType.cxx UnitTestDeviceAdapterAlgorithmDependency.cxx UnitTestDeviceAdapterAlgorithmGeneral.cxx UnitTestDeviceAdapterSerial.cxx diff --git a/vtkm/cont/testing/UnitTestDataSetSingleType.cxx b/vtkm/cont/testing/UnitTestDataSetSingleType.cxx new file mode 100644 index 000000000..6f0e7a605 --- /dev/null +++ b/vtkm/cont/testing/UnitTestDataSetSingleType.cxx @@ -0,0 +1,146 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +// +// Copyright 2014 Sandia Corporation. +// Copyright 2014 UT-Battelle, LLC. +// Copyright 2014 Los Alamos National Security. +// +// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +// the U.S. Government retains certain rights in this software. +// +// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National +// Laboratory (LANL), the U.S. Government retains certain rights in +// this software. +//============================================================================ + +#include +#include +#include +#include + +namespace { + +template +bool TestArrayHandle(const vtkm::cont::ArrayHandle &ah, const T *expected, + vtkm::Id size) +{ + if (size != ah.GetNumberOfValues()) + { + return false; + } + + for (vtkm::Id i = 0; i < size; ++i) + { + if (ah.GetPortalConstControl().Get(i) != expected[i]) + { + return false; + } + } + + return true; +} + + +inline vtkm::cont::DataSet make_SingleTypeDataSet() +{ + using vtkm::cont::Field; + + vtkm::cont::DataSet dataSet; + + const int nVerts = 5; + typedef vtkm::Vec CoordType; + CoordType coordinates[nVerts] = { + CoordType(0, 0, 0), + CoordType(1, 0, 0), + CoordType(1, 1, 0), + CoordType(2, 1, 0), + CoordType(2, 2, 0) + }; + + //Set coordinate system + dataSet.AddCoordinateSystem( + vtkm::cont::CoordinateSystem("coordinates", 1, coordinates, nVerts)); + + //Set point scalar + vtkm::Float32 vars[nVerts] = {10.1f, 20.1f, 30.2f, 40.2f, 50.3f}; + dataSet.AddField(Field("pointvar", 1, vtkm::cont::Field::ASSOC_POINTS, vars, nVerts)); + + std::vector conn; + // First Cell + conn.push_back(0); + conn.push_back(1); + conn.push_back(2); + // Second Cell + conn.push_back(1); + conn.push_back(2); + conn.push_back(3); + // Third Cell + conn.push_back(2); + conn.push_back(3); + conn.push_back(4); + + vtkm::cont::CellSetSingleType<> cellSet(vtkm::CellShapeTagTriangle(), + "cells"); + cellSet.FillViaCopy(conn); + + dataSet.AddCellSet(cellSet); + + return dataSet; +} + +void TestDataSet_Explicit() +{ + + vtkm::cont::DataSet ds = make_SingleTypeDataSet(); + + ds.PrintSummary(std::cout); + + //verify that we can get a CellSetSingleType from a dataset + vtkm::cont::CellSetSingleType<> &cellset = + ds.GetCellSet(0).CastTo >(); + + + //verify that we can compute the cell to point connectivity + cellset.BuildConnectivity(vtkm::TopologyElementTagCell(), + vtkm::TopologyElementTagPoint()); + + + //verify that the point to cell connectivity types are correct + vtkm::cont::ArrayHandleConstant shapesPointToCell = cellset.GetShapesArray( + vtkm::TopologyElementTagPoint(),vtkm::TopologyElementTagCell()); + vtkm::cont::ArrayHandleConstant numIndicesPointToCell = cellset.GetNumIndicesArray( + vtkm::TopologyElementTagPoint(),vtkm::TopologyElementTagCell()); + vtkm::cont::ArrayHandle connPointToCell = cellset.GetConnectivityArray( + vtkm::TopologyElementTagPoint(),vtkm::TopologyElementTagCell()); + + 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::ArrayHandle shapesCellToPoint = cellset.GetShapesArray( + vtkm::TopologyElementTagCell(),vtkm::TopologyElementTagPoint()); + vtkm::cont::ArrayHandle numIndicesCellToPoint = cellset.GetNumIndicesArray( + vtkm::TopologyElementTagCell(),vtkm::TopologyElementTagPoint()); + vtkm::cont::ArrayHandle connCellToPoint = cellset.GetConnectivityArray( + vtkm::TopologyElementTagCell(),vtkm::TopologyElementTagPoint()); + + 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"); + +} + +} + + +int UnitTestDataSetSingleType(int, char *[]) +{ + return vtkm::cont::testing::Testing::Run(TestDataSet_Explicit); +} From c0f3b6ff97a6a4ea653889dd4008c6bbbce48076 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 24 Sep 2015 16:14:09 -0400 Subject: [PATCH 11/11] Make3DExplicitDataSetCowNose now generates a CellSetSingleType. --- vtkm/cont/testing/MakeTestDataSet.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/vtkm/cont/testing/MakeTestDataSet.h b/vtkm/cont/testing/MakeTestDataSet.h index 72a541f59..2e060a14a 100644 --- a/vtkm/cont/testing/MakeTestDataSet.h +++ b/vtkm/cont/testing/MakeTestDataSet.h @@ -250,19 +250,16 @@ MakeTestDataSet::Make3DExplicitDataSetCowNose(double *pBounds) dataSet.AddCoordinateSystem( vtkm::cont::CoordinateSystem("coordinates", 1, coordinates, nVerts)); - vtkm::cont::CellSetExplicit<> cellSet(nVerts, "cells", 2); + vtkm::cont::ArrayHandle connectivity; + connectivity.Allocate(nPointIds); - cellSet.PrepareToAddCells(nPointIds/3, nPointIds); - for (vtkm::Id i=0; i(pointId[i*3], - pointId[i*3+1], - pointId[i*3+2])); + connectivity.GetPortalControl().Set(i, pointId[i]); } - cellSet.CompleteAddingCells(); - + vtkm::cont::CellSetSingleType< > cellSet(vtkm::CellShapeTagTriangle(), + "cells"); + cellSet.Fill(connectivity); dataSet.AddCellSet(cellSet); // copy bounds