Add debug out and refactor for debugging

This commit is contained in:
Gunther H. Weber 2021-05-25 17:08:22 -07:00
parent 968ccfc351
commit 9548ba5100
12 changed files with 719 additions and 85 deletions

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5706bddc644b5b120ffbd424b3073ce989735272726de711ca8dac19b4a30ee1
size 2653
oid sha256:aa4623c6a5f1051038cfdafb9167a1e2625091063e5ee8c1247af45539189eea
size 2657

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ea0a0903fce2b7b42023ca0a2bdc008781a61fa74f75b2b107e6d0788c404551
size 1441
oid sha256:ef15b2a0e8ae45c80c1e55cc8aadb0bbd725d39cf2fb091c2b3dde9d601e3930
size 1445

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:58aed19216ce91b6c9bc7c0d8ee31c1062405ad6f5a4a977b49f213e2ce81307
size 1518
oid sha256:4ec4d071805a7300bf61aa2c017fe5c9892ad10df7495ef40c69799d58c84db8
size 1522

@ -85,10 +85,16 @@ void PrintValues(std::string label,
const vtkm::cont::ArrayHandle<T, StorageType>& dVec,
vtkm::Id nValues = -1,
std::ostream& outStream = std::cout);
template <typename T>
void PrintIndices(std::string label,
const vtkm::cont::ArrayHandle<vtkm::Id>& iVec,
const vtkm::cont::ArrayHandle<T>& iVec,
vtkm::Id nIndices = -1,
std::ostream& outStream = std::cout);
template <typename T>
void PrintArray(std::string label,
const T& iVec,
vtkm::Id nIndices = -1,
std::ostream& outStream = std::cout);
template <typename T, typename StorageType>
void PrintSortedValues(std::string label,
const vtkm::cont::ArrayHandle<T, StorageType>& dVec,
@ -213,8 +219,9 @@ inline void PrintSortedValues(std::string label,
// routine for printing index arrays
template <typename T>
inline void PrintIndices(std::string label,
const vtkm::cont::ArrayHandle<vtkm::Id>& iVec,
const vtkm::cont::ArrayHandle<T>& iVec,
vtkm::Id nIndices,
std::ostream& outStream)
{ // PrintIndices()
@ -235,6 +242,26 @@ inline void PrintIndices(std::string label,
outStream << std::endl;
} // PrintIndices()
// routine for printing index arrays
template <typename T>
inline void PrintArray(std::string label, const T& iVec, vtkm::Id nArray, std::ostream& outStream)
{ // PrintArray()
// -1 means full size
if (nArray == -1)
{
nArray = iVec.GetNumberOfValues();
}
// print the label
PrintLabel(label, outStream);
auto portal = iVec.ReadPortal();
for (vtkm::Id entry = 0; entry < nArray; entry++)
PrintIndexType(portal.Get(entry), outStream);
// and the std::endl
outStream << std::endl;
} // PrintArray()
template <typename T, typename StorageType>
inline void PrintLabelledDataBlock(std::string label,

@ -80,18 +80,21 @@
#include <vtkm/worklet/contourtree_augmented/ArrayTransforms.h>
#include <vtkm/worklet/contourtree_augmented/data_set_mesh/IdRelabeler.h> // This is needed only as an unused default argument.
#include <vtkm/worklet/contourtree_augmented/meshtypes/MeshStructureContourTreeMesh.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/AddToArrayElementsWorklet.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ApplyLookupTableDecorator.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ArcComparator.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedOtherStartIndexNNeighboursWorklet.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedSimulatedSimplicityIndexComparator.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CombinedVectorDifferentFromNext.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CompressNeighboursWorklet.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CopyIntoCombinedArrayWorklet.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CopyIntoCombinedNeighborsWorklet.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CopyNeighborsToPackedArray.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/FindStartIndexWorklet.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/GetArcFromDecorator.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/InitToCombinedSortOrderArraysWorklet.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeCombinedOtherStartIndexWorklet.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeNeighborGroups.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeIntoCombinedNeighborsWorklet.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ReplaceArcNumWithToVertexWorklet.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/SubtractAssignWorklet.h>
#include <vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/UpdateCombinedNeighboursWorklet.h>
@ -115,6 +118,8 @@ VTKM_THIRDPARTY_POST_INCLUDE
namespace contourtree_mesh_inc_ns =
vtkm::worklet::contourtree_augmented::mesh_dem_contourtree_mesh_inc;
#define DEBUG_PRINT
namespace vtkm
{
namespace worklet
@ -507,6 +512,7 @@ inline void ContourTreeMesh<FieldType>::ComputeMaxNeighbors()
auto neighborCounts = make_ArrayHandleOffsetsToNumComponents(this->NeighborOffsets);
vtkm::cont::ArrayHandle<vtkm::Range> rangeArray = vtkm::cont::ArrayRangeCompute(neighborCounts);
this->MaxNeighbors = static_cast<vtkm::Id>(ArrayGetValue(0, rangeArray).Max);
std::cout << this->MaxNeighbors << std::endl;
}
// Define the behavior for the execution object generate by the PrepareForExecution function
@ -535,6 +541,21 @@ struct NotNoSuchElement
VTKM_EXEC_CONT bool operator()(vtkm::Id x) const { return x != NO_SUCH_ELEMENT; }
};
template <typename T>
inline void printNumComponents(const T& arr)
{
auto portal = arr.ReadPortal();
for (vtkm::Id idx = 0; idx < portal.GetNumberOfValues(); ++idx)
{
auto vec = portal.Get(idx);
std::cout << "[ " << idx << " (" << vec.GetNumberOfComponents() << "): ";
for (vtkm::IdComponent c_idx = 0; c_idx < vec.GetNumberOfComponents(); ++c_idx)
std::cout << vec[c_idx] << " ";
std::cout << "]";
}
std::cout << std::endl;
}
// Combine two ContourTreeMeshes
template <typename FieldType>
inline void ContourTreeMesh<FieldType>::MergeWith(ContourTreeMesh<FieldType>& other,
@ -620,9 +641,9 @@ inline void ContourTreeMesh<FieldType>::MergeWith(ContourTreeMesh<FieldType>& ot
// thisToCombinedSortOrder and otherToCombinedSortOrder
IdArrayType thisToCombinedSortOrder;
thisToCombinedSortOrder.Allocate(this->NeighborOffsets.GetNumberOfValues());
thisToCombinedSortOrder.Allocate(this->NumVertices);
IdArrayType otherToCombinedSortOrder;
otherToCombinedSortOrder.Allocate(other.NeighborOffsets.GetNumberOfValues());
otherToCombinedSortOrder.Allocate(other.NumVertices);
contourtree_mesh_inc_ns::InitToCombinedSortOrderArraysWorklet
initToCombinedSortOrderArraysWorklet;
this->Invoke(initToCombinedSortOrderArraysWorklet,
@ -639,105 +660,128 @@ inline void ContourTreeMesh<FieldType>::MergeWith(ContourTreeMesh<FieldType>& ot
<< ": " << timer.GetElapsedTime() << " seconds" << std::endl;
timer.Start();
// Combined neighbor counts (including potential duplicates)
IdArrayType combinedNeighborCounts;
vtkm::cont::Algorithm::Fill(combinedNeighborCounts, vtkm::Id{ 0 }, numVerticesCombined);
{ // New scope so that array gets deleted when leaving scope
IdArrayType nNeighbors;
auto neighborCounts = make_ArrayHandleOffsetsToNumComponents(this->NeighborOffsets);
auto permutedCombinedNNeighbors =
vtkm::cont::make_ArrayHandlePermutation(thisToCombinedSortOrder, combinedNeighborCounts);
vtkm::cont::Algorithm::Copy(neighborCounts, permutedCombinedNNeighbors);
}
timingsStream << " " << std::setw(38) << std::left << "Create CombinedNNeighbours"
<< ": " << timer.GetElapsedTime() << " seconds" << std::endl;
timer.Start();
IdArrayType combinedOtherStartIndex;
vtkm::cont::Algorithm::Fill(combinedOtherStartIndex, vtkm::Id{ 0 }, numVerticesCombined);
{ // New scope so that array gets deleted when leaving scope
auto neighborCounts = make_ArrayHandleOffsetsToNumComponents(other.NeighborOffsets);
this->Invoke(contourtree_mesh_inc_ns::CombinedOtherStartIndexNNeighboursWorklet{},
neighborCounts, // input
otherToCombinedSortOrder, // input
combinedNeighborCounts, // input/output
combinedOtherStartIndex // input/output
);
}
// First, copy our neighbor counts into the correct locations
auto neighborCountsThis = make_ArrayHandleOffsetsToNumComponents(this->NeighborOffsets);
auto permutedCombinedNeighborCountsThis =
vtkm::cont::make_ArrayHandlePermutation(thisToCombinedSortOrder, combinedNeighborCounts);
vtkm::cont::Algorithm::Copy(neighborCountsThis, permutedCombinedNeighborCountsThis);
// Now, add the neighbor counts from the other mesh at the correct positions
auto neighborCountsOther = make_ArrayHandleOffsetsToNumComponents(other.NeighborOffsets);
auto permutedCombinedNeighborCountsOther =
vtkm::cont::make_ArrayHandlePermutation(otherToCombinedSortOrder, combinedNeighborCounts);
this->Invoke(contourtree_mesh_inc_ns::AddToArrayElementsWorklet{},
permutedCombinedNeighborCountsOther,
neighborCountsOther);
#ifdef DEBUG_PRINT
PrintIndices("combinedNeighborCounts", combinedNeighborCounts);
PrintIndices("combinedOtherStartIndex", combinedOtherStartIndex);
#endif
timingsStream << " " << std::setw(38) << std::left << "Create CombinedOtherStartIndex"
<< ": " << timer.GetElapsedTime() << " seconds" << std::endl;
timer.Start();
// Compute offsets from counts
IdArrayType combinedNeighborOffsets;
combinedNeighborOffsets.Allocate(numVerticesCombined + 1);
vtkm::cont::Algorithm::ScanExtended(combinedNeighborCounts, combinedNeighborOffsets);
vtkm::Id nCombinedNeighbours =
ArrayGetValue(combinedNeighborOffsets.GetNumberOfValues() - 1, combinedNeighborOffsets);
vtkm::Id nCombinedNeighbours;
vtkm::cont::ConvertNumComponentsToOffsets(
combinedNeighborCounts, combinedNeighborOffsets, nCombinedNeighbours);
PrintIndices("combinedNeighborCounts", combinedNeighborCounts);
PrintIndices("combinedNeighborOffsets", combinedNeighborOffsets);
// Create combined neighbor connectivity array and grouped view on it
IdArrayType combinedNeighborConnectivity;
combinedNeighborConnectivity.Allocate(nCombinedNeighbours);
auto combinedNeighborGroups = vtkm::cont::make_ArrayHandleGroupVecVariable(
combinedNeighborConnectivity, combinedNeighborOffsets);
printNumComponents(combinedNeighborGroups);
// Update combined neighbours
// Updata neighbours from this
this->Invoke(contourtree_mesh_inc_ns::UpdateCombinedNeighboursWorklet{},
this->NeighborOffsets,
this->NeighborConnectivity,
thisToCombinedSortOrder,
combinedNeighborOffsets,
// Constant 0 array. Just needed so we can use the same worklet for both cases:
vtkm::cont::ArrayHandleConstant<vtkm::Id>(0, numVerticesCombined),
combinedNeighborConnectivity);
// Update neighbours from other
this->Invoke(contourtree_mesh_inc_ns::UpdateCombinedNeighboursWorklet{},
other.NeighborOffsets,
other.NeighborConnectivity,
otherToCombinedSortOrder,
combinedNeighborOffsets,
combinedOtherStartIndex,
combinedNeighborConnectivity);
// Create array to hold merged neighbor counts (after eliminating duplicate neigbors)
vtkm::cont::ArrayHandle<vtkm::IdComponent> mergedNeighborCounts;
vtkm::cont::Algorithm::Fill(mergedNeighborCounts, vtkm::IdComponent{ 0 }, numVerticesCombined);
// Copy connectivity array from this mesh into combined neighbor connectivity
// The following decorator converts vertiex indices from our mesh to the combined mesh
auto thisNeighborConnectivityGlobal =
make_ArrayHandleDecorator(this->NeighborConnectivity.GetNumberOfValues(),
mesh_dem_contourtree_mesh_inc::ApplyLookupTableDecoratorImpl{},
this->NeighborConnectivity,
thisToCombinedSortOrder);
PrintArray("thisNeighborConnectivityGlobal", thisNeighborConnectivityGlobal);
PrintArray("this->NeighborOffsets", this->NeighborOffsets);
auto thisNeighborConnectivityGlobalGroups = vtkm::cont::make_ArrayHandleGroupVecVariable(
thisNeighborConnectivityGlobal, this->NeighborOffsets);
printNumComponents(thisNeighborConnectivityGlobalGroups);
auto permutedMergedNeighborCountsThis =
vtkm::cont::make_ArrayHandlePermutation(thisToCombinedSortOrder, mergedNeighborCounts);
auto permutedCombinedNeighborGroupsThis =
vtkm::cont::make_ArrayHandlePermutation(thisToCombinedSortOrder, combinedNeighborGroups);
this->Invoke(contourtree_mesh_inc_ns::CopyIntoCombinedNeighborsWorklet{},
thisNeighborConnectivityGlobalGroups,
permutedCombinedNeighborGroupsThis,
permutedMergedNeighborCountsThis);
std::cout << "After CopyIntoCombinedNeighborsWorklet" << std::endl;
PrintArray("combinedNeighborConnectivity", combinedNeighborConnectivity);
PrintArray("combinedNeighborOffsets", combinedNeighborOffsets);
printNumComponents(combinedNeighborGroups);
// Insert neighbors from other mesh into combined neighbor connectivity (without duplicates)
// The following decorator converts vertiex indices from our mesh to the combined mesh
//
auto otherNeighborConnectivityGlobal =
make_ArrayHandleDecorator(other.NeighborConnectivity.GetNumberOfValues(),
mesh_dem_contourtree_mesh_inc::ApplyLookupTableDecoratorImpl{},
other.NeighborConnectivity,
otherToCombinedSortOrder);
PrintArray("otherNeighborConnectivityGlobal", otherNeighborConnectivityGlobal);
PrintArray("other.NeighborOffsets", other.NeighborOffsets);
auto otherNeighborConnectivityGlobalGroups = vtkm::cont::make_ArrayHandleGroupVecVariable(
otherNeighborConnectivityGlobal, other.NeighborOffsets);
printNumComponents(otherNeighborConnectivityGlobalGroups);
auto permutedMergedNeighborCountsOther =
vtkm::cont::make_ArrayHandlePermutation(otherToCombinedSortOrder, mergedNeighborCounts);
auto permutedCombinedNeighborGroupsOther =
vtkm::cont::make_ArrayHandlePermutation(otherToCombinedSortOrder, combinedNeighborGroups);
this->Invoke(contourtree_mesh_inc_ns::MergeIntoCombinedNeighborsWorklet{},
otherNeighborConnectivityGlobalGroups,
permutedCombinedNeighborGroupsOther,
permutedMergedNeighborCountsOther);
std::cout << "After MergeIntoCombinedNeighborsWorklet" << std::endl;
PrintArray("combinedNeighborConnectivity", combinedNeighborConnectivity);
PrintArray("combinedNeighborOffsets", combinedNeighborOffsets);
printNumComponents(combinedNeighborGroups);
timingsStream << " " << std::setw(38) << std::left << "Update CombinedNeighbours"
<< ": " << timer.GetElapsedTime() << " seconds" << std::endl;
timer.Start();
std::cout << "A" << std::endl;
// Call the worklet above to merge arrays in each group.
auto neighborGroups = vtkm::cont::make_ArrayHandleGroupVecVariable(combinedNeighborConnectivity,
combinedNeighborOffsets);
vtkm::cont::ArrayHandle<vtkm::IdComponent> mergedNeighborCounts;
this->Invoke(contourtree_mesh_inc_ns::MergeNeighborGroups{},
neighborGroups,
combinedOtherStartIndex,
mergedNeighborCounts);
std::cout << "B" << std::endl;
// Create the new offsets array for the merged groups (without duplicates).
vtkm::Id packedCombinedNeighborConnectivitySize;
vtkm::cont::ArrayHandle<vtkm::Id> packedOffsets;
vtkm::cont::ArrayHandle<vtkm::Id> packedCombinedNeighborOffsets;
vtkm::cont::ConvertNumComponentsToOffsets(
mergedNeighborCounts, packedOffsets, packedCombinedNeighborConnectivitySize);
mergedNeighborCounts, packedCombinedNeighborOffsets, packedCombinedNeighborConnectivitySize);
std::cout << "C" << std::endl;
// Create a new grouped array for the packed connectivity
// Note that you have to pre-allocate the connectivity array.
vtkm::cont::ArrayHandle<vtkm::Id> packedCombinedNeighborConnectivity;
packedCombinedNeighborConnectivity.Allocate(packedCombinedNeighborConnectivitySize);
auto packedNeighborGroups =
vtkm::cont::make_ArrayHandleGroupVecVariable(packedCombinedNeighborConnectivity, packedOffsets);
std::cout << "D" << std::endl;
auto packedNeighborGroups = vtkm::cont::make_ArrayHandleGroupVecVariable(
packedCombinedNeighborConnectivity, packedCombinedNeighborOffsets);
// Copy data to the packed array.
this->Invoke(
contourtree_mesh_inc_ns::CopyNeighborsToPackedArray{}, neighborGroups, packedNeighborGroups);
std::cout << "E" << std::endl;
this->Invoke(contourtree_mesh_inc_ns::CopyNeighborsToPackedArray{},
combinedNeighborGroups,
packedNeighborGroups);
// Compute combined global mesh index arrays
IdArrayType combinedGlobalMeshIndex;
combinedGlobalMeshIndex.Allocate(combinedNeighborOffsets.GetNumberOfValues());
combinedGlobalMeshIndex.Allocate(numVerticesCombined);
{ // make sure arrays used for copy go out of scope
auto permutedCombinedGlobalMeshIndex =
vtkm::cont::make_ArrayHandlePermutation(thisToCombinedSortOrder, combinedGlobalMeshIndex);
@ -755,7 +799,7 @@ inline void ContourTreeMesh<FieldType>::MergeWith(ContourTreeMesh<FieldType>& ot
// Compute combined sorted values
vtkm::cont::ArrayHandle<FieldType> combinedSortedValues;
combinedSortedValues.Allocate(combinedNeighborOffsets.GetNumberOfValues());
combinedSortedValues.Allocate(numVerticesCombined);
{ // make sure arrays used for copy go out of scope
auto permutedCombinedSortedValues =
vtkm::cont::make_ArrayHandlePermutation(thisToCombinedSortOrder, combinedSortedValues);
@ -775,7 +819,7 @@ inline void ContourTreeMesh<FieldType>::MergeWith(ContourTreeMesh<FieldType>& ot
this->SortedValues = combinedSortedValues;
this->GlobalMeshIndex = combinedGlobalMeshIndex;
this->NeighborConnectivity = packedCombinedNeighborConnectivity;
this->NeighborOffsets = combinedNeighborOffsets;
this->NeighborOffsets = packedCombinedNeighborOffsets;
this->NumVertices = SortedValues.GetNumberOfValues();
this->SortIndices = vtkm::cont::ArrayHandleIndex(this->NumVertices);
this->SortOrder = vtkm::cont::ArrayHandleIndex(this->NumVertices);
@ -914,4 +958,6 @@ inline void ContourTreeMesh<FieldType>::GetBoundaryVertices(
} // worklet
} // vtkm
#undef DEBUG_PRINT
#endif

@ -0,0 +1,94 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
// Copyright (c) 2018, The Regents of the University of California, through
// Lawrence Berkeley National Laboratory (subject to receipt of any required approvals
// from the U.S. Dept. of Energy). All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// (1) Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// (2) Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// (3) Neither the name of the University of California, Lawrence Berkeley National
// Laboratory, U.S. Dept. of Energy nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//
//=============================================================================
//
// This code is an extension of the algorithm presented in the paper:
// Parallel Peak Pruning for Scalable SMP Contour Tree Computation.
// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
// (LDAV), October 2016, Baltimore, Maryland.
//
// The PPP2 algorithm and software were jointly developed by
// Hamish Carr (University of Leeds), Gunther H. Weber (LBNL), and
// Oliver Ruebel (LBNL)
//==============================================================================
#ifndef vtk_m_worklet_contourtree_augmented_contourtree_mesh_inc_add_to_array_elements_worklet_h
#define vtk_m_worklet_contourtree_augmented_contourtree_mesh_inc_add_to_array_elements_worklet_h
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_augmented
{
namespace mesh_dem_contourtree_mesh_inc
{
struct AddToArrayElementsWorklet : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldInOut, FieldIn);
VTKM_EXEC void operator()(vtkm::Id& arrayValue, const vtkm::IdComponent& addedValue) const
{
arrayValue += addedValue;
}
}; // AddToArrayElementsWorklet
} // namespace mesh_dem_contourtree_mesh_inc
} // namespace contourtree_augmented
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,105 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
// Copyright (c) 2018, The Regents of the University of California, through
// Lawrence Berkeley National Laboratory (subject to receipt of any required approvals
// from the U.S. Dept. of Energy). All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// (1) Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// (2) Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// (3) Neither the name of the University of California, Lawrence Berkeley National
// Laboratory, U.S. Dept. of Energy nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//
//=============================================================================
//
// This code is an extension of the algorithm presented in the paper:
// Parallel Peak Pruning for Scalable SMP Contour Tree Computation.
// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
// (LDAV), October 2016, Baltimore, Maryland.
//
// The PPP2 algorithm and software were jointly developed by
// Hamish Carr (University of Leeds), Gunther H. Weber (LBNL), and
// Oliver Ruebel (LBNL)
//==============================================================================
#ifndef vtk_m_worklet_contourtree_augmented_contourtree_mesh_inc_apply_lookup_table_decorator_h
#define vtk_m_worklet_contourtree_augmented_contourtree_mesh_inc_apply_lookup_table_decorator_h
namespace vtkm
{
namespace worklet
{
namespace contourtree_augmented
{
namespace mesh_dem_contourtree_mesh_inc
{
class ApplyLookupTableDecoratorImpl
{
public:
template <typename ArrayPortalType, typename LookupTablePortalType>
struct Functor
{
ArrayPortalType ArrayPortal;
LookupTablePortalType LookupTablePortal;
VTKM_EXEC_CONT
typename LookupTablePortalType::ValueType operator()(vtkm::Id i) const
{
vtkm::Id val = ArrayPortal.Get(i);
VTKM_ASSERT(val >= 0 && val < LookupTablePortal.GetNumberOfValues());
return LookupTablePortal.Get(val);
}
};
template <typename PT1, typename PT2>
Functor<PT1, PT2> CreateFunctor(PT1 array, PT2 lookupTable) const
{
return { array, lookupTable };
}
};
} // namespace mesh_dem_contourtree_mesh_inc
} // namespace contourtree_augmented
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,104 @@
/= == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == == ==
== == == == ==
=
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
// Copyright (c) 2018, The Regents of the University of California, through
// Lawrence Berkeley National Laboratory (subject to receipt of any required approvals
// from the U.S. Dept. of Energy). All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// (1) Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// (2) Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// (3) Neither the name of the University of California, Lawrence Berkeley National
// Laboratory, U.S. Dept. of Energy nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//
//=============================================================================
//
// This code is an extension of the algorithm presented in the paper:
// Parallel Peak Pruning for Scalable SMP Contour Tree Computation.
// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
// (LDAV), October 2016, Baltimore, Maryland.
//
// The PPP2 algorithm and software were jointly developed by
// Hamish Carr (University of Leeds), Gunther H. Weber (LBNL), and
// Oliver Ruebel (LBNL)
//==============================================================================
#ifndef vtk_m_worklet_contourtree_augmented_contourtree_mesh_inc_copy_into_combined_neighbors_worklet_h
#define vtk_m_worklet_contourtree_augmented_contourtree_mesh_inc_copy_into_combined_neighbors_worklet_h
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_augmented
{
namespace mesh_dem_contourtree_mesh_inc
{
struct CopyIntoCombinedNeighborsWorklet : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldInOut, FieldOut);
template <typename InGroupType, typename OutGroupType>
VTKM_EXEC void operator()(const InGroupType& newNeighbors,
OutGroupType& combinedNeighbors,
vtkm::IdComponent& actualGroupSize) const
{
actualGroupSize = newNeighbors.GetNumberOfComponents();
std::cout << actualGroupSize << " " << combinedNeighbors.GetNumberOfComponents() << std::endl;
VTKM_ASSERT(actualGroupSize <= combinedNeighbors.GetNumberOfComponents());
for (vtkm::IdComponent index = 0; index < actualGroupSize; ++index)
{
combinedNeighbors[index] = newNeighbors[index];
}
}
}; // CopyIntoCombinedNeighborsWorklet
} // namespace mesh_dem_contourtree_mesh_inc
} // namespace contourtree_augmented
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,104 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
// Copyright (c) 2018, The Regents of the University of California, through
// Lawrence Berkeley National Laboratory (subject to receipt of any required approvals
// from the U.S. Dept. of Energy). All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// (1) Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// (2) Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// (3) Neither the name of the University of California, Lawrence Berkeley National
// Laboratory, U.S. Dept. of Energy nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//
//=============================================================================
//
// This code is an extension of the algorithm presented in the paper:
// Parallel Peak Pruning for Scalable SMP Contour Tree Computation.
// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
// (LDAV), October 2016, Baltimore, Maryland.
//
// The PPP2 algorithm and software were jointly developed by
// Hamish Carr (University of Leeds), Gunther H. Weber (LBNL), and
// Oliver Ruebel (LBNL)
//==============================================================================
#ifndef vtk_m_worklet_contourtree_augmented_contourtree_mesh_inc_get_arc_from_functor_h
#define vtk_m_worklet_contourtree_augmented_contourtree_mesh_inc_get_arc_from_functor_h
namespace vtkm
{
namespace worklet
{
namespace contourtree_augmented
{
namespace mesh_dem_contourtree_mesh_inc
{
class GetArcFromDecoratorImpl
{
public:
template <typename Portal1Type, typename Portal2Type>
struct Functor
{
Portal1Type NeighborConnectivityPortal;
Portal2Type ArcsPortal;
VTKM_EXEC_CONT
vtkm::Id operator()(vtkm::Id arcNo) const
{
vtkm::Id arc = NeighborConnectivityPortal.Get(arcNo);
return (arc % 2 == 0) ? arc / 2 : MaskedIndex(ArcsPortal.Get(arc / 2));
}
};
template <typename PT1, typename PT2>
Functor<PT1, PT2> CreateFunctor(PT1 neighborConnectivityPortal, PT2 arcsPortal) const
{
return { neighborConnectivityPortal, arcsPortal };
}
};
} // namespace mesh_dem_contourtree_mesh_inc
} // namespace contourtree_augmented
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,146 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
// Copyright (c) 2018, The Regents of the University of California, through
// Lawrence Berkeley National Laboratory (subject to receipt of any required approvals
// from the U.S. Dept. of Energy). All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// (1) Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// (2) Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// (3) Neither the name of the University of California, Lawrence Berkeley National
// Laboratory, U.S. Dept. of Energy nor the names of its contributors may be
// used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
// OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
//
//=============================================================================
//
// This code is an extension of the algorithm presented in the paper:
// Parallel Peak Pruning for Scalable SMP Contour Tree Computation.
// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
// (LDAV), October 2016, Baltimore, Maryland.
//
// The PPP2 algorithm and software were jointly developed by
// Hamish Carr (University of Leeds), Gunther H. Weber (LBNL), and
// Oliver Ruebel (LBNL)
//==============================================================================
#ifndef vtk_m_worklet_contourtree_augmented_contourtree_mesh_inc_add_to_array_elements__worklet_worklet_h
#define vtk_m_worklet_contourtree_augmented_contourtree_mesh_inc_add_to_array_elements__worklet_worklet_h
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_augmented
{
namespace mesh_dem_contourtree_mesh_inc
{
struct MergeIntoCombinedNeighborsWorklet : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn, FieldInOut, FieldInOut);
template <typename InGroupType, typename InOutGroupType>
VTKM_EXEC void operator()(const InGroupType& newNeighbors,
InOutGroupType& combinedNeighbors,
vtkm::IdComponent& actualGroupSize) const
{
VTKM_ASSERT(actualGroupSize + newNeighbors.GetNumberOfComponents() <=
combinedNeighbors.GetNumberOfComponents());
if (actualGroupSize == 0)
{
// Most common case, no neighbor list present, yet -> just copy
actualGroupSize = newNeighbors.GetNumberOfComponents();
for (vtkm::IdComponent index = 0; index < actualGroupSize; ++index)
{
combinedNeighbors[index] = newNeighbors[index];
}
}
else
{
// Shared vertex -> Need to merge lists
// TODO/FIXME: Better way to merge two sorted lists?
vtkm::IdComponent numToInsert = newNeighbors.GetNumberOfComponents();
for (vtkm::IdComponent idxToInsert = 0; idxToInsert < numToInsert; ++idxToInsert)
{
std::cout << "actualGroupSize = " << actualGroupSize;
std::cout << " inserting " << newNeighbors[idxToInsert] << std::endl;
vtkm::IdComponent insertPos = 0;
std::cout << insertPos << " " << (insertPos < actualGroupSize) << " "
<< (combinedNeighbors[insertPos] < newNeighbors[idxToInsert]) << std::endl;
while (insertPos < actualGroupSize &&
combinedNeighbors[insertPos] < newNeighbors[idxToInsert])
{
std::cout << insertPos << " " << (insertPos < actualGroupSize) << " "
<< (combinedNeighbors[insertPos] < newNeighbors[idxToInsert]) << std::endl;
++insertPos;
}
std::cout << "Insert pos is " << insertPos << std::endl;
if ((insertPos >= actualGroupSize) ||
combinedNeighbors[insertPos] != newNeighbors[idxToInsert])
{
// Only insert non-duplicate elements
// Shift elements one back
for (vtkm::IdComponent idx = actualGroupSize - 1; idx >= insertPos; --idx)
{
std::cout << "Shifting " << combinedNeighbors[idx] << " from " << idx << " to "
<< idx + 1 << std::endl;
combinedNeighbors[idx + 1] = combinedNeighbors[idx];
}
std::cout << "Saving " << newNeighbors[idxToInsert] << " to pos " << insertPos
<< std::endl;
combinedNeighbors[insertPos] = newNeighbors[idxToInsert];
actualGroupSize += 1;
}
}
}
}
}; // MergeIntoCombinedNeighborsWorklet
} // namespace mesh_dem_contourtree_mesh_inc
} // namespace contourtree_augmented
} // namespace worklet
} // namespace vtkm
#endif

@ -108,13 +108,19 @@ struct MergeNeighborGroups : public vtkm::worklet::WorkletMapField
++secondI;
++mergedSize;
}
else // group[firstI] < group[secondI]
{
// Next insertion from second group. Do this by saving the item in the
else
{ // group[secondI] < group[firstI]
// Next insertion from second group. Do this by saving the item from the
// first group in the second group.
//vtkm::Swap(group[firstI], group[secondI]); // (might not work with GroupType)
//
// Insert at correct location in secind group
// Save element from first group
vtkm::Id tmp = group[firstI];
// Move element from second group into correct position
group[firstI] = group[secondI];
vtkm::IdComponent insertPos = secondI;
while (group[insertPos]
group[secondI] = tmp;
++firstI;

@ -53,6 +53,8 @@
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#define DEBUG_PRINT
#include <vtkm/worklet/contourtree_augmented/meshtypes/ContourTreeMesh.h>
namespace