diff --git a/data/baseline/5x6_7_MC_Rank0_Block0_Round1_CombinedMesh.ctm b/data/baseline/5x6_7_MC_Rank0_Block0_Round1_CombinedMesh.ctm index 650f7a3ac..143be4cd8 100644 --- a/data/baseline/5x6_7_MC_Rank0_Block0_Round1_CombinedMesh.ctm +++ b/data/baseline/5x6_7_MC_Rank0_Block0_Round1_CombinedMesh.ctm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5706bddc644b5b120ffbd424b3073ce989735272726de711ca8dac19b4a30ee1 -size 2653 +oid sha256:aa4623c6a5f1051038cfdafb9167a1e2625091063e5ee8c1247af45539189eea +size 2657 diff --git a/data/data/misc/5x6_7_MC_Rank0_Block0_Round1_BeforeCombineMesh1.ctm b/data/data/misc/5x6_7_MC_Rank0_Block0_Round1_BeforeCombineMesh1.ctm index bef96d092..29df1903a 100644 --- a/data/data/misc/5x6_7_MC_Rank0_Block0_Round1_BeforeCombineMesh1.ctm +++ b/data/data/misc/5x6_7_MC_Rank0_Block0_Round1_BeforeCombineMesh1.ctm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea0a0903fce2b7b42023ca0a2bdc008781a61fa74f75b2b107e6d0788c404551 -size 1441 +oid sha256:ef15b2a0e8ae45c80c1e55cc8aadb0bbd725d39cf2fb091c2b3dde9d601e3930 +size 1445 diff --git a/data/data/misc/5x6_7_MC_Rank0_Block0_Round1_BeforeCombineMesh2.ctm b/data/data/misc/5x6_7_MC_Rank0_Block0_Round1_BeforeCombineMesh2.ctm index ad8171b40..d0c215acd 100644 --- a/data/data/misc/5x6_7_MC_Rank0_Block0_Round1_BeforeCombineMesh2.ctm +++ b/data/data/misc/5x6_7_MC_Rank0_Block0_Round1_BeforeCombineMesh2.ctm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:58aed19216ce91b6c9bc7c0d8ee31c1062405ad6f5a4a977b49f213e2ce81307 -size 1518 +oid sha256:4ec4d071805a7300bf61aa2c017fe5c9892ad10df7495ef40c69799d58c84db8 +size 1522 diff --git a/vtkm/worklet/contourtree_augmented/PrintVectors.h b/vtkm/worklet/contourtree_augmented/PrintVectors.h index cc25d5d48..2a1d49b53 100644 --- a/vtkm/worklet/contourtree_augmented/PrintVectors.h +++ b/vtkm/worklet/contourtree_augmented/PrintVectors.h @@ -85,10 +85,16 @@ void PrintValues(std::string label, const vtkm::cont::ArrayHandle& dVec, vtkm::Id nValues = -1, std::ostream& outStream = std::cout); +template void PrintIndices(std::string label, - const vtkm::cont::ArrayHandle& iVec, + const vtkm::cont::ArrayHandle& iVec, vtkm::Id nIndices = -1, std::ostream& outStream = std::cout); +template +void PrintArray(std::string label, + const T& iVec, + vtkm::Id nIndices = -1, + std::ostream& outStream = std::cout); template void PrintSortedValues(std::string label, const vtkm::cont::ArrayHandle& dVec, @@ -213,8 +219,9 @@ inline void PrintSortedValues(std::string label, // routine for printing index arrays +template inline void PrintIndices(std::string label, - const vtkm::cont::ArrayHandle& iVec, + const vtkm::cont::ArrayHandle& 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 +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 inline void PrintLabelledDataBlock(std::string label, diff --git a/vtkm/worklet/contourtree_augmented/meshtypes/ContourTreeMesh.h b/vtkm/worklet/contourtree_augmented/meshtypes/ContourTreeMesh.h index d069b5c92..e4292ffdb 100644 --- a/vtkm/worklet/contourtree_augmented/meshtypes/ContourTreeMesh.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/ContourTreeMesh.h @@ -80,18 +80,21 @@ #include #include // This is needed only as an unused default argument. #include +#include +#include #include #include #include #include #include #include +#include #include #include #include #include #include -#include +#include #include #include #include @@ -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::ComputeMaxNeighbors() auto neighborCounts = make_ArrayHandleOffsetsToNumComponents(this->NeighborOffsets); vtkm::cont::ArrayHandle rangeArray = vtkm::cont::ArrayRangeCompute(neighborCounts); this->MaxNeighbors = static_cast(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 +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 inline void ContourTreeMesh::MergeWith(ContourTreeMesh& other, @@ -620,9 +641,9 @@ inline void ContourTreeMesh::MergeWith(ContourTreeMesh& 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::MergeWith(ContourTreeMesh& 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(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 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 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 packedOffsets; + vtkm::cont::ArrayHandle 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 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::MergeWith(ContourTreeMesh& ot // Compute combined sorted values vtkm::cont::ArrayHandle 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::MergeWith(ContourTreeMesh& 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::GetBoundaryVertices( } // worklet } // vtkm +#undef DEBUG_PRINT + #endif diff --git a/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/AddToArrayElementsWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/AddToArrayElementsWorklet.h new file mode 100644 index 000000000..d7421c618 --- /dev/null +++ b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/AddToArrayElementsWorklet.h @@ -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 +#include + +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 diff --git a/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ApplyLookupTableDecorator.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ApplyLookupTableDecorator.h new file mode 100644 index 000000000..2edd093e6 --- /dev/null +++ b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/ApplyLookupTableDecorator.h @@ -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 + 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 + Functor CreateFunctor(PT1 array, PT2 lookupTable) const + { + return { array, lookupTable }; + } +}; + +} // namespace mesh_dem_contourtree_mesh_inc +} // namespace contourtree_augmented +} // namespace worklet +} // namespace vtkm + +#endif diff --git a/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CopyIntoCombinedNeighborsWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CopyIntoCombinedNeighborsWorklet.h new file mode 100644 index 000000000..c396102dd --- /dev/null +++ b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/CopyIntoCombinedNeighborsWorklet.h @@ -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 +#include + + 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 + 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 diff --git a/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/GetArcFromDecorator.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/GetArcFromDecorator.h new file mode 100644 index 000000000..93099172c --- /dev/null +++ b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/GetArcFromDecorator.h @@ -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 + 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 + Functor CreateFunctor(PT1 neighborConnectivityPortal, PT2 arcsPortal) const + { + return { neighborConnectivityPortal, arcsPortal }; + } +}; + +} // namespace mesh_dem_contourtree_mesh_inc +} // namespace contourtree_augmented +} // namespace worklet +} // namespace vtkm + +#endif diff --git a/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeIntoCombinedNeighborsWorklet.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeIntoCombinedNeighborsWorklet.h new file mode 100644 index 000000000..c7e782b24 --- /dev/null +++ b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeIntoCombinedNeighborsWorklet.h @@ -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 +#include + +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 + 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 diff --git a/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeNeighborGroups.h b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeNeighborGroups.h index df19167bd..af888848d 100644 --- a/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeNeighborGroups.h +++ b/vtkm/worklet/contourtree_augmented/meshtypes/contourtreemesh/MergeNeighborGroups.h @@ -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; diff --git a/vtkm/worklet/testing/UnitTestContourTreeUniformDistributed.cxx b/vtkm/worklet/testing/UnitTestContourTreeUniformDistributed.cxx index 061177dc3..0cbe9b315 100644 --- a/vtkm/worklet/testing/UnitTestContourTreeUniformDistributed.cxx +++ b/vtkm/worklet/testing/UnitTestContourTreeUniformDistributed.cxx @@ -53,6 +53,8 @@ #include #include +#define DEBUG_PRINT + #include namespace