VTK-m  2.0
ChainGraph.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) 2016, Los Alamos National Security, LLC
11 // All rights reserved.
12 //
13 // Copyright 2016. Los Alamos National Security, LLC.
14 // This software was produced under U.S. Government contract DE-AC52-06NA25396
15 // for Los Alamos National Laboratory (LANL), which is operated by
16 // Los Alamos National Security, LLC for the U.S. Department of Energy.
17 // The U.S. Government has rights to use, reproduce, and distribute this
18 // software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY, LLC
19 // MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE
20 // USE OF THIS SOFTWARE. If software is modified to produce derivative works,
21 // such modified software should be clearly marked, so as not to confuse it
22 // with the version available from LANL.
23 //
24 // Additionally, redistribution and use in source and binary forms, with or
25 // without modification, are permitted provided that the following conditions
26 // are met:
27 //
28 // 1. Redistributions of source code must retain the above copyright notice,
29 // this list of conditions and the following disclaimer.
30 // 2. Redistributions in binary form must reproduce the above copyright notice,
31 // this list of conditions and the following disclaimer in the documentation
32 // and/or other materials provided with the distribution.
33 // 3. Neither the name of Los Alamos National Security, LLC, Los Alamos
34 // National Laboratory, LANL, the U.S. Government, nor the names of its
35 // contributors may be used to endorse or promote products derived from
36 // this software without specific prior written permission.
37 //
38 // THIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC AND
39 // CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
40 // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
41 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS
42 // NATIONAL SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
43 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
44 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
45 // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
46 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
48 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 //============================================================================
50 
51 // This code is based on the algorithm presented in the paper:
52 // “Parallel Peak Pruning for Scalable SMP Contour Tree Computation.”
53 // Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
54 // Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
55 // (LDAV), October 2016, Baltimore, Maryland.
56 
57 //=======================================================================================
58 //
59 // COMMENTS:
60 //
61 // The old ChainGraph has been abstracted a little further - it still does the same job
62 // of carrying most of the intermediate stages. However, since the chain building is
63 // also needed by the mesh to set up the initial graph input, it has been moved (for now
64 // to Types.h)
65 //
66 // There will be no explicit constructor - instead, it's the mesh's job to initialise
67 // a valid object of this type
68 //
69 //=======================================================================================
70 
71 #ifndef vtkm_worklet_contourtree_chaingraph_h
72 #define vtkm_worklet_contourtree_chaingraph_h
73 
85 
86 #include <vtkm/cont/Algorithm.h>
87 #include <vtkm/cont/ArrayCopy.h>
91 
92 //#define DEBUG_PRINT 1
93 //#define DEBUG_FUNCTION_ENTRY 1
94 //#define DEBUG_TIMING 1
95 
96 namespace vtkm
97 {
98 namespace worklet
99 {
100 namespace contourtree
101 {
102 
103 #define DEBUG_STRING_TRANSFER_GOVERNING_SADDLES "Extrema should now be assigned"
104 #define DEBUG_STRING_TRANSFER_SADDLE_STARTS "Transfer Saddle Starts "
105 #define DEBUG_STRING_TRANSFERRED_SADDLE_STARTS "Saddle Starts Transferred"
106 #define DEBUG_STRING_TRANSFER_TO_MERGE_TREE "Transfer to Merge Tree"
107 #define DEBUG_STRING_OUTDEGREE "Outdegree"
108 #define DEBUG_STRING_CHAINEXT "Chain Ext"
109 #define DEBUG_STRING_ACTIVE_OUTDEGREE "Active Outdegree"
110 #define DEBUG_STRING_ACTIVE_CHAINEXT "Active Chain Ext"
111 #define DEBUG_STRING_FAR_ID "Far"
112 #define DEBUG_STRING_FAR_INDEX "Far Index"
113 #define DEBUG_STRING_FAR_VALUE "Far Value"
114 #define DEBUG_STRING_NEAR_ID "Near"
115 #define DEBUG_STRING_NEAR_INDEX "Near Index"
116 #define DEBUG_STRING_NEAR_VALUE "Near Value"
117 #define DEBUG_STRING_EDGE_FAR_ID "Edge Far"
118 #define DEBUG_STRING_EDGE_NEAR_ID "Edge Near"
119 #define DEBUG_STRING_EDGE_NEAR_INDEX "Edge Near Index"
120 #define DEBUG_STRING_EDGE_NEAR_VALUE "Edge Near Value"
121 #define DEBUG_STRING_SORTED_NEAR_ID "Sorted Near"
122 #define DEBUG_STRING_SORTED_NEAR_INDEX "Sorted Near Index"
123 #define DEBUG_STRING_SORTED_NEAR_VALUE "Sorted Near Value"
124 #define DEBUG_STRING_SORTED_FAR_ID "Sorted Far"
125 
126 template <typename T, typename StorageType>
128 {
129 public:
130  // we will want a reference to the original data array
132 
133  // we will also want a reference to the arc array where we write the output
135 
136  // for each vertex, we need to know where it is in the original data array
138 
139  // and we also need the orientation of the edges (i.e. is it join or split)
141 
142  // and we will store the number of iterations the computation took here
144 
145  // array recording pruning sequence
146  // pseudo-extrema prune to pseudo-saddles
147  // all others prune to pseudo-extrema
149 
150  // we also want to keep track of the first edge for each vertex
152 
153  // and the outdegree for each vertex
155 
156  // finally, we need to keep track of the chain extremum for each vertex
158 
159  // we will also need to keep track of both near and far ends of each edge
162 
163  // we will also keep track of the currently active set of vertices and edges
166 
167  // and an array for sorting edges
169 
170  // constructor takes necessary references
173  bool IsJoinGraph)
174  : values(Values)
175  , arcArray(ArcArray)
176  , isJoinGraph(IsJoinGraph)
177  {
178  }
179 
180  // sets initial size of vertex arrays
181  void AllocateVertexArrays(vtkm::Id Size);
182 
183  // sets initial size of edge arrays
184  void AllocateEdgeArrays(vtkm::Id Size);
185 
186  // routine that builds the merge graph once the initial vertices & edges are set
188 
189  // sorts saddle starts to find governing saddles
190  void FindGoverningSaddles();
191 
192  // marks now regular points for removal
193  void TransferRegularPoints();
194 
195  // compacts the active vertex list
196  void CompactActiveVertices();
197 
198  // compacts the active edge list
199  void CompactActiveEdges();
200 
201  // builds the chains for the new active vertices
202  void BuildChains();
203 
204  // suppresses non-saddles for the governing saddles pass
205  void TransferSaddleStarts();
206 
207  // sets all remaining active vertices
208  void BuildTrunk();
209 
210  // transfers partial results to merge tree array
212 
213  // prints the contents of the topology graph in a standard format
214  void DebugPrint(const char* message);
215 }; // class ChainGraph
216 
217 // sets initial size of vertex arrays
218 template <typename T, typename StorageType>
220 {
221  valueIndex.Allocate(Size);
222  prunesTo.Allocate(Size);
223  firstEdge.Allocate(Size);
224  outdegree.Allocate(Size);
225  chainExtremum.Allocate(Size);
226  activeVertices.Allocate(Size);
227 } // AllocateVertexArrays()
228 
229 // sets initial size of edge arrays
230 template <typename T, typename StorageType>
232 {
233  edgeFar.Allocate(Size);
234  edgeNear.Allocate(Size);
235  activeEdges.Allocate(Size);
236 } // AllocateEdgeArrays()
237 
238 // routine that builds the merge graph once the initial vertices & edges are set
239 template <typename T, typename StorageType>
241 {
242 #ifdef DEBUG_FUNCTION_ENTRY
243  std::cout << std::endl;
244  std::cout << "===================" << std::endl;
245  std::cout << "Compute Chain Graph" << std::endl;
246  std::cout << "===================" << std::endl;
247  std::cout << std::endl;
248 #endif
249 
250 #ifdef DEBUG_PRINT
251  DebugPrint("Chain Graph Computation Starting");
252 #endif
253 
254  // loop until we run out of active edges
255  nIterations = 0;
256  while (edgeSorter.GetNumberOfValues() > 0)
257  {
258  // find & label the extrema with their governing saddles
259  FindGoverningSaddles();
260 
261  // label the regular points
262  TransferRegularPoints();
263 
264  // compact the active set of vertices & edges
265  CompactActiveVertices();
266  CompactActiveEdges();
267 
268  // rebuild the chains
269  BuildChains();
270 
271  // choose the subset of edges for the governing saddles
272  TransferSaddleStarts();
273 
274  // increment the iteration count
275  nIterations++;
276  } // main loop
277 
278  // final pass to label the trunk vertices
279  BuildTrunk();
280 
281  // we can now release many of the arrays to free up space
282  firstEdge.ReleaseResources();
283  outdegree.ReleaseResources();
284  edgeNear.ReleaseResources();
285  edgeFar.ReleaseResources();
286  activeEdges.ReleaseResources();
287  activeVertices.ReleaseResources();
288  edgeSorter.ReleaseResources();
289 
290  // and transfer results to mergearcs
291  TransferToMergeTree(saddles);
292 
293  // then release the remaining memory
294  chainExtremum.ReleaseResources();
295  prunesTo.ReleaseResources();
296 
297 #ifdef DEBUG_PRINT
298  DebugPrint("Chain Graph Computed");
299 #endif
300 } // Compute()
301 
302 // sorts saddle ascents to find governing saddles
303 template <typename T, typename StorageType>
305 {
306 #ifdef DEBUG_FUNCTION_ENTRY
307  std::cout << std::endl;
308  std::cout << "======================" << std::endl;
309  std::cout << "Find Governing Saddles" << std::endl;
310  std::cout << "======================" << std::endl;
311  std::cout << std::endl;
312 #endif
313 
314  // sort with the comparator
315  vtkm::cont::Algorithm::Sort(edgeSorter,
317  values, valueIndex, edgeFar, edgeNear, arcArray, isJoinGraph));
318 
319 #ifdef DEBUG_PRINT
320  DebugPrint("After Sorting");
321 #endif
322 
323  // now loop through the edges
324  GoverningSaddleFinder governingSaddleFinder;
325  vtkm::worklet::DispatcherMapField<GoverningSaddleFinder> governingSaddleFinderDispatcher(
326  governingSaddleFinder);
327  vtkm::Id nEdges = edgeSorter.GetNumberOfValues();
328  vtkm::cont::ArrayHandleIndex edgeIndexArray(nEdges);
329 
330  governingSaddleFinderDispatcher.Invoke(edgeIndexArray, // input
331  edgeSorter, // input (whole array)
332  edgeFar, // input (whole array)
333  edgeNear, // input (whole array)
334  prunesTo, // output (whole array)
335  outdegree); // output (whole array)
336 #ifdef DEBUG_PRINT
338 #endif
339 } // FindGoverningSaddles()
340 
341 // marks now regular points for removal
342 template <typename T, typename StorageType>
344 {
345 #ifdef DEBUG_FUNCTION_ENTRY
346  std::cout << std::endl;
347  std::cout << "=======================" << std::endl;
348  std::cout << "Transfer Regular Points" << std::endl;
349  std::cout << "=======================" << std::endl;
350  std::cout << std::endl;
351 #endif
352  RegularPointTransferrer<T> regularPointTransferrer(isJoinGraph);
353  vtkm::worklet::DispatcherMapField<RegularPointTransferrer<T>> regularPointTransferrerDispatcher(
354  regularPointTransferrer);
355 
356  regularPointTransferrerDispatcher.Invoke(activeVertices, // input
357  chainExtremum, // input (whole array)
358  values, // input (whole array)
359  valueIndex, // input (whole array)
360  prunesTo, // i/o (whole array)
361  outdegree); // output (whole array)
362 #ifdef DEBUG_PRINT
363  DebugPrint("Regular Points Should Now Be Labelled");
364 #endif
365 } // TransferRegularPoints()
366 
367 // compacts the active vertex list
368 template <typename T, typename StorageType>
370 {
371 #ifdef DEBUG_FUNCTION_ENTRY
372  std::cout << std::endl;
373  std::cout << "=======================" << std::endl;
374  std::cout << "Compact Active Vertices" << std::endl;
375  std::cout << "=======================" << std::endl;
376  std::cout << std::endl;
377 #endif
380 
381  // create a temporary array the same size
382  vtkm::cont::ArrayHandle<vtkm::Id> newActiveVertices;
383 
384  // Use only the current activeVertices outdegree to match size on CopyIf
385  vtkm::cont::ArrayHandle<vtkm::Id> outdegreeLookup;
386  vtkm::cont::ArrayCopy(PermuteIndexType(activeVertices, outdegree), outdegreeLookup);
387 
388  // compact the activeVertices array to keep only the ones of interest
389  vtkm::cont::Algorithm::CopyIf(activeVertices, outdegreeLookup, newActiveVertices);
390 
391  activeVertices.ReleaseResources();
392  vtkm::cont::Algorithm::Copy(newActiveVertices, activeVertices);
393 
394 #ifdef DEBUG_PRINT
395  DebugPrint("Active Vertex List Compacted");
396 #endif
397 } // CompactActiveVertices()
398 
399 // compacts the active edge list
400 template <typename T, typename StorageType>
402 {
403 #ifdef DEBUG_FUNCTION_ENTRY
404  std::cout << std::endl;
405  std::cout << "====================" << std::endl;
406  std::cout << "Compact Active Edges" << std::endl;
407  std::cout << "====================" << std::endl;
408  std::cout << std::endl;
409 #endif
410  // grab the size of the array for easier reference
411  vtkm::Id nActiveVertices = activeVertices.GetNumberOfValues();
412 
413  // first, we have to work out the first edge for each active vertex
414  // we start with a temporary new updegree
416  newOutdegree.Allocate(nActiveVertices);
417 
418  // do a parallel computation using the vertex degree updater
419  // WARNING: Using chainMaximum for I/O in parallel loop
420  // See functor description for algorithmic justification of safety
421  VertexDegreeUpdater vertexDegreeUpdater;
422  vtkm::worklet::DispatcherMapField<VertexDegreeUpdater> vertexDegreeUpdaterDispatcher(
423  vertexDegreeUpdater);
424 
425  vertexDegreeUpdaterDispatcher.Invoke(activeVertices, // input
426  activeEdges, // input (whole array)
427  edgeFar, // input (whole array)
428  firstEdge, // input (whole array)
429  prunesTo, // input (whole array)
430  outdegree, // input (whole array)
431  chainExtremum, // i/o (whole array)
432  newOutdegree); // output
433 
434  // now we do a reduction to compute the offsets of each vertex
436  vtkm::cont::Algorithm::ScanExclusive(newOutdegree, newPosition);
437  vtkm::Id nNewEdges = vtkm::cont::ArrayGetValue(nActiveVertices - 1, newPosition) +
438  vtkm::cont::ArrayGetValue(nActiveVertices - 1, newOutdegree);
439 
440  // create a temporary vector for copying
441  vtkm::cont::ArrayHandle<vtkm::Id> newActiveEdges;
442  newActiveEdges.Allocate(nNewEdges);
443 
444  // now copy the relevant edges into the active edge array
445  // WARNING: Using chainMaximum, edgeHigh, firstEdge, updegree for I/O in parallel loop
446  // See functor description for algorithmic justification of safety
448  activeVertices, // input
449  newPosition, // input
450  newOutdegree, // input
451  activeEdges, // input (whole array)
452  prunesTo, // input (whole array)
453  firstEdge, // i/o (whole array)
454  outdegree, // i/o (whole array)
455  chainExtremum, // i/o (whole array)
456  edgeFar, // i/o (whole array)
457  newActiveEdges); // output (whole array)
458 
459  // resize the original array and recopy
460  vtkm::cont::ArrayCopy(newActiveEdges, activeEdges);
461 
462 #ifdef DEBUG_PRINT
463  DebugPrint("Active Edges Now Compacted");
464 #endif
465 } // CompactActiveEdges()
466 
467 // builds the chains for the new active vertices
468 template <typename T, typename StorageType>
470 {
471 #ifdef DEBUG_FUNCTION_ENTRY
472  std::cout << std::endl;
473  std::cout << "============" << std::endl;
474  std::cout << "Build Chains" << std::endl;
475  std::cout << "============" << std::endl;
476  std::cout << std::endl;
477 #endif
478  // a temporary array the full size of the graph
479  vtkm::cont::ArrayHandle<vtkm::Id> tempChainExtremum;
480  tempChainExtremum.Allocate(edgeNear.GetNumberOfValues());
481 
482  // compute the number of log steps required in this pass
483  vtkm::Id nActiveVertices = activeVertices.GetNumberOfValues();
484  vtkm::Id nLogSteps = 1;
485  for (vtkm::Id shifter = nActiveVertices; shifter != 0; shifter >>= 1)
486  nLogSteps++;
487 
488  ChainDoubler chainDoubler;
489  vtkm::worklet::DispatcherMapField<ChainDoubler> chainDoublerDispatcher(chainDoubler);
490 
491  // 2. Use path compression / step doubling to collect vertices along ascending chains
492  // until every vertex has been assigned to *an* extremum
493  // Step two at a time, so that we rock between the original and the temp
494  for (vtkm::Id logStep = 0; logStep < nLogSteps; logStep++)
495  {
496  chainDoublerDispatcher.Invoke(activeVertices, // input
497  chainExtremum); // i/o (whole array)
498  }
499 
500 #ifdef DEBUG_PRINT
501  DebugPrint("Chains Built");
502 #endif
503 } // BuildChains()
504 
505 // transfers saddle ascent edges into edge sorter
506 template <typename T, typename StorageType>
508 {
509 #ifdef DEBUG_FUNCTION_ENTRY
510  std::cout << std::endl;
511  std::cout << "=======================" << std::endl;
512  std::cout << DEBUG_STRING_TRANSFER_SADDLE_STARTS << std::endl;
513  std::cout << "=======================" << std::endl;
514  std::cout << std::endl;
515 #endif
516 
517  // grab the size of the array for easier reference
518  vtkm::Id nActiveVertices = activeVertices.GetNumberOfValues();
519 
520  // reset number of edges to sort
521  vtkm::Id nEdgesToSort = 0;
522 
523  // in parallel, we need to create a vector to count the first edge for each vertex
526  newFirstEdge.Allocate(nActiveVertices);
527  newOutdegree.Allocate(nActiveVertices);
528 
529  // 2. now test all active vertices to see if they have only one chain maximum
530  SaddleAscentFunctor saddleAscentFunctor;
531  vtkm::worklet::DispatcherMapField<SaddleAscentFunctor> saddleAscentFunctorDispatcher(
532  saddleAscentFunctor);
533 
534  saddleAscentFunctorDispatcher.Invoke(activeVertices, // input
535  firstEdge, // input (whole array)
536  outdegree, // input (whole array)
537  activeEdges, // input (whole array)
538  chainExtremum, // input (whole array)
539  edgeFar, // input (whole array)
540  newOutdegree); // output
541 
542  // 3. now compute the new offsets in the newFirstEdge array
543  vtkm::cont::Algorithm::ScanExclusive(newOutdegree, newFirstEdge);
544  nEdgesToSort = vtkm::cont::ArrayGetValue(nActiveVertices - 1, newFirstEdge) +
545  vtkm::cont::ArrayGetValue(nActiveVertices - 1, newOutdegree);
546 
547  edgeSorter.ReleaseResources();
548  edgeSorter.Allocate(nEdgesToSort);
549 
550  SaddleAscentTransferrer saddleAscentTransferrer;
551  vtkm::worklet::DispatcherMapField<SaddleAscentTransferrer> saddleAscentTransferrerDispatcher(
552  saddleAscentTransferrer);
553 
554  saddleAscentTransferrerDispatcher.Invoke(activeVertices, // input
555  newOutdegree, // input
556  newFirstEdge, // input
557  activeEdges, // input (whole array)
558  firstEdge, // input (whole array)
559  edgeSorter); // output (whole array)
560 
561 #ifdef DEBUG_PRINT
563 #endif
564 } // TransferSaddleStarts()
565 
566 // sets all remaining active vertices
567 template <typename T, typename StorageType>
569 {
570 #ifdef DEBUG_FUNCTION_ENTRY
571  std::cout << std::endl;
572  std::cout << "===========" << std::endl;
573  std::cout << "Build Trunk" << std::endl;
574  std::cout << "============" << std::endl;
575  std::cout << std::endl;
576 #endif
577 
578  TrunkBuilder trunkBuilder;
579  vtkm::worklet::DispatcherMapField<TrunkBuilder> trunkBuilderDispatcher(trunkBuilder);
580 
581  trunkBuilderDispatcher.Invoke(activeVertices, // input
582  chainExtremum, // input (whole array)
583  prunesTo); // output (whole array)
584 #ifdef DEBUG_PRINT
585  DebugPrint("Trunk Built");
586 #endif
587 } // BuildTrunk()
588 
589 // transfers partial results to merge tree array
590 template <typename T, typename StorageType>
592 {
593 #ifdef DEBUG_FUNCTION_ENTRY
594  std::cout << std::endl;
595  std::cout << "=====================" << std::endl;
596  std::cout << DEBUG_STRING_TRANSFER_TO_MERGE_TREE << std::endl;
597  std::cout << "=====================" << std::endl;
598  std::cout << std::endl;
599 #endif
600 
601  // first allocate memory for the target array
602  saddles.ReleaseResources();
603 
604  // initialise it to the arcArray
605  vtkm::cont::ArrayCopy(arcArray, saddles);
606 
607  JoinTreeTransferrer joinTreeTransferrer;
608  vtkm::worklet::DispatcherMapField<JoinTreeTransferrer> joinTreeTransferrerDispatcher(
609  joinTreeTransferrer);
610  vtkm::cont::ArrayHandleIndex valueIndexArray(valueIndex.GetNumberOfValues());
611 
612  joinTreeTransferrerDispatcher.Invoke(valueIndexArray, // input
613  prunesTo, // input
614  valueIndex, // input (whole array)
615  chainExtremum, // input (whole array)
616  saddles, // output (whole array)
617  arcArray); // output (whole array)
618 } // TransferToMergeTree()
619 
620 // prints the contents of the topology graph in standard format
621 template <typename T, typename StorageType>
622 void ChainGraph<T, StorageType>::DebugPrint(const char* message)
623 {
624  std::cout << "---------------------------" << std::endl;
625  std::cout << std::string(message) << std::endl;
626  std::cout << "---------------------------" << std::endl;
627  std::cout << std::endl;
628 
630  using ValueArrayType = vtkm::cont::ArrayHandle<T>;
633 
634  // Full Vertex Arrays
635  vtkm::Id nValues = valueIndex.GetNumberOfValues();
637 
638  std::cout << "Full Vertex Arrays - Size: " << nValues << std::endl;
639  PrintHeader(nValues);
640  PrintIndices("Index", valueIndex);
641  vtkm::cont::ArrayCopy(PermuteValueType(valueIndex, values), vertexValues);
642  PrintValues("Value", vertexValues);
643  PrintIndices("First Edge", firstEdge);
644  PrintIndices("Outdegree", outdegree);
645  PrintIndices("Chain Ext", chainExtremum);
646  PrintIndices("Prunes To", prunesTo);
647  std::cout << std::endl;
648 
649  // Active Vertex Arrays
650  vtkm::Id nActiveVertices = activeVertices.GetNumberOfValues();
651  std::cout << "Active Vertex Arrays - Size: " << nActiveVertices << std::endl;
652  if (nActiveVertices > 0)
653  {
655  vtkm::cont::ArrayHandle<T> tempValue;
656 
657  PrintHeader(nActiveVertices);
658  PrintIndices("Active Vertices", activeVertices);
659  vtkm::cont::ArrayCopy(PermuteIndexType(activeVertices, valueIndex), tempIndex);
660  PrintIndices("Active Indices", tempIndex);
661  vtkm::cont::ArrayCopy(PermuteValueType(activeVertices, vertexValues), tempValue);
662  PrintValues("Active Values", tempValue);
663  vtkm::cont::ArrayCopy(PermuteIndexType(activeVertices, firstEdge), tempIndex);
664  PrintIndices("Active First Edge", tempIndex);
665  vtkm::cont::ArrayCopy(PermuteIndexType(activeVertices, outdegree), tempIndex);
666  PrintIndices("Active Outdegree", tempIndex);
667  vtkm::cont::ArrayCopy(PermuteIndexType(activeVertices, chainExtremum), tempIndex);
668  PrintIndices("Active Chain Ext", tempIndex);
669  vtkm::cont::ArrayCopy(PermuteIndexType(activeVertices, prunesTo), tempIndex);
670  PrintIndices("Active Prunes To", tempIndex);
671  std::cout << std::endl;
672  }
673 
674  // Full Edge Arrays
675  vtkm::Id nEdges = edgeNear.GetNumberOfValues();
676  std::cout << "Full Edge Arrays - Size: " << nEdges << std::endl;
681  if (nEdges > 0)
682  {
683  PrintHeader(nEdges);
684  PrintIndices("Far", edgeFar);
685  vtkm::cont::ArrayCopy(PermuteIndexType(edgeFar, valueIndex), farIndices);
686  PrintIndices("Far Index", farIndices);
687  vtkm::cont::ArrayCopy(PermuteValueType(farIndices, values), farValues);
688  PrintValues("Far Value", farValues);
689 
690  PrintHeader(nEdges);
691  PrintIndices("Near", edgeNear);
692  vtkm::cont::ArrayCopy(PermuteIndexType(edgeNear, valueIndex), nearIndices);
693  PrintIndices("Near Index", nearIndices);
694  vtkm::cont::ArrayCopy(PermuteValueType(nearIndices, values), nearValues);
695  PrintValues("Near Value", nearValues);
696  }
697 
698  // Active Edge Arrays
699  vtkm::Id nActiveEdges = activeEdges.GetNumberOfValues();
700  std::cout << "Active Edge Arrays - Size: " << nActiveEdges << std::endl;
701  if (nActiveEdges > 0)
702  {
703  vtkm::cont::ArrayHandle<vtkm::Id> activeFarIndices;
704  vtkm::cont::ArrayHandle<vtkm::Id> activeNearIndices;
705  vtkm::cont::ArrayHandle<vtkm::Id> activeNearLookup;
707 
708  PrintHeader(nActiveEdges);
709  PrintIndices("Active Edges", activeEdges);
710 
711  vtkm::cont::ArrayCopy(PermuteIndexType(activeEdges, edgeFar), activeFarIndices);
712  PrintIndices("Edge Far", activeFarIndices);
713  vtkm::cont::ArrayCopy(PermuteIndexType(activeEdges, edgeNear), activeNearIndices);
714  PrintIndices("Edge Near", activeNearIndices);
715  vtkm::cont::ArrayCopy(PermuteIndexType(activeNearIndices, valueIndex), activeNearLookup);
716  PrintIndices("Edge Near Index", activeNearLookup);
717  vtkm::cont::ArrayCopy(PermuteValueType(activeNearLookup, values), activeNearValues);
718  PrintValues("Edge Near Value", activeNearValues);
719  std::cout << std::endl;
720  }
721 
722  // Edge Sorter Array
723  vtkm::Id nEdgeSorter = edgeSorter.GetNumberOfValues();
724  std::cout << "Edge Sorter - Size: " << nEdgeSorter << std::endl;
725  if (nEdgeSorter > 0)
726  {
727  vtkm::cont::ArrayHandle<vtkm::Id> tempSortIndex;
728  vtkm::cont::ArrayHandle<T> tempSortValue;
729 
730  PrintHeader(nEdgeSorter);
731  PrintIndices("Edge Sorter", edgeSorter);
732  vtkm::cont::ArrayCopy(PermuteIndexType(edgeSorter, edgeNear), tempSortIndex);
733  PrintIndices("Sorted Near", tempSortIndex);
734  vtkm::cont::ArrayCopy(PermuteIndexType(edgeSorter, nearIndices), tempSortIndex);
735  PrintIndices("Sorted Near Index", tempSortIndex);
736  vtkm::cont::ArrayCopy(PermuteIndexType(edgeSorter, edgeFar), tempSortIndex);
737  PrintIndices("Sorted Far", tempSortIndex);
738  vtkm::cont::ArrayCopy(PermuteValueType(edgeSorter, nearValues), tempSortValue);
739  PrintValues("Sorted Near Value", tempSortValue);
740  std::cout << std::endl;
741  }
742 
743  std::cout << "---------------------------" << std::endl;
744  std::cout << std::endl;
745 } // DebugPrint()
746 }
747 }
748 }
749 
750 #endif
vtkm::worklet::contourtree::PrintHeader
void PrintHeader(vtkm::Id howMany)
Definition: PrintVectors.h:155
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::ChainGraph
Definition: ChainGraph.h:127
vtkm::worklet::contourtree::ChainGraph::prunesTo
vtkm::cont::ArrayHandle< vtkm::Id > prunesTo
Definition: ChainGraph.h:148
vtkm::worklet::contourtree::SaddleAscentTransferrer
Definition: SaddleAscentTransferrer.h:83
vtkm::cont::ArrayHandle< T, StorageType >
vtkm::worklet::contourtree::ChainGraph::TransferSaddleStarts
void TransferSaddleStarts()
Definition: ChainGraph.h:507
vtkm::worklet::contourtree::ChainGraph::AllocateEdgeArrays
void AllocateEdgeArrays(vtkm::Id Size)
Definition: ChainGraph.h:231
vtkm::worklet::contourtree::EdgePeakComparator
Definition: EdgePeakComparator.h:87
vtkm::worklet::contourtree::ChainGraph::activeVertices
vtkm::cont::ArrayHandle< vtkm::Id > activeVertices
Definition: ChainGraph.h:164
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
vtkm::worklet::contourtree::ChainGraph::isJoinGraph
bool isJoinGraph
Definition: ChainGraph.h:140
vtkm::worklet::contourtree::ChainGraph::values
const vtkm::cont::ArrayHandle< T, StorageType > & values
Definition: ChainGraph.h:131
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
DEBUG_STRING_TRANSFER_TO_MERGE_TREE
#define DEBUG_STRING_TRANSFER_TO_MERGE_TREE
Definition: ChainGraph.h:106
vtkm::worklet::contourtree::ChainGraph::chainExtremum
vtkm::cont::ArrayHandle< vtkm::Id > chainExtremum
Definition: ChainGraph.h:157
vtkm::worklet::contourtree::ChainGraph::CompactActiveEdges
void CompactActiveEdges()
Definition: ChainGraph.h:401
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::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
SaddleAscentFunctor.h
TrunkBuilder.h
GoverningSaddleFinder.h
vtkm::Id
vtkm::Int32 Id
Represents an ID (index into arrays).
Definition: Types.h:191
ArrayCopy.h
RegularPointTransferrer.h
DispatcherMapField.h
vtkm::worklet::contourtree::ChainGraph::outdegree
vtkm::cont::ArrayHandle< vtkm::Id > outdegree
Definition: ChainGraph.h:154
vtkm::worklet::contourtree::ChainGraph::BuildTrunk
void BuildTrunk()
Definition: ChainGraph.h:568
vtkm::worklet::contourtree::ChainGraph::nIterations
vtkm::Id nIterations
Definition: ChainGraph.h:143
vtkm::worklet::contourtree::PrintValues
void PrintValues(std::string label, vtkm::cont::ArrayHandle< T, StorageType > &dVec, vtkm::Id nValues=-1)
Definition: PrintVectors.h:174
vtkm::worklet::contourtree::ChainGraph::TransferToMergeTree
void TransferToMergeTree(vtkm::cont::ArrayHandle< vtkm::Id > &saddles)
Definition: ChainGraph.h:591
vtkm::worklet::contourtree::ChainGraph::AllocateVertexArrays
void AllocateVertexArrays(vtkm::Id Size)
Definition: ChainGraph.h:219
JoinTreeTransferrer.h
vtkm::worklet::DispatcherMapField
Dispatcher for worklets that inherit from WorkletMapField.
Definition: DispatcherMapField.h:25
vtkm::worklet::contourtree::ChainGraph::edgeFar
vtkm::cont::ArrayHandle< vtkm::Id > edgeFar
Definition: ChainGraph.h:160
vtkm::worklet::contourtree::ChainGraph::Compute
void Compute(vtkm::cont::ArrayHandle< vtkm::Id > &saddles)
Definition: ChainGraph.h:240
ArrayHandlePermutation.h
Algorithm.h
vtkm::worklet::contourtree::JoinTreeTransferrer
Definition: JoinTreeTransferrer.h:88
vtkm::worklet::contourtree::ChainGraph::edgeSorter
vtkm::cont::ArrayHandle< vtkm::Id > edgeSorter
Definition: ChainGraph.h:168
vtkm::cont::Algorithm::ScanExclusive
static VTKM_CONT T ScanExclusive(vtkm::cont::DeviceAdapterId devId, const vtkm::cont::ArrayHandle< T, CIn > &input, vtkm::cont::ArrayHandle< T, COut > &output)
Definition: Algorithm.h:816
vtkm::cont::ArrayHandlePermutation
Implicitly permutes the values in an array.
Definition: ArrayHandlePermutation.h:227
ActiveEdgeTransferrer.h
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::IdArrayType
vtkm::cont::ArrayHandle< vtkm::Id > IdArrayType
Definition: filter/scalar_topology/worklet/contourtree_augmented/Types.h:90
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::ChainGraph::CompactActiveVertices
void CompactActiveVertices()
Definition: ChainGraph.h:369
DEBUG_STRING_TRANSFER_GOVERNING_SADDLES
#define DEBUG_STRING_TRANSFER_GOVERNING_SADDLES
Definition: ChainGraph.h:103
ChainDoubler.h
vtkm::worklet::contourtree::ChainGraph::DebugPrint
void DebugPrint(const char *message)
Definition: ChainGraph.h:622
vtkm::worklet::contourtree::ChainGraph::ChainGraph
ChainGraph(const vtkm::cont::ArrayHandle< T, StorageType > &Values, vtkm::cont::ArrayHandle< vtkm::Id > &ArcArray, bool IsJoinGraph)
Definition: ChainGraph.h:171
vtkm::worklet::contourtree::ChainGraph::valueIndex
vtkm::cont::ArrayHandle< vtkm::Id > valueIndex
Definition: ChainGraph.h:137
ArrayGetValues.h
vtkm::worklet::contourtree::ChainGraph::arcArray
vtkm::cont::ArrayHandle< vtkm::Id > & arcArray
Definition: ChainGraph.h:134
EdgePeakComparator.h
vtkm::worklet::contourtree::ChainGraph::firstEdge
vtkm::cont::ArrayHandle< vtkm::Id > firstEdge
Definition: ChainGraph.h:151
vtkm::worklet::contourtree::ChainGraph::activeEdges
vtkm::cont::ArrayHandle< vtkm::Id > activeEdges
Definition: ChainGraph.h:165
vtkm::worklet::contourtree::GoverningSaddleFinder
Definition: GoverningSaddleFinder.h:86
vtkm::worklet::contourtree::ChainGraph::BuildChains
void BuildChains()
Definition: ChainGraph.h:469
vtkm::worklet::contourtree::ChainDoubler
Definition: ChainDoubler.h:91
vtkm::worklet::contourtree::ChainGraph::edgeNear
vtkm::cont::ArrayHandle< vtkm::Id > edgeNear
Definition: ChainGraph.h:161
vtkm::worklet::contourtree::ChainGraph::FindGoverningSaddles
void FindGoverningSaddles()
Definition: ChainGraph.h:304
PrintVectors.h
vtkm::worklet::contourtree::PrintIndices
void PrintIndices(std::string label, vtkm::cont::ArrayHandle< vtkm::Id > &iVec, vtkm::Id nIndices=-1)
Definition: PrintVectors.h:202
DEBUG_STRING_TRANSFER_SADDLE_STARTS
#define DEBUG_STRING_TRANSFER_SADDLE_STARTS
Definition: ChainGraph.h:104
SaddleAscentTransferrer.h
vtkm::worklet::contourtree::ChainGraph::TransferRegularPoints
void TransferRegularPoints()
Definition: ChainGraph.h:343
DEBUG_STRING_TRANSFERRED_SADDLE_STARTS
#define DEBUG_STRING_TRANSFERRED_SADDLE_STARTS
Definition: ChainGraph.h:105
vtkm::worklet::contourtree::SaddleAscentFunctor
Definition: SaddleAscentFunctor.h:84
vtkm::cont::ArrayHandle::ReleaseResources
VTKM_CONT void ReleaseResources() const
Releases all resources in both the control and execution environments.
Definition: ArrayHandle.h:559
vtkm::worklet::contourtree::RegularPointTransferrer
Definition: RegularPointTransferrer.h:90
vtkm::worklet::contourtree::TrunkBuilder
Definition: TrunkBuilder.h:88
VertexDegreeUpdater.h
vtkm::cont::ArrayHandleIndex
An implicit array handle containing the its own indices.
Definition: ArrayHandleIndex.h:54
vtkm::worklet::contourtree::VertexDegreeUpdater
Definition: VertexDegreeUpdater.h:87