VTK-m  2.0
HierarchicalContourTree.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 // Parallel Peak Pruning v. 2.0
43 //
44 // Started June 15, 2017
45 //
46 // Copyright Hamish Carr, University of Leeds
47 //
48 // HierarchicalContourTree.cpp - Hierarchical version of contour tree that captures all of the
49 // superarcs relevant for a particular block. It is constructed by grafting missing edges
50 // into the tree at all levels
51 //
52 //=======================================================================================
53 //
54 // COMMENTS:
55 //
56 // There are several significant differences from the ContourTree class, in particular the
57 // semantics of storage:
58 // i. Hyper arcs are processed inside to outside instead of outside to inside
59 // This is to allow the superarcs in higher blocks to be a prefix of those in lower blocks
60 // We can do this by inverting the loop order and processing each level separately, so
61 // we don't need to renumber (whew!)
62 // ii. If the superarc is -1, it USED to mean the root of the tree. Now it can also mean
63 // the root of a lower-level subtree. in this case, the superparent will show which
64 // existing superarc it inserts into.
65 //
66 //=======================================================================================
67 
68 #ifndef vtk_m_worklet_contourtree_distributed_hierarchical_contour_tree_h
69 #define vtk_m_worklet_contourtree_distributed_hierarchical_contour_tree_h
70 
71 #define VOLUME_PRINT_WIDTH 8
72 
73 #include <vtkm/Types.h>
74 #include <vtkm/cont/ArrayCopy.h>
75 #include <vtkm/cont/DataSet.h>
84 
85 namespace vtkm
86 {
87 namespace worklet
88 {
89 namespace contourtree_distributed
90 {
91 
92 
99 template <typename FieldType>
101 {
102 public:
103  VTKM_CONT
105 
106  // REGULAR arrays: i.e. over all nodes in the tree, including regular
107  // the full list of global IDs for the regular nodes
109  // we will also need to track the data values
111 
112  // an array to support searching by global ID
113  // given a global ID, find its position in the regular node index
114  // To do so, we keep an index by global ID of their positions in the array
116  // the supernode ID for each regular node: for most, this will be NO_SUCH_ELEMENT
117  // but this makes lookups for supernode ID a lot easier
119  // the superparent for each regular node
121 
122  // SUPER arrays: i.e. over all supernodes in the tree
123  // the ID in the globalID array
125  // where the supernode connects to
127  // the hyperparent for each supernode
129  // the hypernode ID for each supernode: often NO_SUCH_ELEMENT
130  // but it makes lookups easier
132 
133  // which iteration & round the vertex is transferred in
134  // the second of these is the same as "whenTransferred", but inverted order
137 
138  // HYPER arrays: i.e. over all hypernodes in the tree
139  // the ID in the supernode array
141  // where the hypernode connects to
143  // the number of child supernodes on the superarc (including the start node)
144  // and not including any inserted in the hierarchy
146 
147  // how many rounds of fan-in were used to construct it
149 
150  // use for debugging? -> This makes more sense in hyper sweeper?
151  // vtkm::Id NumOwnedRegularVertices;
152 
153  // The following arrays store the numbers of reg/super/hyper nodes at each level of the hierarchy
154  // They are filled in from the top down, and are fundamentally CPU side control variables
155  // They will be needed for hypersweeps.
156 
157  // May be for hypersweeps later on. SHOULD be primarily CPU side
162 
165 
167  // TODO/FIXME: Consider using ArrayHandleGroupVecVariable instead of an STL vector
168  // of ArrayHandles. (Though that may be a bit tricky with dynamic resizing.)
169  std::vector<vtkm::worklet::contourtree_augmented::IdArrayType> FirstSupernodePerIteration;
170  std::vector<vtkm::worklet::contourtree_augmented::IdArrayType> FirstHypernodePerIteration;
171 
173  VTKM_CONT
175  {
176  return FindRegularByGlobal(this->RegularNodeSortOrder, this->RegularNodeGlobalIds);
177  }
178 
180  VTKM_CONT
182  {
183  return FindSuperArcForUnknownNode<FieldType>(this->Superparents,
184  this->Supernodes,
185  this->Superarcs,
186  this->Superchildren,
187  this->WhichRound,
188  this->WhichIteration,
189  this->Hyperparents,
190  this->Hypernodes,
191  this->Hyperarcs,
192  this->RegularNodeGlobalIds,
193  this->DataValues);
194  }
195 
197  VTKM_CONT
199  {
200  return FindSuperArcBetweenNodes(this->Superarcs);
201  }
202 
204  VTKM_CONT
205  void Initialize(vtkm::Id numRounds,
208 
210  VTKM_CONT
211  std::string RegularString(const vtkm::Id regularId) const;
212 
213  VTKM_CONT
214  std::string SuperString(const vtkm::Id superId) const;
215 
216  VTKM_CONT
217  std::string HyperString(const vtkm::Id hyperId) const;
218 
220  VTKM_CONT
221  std::string ProbeHyperPath(const vtkm::Id regularId, const vtkm::Id maxLength = -1) const;
222 
224  VTKM_CONT
225  std::string ProbeSuperPath(const vtkm::Id regularId, const vtkm::Id maxLength = -1) const;
226 
228  VTKM_CONT
229  std::string PrintDotSuperStructure(const char* label) const;
230 
232  VTKM_CONT
233  std::string PrintTreeStats() const;
234 
236  VTKM_CONT
237  std::string DebugPrint(std::string message, const char* fileName, long lineNum) const;
238 
239  // modified version of dumpSuper() that also gives volume counts
240  VTKM_CONT
241  static std::string DumpVolumes(
244  const vtkm::worklet::contourtree_augmented::IdArrayType& regularNodeGlobalIds,
245  vtkm::Id totalVolume,
248 
249  // Helper function to convert an STL vector of VTK-m arrays into components and
250  // group arrays (for packing into a vtkm::cont::DataSet and using with an
251  // ArrayHandleGroupVecVariable for access)
252  // TODO/FIXME: Ultimately, we should get rid of the STL arrays and use an
253  // ArrayHandleGroupVecVariable in this class.
254  VTKM_CONT
256  const std::vector<vtkm::worklet::contourtree_augmented::IdArrayType>& inputVec,
258  vtkm::cont::ArrayHandle<vtkm::Id>& outputOffsets);
259 
260  VTKM_CONT
261  void AddToVTKMDataSet(vtkm::cont::DataSet& ds) const;
262 
263 private:
266 };
267 
268 template <typename FieldType>
270 //: NumOwnedRegularVertices(static_cast<vtkm::Id>(0))
271 { // constructor
272  NumRegularNodesInRound.ReleaseResources();
273  NumSupernodesInRound.ReleaseResources();
274  NumHypernodesInRound.ReleaseResources();
275  NumIterations.ReleaseResources();
276 } // constructor
277 
278 
280 template <typename FieldType>
282  vtkm::Id numRounds,
285 { // Initialize(..)
286  // TODO: If any other arrays are only copied in this function but will not be modified then we could just assign instead of copy them and make them const
287  // set the initial logical size of the arrays: note that we need to keep level 0 separate, so have an extra level at the top
288  this->NumRounds = numRounds;
289  {
290  auto tempZeroArray = vtkm::cont::ArrayHandleConstant<vtkm::Id>(0, this->NumRounds + 1);
291  vtkm::cont::Algorithm::Copy(tempZeroArray, this->NumIterations);
292  vtkm::cont::Algorithm::Copy(tempZeroArray, this->NumRegularNodesInRound);
294  this->NumRounds, tree.Nodes.GetNumberOfValues(), this->NumRegularNodesInRound);
295  vtkm::cont::Algorithm::Copy(tempZeroArray, this->NumSupernodesInRound);
297  this->NumRounds, tree.Supernodes.GetNumberOfValues(), this->NumSupernodesInRound);
298  vtkm::cont::Algorithm::Copy(tempZeroArray, this->NumHypernodesInRound);
300  this->NumRounds, tree.Hypernodes.GetNumberOfValues(), this->NumHypernodesInRound);
301  }
302  // copy the iterations of the top level hypersweep - this is +1: one because we are counting inclusively
303  // HAC JAN 15, 2020: In order to make this consistent with grafting rounds for hybrid hypersweeps, we add one to the logical number of
304  // iterations instead of the prior version which stored an extra extra element (ie +2)
305  // WARNING! WARNING! WARNING! This is a departure from the treatment in the contour tree, where the last iteration to the NULL root was
306  // treated as an implicit round.
307  {
308  vtkm::Id tempSizeVal = vtkm::cont::ArrayGetValue(this->NumRounds, this->NumIterations) + 1;
310  this->NumRounds, tree.NumIterations + 1, this->NumIterations);
311  this->FirstSupernodePerIteration.resize(static_cast<std::size_t>(this->NumRounds + 1));
312  this->FirstSupernodePerIteration[static_cast<std::size_t>(this->NumRounds)].Allocate(
313  tempSizeVal);
314  this->FirstHypernodePerIteration.resize(static_cast<std::size_t>(this->NumRounds + 1));
315  this->FirstHypernodePerIteration[static_cast<std::size_t>(this->NumRounds)].Allocate(
316  tempSizeVal);
317  }
318  // now copy in the details. Use CopySubRagnge to ensure that the Copy does not shrink the size
319  // of the array as the arrays are in this case allocated above to the approbriate size
321  tree.FirstSupernodePerIteration, // copy this
322  0, // start at index 0
323  tree.FirstSupernodePerIteration.GetNumberOfValues(), // copy all values
324  this->FirstSupernodePerIteration[static_cast<std::size_t>(this->NumRounds)]);
327  0, // start at index 0
328  tree.FirstHypernodePerIteration.GetNumberOfValues(), // copy all values
329  this->FirstHypernodePerIteration[static_cast<std::size_t>(this->NumRounds)]);
330 
331  // set the sizes for the arrays
332  this->RegularNodeGlobalIds.Allocate(tree.Nodes.GetNumberOfValues());
333  this->DataValues.Allocate(mesh.SortedValues.GetNumberOfValues());
334  this->RegularNodeSortOrder.Allocate(tree.Nodes.GetNumberOfValues());
335  this->Superparents.Allocate(tree.Superparents.GetNumberOfValues());
336  {
339  vtkm::cont::Algorithm::Copy(tempNSE, this->Regular2Supernode);
340  }
341 
342  this->Supernodes.Allocate(tree.Supernodes.GetNumberOfValues());
343  this->Superarcs.Allocate(tree.Superarcs.GetNumberOfValues());
344  this->Hyperparents.Allocate(tree.Hyperparents.GetNumberOfValues());
345  {
348  vtkm::cont::Algorithm::Copy(tempNSE, this->Super2Hypernode);
349  }
350  this->WhichRound.Allocate(tree.Supernodes.GetNumberOfValues());
351  this->WhichIteration.Allocate(tree.Supernodes.GetNumberOfValues());
352 
353  this->Hypernodes.Allocate(tree.Hypernodes.GetNumberOfValues());
354  this->Hyperarcs.Allocate(tree.Hyperarcs.GetNumberOfValues());
355  this->Superchildren.Allocate(tree.Hyperarcs.GetNumberOfValues());
356 
357  //copy the regular nodes
358  vtkm::cont::Algorithm::Copy(mesh.GlobalMeshIndex, this->RegularNodeGlobalIds);
359  vtkm::cont::Algorithm::Copy(mesh.SortedValues, this->DataValues);
360 
361  // we want to be able to search by global mesh index. That means we need to have an index array, sorted indirectly on globalMeshIndex
363  vtkm::cont::ArrayHandleIndex(RegularNodeSortOrder.GetNumberOfValues()), RegularNodeSortOrder);
364  vtkm::cont::Algorithm::Sort(RegularNodeSortOrder, PermuteComparator(this->RegularNodeGlobalIds));
365  vtkm::cont::Algorithm::Copy(tree.Superparents, this->Superparents);
366 
367  // copy in the supernodes
368  vtkm::cont::Algorithm::Copy(tree.Supernodes, this->Supernodes);
369  vtkm::cont::Algorithm::Copy(tree.Superarcs, this->Superarcs);
370  vtkm::cont::Algorithm::Copy(tree.Hyperparents, this->Hyperparents);
371 
373  vtkm::cont::ArrayHandleConstant<vtkm::Id>(numRounds, this->WhichRound.GetNumberOfValues()),
374  this->WhichRound);
375  vtkm::cont::Algorithm::Copy(tree.WhenTransferred, this->WhichIteration);
376 
377  // now set the regular to supernode array up: it's already been set to NO_SUCH_ELEMENT
378  {
379  auto regular2SupernodePermuted =
380  vtkm::cont::make_ArrayHandlePermutation(this->Supernodes, this->Regular2Supernode);
381  vtkm::cont::Algorithm::Copy(vtkm::cont::ArrayHandleIndex(this->Supernodes.GetNumberOfValues()),
382  regular2SupernodePermuted);
383  }
384  // copy in the hypernodes
385  vtkm::cont::Algorithm::Copy(tree.Hypernodes, this->Hypernodes);
386  vtkm::cont::Algorithm::Copy(tree.Hyperarcs, this->Hyperarcs);
387 
388  // now set the supernode to hypernode array up: it's already been set to NO_SUCH_ELEMENT
389  {
390  auto super2HypernodePermuted =
391  vtkm::cont::make_ArrayHandlePermutation(this->Hypernodes, this->Super2Hypernode);
392  vtkm::cont::Algorithm::Copy(vtkm::cont::ArrayHandleIndex(this->Hypernodes.GetNumberOfValues()),
393  super2HypernodePermuted);
394  }
395  {
396  auto initalizeSuperchildrenWorklet = InitalizeSuperchildrenWorklet();
397  this->Invoke(initalizeSuperchildrenWorklet,
398  this->Hyperarcs, // Input
399  this->Hypernodes, // Input
400  this->Superchildren // Output
401  );
402  }
403 } // Initialize(..)
404 
405 
407 template <typename FieldType>
409 { // RegularString()
410  std::stringstream resultStream;
411  // this can get called before the regular ID is fully stored
412  if (regularId >= this->DataValues.GetNumberOfValues())
413  {
414  resultStream << "Regular ID: ";
416  resultStream << " Value: N/A Global ID: N/A Regular ID: ";
418  resultStream << " SNode ID: N/A Superparent: N/A";
419  }
420  else
421  {
422  resultStream << "Regular ID: ";
424  resultStream << " Value: " << vtkm::cont::ArrayGetValue(regularId, this->DataValues);
425  resultStream << " Global ID: ";
427  vtkm::cont::ArrayGetValue(regularId, this->RegularNodeGlobalIds), resultStream);
428  resultStream << " Regular ID: ";
430  resultStream << " SNode ID: ";
432  vtkm::cont::ArrayGetValue(regularId, this->Regular2Supernode), resultStream);
433  resultStream << "Superparents: ";
435  vtkm::cont::ArrayGetValue(regularId, this->Superparents));
436  }
437  return resultStream.str();
438 } // RegularString()
439 
440 
442 template <typename FieldType>
444 { // SuperString()
445  std::stringstream resultStream;
447  {
448  resultStream << "Super ID: ";
450  }
451  else
452  {
454  vtkm::Id tempSupernodeOfSuperId = vtkm::cont::ArrayGetValue(unmaskedSuperId, this->Supernodes);
455  resultStream << "Super ID: ";
457  resultStream << " Value: "
458  << vtkm::cont::ArrayGetValue(tempSupernodeOfSuperId, this->DataValues);
459  resultStream << " Global ID: ";
461  vtkm::cont::ArrayGetValue(tempSupernodeOfSuperId, this->RegularNodeGlobalIds), resultStream);
462  resultStream << " Regular Id: ";
463  vtkm::worklet::contourtree_augmented::PrintIndexType(tempSupernodeOfSuperId, resultStream);
464  resultStream << " Superarc: ";
466  vtkm::cont::ArrayGetValue(unmaskedSuperId, this->Superarcs), resultStream);
467  resultStream << " HNode ID: ";
469  vtkm::cont::ArrayGetValue(unmaskedSuperId, this->Super2Hypernode), resultStream);
470  resultStream << " Hyperparent: ";
472  vtkm::cont::ArrayGetValue(unmaskedSuperId, this->Hyperparents), resultStream);
473  resultStream << " Round: ";
475  vtkm::cont::ArrayGetValue(unmaskedSuperId, this->WhichRound), resultStream);
476  resultStream << " Iteration: ";
478  vtkm::cont::ArrayGetValue(unmaskedSuperId, this->WhichIteration), resultStream);
479  }
480  return resultStream.str();
481 } // SuperString()
482 
483 
485 template <typename FieldType>
487 { // HyperString()
488  std::stringstream resultStream;
490  {
491  resultStream << "Hyper ID: ";
493  }
494  else
495  {
497  vtkm::Id hypernodeOfHyperId = vtkm::cont::ArrayGetValue(unmaskedHyperId, this->Hypernodes);
498  vtkm::Id supernodeOfHyperId = vtkm::cont::ArrayGetValue(hypernodeOfHyperId, this->Supernodes);
499  resultStream << "Hyper Id: ";
501  resultStream << " Value: " << vtkm::cont::ArrayGetValue(supernodeOfHyperId, this->DataValues);
502  resultStream << " Global ID: ";
504  vtkm::cont::ArrayGetValue(supernodeOfHyperId, this->RegularNodeGlobalIds), resultStream);
505  resultStream << " Regular ID: ";
506  vtkm::worklet::contourtree_augmented::PrintIndexType(supernodeOfHyperId, resultStream);
507  resultStream << " Super ID: ";
508  vtkm::worklet::contourtree_augmented::PrintIndexType(hypernodeOfHyperId, resultStream);
509  resultStream << " Hyperarc: ";
511  vtkm::cont::ArrayGetValue(unmaskedHyperId, this->Hyperarcs), resultStream);
512  resultStream << " Superchildren: "
513  << vtkm::cont::ArrayGetValue(unmaskedHyperId, this->Superchildren);
514  }
515  return resultStream.str();
516 } // HyperString()
517 
519 template <typename FieldType>
521  const vtkm::Id maxLength) const
522 { // ProbeHyperPath()
523  std::stringstream resultStream;
524  resultStream << "Probing HyperPath\n";
525  resultStream << "Node: " << this->RegularString(regularId) << std::endl;
526 
527  // find the superparent
528  vtkm::Id superparent = vtkm::cont::ArrayGetValue(regularId, this->Superparents);
529  resultStream << "Superparent: " << SuperString(superparent) << std::endl;
530 
531  // and the hyperparent
532  vtkm::Id hyperparent = vtkm::cont::ArrayGetValue(superparent, this->Hyperparents);
533 
534  // now trace the path inwards: terminate on last round when we have null hyperarc
535  vtkm::Id length = 0;
536  while (true)
537  { // loop inwards
538  length++;
539  if (length > maxLength && maxLength > 0)
540  {
541  break;
542  }
543  resultStream << "Hyperparent: " << this->HyperString(hyperparent) << std::endl;
544 
545  // retrieve the target of the hyperarc
546  vtkm::Id hypertarget = vtkm::cont::ArrayGetValue(hyperparent, this->Hyperarcs);
547 
548  resultStream << "Hypertarget: "
549  << SuperString(vtkm::worklet::contourtree_augmented::MaskedIndex(hypertarget))
550  << std::endl;
551 
552  // mask the hypertarget
553  vtkm::Id maskedHypertarget = vtkm::worklet::contourtree_augmented::MaskedIndex(hypertarget);
554 
555  // test for null superarc: can only be root or attachment point
557  { // root or attachment point
558  // we're done
559  break;
560  } // root or attachment point
561  else
562  { // ordinary supernode
563  hyperparent = vtkm::cont::ArrayGetValue(maskedHypertarget, this->Hyperparents);
564  } // ordinary supernode
565 
566  // now take the new superparent's hyperparent/hypertarget
567  hypertarget = vtkm::cont::ArrayGetValue(hyperparent, this->Hyperarcs);
568  } // loop inwards
569 
570  resultStream << "Probe Complete" << std::endl << std::endl;
571  return resultStream.str();
572 } // ProbeHyperPath()
573 
574 
576 template <typename FieldType>
578  const vtkm::Id maxLength) const
579 {
580  std::stringstream resultStream;
581  // find the superparent
582  vtkm::Id superparent = vtkm::cont::ArrayGetValue(regularId, this->Superparents);
583  // now trace the path inwards: terminate on last round when we have null hyperarc
584  vtkm::Id length = 0;
585  while (true)
586  { // loop inwards
587  length++;
588  if (length > maxLength && maxLength > 0)
589  {
590  break;
591  }
592  // retrieve the target of the superarc
593  vtkm::Id supertarget = vtkm::cont::ArrayGetValue(superparent, this->Superarcs);
594 
595  resultStream << "Superparent: " << this->SuperString(superparent) << std::endl;
596  resultStream << "Supertarget: "
597  << this->SuperString(
599  << std::endl;
600 
601  // mask the supertarget
602  vtkm::Id maskedSupertarget = vtkm::worklet::contourtree_augmented::MaskedIndex(supertarget);
603  // and retrieve it's supertarget
604  vtkm::Id nextSupertarget = vtkm::cont::ArrayGetValue(maskedSupertarget, this->Superarcs);
605  vtkm::Id maskedNextSupertarget =
607  resultStream << "Next target: " << this->SuperString(nextSupertarget) << std::endl;
608 
609  // test for null superarc: can only be root or attachment point
611  { // root or attachment point
612  // test round: if it's the last one, only the root has a null edge
613  if (vtkm::cont::ArrayGetValue(maskedNextSupertarget, this->WhichRound) == this->NumRounds)
614  // we're done
615  break;
616  else // attachment point
617  superparent = maskedNextSupertarget;
618  } // root or attachment point
619  else
620  { // ordinary supernode
621  superparent = maskedSupertarget;
622  } // ordinary supernode
623  } // loop inwards
624 
625  resultStream << "Probe Complete" << std::endl << std::endl;
626  return resultStream.str();
627 }
628 
630 template <typename FieldType>
632 { // PrintDotSuperStructure
633  // make a copy of the label
634  std::string filename("temp/");
635  filename += label;
636 
637  // replace spaces with underscores
638  for (unsigned int strChar = 0; strChar < filename.length(); strChar++)
639  if (filename[strChar] == ' ')
640  filename[strChar] = '_';
641 
642  // add the .gv suffix
643  filename += ".gv";
644 
645  // generate an output stream
646  std::ofstream outstream(filename);
647 
648  // print the header information
649  outstream << "digraph RegularTree\n\t{\n";
650  outstream << "\tsize=\"6.5, 9\"\n\tratio=\"fill\"\n";
651  outstream << "\tlabel=\"" << label << "\"\n\tlabelloc=t\n\tfontsize=30\n";
652 
653  // create the NULL (root) node
654  outstream << "\t// NULL node to use as a root for the tree\n";
655  outstream << "\tNULL [style=filled,fillcolor=white,shape=point,label=\"NULL\"];\n";
656 
657  outstream << "\t// Supernodes\n";
658  // loop through all supernodes
659  // We use regular ReadPortals here since this requires access to many values anyways
660  auto supernodesPortal = this->Supernodes.ReadPortal();
661  auto hypernodesPortal = this->Hypernodes.ReadPortal();
662  auto hyperparentsPortal = this->Hyperparents.ReadPortal();
663  auto hyperarcsPortal = this->Hyperarcs.ReadPortal();
664  auto regularNodeGlobalIdsPortal = this->RegularNodeGlobalIds.ReadPortal();
665  auto whichIterationPortal = this->WhichIteration.ReadPortal();
666  auto whichRoundPortal = this->whichRound.ReadPortal();
667  auto superarcsPortal = this->Superarcs.ReadPortal();
668  auto superparentsPortal = this->Superparents.ReadPortal();
669  for (vtkm::Id supernode = 0; supernode < this->Supernodes.GetNumberOfValues(); supernode++)
670  { // per supernode
671  vtkm::Id regularID = supernodesPortal.Get(supernode);
672  // print the supernode, making hypernodes double octagons
673  outstream
674  << " SN" << std::setw(1) << supernode
675  << " [style=filled,fillcolor=white,shape=" << std::setw(1)
676  << ((hypernodesPortal.Get(hyperparentsPortal.Get(supernode)) == supernode)
677  ? "doublecircle"
678  : "circle") // hypernodes are double-circles
679  << ",label=\"sn" << std::setw(4) << supernode << " h" << std::setw(1)
680  << ((hypernodesPortal.Get(hyperparentsPortal.Get(supernode)) == supernode)
681  ? "n"
682  : "p") // hypernodes show "hn001" (their own ID), supernodes show "hp001" (their hyperparent)
683  << std::setw(4) << hyperparentsPortal.Get(supernode) << "\\nm" << std::setw(1) << regularID
684  << " g" << std::setw(4) << regularNodeGlobalIdsPortal.Get(regularID) << "\\nrd"
685  << std::setw(1) << whichIterationPortal.Get(supernode) << " it" << std::setw(4)
686  << contourtree_augmented::MaskedIndex(whichIterationPortal.Get(supernode)) << "\"];\n";
687  } // per supernode
688 
689  outstream << "\t// Superarc nodes\n";
690  // now repeat to create nodes for the middle of each superarc (to represent the superarcs themselves)
691  for (vtkm::Id superarc = 0; superarc < this->Superarcs.GetNumberOfValues(); superarc++)
692  { // per superarc
693  // print the superarc vertex
694  outstream
695  << "\tSA" << std::setw(1) << superarc
696  << " [shape=circle,fillcolor=white,fixedsize=true,height=0.5,width=0.5,label=\"\"];\n";
697  } // per superarc
698 
699  outstream << "\t// Superarc edges\n";
700  // loop through all superarcs to draw them
701  for (vtkm::Id superarc = 0; superarc < this->Superarcs.GetNumberOfValues(); superarc++)
702  { // per superarc
703  // retrieve ID of target supernode
704  vtkm::Id superarcFrom = superarc;
705  vtkm::Id superarcTo = superarcsPortal.Get(superarcFrom);
706 
707  // if this is true, it may be the last pruned vertex
708  if (contourtree_augmented::NoSuchElement(superarcTo))
709  { // no superarc
710  // if it occurred on the final round, it's the global root and is shown as the NULL node
711  if (whichRoundPortal.Get(superarcFrom) == this->NRounds)
712  { // root node
713  outstream << "\tSN" << std::setw(1) << superarcFrom << " -> SA" << std::setw(1) << superarc
714  << " [label=\"S" << std::setw(1) << superarc << "\",style=dotted]\n";
715  outstream << "\tSN" << std::setw(1) << superarc << " -> NULL[label=\"S" << std::setw(1)
716  << superarc << "\",style=dotted]\n";
717  } // root node
718  else
719  { // attachment point
720  // otherwise, the target is actually a superarc vertex not a supernode vertex
721  // so we use the regular ID to retrieve the superparent which tells us which superarc we insert into
722  vtkm::Id regularFrom = supernodesPortal.Get(superarcFrom);
723  superarcTo = superparentsPortal.Get(regularFrom);
724 
725  // output a suitable edge
726  outstream << "\tSN" << std::setw(1) << superarcFrom << " -> SA" << std::setw(1)
727  << superarcTo << "[label=\"S" << std::setw(1) << superarc << "\",style=dotted]\n";
728  } // attachment point
729  } // no superarc
730 
731  else
732  { // there is a superarc
733  // retrieve the ascending flag
734  bool ascendingSuperarc = contourtree_augmented::IsAscending(superarcTo);
735 
736  // strip out the flags
737  superarcTo = contourtree_augmented::MaskedIndex(superarcTo);
738 
739  // how we print depends on whether the superarc ascends
740  outstream << "\tSN" << std::setw(1) << (ascendingSuperarc ? superarcTo : superarcFrom)
741  << " -> SA" << std::setw(1) << superarc << " [label=\"S" << std::setw(1) << superarc
742  << "\"" << (ascendingSuperarc ? ",dir=\"back\"" : "") << ",arrowhead=\"none\"]\n";
743  outstream << "\tSA" << std::setw(1) << superarc << " -> SN" << std::setw(1)
744  << (ascendingSuperarc ? superarcFrom : superarcTo) << " [label=\"S" << std::setw(1)
745  << superarc << "\"" << (ascendingSuperarc ? ",dir=\"back\"" : "")
746  << ",arrowhead=\"none\"]\n";
747  } // there is a superarc
748  } // per superarc
749 
750  outstream << "\t// Hyperarcs\n";
751  // now loop through the hyperarcs to draw them
752  for (vtkm::Id hyperarc = 0; hyperarc < this->Hyperarcs.GetNumberOfValues(); hyperarc++)
753  { // per hyperarc
754  // retrieve ID of target hypernode
755  vtkm::Id hyperarcFrom = hypernodesPortal.Get(hyperarc);
756  vtkm::Id hyperarcTo = hyperarcsPortal.Get(hyperarc);
757 
758  // if this is true, it is the last pruned vertex & needs a hyperarc to the root
759  if (contourtree_augmented::NoSuchElement(hyperarcTo))
760  outstream << "\tSN" << std::setw(1) << hyperarcFrom << " -> NULL[label=\"H" << std::setw(1)
761  << hyperarc << "\",penwidth=5.0,style=dotted]\n";
762  else
763  { // not the last one
764  // otherwise, retrieve the ascending flag
765  bool ascendingHyperarc = contourtree_augmented::IsAscending(hyperarcTo);
766 
767  // strip out the flags
768  hyperarcTo = contourtree_augmented::MaskedIndex(hyperarcTo);
769 
770  // how we print depends on whether the hyperarc ascends
771  outstream << "\tSN" << std::setw(1) << (ascendingHyperarc ? hyperarcTo : hyperarcFrom)
772  << " -> SN" << std::setw(1) << (ascendingHyperarc ? hyperarcFrom : hyperarcTo)
773  << "[label=\"H" << std::setw(1) << hyperarc << "\",penwidth=5.0,dir=\"back\"]\n";
774  } // not the last one
775  } // per hyperarc
776 
777  // print the footer information
778  outstream << "\t}\n";
779 
780  return std::string("HierarchicalContourTree<FieldType>::PrintDotSuperStructure() Complete");
781 } // PrintDotSuperStructure
782 
784 template <typename FieldType>
785 std::string HierarchicalContourTree<FieldType>::DebugPrint(std::string message,
786  const char* fileName,
787  long lineNum) const
788 { // DebugPrint
789  std::stringstream resultStream;
790  resultStream << std::endl;
791  resultStream << "[CUTHERE]-------------------------------" << std::endl;
792  resultStream << std::setw(30) << std::left << fileName << ":" << std::right << std::setw(4)
793  << lineNum << std::endl;
794  resultStream << std::left << std::string(message) << std::endl;
795  resultStream << "Hierarchical Contour Tree Contains: " << std::endl;
796  resultStream << "----------------------------------------" << std::endl;
797  resultStream << std::endl;
798 
799  vtkm::worklet::contourtree_augmented::PrintHeader(this->RegularNodeGlobalIds.GetNumberOfValues(),
800  resultStream);
802  "Regular Nodes (global ID)", this->RegularNodeGlobalIds, -1, resultStream);
804  "Data Values", this->DataValues, -1, resultStream);
806  "Regular Node Sort Order", this->RegularNodeSortOrder, -1, resultStream);
808  "Superparents (unsorted)", this->Superparents, -1, resultStream);
810  "Supernode ID (if any)", this->Regular2Supernode, -1, resultStream);
811  resultStream << std::endl;
812  vtkm::worklet::contourtree_augmented::PrintHeader(this->Supernodes.GetNumberOfValues(),
813  resultStream);
815  "Supernodes (regular index)", this->Supernodes, -1, resultStream);
817  "Superarcs (supernode index)", this->Superarcs, -1, resultStream);
819  "Hyperparents (hypernode index)", this->Hyperparents, -1, resultStream);
821  "Hypernode ID (if any)", this->Super2Hypernode, -1, resultStream);
823  "Which Round", this->WhichRound, -1, resultStream);
825  "Which Iteration", this->WhichIteration, -1, resultStream);
826  resultStream << std::endl;
827  vtkm::worklet::contourtree_augmented::PrintHeader(this->Hypernodes.GetNumberOfValues(),
828  resultStream);
830  "Hypernodes (supernode index)", this->Hypernodes, -1, resultStream);
832  "Hyperarcs (supernode index)", this->Hyperarcs, -1, resultStream);
834  "Superchildren", this->Superchildren, -1, resultStream);
835  resultStream << std::endl;
836  resultStream << "nRounds: " << this->NumRounds << std::endl;
838  this->NumRegularNodesInRound.GetNumberOfValues(), resultStream);
840  "nRegular Nodes In Round", this->NumRegularNodesInRound, -1, resultStream);
842  "nSupernodes In Round", this->NumSupernodesInRound, -1, resultStream);
844  "nHypernodes In Round", this->NumHypernodesInRound, -1, resultStream);
845  //resultStream << "Owned Regular Vertices: " << this->NumOwnedRegularVertices << std::endl;
846  vtkm::worklet::contourtree_augmented::PrintHeader(this->NumIterations.GetNumberOfValues(),
847  resultStream);
849  "nIterations", this->NumIterations, -1, resultStream);
850  for (vtkm::Id whichRound = 0; whichRound < this->NumIterations.GetNumberOfValues(); whichRound++)
851  { // per round
852  resultStream << "Round " << whichRound << std::endl;
854  this->FirstSupernodePerIteration[static_cast<std::size_t>(whichRound)].GetNumberOfValues(),
855  resultStream);
857  "First Supernode Per Iteration",
858  this->FirstSupernodePerIteration[static_cast<std::size_t>(whichRound)],
859  -1,
860  resultStream);
862  "First Hypernode Per Iteration",
863  this->FirstHypernodePerIteration[static_cast<std::size_t>(whichRound)],
864  -1,
865  resultStream);
866  resultStream << std::endl;
867  } // per round
868  return resultStream.str();
869 } // DebugPrint
870 
871 template <typename FieldType>
873 { // PrintTreeStats
874  std::stringstream resultStream;
875  resultStream << std::setw(42) << std::left << " NumRounds"
876  << ": " << this->NumRounds << std::endl;
878  " NumIterations", this->NumIterations, -1, resultStream);
880  " NumRegularNodesInRound", this->NumRegularNodesInRound, -1, resultStream);
882  " NumSupernodesInRound", this->NumSupernodesInRound, -1, resultStream);
884  " NumHypernodesInRound", this->NumHypernodesInRound, -1, resultStream);
885 
886  return resultStream.str();
887 } // PrintTreeStats
888 
889 
890 // modified version of dumpSuper() that also gives volume counts
891 template <typename FieldType>
895  const vtkm::worklet::contourtree_augmented::IdArrayType& regularNodeGlobalIds,
896  vtkm::Id totalVolume,
899 { // DumpVolumes()
900  // a local string stream to build the output
901  std::stringstream outStream;
902 
903  // header info
904  outStream << "============" << std::endl;
905  outStream << "Contour Tree" << std::endl;
906 
907  // loop through all superarcs.
908  // We use regular ReadPortals here since this requires access to many values anyways
909  auto supernodesPortal = supernodes.ReadPortal();
910  auto regularNodeGlobalIdsPortal = regularNodeGlobalIds.ReadPortal();
911  auto superarcsPortal = superarcs.ReadPortal();
912  auto intrinsicVolumePortal = intrinsicVolume.ReadPortal();
913  auto dependentVolumePortal = dependentVolume.ReadPortal();
914  for (vtkm::Id supernode = 0; supernode < supernodes.GetNumberOfValues(); supernode++)
915  { // per supernode
916  // convert all the way down to global regular IDs
917  vtkm::Id fromRegular = supernodesPortal.Get(supernode);
918  vtkm::Id fromGlobal = regularNodeGlobalIdsPortal.Get(fromRegular);
919 
920  // retrieve the superarc target
921  vtkm::Id toSuper = superarcsPortal.Get(supernode);
922 
923  // if it is NO_SUCH_ELEMENT, it is the root or an attachment point
924  // for an augmented tree, it can only be the root
925  // in any event, we don't want to print them
927  {
928  continue;
929  }
930  // now break out the ascending flag & the underlying ID
931  bool superarcAscends = vtkm::worklet::contourtree_augmented::IsAscending(toSuper);
933  vtkm::Id toRegular = supernodesPortal.Get(toSuper);
934  vtkm::Id toGlobal = regularNodeGlobalIdsPortal.Get(toRegular);
935 
936  // compute the weights
937  vtkm::Id weight = dependentVolumePortal.Get(supernode);
938  // -1 because the validation output does not count the supernode for the superarc
939  vtkm::Id arcWeight = intrinsicVolumePortal.Get(supernode) - 1;
940  vtkm::Id counterWeight = totalVolume - weight + arcWeight;
941 
942  // orient with high end first
943  if (superarcAscends)
944  { // ascending superarc
945  outStream << "H: " << std::setw(VOLUME_PRINT_WIDTH) << toGlobal;
946  outStream << " L: " << std::setw(VOLUME_PRINT_WIDTH) << fromGlobal;
947  outStream << " VH: " << std::setw(VOLUME_PRINT_WIDTH) << weight;
948  outStream << " VR: " << std::setw(VOLUME_PRINT_WIDTH) << arcWeight;
949  outStream << " VL: " << std::setw(VOLUME_PRINT_WIDTH) << counterWeight;
950  outStream << std::endl;
951  } // ascending superarc
952  else
953  { // descending superarc
954  outStream << "H: " << std::setw(VOLUME_PRINT_WIDTH) << fromGlobal;
955  outStream << " L: " << std::setw(VOLUME_PRINT_WIDTH) << toGlobal;
956  outStream << " VH: " << std::setw(VOLUME_PRINT_WIDTH) << counterWeight;
957  outStream << " VR: " << std::setw(VOLUME_PRINT_WIDTH) << arcWeight;
958  outStream << " VL: " << std::setw(VOLUME_PRINT_WIDTH) << weight;
959  outStream << std::endl;
960  } // descending superarc
961 
962  } // per supernode
963  // return the string
964  return outStream.str();
965 } // DumpVolumes()
966 
967 template <typename FieldType>
969  const std::vector<vtkm::worklet::contourtree_augmented::IdArrayType>& inputVec,
971  vtkm::cont::ArrayHandle<vtkm::Id>& outputOffsets)
972 {
973  // Compute num components vector
975  numComponents.Allocate(inputVec.size());
976  auto numComponentsWritePortal = numComponents.WritePortal();
977 
978  for (vtkm::Id i = 0; i < static_cast<vtkm::Id>(inputVec.size()); ++i)
979  {
980  numComponentsWritePortal.Set(i,
981  static_cast<vtkm::IdComponent>(inputVec[i].GetNumberOfValues()));
982  }
983 
984  // Convert to offsets and store in output array
985  vtkm::Id componentsArraySize;
986  vtkm::cont::ConvertNumComponentsToOffsets(numComponents, outputOffsets, componentsArraySize);
987 
988  // Copy data to components array
989  auto outputOffsetsReadPortal = outputOffsets.ReadPortal();
990  outputComponents.Allocate(componentsArraySize);
991  auto numComponentsReadPortal = numComponents.ReadPortal();
992  for (vtkm::Id i = 0; i < static_cast<vtkm::Id>(inputVec.size()); ++i)
993  {
994  auto outputView = vtkm::cont::make_ArrayHandleView(
995  outputComponents, outputOffsetsReadPortal.Get(i), numComponentsReadPortal.Get(i));
996  vtkm::cont::ArrayCopy(inputVec[i], outputView);
997  }
998 }
999 
1000 template <typename FieldType>
1002 {
1003  // Create data set from output
1004  vtkm::cont::Field regularNodeGlobalIdsField("RegularNodeGlobalIds",
1006  this->RegularNodeGlobalIds);
1007  ds.AddField(regularNodeGlobalIdsField);
1008  vtkm::cont::Field dataValuesField(
1009  "DataValues", vtkm::cont::Field::Association::WholeDataSet, this->DataValues);
1010  ds.AddField(dataValuesField);
1011  vtkm::cont::Field regularNodeSortOrderField("RegularNodeSortOrder",
1013  this->RegularNodeSortOrder);
1014  ds.AddField(regularNodeSortOrderField);
1015  vtkm::cont::Field regular2SupernodeField(
1016  "Regular2Supernode", vtkm::cont::Field::Association::WholeDataSet, this->Regular2Supernode);
1017  ds.AddField(regular2SupernodeField);
1018  vtkm::cont::Field superparentsField(
1019  "Superparents", vtkm::cont::Field::Association::WholeDataSet, this->Superparents);
1020  ds.AddField(superparentsField);
1021  vtkm::cont::Field supernodesField(
1022  "Supernodes", vtkm::cont::Field::Association::WholeDataSet, this->Supernodes);
1023  ds.AddField(supernodesField);
1024  vtkm::cont::Field superarcsField(
1025  "Superarcs", vtkm::cont::Field::Association::WholeDataSet, this->Superarcs);
1026  ds.AddField(superarcsField);
1027  vtkm::cont::Field hyperparentsField(
1028  "Hyperparents", vtkm::cont::Field::Association::WholeDataSet, this->Hyperparents);
1029  ds.AddField(hyperparentsField);
1030  vtkm::cont::Field super2HypernodeField(
1031  "Super2Hypernode", vtkm::cont::Field::Association::WholeDataSet, this->Super2Hypernode);
1032  ds.AddField(super2HypernodeField);
1033  vtkm::cont::Field whichRoundField(
1034  "WhichRound", vtkm::cont::Field::Association::WholeDataSet, this->WhichRound);
1035  ds.AddField(whichRoundField);
1036  vtkm::cont::Field whichIterationField(
1037  "WhichIteration", vtkm::cont::Field::Association::WholeDataSet, this->WhichIteration);
1038  ds.AddField(whichIterationField);
1039  // TODO/FIXME: See what other fields we need to add
1040  vtkm::worklet::contourtree_augmented::IdArrayType firstSupernodePerIterationComponents;
1041  vtkm::cont::ArrayHandle<vtkm::Id> firstSupernodePerIterationOffsets;
1042  ConvertSTLVecOfHandlesToVTKMComponentsAndOffsetsArray(FirstSupernodePerIteration,
1043  firstSupernodePerIterationComponents,
1044  firstSupernodePerIterationOffsets);
1045  vtkm::cont::Field firstSupernodePerIterationComponentsField(
1046  "FirstSupernodePerIterationComponents",
1048  firstSupernodePerIterationComponents);
1049  ds.AddField(firstSupernodePerIterationComponentsField);
1050  vtkm::cont::Field firstSupernodePerIterationOffsetsField(
1051  "FirstSupernodePerIterationOffsets",
1053  firstSupernodePerIterationOffsets);
1054  ds.AddField(firstSupernodePerIterationOffsetsField);
1055  // TODO/FIXME: It seems we may only need the counts for the first iteration, so check, which
1056  // information we actually need.
1057 }
1058 
1059 } // namespace contourtree_distributed
1060 } // namespace worklet
1061 } // namespace vtkm
1062 
1063 
1064 #endif
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::Invoke
vtkm::cont::Invoker Invoke
Used internally to Invoke worklets.
Definition: HierarchicalContourTree.h:265
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::Supernodes
vtkm::worklet::contourtree_augmented::IdArrayType Supernodes
Definition: HierarchicalContourTree.h:124
vtkm::worklet::contourtree_augmented::ContourTreeMesh::GlobalMeshIndex
IdArrayType GlobalMeshIndex
Definition: ContourTreeMesh.h:200
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::Superparents
vtkm::worklet::contourtree_augmented::IdArrayType Superparents
Definition: HierarchicalContourTree.h:120
vtkm::cont::ArrayHandle::GetNumberOfValues
VTKM_CONT vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:448
vtkm::worklet::contourtree_augmented::ContourTree::Hyperparents
IdArrayType Hyperparents
Definition: augmented/ContourTree.h:136
vtkm::worklet::contourtree_distributed::HierarchicalContourTree
Hierarchical Contour Tree data structure.
Definition: HierarchicalContourTree.h:100
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::Superarcs
vtkm::worklet::contourtree_augmented::IdArrayType Superarcs
Definition: HierarchicalContourTree.h:126
vtkm::cont::ArrayHandle< vtkm::Id >
vtkm::worklet::contourtree_augmented::IsAscending
VTKM_EXEC_CONT bool IsAscending(vtkm::Id flaggedIndex)
Definition: filter/scalar_topology/worklet/contourtree_augmented/Types.h:121
vtkm::worklet::contourtree_augmented::ContourTree::Hyperarcs
IdArrayType Hyperarcs
Definition: augmented/ContourTree.h:149
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::AddToVTKMDataSet
VTKM_CONT void AddToVTKMDataSet(vtkm::cont::DataSet &ds) const
Definition: HierarchicalContourTree.h:1001
vtkm::worklet::contourtree_distributed::PermuteComparator
Definition: hierarchical_contour_tree/PermuteComparator.h:121
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::WhichRound
vtkm::worklet::contourtree_augmented::IdArrayType WhichRound
Definition: HierarchicalContourTree.h:135
vtkm::cont::make_ArrayHandleView
ArrayHandleView< ArrayHandleType > make_ArrayHandleView(const ArrayHandleType &array, vtkm::Id startIndex, vtkm::Id numValues)
Definition: ArrayHandleView.h:222
vtkm::worklet::contourtree_augmented::ContourTree::Supernodes
IdArrayType Supernodes
Definition: augmented/ContourTree.h:125
Types.h
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::HierarchicalContourTree
VTKM_CONT HierarchicalContourTree()
Definition: HierarchicalContourTree.h:269
vtkm::worklet::contourtree_augmented::ContourTree
Definition: augmented/ContourTree.h:106
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::IdComponent
vtkm::Int32 IdComponent
Represents a component ID (index of component in a vector).
Definition: Types.h:168
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::PrintTreeStats
VTKM_CONT std::string PrintTreeStats() const
Print hierarchical tree construction stats, usually used for logging.
Definition: HierarchicalContourTree.h:872
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::DebugPrint
VTKM_CONT std::string DebugPrint(std::string message, const char *fileName, long lineNum) const
debug routine
Definition: HierarchicalContourTree.h:785
vtkm::worklet::contourtree_augmented::ContourTree::Superparents
IdArrayType Superparents
Definition: augmented/ContourTree.h:118
vtkm::worklet::contourtree_augmented::ContourTree::Hypernodes
IdArrayType Hypernodes
Definition: augmented/ContourTree.h:144
PermuteComparator.h
FindRegularByGlobal.h
vtkm::worklet::contourtree_augmented::ContourTree::Nodes
IdArrayType Nodes
Definition: augmented/ContourTree.h:112
vtkm::cont::Algorithm::CopySubRange
static VTKM_CONT bool CopySubRange(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CIn > &input, vtkm::Id inputStartIndex, vtkm::Id numberOfElementsToCopy, vtkm::cont::ArrayHandle< U, COut > &output, vtkm::Id outputIndex=0)
Definition: Algorithm.h:472
vtkm::cont::DataSet
Definition: DataSet.h:34
vtkm::cont::Algorithm::Sort
static VTKM_CONT void Sort(vtkm::cont::DeviceAdapterId devId, vtkm::cont::ArrayHandle< T, Storage > &values)
Definition: Algorithm.h:965
vtkm::cont::Field::Association::WholeDataSet
@ WholeDataSet
vtkm::cont::ArrayGetValue
VTKM_CONT T ArrayGetValue(vtkm::Id id, const vtkm::cont::ArrayHandle< T, S > &data)
Obtain a small set of values from an ArrayHandle with minimal device transfers.
Definition: ArrayGetValues.h:264
vtkm::cont::Algorithm::Copy
static VTKM_CONT bool Copy(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CIn > &input, vtkm::cont::ArrayHandle< U, COut > &output)
Definition: Algorithm.h:410
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::Initialize
VTKM_CONT void Initialize(vtkm::Id numRounds, vtkm::worklet::contourtree_augmented::ContourTree &tree, vtkm::worklet::contourtree_augmented::ContourTreeMesh< FieldType > &mesh)
routine to initialize the hierarchical tree with the top level tree
Definition: HierarchicalContourTree.h:281
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::RegularString
VTKM_CONT std::string RegularString(const vtkm::Id regularId) const
utility routines for the path probes
Definition: HierarchicalContourTree.h:408
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::ConvertSTLVecOfHandlesToVTKMComponentsAndOffsetsArray
static VTKM_CONT void ConvertSTLVecOfHandlesToVTKMComponentsAndOffsetsArray(const std::vector< vtkm::worklet::contourtree_augmented::IdArrayType > &inputVec, vtkm::worklet::contourtree_augmented::IdArrayType &outputComponents, vtkm::cont::ArrayHandle< vtkm::Id > &outputOffsets)
Definition: HierarchicalContourTree.h:968
vtkm::worklet::contourtree_augmented::MaskedIndex
VTKM_EXEC_CONT vtkm::Id MaskedIndex(vtkm::Id flaggedIndex)
Definition: filter/scalar_topology/worklet/contourtree_augmented/Types.h:127
FindSuperArcBetweenNodes.h
vtkm::worklet::contourtree_augmented::ContourTreeMesh
Definition: ContourTreeMesh.h:129
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::GetFindRegularByGlobal
VTKM_CONT FindRegularByGlobal GetFindRegularByGlobal() const
routine to create a FindRegularByGlobal object that we can use as an input for worklets to call the f...
Definition: HierarchicalContourTree.h:174
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
ArrayCopy.h
vtkm::worklet::contourtree_augmented::ContourTree::Superarcs
IdArrayType Superarcs
Definition: augmented/ContourTree.h:129
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::RegularNodeGlobalIds
vtkm::worklet::contourtree_augmented::IdArrayType RegularNodeGlobalIds
Definition: HierarchicalContourTree.h:108
vtkm::worklet::contourtree_augmented::ContourTree::NumIterations
vtkm::Id NumIterations
Definition: augmented/ContourTree.h:153
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::NumRounds
vtkm::Id NumRounds
Definition: HierarchicalContourTree.h:148
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::HyperString
VTKM_CONT std::string HyperString(const vtkm::Id hyperId) const
utility routine for the path probes
Definition: HierarchicalContourTree.h:486
vtkm::worklet::contourtree_augmented::NoSuchElement
VTKM_EXEC_CONT bool NoSuchElement(vtkm::Id flaggedIndex)
Definition: filter/scalar_topology/worklet/contourtree_augmented/Types.h:97
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::Hyperparents
vtkm::worklet::contourtree_augmented::IdArrayType Hyperparents
Definition: HierarchicalContourTree.h:128
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::FirstSupernodePerIteration
std::vector< vtkm::worklet::contourtree_augmented::IdArrayType > FirstSupernodePerIteration
vectors tracking the segments used in each iteration of the hypersweep
Definition: HierarchicalContourTree.h:169
FindSuperArcForUnknownNode.h
ContourTreeMesh.h
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::Superchildren
vtkm::worklet::contourtree_augmented::IdArrayType Superchildren
Definition: HierarchicalContourTree.h:145
vtkm::cont::Field
A Field encapsulates an array on some piece of the mesh, such as the points, a cell set,...
Definition: cont/Field.h:31
vtkm::cont::Invoker
Allows launching any worklet without a dispatcher.
Definition: Invoker.h:41
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::worklet::contourtree_augmented::ContourTreeMesh::SortedValues
vtkm::cont::ArrayHandle< FieldType > SortedValues
Definition: ContourTreeMesh.h:199
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::DumpVolumes
static VTKM_CONT std::string DumpVolumes(const vtkm::worklet::contourtree_augmented::IdArrayType &supernodes, const vtkm::worklet::contourtree_augmented::IdArrayType &superarcs, const vtkm::worklet::contourtree_augmented::IdArrayType &regularNodeGlobalIds, vtkm::Id totalVolume, const vtkm::worklet::contourtree_augmented::IdArrayType &intrinsicVolume, const vtkm::worklet::contourtree_augmented::IdArrayType &dependentVolume)
Definition: HierarchicalContourTree.h:892
Types.h
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::WhichIteration
vtkm::worklet::contourtree_augmented::IdArrayType WhichIteration
Definition: HierarchicalContourTree.h:136
VTKM_CONT
#define VTKM_CONT
Definition: ExportMacros.h:57
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::Hypernodes
vtkm::worklet::contourtree_augmented::IdArrayType Hypernodes
Definition: HierarchicalContourTree.h:140
vtkm::cont::ArrayHandle::WritePortal
VTKM_CONT WritePortalType WritePortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:435
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::NumHypernodesInRound
vtkm::worklet::contourtree_augmented::IdArrayType NumHypernodesInRound
Definition: HierarchicalContourTree.h:161
vtkm::cont::ArrayHandleConstant
An array handle with a constant value.
Definition: ArrayHandleConstant.h:63
vtkm::worklet::contourtree_augmented::PrintValues
void PrintValues(std::string label, const vtkm::cont::ArrayHandle< T, StorageType > &dVec, vtkm::Id nValues=-1, std::ostream &outStream=std::cout)
Definition: augmented/PrintVectors.h:197
vtkm::worklet::contourtree_distributed::FindSuperArcBetweenNodes
ExecutionObject to generate a device object to use FindSuperArcBetweenNodes for the HierarchicalConto...
Definition: FindSuperArcBetweenNodes.h:116
InitalizeSuperchildrenWorklet.h
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
vtkm::cont::DataSet::AddField
VTKM_CONT void AddField(const Field &field)
Adds a field to the DataSet.
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::Hyperarcs
vtkm::worklet::contourtree_augmented::IdArrayType Hyperarcs
Definition: HierarchicalContourTree.h:142
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::DataValues
vtkm::cont::ArrayHandle< FieldType > DataValues
Definition: HierarchicalContourTree.h:110
vtkm::cont::ConvertNumComponentsToOffsets
VTKM_CONT_EXPORT void ConvertNumComponentsToOffsets(const vtkm::cont::UnknownArrayHandle &numComponentsArray, vtkm::cont::ArrayHandle< vtkm::Id > &offsetsArray, vtkm::Id &componentsArraySize, vtkm::cont::DeviceAdapterId device=vtkm::cont::DeviceAdapterTagAny{})
vtkm::worklet::contourtree_augmented::PrintIndexType
void PrintIndexType(vtkm::Id index, std::ostream &outStream=std::cout)
Definition: augmented/PrintVectors.h:127
VOLUME_PRINT_WIDTH
#define VOLUME_PRINT_WIDTH
Definition: HierarchicalContourTree.h:71
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::Super2Hypernode
vtkm::worklet::contourtree_augmented::IdArrayType Super2Hypernode
Definition: HierarchicalContourTree.h:131
vtkm::cont::ArrayHandle::ReadPortal
VTKM_CONT ReadPortalType ReadPortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:414
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::Regular2Supernode
vtkm::worklet::contourtree_augmented::IdArrayType Regular2Supernode
Definition: HierarchicalContourTree.h:118
vtkm::worklet::contourtree_distributed::FindRegularByGlobal
ExecutionObject to generate a device object to use FindRegularByGlobal for the HierarchicalContourTre...
Definition: FindRegularByGlobal.h:167
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::PrintDotSuperStructure
VTKM_CONT std::string PrintDotSuperStructure(const char *label) const
Outputs the Hierarchical Tree in Dot format for visualization.
Definition: HierarchicalContourTree.h:631
vtkm::worklet::contourtree_augmented::ContourTree::FirstHypernodePerIteration
IdArrayType FirstHypernodePerIteration
Definition: augmented/ContourTree.h:157
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::PrintHeader
void PrintHeader(vtkm::Id howMany, std::ostream &outStream=std::cout)
Definition: augmented/PrintVectors.h:151
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::GetFindSuperArcForUnknownNode
VTKM_CONT FindSuperArcForUnknownNode< FieldType > GetFindSuperArcForUnknownNode()
routine to create a FindSuperArcForUnknownNode object that we can use as an input for worklets to cal...
Definition: HierarchicalContourTree.h:181
vtkm::worklet::contourtree_augmented::IdArraySetValue
VTKM_CONT void IdArraySetValue(vtkm::Id index, vtkm::Id value, IdArrayType &arr)
Helper function to set a single array valye with CopySubRange to avoid pulling the array to the contr...
Definition: filter/scalar_topology/worklet/contourtree_augmented/Types.h:165
ContourTree.h
vtkm::worklet::contourtree_distributed::InitalizeSuperchildrenWorklet
Compute the superarc "to" for every boundary tree node.
Definition: InitalizeSuperchildrenWorklet.h:67
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::FirstHypernodePerIteration
std::vector< vtkm::worklet::contourtree_augmented::IdArrayType > FirstHypernodePerIteration
Definition: HierarchicalContourTree.h:170
vtkm::worklet::contourtree_distributed::FindSuperArcForUnknownNode
ExecutionObject to generate a device object to use FindSuperArcForUnknownNode for the HierarchicalCon...
Definition: FindSuperArcForUnknownNode.h:428
vtkm::worklet::contourtree_augmented::ContourTree::FirstSupernodePerIteration
IdArrayType FirstSupernodePerIteration
Definition: augmented/ContourTree.h:156
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::NumIterations
vtkm::worklet::contourtree_augmented::IdArrayType NumIterations
how many iterations needed for the hypersweep at each level
Definition: HierarchicalContourTree.h:164
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::ProbeSuperPath
VTKM_CONT std::string ProbeSuperPath(const vtkm::Id regularId, const vtkm::Id maxLength=-1) const
routine to probe a given node and trace it's superpath to the root
Definition: HierarchicalContourTree.h:577
vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT
constexpr vtkm::Id NO_SUCH_ELEMENT
Definition: filter/scalar_topology/worklet/contourtree_augmented/Types.h:73
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::NumRegularNodesInRound
vtkm::worklet::contourtree_augmented::IdArrayType NumRegularNodesInRound
arrays holding the logical size of the arrays at each level
Definition: HierarchicalContourTree.h:159
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::ProbeHyperPath
VTKM_CONT std::string ProbeHyperPath(const vtkm::Id regularId, const vtkm::Id maxLength=-1) const
routine to probe a given node and trace it's hyperpath to the root
Definition: HierarchicalContourTree.h:520
DataSet.h
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::SuperString
VTKM_CONT std::string SuperString(const vtkm::Id superId) const
utility routine for the path probes
Definition: HierarchicalContourTree.h:443
vtkm::cont::ArrayHandleIndex
An implicit array handle containing the its own indices.
Definition: ArrayHandleIndex.h:54
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::NumSupernodesInRound
vtkm::worklet::contourtree_augmented::IdArrayType NumSupernodesInRound
Definition: HierarchicalContourTree.h:160
vtkm::worklet::contourtree_augmented::ContourTree::WhenTransferred
IdArrayType WhenTransferred
Definition: augmented/ContourTree.h:139
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::RegularNodeSortOrder
vtkm::worklet::contourtree_augmented::IdArrayType RegularNodeSortOrder
Definition: HierarchicalContourTree.h:115
vtkm::worklet::contourtree_distributed::HierarchicalContourTree::GetFindSuperArcBetweenNodes
VTKM_CONT FindSuperArcBetweenNodes GetFindSuperArcBetweenNodes() const
routine to create a FindSuperArcBetweenNodes object that we can use as an input for worklets to call ...
Definition: HierarchicalContourTree.h:198