VTK-m  2.0
DataSetMesh.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 // Copyright (c) 2018, The Regents of the University of California, through
11 // Lawrence Berkeley National Laboratory (subject to receipt of any required approvals
12 // from the U.S. Dept. of Energy). All rights reserved.
13 //
14 // Redistribution and use in source and binary forms, with or without modification,
15 // are permitted provided that the following conditions are met:
16 //
17 // (1) Redistributions of source code must retain the above copyright notice, this
18 // list of conditions and the following disclaimer.
19 //
20 // (2) Redistributions in binary form must reproduce the above copyright notice,
21 // this list of conditions and the following disclaimer in the documentation
22 // and/or other materials provided with the distribution.
23 //
24 // (3) Neither the name of the University of California, Lawrence Berkeley National
25 // Laboratory, U.S. Dept. of Energy nor the names of its contributors may be
26 // used to endorse or promote products derived from this software without
27 // specific prior written permission.
28 //
29 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
30 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
31 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32 // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
36 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
37 // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
38 // OF THE POSSIBILITY OF SUCH DAMAGE.
39 //
40 //=============================================================================
41 //
42 // This code is an extension of the algorithm presented in the paper:
43 // Parallel Peak Pruning for Scalable SMP Contour Tree Computation.
44 // Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
45 // Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
46 // (LDAV), October 2016, Baltimore, Maryland.
47 //
48 // The PPP2 algorithm and software were jointly developed by
49 // Hamish Carr (University of Leeds), Gunther H. Weber (LBNL), and
50 // Oliver Ruebel (LBNL)
51 //==============================================================================
52 //
53 // Parallel Peak Pruning v. 2.0
54 //
55 // Mesh_2D_DEM_Triangulation.h - a 2D regular mesh
56 //
57 //==============================================================================
58 //
59 // COMMENTS:
60 //
61 // This is an abstraction to separate out the mesh from the graph algorithm
62 // that we will be executing.
63 //
64 // In this version, we will sort the values up front, and then keep track of
65 // them using indices only, without looking up their values. This should
66 // simplify several parts of code significantly, and reduce the memory bandwidth.
67 // Of course, in moving to 64-bit indices, we will not necessarily see gains.
68 //
69 //==============================================================================
70 
71 #ifndef vtk_m_worklet_contourtree_augmented_data_set_mesh_h
72 #define vtk_m_worklet_contourtree_augmented_data_set_mesh_h
73 
74 #include <vtkm/cont/Algorithm.h>
75 #include <vtkm/cont/ArrayCopy.h>
76 #include <vtkm/cont/ArrayHandle.h>
79 #include <vtkm/cont/Invoker.h>
80 
88 
89 //Define namespace alias for the freudenthal types to make the code a bit more readable
90 
91 namespace vtkm
92 {
93 namespace worklet
94 {
95 namespace contourtree_augmented
96 {
98 {
99 public:
100  // common mesh size parameter, use all three dimensions ofr MeshSize with third determining if 2D or 3D
101  // (convention: MeshSize[2] is always >= 1, even for empty data set, so that we can detect 2D
102  // data as MeshSize[2] == 1)
105 
106  // Array with the sorted order of the mesh vertices
108 
109  // Array with the sort index for each vertex
110  // i.e. the inverse permutation for SortOrder
112 
113  //empty constructor
115  : MeshSize{ 0, 0, 1 } // Always set third dimension to 1 for easy detection of 2D vs 3D
116  , NumVertices(0)
117  , NumLogSteps(1)
118  {
119  }
120 
121  // base constructor
123  : MeshSize{ meshSize }
124  , NumVertices{ meshSize[0] * meshSize[1] * meshSize[2] }
125  // per convention meshSize[2] == 1 for 2D
126  , NumLogSteps(1)
127 
128  {
129  // Per convention the third dimension should be 1 (even for an empty
130  // mesh) or higher to make it easier to check for 2D vs. 3D data)
131  VTKM_ASSERT(MeshSize[2] >= 1);
132  // TODO/FIXME: An empty mesh will likely cause a crash down the
133  // road anyway, so we may want to detect that case and handle
134  // it appropriately.
135 
136  // Compute the number of log-jumping steps (i.e. lg_2 (NumVertices))
137  // this->NumLogSteps = 1; // already set in initializer list
138  for (vtkm::Id shifter = this->NumVertices; shifter > 0; shifter >>= 1)
139  this->NumLogSteps++;
140  }
141 
142  virtual ~DataSetMesh() {}
143 
144  // Getter function for NumVertices
145  vtkm::Id GetNumberOfVertices() const { return this->NumVertices; }
146 
147  // Sorts the data and initializes SortOrder & SortIndices
148  template <typename T, typename StorageType>
150 
161  const mesh_dem::IdRelabeler* localToGlobalIdRelabeler) const
162  { // GetGlobalIDsFromSortIndices()
163  auto permutedSortOrder = vtkm::cont::make_ArrayHandlePermutation(sortIds, this->SortOrder);
166  mesh_dem::IdRelabeler>(permutedSortOrder, *localToGlobalIdRelabeler);
167  } // GetGlobalIDsFromSortIndices()
168 
177  template <typename MeshIdArrayType>
179  GetGlobalIdsFromMeshIndices(const MeshIdArrayType& meshIds,
180  const mesh_dem::IdRelabeler* localToGlobalIdRelabeler) const
181  { // GetGlobalIDsFromMeshIndices()
183  meshIds, *localToGlobalIdRelabeler);
184  } // GetGlobalIDsFromMeshIndices()
185 
186  //routine that dumps out the contents of the mesh
187  void DebugPrint(const char* message, const char* fileName, long lineNum);
188 
189 protected:
190  //TODO/FIXME: Update comment, possibly refactor and move somewhere else (helper function outside class?)
203  template <typename MeshTypeObj>
205  const MeshTypeObj* mesh,
206  const vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler& localToGlobalIdRelabeler,
207  IdArrayType& ownedVertices) const;
208 
209  virtual void DebugPrintExtends();
210  template <typename T, typename StorageType>
212 }; // class DataSetMesh
213 
214 // Implementation of GetOwnedVerticesByGlobalId used by subclasses
215 template <typename MeshTypeObj>
217  const MeshTypeObj* mesh,
218  const vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler& localToGlobalIdRelabeler,
219  IdArrayType& ownedVertices) const
220 {
221  // use temporary array since we need to compress these at the end via CopyIf so we
222  // can move the values to keep to the ownedVertices ouput array then
223  IdArrayType tempOwnedVertices;
224  // Fancy array for the running mesh index
225  vtkm::cont::ArrayHandleIndex meshIndexArray(this->GetNumberOfVertices());
226  auto ownedVerticesWorklet =
228  localToGlobalIdRelabeler);
229  vtkm::cont::Invoker invoke;
230  invoke(ownedVerticesWorklet, // worklet ot run
231  meshIndexArray, // input mesh index to map
232  mesh, // input the mesh object
233  tempOwnedVertices // output
234  );
235  // now compress out the NO_SUCH_ELEMENT ones
237  // compress the array
239  tempOwnedVertices, // compress the array of owned vertices
240  tempOwnedVertices, // stencil. Same as input. Values to remove have NO_SUCH_ELEMENT flag
241  ownedVertices, // array where the compressed ownedVertices are stored
242  notNoSuchElementPredicate // unary predicate for deciding which nodes are considered true. Here those that do not have a NO_SUCH_ELEMENT flag.
243  );
244 }
245 
246 
247 // Sorts the data and initialises the SortIndices & SortOrder
248 template <typename T, typename StorageType>
250 {
251  // Define namespace alias for mesh dem worklets
252  namespace mesh_dem_worklets = vtkm::worklet::contourtree_augmented::mesh_dem;
253 
254  // Make sure that the values have the correct size
255  VTKM_ASSERT(values.GetNumberOfValues() == this->NumVertices);
256 
257  // Make sure that we are not running on an empty mesh
258  VTKM_ASSERT(this->NumVertices > 0);
259 
260  // Just in case, make sure that everything is cleaned up
261  this->SortIndices.ReleaseResources();
262  this->SortOrder.ReleaseResources();
263 
264  // allocate memory for the sort arrays
265  this->SortOrder.Allocate(this->NumVertices);
266  this->SortIndices.Allocate(this->NumVertices);
267 
268  // now sort the sort order vector by the values, i.e,. initialize the SortOrder member variable
269  vtkm::cont::ArrayHandleIndex initVertexIds(
270  this->NumVertices); // create sequence 0, 1, .. NumVertices
271  vtkm::cont::ArrayCopy(initVertexIds, this->SortOrder);
272 
273  vtkm::cont::Algorithm::Sort(this->SortOrder,
275 
276  // now set the index lookup, i.e., initialize the SortIndices member variable
277  // In serial this would be
278  // for (indexType vertex = 0; vertex < NumVertices; vertex++)
279  // SortIndices[SortOrder[vertex]] = vertex;
280  data_set_mesh::SortIndices sortIndicesWorklet;
281  vtkm::cont::Invoker invoke;
282  invoke(sortIndicesWorklet, this->SortOrder, this->SortIndices);
283 
284  // Debug print statement
285  DebugPrint("Data Sorted", __FILE__, __LINE__);
286  DebugPrintValues(values);
287 } // SortData()
288 
289 // Print mesh extends
291 {
292  // For compatibility with the output of the original PPP Implementation, print size
293  // as NumRows, NumColumns and NumSlices (if applicable)
294  PrintLabel("NumRows");
295  PrintIndexType(this->MeshSize[1]);
296  std::cout << std::endl;
297  PrintLabel("NumColumns");
298  PrintIndexType(this->MeshSize[0]);
299  std::cout << std::endl;
300  if (MeshSize[2] > 1)
301  {
302  PrintLabel("NumSlices");
303  PrintIndexType(this->MeshSize[2]);
304  std::cout << std::endl;
305  }
306 } // DebugPrintExtends
307 
308 inline void DataSetMesh::DebugPrint(const char* message, const char* fileName, long lineNum)
309 { // DebugPrint()
310 #ifdef DEBUG_PRINT
311  std::cout << "------------------------------------------------------" << std::endl;
312  std::cout << std::setw(30) << std::left << fileName << ":" << std::right << std::setw(4)
313  << lineNum << std::endl;
314  std::cout << std::left << std::string(message) << std::endl;
315  std::cout << "Mesh Contains: " << std::endl;
316  std::cout << "------------------------------------------------------" << std::endl;
317  //DebugPrintExtents();
318  PrintLabel("NumVertices");
319  PrintIndexType(this->NumVertices);
320  std::cout << std::endl;
321  PrintLabel("NumLogSteps");
322  PrintIndexType(this->NumLogSteps);
323  std::cout << std::endl;
324  PrintIndices("Sort Indices", this->SortIndices);
325  PrintIndices("Sort Order", this->SortOrder);
326  std::cout << std::endl;
327 #else
328  // Avoid unused parameter warning
329  (void)message;
330  (void)fileName;
331  (void)lineNum;
332 #endif
333 } // DebugPrint()
334 
335 template <typename T, typename StorageType>
337 {
338 #ifdef DEBUG_PRINT
339  if (MeshSize[0] > 0)
340  {
341  PrintLabelledDataBlock<T, StorageType>("Value", values, MeshSize[0]);
342  PrintSortedValues("Sorted Values", values, this->SortOrder);
343  }
344  PrintHeader(values.GetNumberOfValues());
345 #else
346  // Avoid unused parameter warning
347  (void)values;
348 #endif
349 } // DebugPrintValues
350 
351 } // namespace contourtree_augmented
352 } // worklet
353 } // vtkm
354 
355 // Include specialized mesh classes providing triangulation/connectivity information
359 
360 #endif
vtkm::cont::ArrayHandle::GetNumberOfValues
VTKM_CONT vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:448
vtkm::cont::ArrayHandle< vtkm::Id >
ArrayHandle.h
vtkm::worklet::contourtree_augmented::PrintLabel
void PrintLabel(std::string label, std::ostream &outStream=std::cout)
Definition: augmented/PrintVectors.h:101
vtkm::worklet::contourtree_augmented::DataSetMesh::GetNumberOfVertices
vtkm::Id GetNumberOfVertices() const
Definition: DataSetMesh.h:145
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
GetOwnedVerticesByGlobalIdWorklet.h
SortIndices.h
vtkm::worklet::contourtree_augmented::DataSetMesh::SortOrder
IdArrayType SortOrder
Definition: DataSetMesh.h:107
VTKM_ASSERT
#define VTKM_ASSERT(condition)
Definition: Assert.h:43
vtkm::cont::ArrayHandle::Allocate
VTKM_CONT void Allocate(vtkm::Id numberOfValues, vtkm::CopyFlag preserve, vtkm::cont::Token &token) const
Allocates an array large enough to hold the given number of values.
Definition: ArrayHandle.h:465
vtkm::worklet::contourtree_augmented::DataSetMesh::DataSetMesh
DataSetMesh()
Definition: DataSetMesh.h:114
vtkm::worklet::contourtree_augmented::DataSetMesh::DataSetMesh
DataSetMesh(vtkm::Id3 meshSize)
Definition: DataSetMesh.h:122
vtkm::worklet::contourtree_augmented::DataSetMesh::DebugPrintValues
void DebugPrintValues(const vtkm::cont::ArrayHandle< T, StorageType > &values)
Definition: DataSetMesh.h:336
vtkm::worklet::contourtree_augmented::DataSetMesh::NumVertices
vtkm::Id NumVertices
Definition: DataSetMesh.h:104
vtkm::worklet::contourtree_augmented::DataSetMesh::SortIndices
IdArrayType SortIndices
Definition: DataSetMesh.h:111
vtkm::worklet::contourtree_augmented::DataSetMesh::DebugPrint
void DebugPrint(const char *message, const char *fileName, long lineNum)
Definition: DataSetMesh.h:308
vtkm::cont::Algorithm::Sort
static VTKM_CONT void Sort(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle< T, Storage > &values)
Definition: Algorithm.h:965
PrintVectors.h
Invoker.h
vtkm::worklet::contourtree_augmented::DataSetMesh::GetOwnedVerticesByGlobalIdImpl
void GetOwnedVerticesByGlobalIdImpl(const MeshTypeObj *mesh, const vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler &localToGlobalIdRelabeler, IdArrayType &ownedVertices) const
Compute a list of the global Iss of all vertices that logically belong to the data block represented ...
Definition: DataSetMesh.h:216
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
ArrayCopy.h
DataSetMeshTriangulation2DFreudenthal.h
vtkm::worklet::contourtree_augmented::data_set_mesh::GetOwnedVerticesByGlobalIdWorklet
Definition: GetOwnedVerticesByGlobalIdWorklet.h:69
IdRelabeler.h
vtkm::worklet::contourtree_augmented::DataSetMesh::~DataSetMesh
virtual ~DataSetMesh()
Definition: DataSetMesh.h:142
vtkm::worklet::contourtree_augmented::data_set_mesh::SortIndices
Definition: SortIndices.h:68
ArrayHandlePermutation.h
Algorithm.h
ArrayHandleIndex.h
vtkm::cont::ArrayHandlePermutation
Implicitly permutes the values in an array.
Definition: ArrayHandlePermutation.h:227
vtkm::cont::Invoker
Allows launching any worklet without a dispatcher.
Definition: Invoker.h:41
vtkm::worklet::contourtree_augmented::mesh_dem
Definition: IdRelabeler.h:75
vtkm::cont::ArrayCopy
void ArrayCopy(const SourceArrayType &source, DestArrayType &destination)
Does a deep copy from one array to another array.
Definition: ArrayCopy.h:142
vtkm::cont::Algorithm::CopyIf
static VTKM_CONT void CopyIf(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CIn > &input, const vtkm::cont::ArrayHandle< U, CStencil > &stencil, vtkm::cont::ArrayHandle< T, COut > &output)
Definition: Algorithm.h:435
vtkm::worklet::contourtree_augmented::PrintSortedValues
void PrintSortedValues(std::string label, const vtkm::cont::ArrayHandle< T, StorageType > &dVec, IdArrayType &sortVec, vtkm::Id nValues=-1, std::ostream &outStream=std::cout)
Definition: augmented/PrintVectors.h:224
Types.h
vtkm::cont::ArrayHandleTransform
Implicitly transform values of one array to another with a functor.
Definition: ArrayHandleTransform.h:437
vtkm::worklet::contourtree_augmented::DataSetMesh::MeshSize
vtkm::Id3 MeshSize
Definition: DataSetMesh.h:103
NotNoSuchElementPredicate.h
vtkm::worklet::contourtree_augmented::NotNoSuchElementPredicate
Definition: NotNoSuchElementPredicate.h:67
vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler
A utility class that converts Ids from local to global given a mesh.
Definition: IdRelabeler.h:79
vtkm::cont::make_ArrayHandlePermutation
VTKM_CONT vtkm::cont::ArrayHandlePermutation< IndexArrayHandleType, ValueArrayHandleType > make_ArrayHandlePermutation(IndexArrayHandleType indexArray, ValueArrayHandleType valueArray)
make_ArrayHandleTransform is convenience function to generate an ArrayHandleTransform.
Definition: ArrayHandlePermutation.h:279
DataSetMeshTriangulation3DMarchingCubes.h
vtkm::Vec< vtkm::Id, 3 >
DataSetMeshTriangulation3DFreudenthal.h
vtkm::worklet::contourtree_augmented::DataSetMesh::SortData
void SortData(const vtkm::cont::ArrayHandle< T, StorageType > &values)
Definition: DataSetMesh.h:249
vtkm::worklet::contourtree_augmented::PrintIndexType
void PrintIndexType(vtkm::Id index, std::ostream &outStream=std::cout)
Definition: augmented/PrintVectors.h:127
vtkm::worklet::contourtree_augmented::DataSetMesh::GetGlobalIdsFromSortIndices
vtkm::cont::ArrayHandleTransform< vtkm::cont::ArrayHandlePermutation< IdArrayType, IdArrayType >, mesh_dem::IdRelabeler > GetGlobalIdsFromSortIndices(const IdArrayType &sortIds, const mesh_dem::IdRelabeler *localToGlobalIdRelabeler) const
Routine to return the global IDs for a set of vertices We here return a fancy array handle to convert...
Definition: DataSetMesh.h:160
vtkm::worklet::contourtree_augmented::mesh_dem::SimulatedSimplicityIndexComparator
Definition: SimulatedSimplicityComperator.h:105
vtkm::worklet::contourtree_augmented::PrintHeader
void PrintHeader(vtkm::Id howMany, std::ostream &outStream=std::cout)
Definition: augmented/PrintVectors.h:151
vtkm::worklet::contourtree_augmented::PrintIndices
void PrintIndices(std::string label, const vtkm::cont::ArrayHandle< T > &iVec, vtkm::Id nIndices=-1, std::ostream &outStream=std::cout)
Definition: augmented/PrintVectors.h:253
vtkm::worklet::contourtree_augmented::DataSetMesh::DebugPrintExtends
virtual void DebugPrintExtends()
Definition: DataSetMesh.h:290
vtkm::worklet::contourtree_augmented::DataSetMesh
Definition: DataSetMesh.h:97
vtkm::worklet::contourtree_augmented::DataSetMesh::GetGlobalIdsFromMeshIndices
vtkm::cont::ArrayHandleTransform< MeshIdArrayType, mesh_dem::IdRelabeler > GetGlobalIdsFromMeshIndices(const MeshIdArrayType &meshIds, const mesh_dem::IdRelabeler *localToGlobalIdRelabeler) const
Routine to return the global IDs for a set of vertices We here return a fancy array handle to convert...
Definition: DataSetMesh.h:179
vtkm::cont::ArrayHandle::ReleaseResources
VTKM_CONT void ReleaseResources() const
Releases all resources in both the control and execution environments.
Definition: ArrayHandle.h:559
SimulatedSimplicityComperator.h
vtkm::worklet::contourtree_augmented::DataSetMesh::NumLogSteps
vtkm::Id NumLogSteps
Definition: DataSetMesh.h:104
vtkm::cont::ArrayHandleIndex
An implicit array handle containing the its own indices.
Definition: ArrayHandleIndex.h:54