Port/implement HierarchicalAugmenter

This commit is contained in:
Oliver Ruebel 2021-03-21 01:46:01 -07:00 committed by Gunther H. Weber
parent a69f83f3a5
commit 9dbccaae1d
19 changed files with 3683 additions and 0 deletions

@ -75,6 +75,7 @@
#include <vtkm/worklet/contourtree_distributed/TreeGrafter.h>
#include <vtkm/worklet/contourtree_distributed/HierarchicalAugmenter.h>
#include <vtkm/worklet/contourtree_distributed/HierarchicalHyperSweeper.h>
// DIY includes

@ -16,6 +16,7 @@ set(headers
DistributedContourTreeBlockData.h
HierarchicalContourTree.h
HierarchicalHyperSweeper.h
HierarchicalAugmenter.h
InteriorForest.h
MergeBlockFunctor.h
MultiBlockContourTreeHelper.h
@ -31,3 +32,4 @@ add_subdirectory(boundary_tree_maker)
add_subdirectory(tree_grafter)
add_subdirectory(hierarchical_contour_tree)
add_subdirectory(hierarchical_hyper_sweeper)
add_subdirectory(hierarchical_augmenter)

File diff suppressed because it is too large Load Diff

@ -683,6 +683,7 @@ std::string HierarchicalHyperSweeper<MeshType, FieldType>::DebugPrint(std::strin
"Sorted Transfer", this->SortedTransferTarget - 1, resultStream);
vtkm::worklet::contourtree_augmented::PrintIndices(
"Sort Permute", this->SuperSortPermute - 1, resultStream);
return resultStream.str();
} // DebugPrint()

@ -0,0 +1,202 @@
//============================================================================
// 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 (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.
//
//=============================================================================
//
// COMMENTS:
//
// A comparator that sorts supernode pairs by:
// 1. the superparent (ie the superarc into which an attachment point inserts)
// note that this implicitly sorts on round of insertion as well
// 2. data value
// 3. global regular ID
//
// The superparent is assumed to have a flag indicating ascending/descending, and this
// needs to be used to get the correct inwards ordering along each superarc
//
//=======================================================================================
#ifndef vtk_m_worklet_contourtree_distributed_hierarchical_hyper_augmenter_attachment_and_supernode_comparator_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_hyper_augmenter_attachment_and_supernode_comparator_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ExecutionObjectBase.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Compartor implementation used in HierarchicalAugmenter<FieldType>::ResizeArrays to sort this->SupernodeSorter
/// A comparator that sorts supernode pairs by:
/// 1. the superparent (ie the superarc into which an attachment point inserts)
/// note that this implicitly sorts on round of insertion as well
/// 2. data value
/// 3. global regular ID
///
/// The superparent is assumed to have a flag indicating ascending/descending, and this
/// needs to be used to get the correct inwards ordering along each superarc
template <typename FieldArrayType>
class AttachmentAndSupernodeComparatorImpl
{
public:
using IdArrayPortalType =
typename vtkm::worklet::contourtree_augmented::IdArrayType::ReadPortalType;
using FieldArrayPortalType = typename FieldArrayType::ReadPortalType;
// constructor
VTKM_CONT
AttachmentAndSupernodeComparatorImpl(IdArrayPortalType superparentSetPortal,
IdArrayPortalType dataValueSetPortal,
IdArrayPortalType globalRegularIdSetPortal)
: SuperparentSetPortal(superparentSetPortal)
, DataValueSetPortal(dataValueSetPortal)
, GlobalRegularIdSetPortal(globalRegularIdSetPortal)
{ // constructor
} // constructor
// () operator - gets called to do comparison
VTKM_EXEC
bool operator()(const vtkm::Id& left, const vtkm::Id& right) const
{ // operator()
// first comparison is on superparent WITHOUT ascending descending flag
if (vtkm::worklet::contourtree_augmented::MaskedIndex(this->SuperparentSetPortal.Get(left)) <
vtkm::worklet::contourtree_augmented::MaskedIndex(this->SuperparentSetPortal.Get(right)))
{
return true;
}
if (vtkm::worklet::contourtree_augmented::MaskedIndex(this->SuperparentSetPortal.Get(left)) >
vtkm::worklet::contourtree_augmented::MaskedIndex(this->SuperparentSetPortal.Get(right)))
{
return false;
}
// second comparison is on data value
if (this->DataValueSetPortal.Get(left) < this->DataValueSetPortal.Get(right))
{
return vtkm::worklet::contourtree_augmented::IsAscending(
this->SuperparentSetPortal.Get(left));
}
if (this->DataValueSetPortal.Get(left) > this->DataValueSetPortal.Get(right))
{
return !vtkm::worklet::contourtree_augmented::IsAscending(
this->SuperparentSetPortal.Get(left));
}
// third comparison is on global regular ID
if (this->GlobalRegularIdSetPortal.Get(left) < this->GlobalRegularIdSetPortal.Get(right))
{
return vtkm::worklet::contourtree_augmented::IsAscending(
this->SuperparentSetPortal.Get(left));
}
if (this->GlobalRegularIdSetPortal.Get(left) > this->GlobalRegularIdSetPortal.Get(right))
{
return !vtkm::worklet::contourtree_augmented::IsAscending(
this->SuperparentSetPortal.Get(left));
}
// fall-through (should never happen)
return false;
} // operator()
private:
IdArrayPortalType SuperparentSetPortal;
FieldArrayPortalType DataValueSetPortal;
IdArrayPortalType GlobalRegularIdSetPortal;
}; // AttachmentAndSupernodeComparatorImpl
/// Execution object for Compartor used in HierarchicalAugmenter<FieldType>::ResizeArrays to sort this->SupernodeSorter
/// A comparator that sorts supernode pairs by:
/// 1. the superparent (ie the superarc into which an attachment point inserts)
/// note that this implicitly sorts on round of insertion as well
/// 2. data value
/// 3. global regular ID
///
/// The superparent is assumed to have a flag indicating ascending/descending, and this
/// needs to be used to get the correct inwards ordering along each superarc
template <typename FieldArrayType>
class AttachmentAndSupernodeComparator : public vtkm::cont::ExecutionObjectBase
{
public:
// constructor - takes vectors as parameters
VTKM_CONT
AttachmentAndSupernodeComparator(
const vtkm::worklet::contourtree_augmented::IdArrayType superparentSet,
const vtkm::worklet::contourtree_augmented::IdArrayType dataValueSet,
const vtkm::worklet::contourtree_augmented::IdArrayType globalRegularIdSet)
: SuperparentSet(superparentSet)
, DataValueSet(dataValueSet)
, GlobalRegularIdSet(globalRegularIdSet)
{ // constructor
} // constructor
/// Create a AttachmentAndSupernodeComparatorImpl object for use in the sort or worklet
VTKM_CONT AttachmentAndSupernodeComparatorImpl<FieldArrayType> PrepareForExecution(
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
return AttachmentAndSupernodeComparatorImpl<FieldArrayType>(
this->SuperparentSet.PrepareForInput(device, token),
this->DataValueSet.PrepareForInput(device, token),
this->GlobalRegularIdSet.PrepareForInput(device, token));
}
private:
/// the superparent Id
vtkm::worklet::contourtree_augmented::IdArrayType SuperparentSet;
/// the global rergular Id for tiebreak
FieldArrayType DataValueSet;
/// the supernode Id for tiebreak
vtkm::worklet::contourtree_augmented::IdArrayType GlobalRegularIdSet;
}; // AttachmentAndSupernodeComparator
} // namespace hierarchical_augmenter
} // namespace contourtree_distributed
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,187 @@
//============================================================================
// 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 (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.
//
//=============================================================================
//
// COMMENTS:
//
// A comparator that sorts supernode pairs by:
// 1. the superparent round
// 2. global regular Id
// 3. supernode Id (if any)
//
// We don't care about the orientation of the superarc for this comparator
//
// For duplicates, we assume that at MOST one (in fact, it should always be EXACTLY one)
// copy has a supernode Id set. This is because when we exchange between blocks, we set
// the supernode Id to NO_SUCH_ELEMENT. That way, only the copy that belongs on the block
// has the supernode Id set. We want to ensure that it appears at the beginning of the segment,
// and don't care about the ordering of any others.
//
//=======================================================================================
#ifndef vtk_m_worklet_contourtree_distributed_hierarchical_hyper_augmenter_attachment_superparent_and_index_comparator_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_hyper_augmenter_attachment_superparent_and_index_comparator_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ExecutionObjectBase.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Implementation for a comparator that sorts supernode pairs by:
/// 1. the superparent round
/// 2. global regular Id
/// 3. supernode Id (if any)
class AttachmentSuperparentAndIndexComparatorImpl
{
public:
using IdArrayPortalType =
typename vtkm::worklet::contourtree_augmented::IdArrayType::ReadPortalType;
// constructor
VTKM_CONT
AttachmentSuperparentAndIndexComparatorImpl(IdArrayPortalType superparentsPortal,
IdArrayPortalType globalRegularIdsPortal,
IdArrayPortalType supernodeIdsPortal)
: SuperparentsPortal(superparentsPortal)
, GlobalRegularIdsPortal(globalRegularIdsPortal)
, SupernodeIdsPortal(supernodeIdsPortal)
{ // constructor
} // constructor
// () operator - gets called to do comparison
VTKM_EXEC
bool operator()(const vtkm::Id& left, const vtkm::Id& right) const
{ // operator()
// first comparison is on superparent WITHOUT ascending descending flag
if (vtkm::worklet::contourtree_augmented::MaskedIndex(this->SuperparentsPortal.Get(left)) <
vtkm::worklet::contourtree_augmented::MaskedIndex(this->SuperparentsPortal.Get(right)))
{
return true;
}
if (vtkm::worklet::contourtree_augmented::MaskedIndex(this->SuperparentsPortal.Get(left)) >
vtkm::worklet::contourtree_augmented::MaskedIndex(this->SuperparentsPortal.Get(right)))
{
return false;
}
// second comparison is on global regular Id
if (this->GlobalRegularIdsPortal.Get(left) < this->GlobalRegularIdsPortal.Get(right))
{
return vtkm::worklet::contourtree_augmented::IsAscending(this->SuperparentsPortal.Get(left));
}
if (this->GlobalRegularIdsPortal.Get(left) > this->GlobalRegularIdsPortal.Get(right))
{
return !vtkm::worklet::contourtree_augmented::IsAscending(this->SuperparentsPortal.Get(left));
}
// third comparison is on supernode Ids
if (!vtkm::worklet::contourtree_augmented::NoSuchElement(this->SupernodeIdsPortal.Get(left)))
{
return true;
}
else if (!vtkm::worklet::contourtree_augmented::NoSuchElement(
this->SupernodeIdsPortal.Get(right)))
{
return false;
}
// in this case, both were NSE, so sort on the index values
return (left < right);
} // operator()
private:
IdArrayPortalType SuperparentsPortal;
IdArrayPortalType GlobalRegularIdsPortal;
IdArrayPortalType SupernodeIdsPortal;
}; // AttachmentSuperparentAndIndexComparatorImpl
/// Execution object for a comparator that sorts supernode pairs by:
/// 1. the superparent round
/// 2. global regular Id
/// 3. supernode Id (if any)
class AttachmentSuperparentAndIndexComparator : public vtkm::cont::ExecutionObjectBase
{
public:
// constructor - takes vectors as parameters
VTKM_CONT
AttachmentSuperparentAndIndexComparator(
const vtkm::worklet::contourtree_augmented::IdArrayType superparents,
const vtkm::worklet::contourtree_augmented::IdArrayType globalRegularIds,
const vtkm::worklet::contourtree_augmented::IdArrayType supernodeIds)
: Superparents(superparents)
, GlobalRegularIds(globalRegularIds)
, SupernodeIds(supernodeIds)
{ // constructor
} // constructor
/// Create a AttachmentSuperparentAndIndexComparatorImpl object for use in the sort or worklet
VTKM_CONT AttachmentSuperparentAndIndexComparatorImpl
PrepareForExecution(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) const
{
return AttachmentSuperparentAndIndexComparatorImpl(
this->Superparents.PrepareForInput(device, token),
this->GlobalRegularIds.PrepareForInput(device, token),
this->SupernodeIds.PrepareForInput(device, token));
}
private:
/// the superparent Id
vtkm::worklet::contourtree_augmented::IdArrayType Superparents;
/// the global rergular Id for tiebreak
vtkm::worklet::contourtree_augmented::IdArrayType GlobalRegularIds;
/// the supernode Id for tiebreak
vtkm::worklet::contourtree_augmented::IdArrayType SupernodeIds;
}; // AttachmentSuperparentAndIndexComparator
} // namespace hierarchical_augmenter
} // namespace contourtree_distributed
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,28 @@
##============================================================================
## 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.
##============================================================================
set(headers
IsAttachementPointPredicate.h
IsAscendingDecorator.h
IsAttachementPointNeededPredicate.h
AttachmentSuperparentAndIndexComparator.h
SetFirstAttachmentPointInRoundWorklet.h
UpdateHyperstructureSetHyperarcsAndNodesWorklet.h
UpdateHyperstructureSetSuperchildrenWorklet.h
FindSuperparentForNecessaryNodesWorklet.h
CopyBaseRegularStructureWorklet.h
NotNoSuchElementPredicate.h
SetSuperparentSetDecorator.h
AttachmentAndSupernodeComparator.h
ResizeArraysBuildNewSupernodeIdsWorklet.h
CreateSuperarcsWorklet.h
)
vtkm_declare_headers(${headers})

@ -0,0 +1,166 @@
//============================================================================
// 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 (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.
//
//=============================================================================
// 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_distributed_hierarchical_augmenter_copy_base_regular_structure_worklet_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_copy_base_regular_structure_worklet_h
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Worklet used in HierarchicalAugmenter::CopyBaseRegularStructure for
/// finding the superparent for each node needed
class CopyBaseRegularStructureWorklet : public vtkm::worklet::WorkletMapField
{
public:
/// Control signature for the worklet
/// NOTE: We require the input arrays (aside form the input domain) to be permutted by the
/// regularNodesNeeded input domain so that we can use FieldIn instead of WholeArrayIn
/// NOTE: We require ArrayHandleView for the output arrays of the range [numExistingRegular:end] so
/// that we can use FieldOut instead of requiring WholeArrayInOut
using ControlSignature = void(
FieldIn
regularNodesNeededRange, // input domain ArrayHandleIndex of [0, regularNodesNeeded.GetNumberOfValues()]
FieldIn
baseTreeRegularNodeGlobalIdsPermuted, // input baseTree->regularNodeGlobalIds permuted by regularNodesNeeded
FieldIn baseTreeDataValuesPermuted, // input baseTree->dataValues permuted by regularNodesNeeded
FieldIn regularSuperparentsPermuted, // input regularSuperparents permuted by regularNodesNeeded
FieldOut
augmentedTreeRegularNodeGlobalIdsView, // output view of augmentedTree->regularNodeGlobalIds[numExistingRegular:]
FieldOut
augmentedTreeDataValuesView, // output view of augmentedTree->dataValues[numExistingRegular:]
FieldOut
augmentedTreeSuperparentsView, // output view of augmentedTree->superparents[numExistingRegular:]
FieldOut
augmentedTreeRegularNodeSortOrderView // output view of augmentedTree->regularNodeSortOrder[numExistingRegular:]
);
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6, _7, _8);
using InputDomain = _1;
/// Default Constructor
VTKM_EXEC_CONT
CopyBaseRegularStructureWorklet(const vtkm::Id& numExistingRegular)
: NumExistingRegular(numExistingRegular)
{
}
/// operator() of the workelt
template <typename FieldType>
VTKM_EXEC void operator()(
const vtkm::Id& neededRegNode, // InputIndex in [0, regularNodesNeeded.GetNumberOfValues()]
const vtkm::Id&
baseTreeRegularNodeGlobalId, // same as baseTree->regularNodeGlobalIds[oldRegularID]
const FieldType& baseTreeDataValue, // same as baseTree->dataValues[oldRegularID]
const vtkm::Id& regularSuperparentsValue, // same regularSuperparents[oldRegularID]
vtkm::Id&
augmentedTreeRegularNodeGlobalIdValue, // same as augmentedTree->regularNodeGlobalIDs[NumExistingRegular + neededRegNode] = ...
FieldType&
augmentedTreeDataValue, // same as augmentedTree->dataValues[NumExistingRegular + neededRegNode] = ...
vtkm::Id&
augmentedTreeSuperparentsValue, // same as augmentedTree->superparents[NumExistingRegular + neededRegNode] = ...
vtkm::Id&
augmentedTreeRegularNodeSortOrderValue // same as augmentedTree->regularNodeSortOrder [NumExistingRegular + neededRegNode] = ...
) const
{
// per regular node needing addition
// retrieve the existing index. oldRegularID is set on input
vtkm::Id newRegularId = this->NumExistingRegular +
neededRegNode; // not needed since we do ArrayHandleViews on the outside
// now use them to copy data
augmentedTreeRegularNodeGlobalIdValue = baseTreeRegularNodeGlobalId;
augmentedTreeDataValue = baseTreeDataValue;
augmentedTreeSuperparentsValue = regularSuperparentsValue;
// this one is special since we need to resort - set it to identity, leaving the sort order of old vertices alone
// this *MAY* make certain sorts run faster
augmentedTreeRegularNodeSortOrderValue = newRegularId;
// NOTE: we can skip this step since Regular2supernode is already initalized with NO_SUCH_ELEMENT
// since these are *ALL* only regular nodes, this one's easy:
// augmentedTree->regular2supernode [newRegularID] = NO_SUCH_ELEMENT;
// In serial this worklet implements the following operation
/*
for (vtkm::Id neededRegNode = 0; neededRegNode < nRegNeeded; neededRegNode++)
{ // per regular node needing addition
// retrieve the existing index
vtkm::Id oldRegularID = regularNodesNeeded[neededRegNode];
// and compute the new index
vtkm::Id newRegularID = nExistingRegular + neededRegNode;
// now use them to copy data
augmentedTree->regularNodeGlobalIDs [newRegularID] = baseTree->regularNodeGlobalIDs [oldRegularID];
augmentedTree->dataValues [newRegularID] = baseTree->dataValues [oldRegularID];
augmentedTree->superparents [newRegularID] = regularSuperparents [oldRegularID];
// this one is special since we need to resort - set it to identity, leaving the sort order of old vertices alone
// this *MAY* make certain sorts run faster
augmentedTree->regularNodeSortOrder [newRegularID] = newRegularID;
// since these are *ALL* only regular nodes, this one's easy:
augmentedTree->regular2supernode [newRegularID] = NO_SUCH_ELEMENT;
} // per regular node needing addition
*/
} // operator()()
private:
const vtkm::Id NumExistingRegular;
}; // CopyBaseRegularStructureWorklet
} // namespace hierarchical_augmenter
} // namespace contourtree_distributed
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,445 @@
//============================================================================
// 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 (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.
//
//=============================================================================
// 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_distributed_hierarchical_augmenter_create_superarcs_worklet_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_create_superarcs_worklet_h
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Worklet used to implement the main part of HierarchicalAugmenter::CreateSuperarcs
/// Connect superarcs for the level & set hyperparents & superchildren count, whichRound,
/// whichIteration, super2hypernode
class CreateSuperarcsWorklet : public vtkm::worklet::WorkletMapField
{
public:
// VTKm only defines 20 placeholders for the execution signature, but we need a few more here
using _21 = vtkm::placeholders::Arg<21>;
using _22 = vtkm::placeholders::Arg<22>;
using _23 = vtkm::placeholders::Arg<23>;
// TODO: This worklet could probably be optimized further to reduce the use of WholeArray passing
/// Control signature for the worklet
using ControlSignature = void(
WholeArrayIn supernodeSorter, // input domain (we need access to InputIndex and InputIndex+1)
WholeArrayIn superparentSet, // input
WholeArrayIn baseTreeSuperarcs, // input
WholeArrayIn newSupernodeIds, // input
WholeArrayIn
baseTreeHyperparents, // input TODO: could potentially be a FieldIn with some array shuffle magic
WholeArrayIn
baseTreeSupernodes, // input TODO: could potentially be a FieldIn with some array shuffle magic
WholeArrayIn
baseTreeRegularNodeGlobalIds, // input TODO: could potentially be a FieldIn with some array shuffle magic
WholeArrayIn
globalRegularIdSet, // input TODO: could potentially be a FieldIn with some array shuffle magic
WholeArrayIn baseTreeSuper2Hypernode, // input TODO: FieldIn possible with array shuffle?
WholeArrayIn baseTreeWhichRound, // input TODO: FieldIn possible with array shuffle?
WholeArrayIn baseTreeWhichIteration, // input TODO: FieldIn possible with array shuffle?
WholeArrayIn dataValueSet, // input TODO: FieldIn possible with array shuffle?
FieldOut
augmentedTreeSuperarcsView, // output view of ArrayHandleView(this->AugmentedTree->Superarcs[, this->NumSupernodesAlready, this->SupernodeSorter.GetNumberOfValues())
WholeArrayInOut augmentedTreeHyperparents, // input/output
WholeArrayInOut
augmentedTreeFirstSupernodePerIteration, // input/output augmentedTree->firstSupernodePerIteration[roundNumber]
WholeArrayInOut
augmentedTreeSupernodes, // input/output TODO: Could potentially change to FieldIn/FieldInOut when permutting the array
WholeArrayInOut
augmentedTreeSuper2hypernode, // input/ouput TODO: Is FieldOut possible with array shuffle?
WholeArrayInOut
augmentedTreeWhichRound, // input/ouput TODO: Is FieldOut possible with array shuffle?
WholeArrayInOut
augmentedTreeWhichIteration, // input/ouput TODO: Is FieldOut possible with array shuffle?
WholeArrayInOut
augmentedTreeRegularNodeGlobalIds, // input/ouput TODO: Is FieldOut possible with array shuffle?
WholeArrayInOut
augmentedTreeDataValues, // input/ouput TODO: Is FieldOut possible with array shuffle?
WholeArrayInOut
augmentedTreeRegular2Supernode, // input/ouput TODO: Is FieldOut possible with array shuffle?
WholeArrayInOut
augmentedTreeSuperparents // input/ouput TODO: Is FieldOut possible with array shuffle?
);
using ExecutionSignature = void(InputIndex,
_1,
_2,
_3,
_4,
_5,
_6,
_7,
_8,
_9,
_10,
_11,
_12,
_13,
_14,
_15,
_16,
_17,
_18,
_19,
_20,
_21,
_22,
_23);
using InputDomain = _1;
/// Default Constructor
VTKM_EXEC_CONT
CreateSuperarcsWorklet(
const vtkm::Id& numSupernodesAlready,
const vtkm::Id& baseTreeNumRounds,
const vtkm::Id&
augmentedTreeNumIterations, // set to vtkm::cont::ArrayGetValue(roundNumber, this->AugmentedTree->NumIterations)
const vtkm::Id& roundNumber)
: NumSupernodesAlready(numSupernodesAlready)
, BaseTreeNumRounds(baseTreeNumRounds)
, AugmentedTreeNumIterations(augmentedTreeNumIterations)
, RoundNumber(roundNumber)
{
}
/// operator() of the workelt
template <typename InFieldPortalType,
typename InFieldPortalType2,
typename InOutFieldPortalType,
typename InOutFieldPortalType2>
VTKM_EXEC void operator()(
const vtkm::Id& supernode, // InputIndex of supernodeSorter
const InFieldPortalType& supernodeSorterPortal,
const InFieldPortalType& superparentSetPortal,
const InFieldPortalType& baseTreeSuperarcsPortal,
const InFieldPortalType& newSupernodeIdsPortal,
const InFieldPortalType& baseTreeHyperparentsPortal,
const InFieldPortalType& baseTreeSupernodesPortal,
const InFieldPortalType& baseTreeRegularNodeGlobalIdsPortal,
const InFieldPortalType& globalRegularIdSetPortal,
const InFieldPortalType& baseTreeSuper2hypernodePortal,
const InFieldPortalType& baseTreeWhichRoundPortal,
const InFieldPortalType& baseTreeWhichIterationPortal,
const InFieldPortalType2& dataValueSetPortal,
vtkm::Id& augmentedTreeSuperarcsValue, // same as augmentedTree->superarcs[newSupernodeId]
const InOutFieldPortalType& augmentedTreeHyperparentsPortal,
const InOutFieldPortalType&
augmentedTreeFirstSupernodePerIterationPortal, // augmentedTree->firstSupernodePerIteration[roundNumber]
const InOutFieldPortalType& augmentedTreeSupernodesPortal,
const InOutFieldPortalType& augmentedTreeSuper2hypernodePortal,
const InOutFieldPortalType& augmentedTreeWhichRoundPortal,
const InOutFieldPortalType& augmentedTreeWhichIterationPortal,
const InOutFieldPortalType& augmentedTreeRegularNodeGlobalIdsPortal,
const InOutFieldPortalType2& augmentedTreeDataValuesPortal,
const InOutFieldPortalType& augmentedTreeRegular2SupernodePortal,
const InOutFieldPortalType& augmentedTreeSuperparentsPortal) const
{
// per supernode in the set
// retrieve the index from the sorting index array
vtkm::Id supernodeSetIndex = supernodeSorterPortal.Get(supernode);
// work out the new supernode Id
vtkm::Id newSupernodeId = this->NumSupernodesAlready + supernode;
// At all levels above 0, we used to keep regular vertices in case
// they are attachment points. After augmentation, we don't need to.
// Instead, at all levels above 0, the regular nodes in each round
// are identical to the supernodes. In order to avoid confusion,
// we will copy the Id into a separate variable
vtkm::Id newRegularId = newSupernodeId;
// setting the supernode's regular Id is now trivial
augmentedTreeSupernodesPortal.Set(newSupernodeId, newRegularId);
// retrieve the ascending flag from the superparent
vtkm::Id superparentSetVal = superparentSetPortal.Get(supernodeSetIndex);
bool superarcAscends = vtkm::worklet::contourtree_augmented::IsAscending(superparentSetVal);
// strip the ascending flag from the superparent
vtkm::Id superparentOldSuperId =
vtkm::worklet::contourtree_augmented::MaskedIndex(superparentSetVal);
// setting the superarc is done the usual way. Our sort routine has ended up
// with the supernodes arranged in either ascending or descending order
// inwards along the parent superarc (as expressed by the superparent Id).
// Each superarc except the last in the segment points to the next one:
// the last one points to the target of the original superarc.
// first test to see if we're the last in the array
if (supernode == supernodeSorterPortal.GetNumberOfValues() - 1)
{ // last in the array
// special case for root of entire tree at end of top level
if (RoundNumber == this->BaseTreeNumRounds)
{
augmentedTreeSuperarcsValue = vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
}
else
{ // not the tree root
// retrieve the target of the superarc from the base tree (masking to strip out the ascending flag)
vtkm::Id oldTargetSuperId = vtkm::worklet::contourtree_augmented::MaskedIndex(
baseTreeSuperarcsPortal.Get(superparentOldSuperId));
// convert to a new supernode Id
vtkm::Id newTargetSuperId = newSupernodeIdsPortal.Get(oldTargetSuperId);
// add the ascending flag back in and store in the array
augmentedTreeSuperarcsValue = newTargetSuperId |
(superarcAscends ? vtkm::worklet::contourtree_augmented::IS_ASCENDING : 0x00);
} // not the tree root
// since there's an extra entry in the firstSupernode array as a sentinel, set it
augmentedTreeFirstSupernodePerIterationPortal.Set(
this->AugmentedTreeNumIterations, augmentedTreeSupernodesPortal.GetNumberOfValues());
} // last in the array
else if (superparentOldSuperId !=
vtkm::worklet::contourtree_augmented::MaskedIndex(
superparentSetPortal.Get(supernodeSorterPortal.Get(supernode + 1))))
{ // last in the segment
// retrieve the target of the superarc from the base tree (masking to strip out the ascending flag)
vtkm::Id oldTargetSuperId = vtkm::worklet::contourtree_augmented::MaskedIndex(
baseTreeSuperarcsPortal.Get(superparentOldSuperId));
// convert to a new supernode Id
vtkm::Id newTargetSuperId = newSupernodeIdsPortal.Get(oldTargetSuperId);
// add the ascending flag back in and store in the array
augmentedTreeSuperarcsValue = newTargetSuperId |
(superarcAscends ? vtkm::worklet::contourtree_augmented::IS_ASCENDING : 0x00);
// since we're the last in the segment, we check to see if we are at the end of an iteration
vtkm::Id iterationNumber = vtkm::worklet::contourtree_augmented::MaskedIndex(
baseTreeWhichIterationPortal.Get(superparentOldSuperId));
vtkm::Id iterationNumberOfNext = vtkm::worklet::contourtree_augmented::MaskedIndex(
baseTreeWhichIterationPortal.Get(superparentOldSuperId + 1));
if (iterationNumber != iterationNumberOfNext)
{ // boundary of iterations
// If so, we set the "firstSupernodePerIteration" for the next
augmentedTreeFirstSupernodePerIterationPortal.Set(iterationNumberOfNext,
newSupernodeId + 1);
} // boundary of iterations
} // last in the segment
else
{ // not last in the segment
// the target is always the next one, so just store it with the ascending flag
augmentedTreeSuperarcsValue = (newSupernodeId + 1) |
(superarcAscends ? vtkm::worklet::contourtree_augmented::IS_ASCENDING : 0x00);
} // not last in the segment
// set the first supernode in the first iteration to the beginning of the round
augmentedTreeFirstSupernodePerIterationPortal.Set(0, this->NumSupernodesAlready);
// setting the hyperparent is straightforward since the hyperstructure is preserved
// we take the superparent (which is guaranteed to be in the baseTree), find it's hyperparent and use that
augmentedTreeHyperparentsPortal.Set(newSupernodeId,
baseTreeHyperparentsPortal.Get(superparentOldSuperId));
// similarly, the super2hypernode should carry over, but it's harder to test because of the attachment points which
// do not have valid old supernode Ids. Instead, we check their superparent's regular global Id against them: if it
// matches, then it must be the start of the superarc, in which case it does have an old Id, and we can then use the
// existing hypernode Id
vtkm::Id superparentOldRegularId = baseTreeSupernodesPortal.Get(superparentOldSuperId);
vtkm::Id superparentGlobalId = baseTreeRegularNodeGlobalIdsPortal.Get(superparentOldRegularId);
if (superparentGlobalId == globalRegularIdSetPortal.Get(supernodeSetIndex))
{
augmentedTreeSuper2hypernodePortal.Set(
newSupernodeId, baseTreeSuper2hypernodePortal.Get(superparentOldSuperId));
}
else
{
augmentedTreeSuper2hypernodePortal.Set(newSupernodeId,
vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT);
}
// which round and iteration carry over
augmentedTreeWhichRoundPortal.Set(newSupernodeId,
baseTreeWhichRoundPortal.Get(superparentOldSuperId));
augmentedTreeWhichIterationPortal.Set(newSupernodeId,
baseTreeWhichIterationPortal.Get(superparentOldSuperId));
// now we deal with the regular-sized arrays
// copy the global regular Id and data value
augmentedTreeRegularNodeGlobalIdsPortal.Set(newRegularId,
globalRegularIdSetPortal.Get(supernodeSetIndex));
augmentedTreeDataValuesPortal.Set(newRegularId, dataValueSetPortal.Get(supernodeSetIndex));
// the sort order will be dealt with later
// since all of these nodes are supernodes, they will be their own superparent, which means that:
// a. the regular2node can be set immediately
augmentedTreeRegular2SupernodePortal.Set(newRegularId, newSupernodeId);
// b. as can the superparent
augmentedTreeSuperparentsPortal.Set(newRegularId, newSupernodeId);
// In serial this worklet implements the following operation
/*
for (vtkm::Id supernode = 0; supernode < supernodeSorter.size(); supernode++)
{ // per supernode in the set
// retrieve the index from the sorting index array
vtkm::Id supernodeSetIndex = supernodeSorter[supernode];
// work out the new supernode ID
vtkm::Id newSupernodeID = numSupernodesAlready + supernode;
// At all levels above 0, we used to keep regular vertices in case they are attachment points. After augmentation, we don't need to.
// Instead, at all levels above 0, the regular nodes in each round are identical to the supernodes
// In order to avoid confusion, we will copy the ID into a separate variable
vtkm::Id newRegularID = newSupernodeID;
// setting the supernode's regular ID is now trivial
augmentedTree->supernodes [newSupernodeID] = newRegularID;
// retrieve the ascending flag from the superparent
bool superarcAscends = isAscending(superparentSet[supernodeSetIndex]);
// strip the ascending flag from the superparent
vtkm::Id superparentOldSuperID = maskedIndex(superparentSet[supernodeSetIndex]);
// setting the superarc is done the usual way. Our sort routine has ended up with the supernodes arranged in either ascending or descending order
// inwards along the parent superarc (as expressed by the superparent ID). Each superarc except the last in the segment points to the next one:
// the last one points to the target of the original superarc.
// first test to see if we're the last in the array
if (supernode == supernodeSorter.size() - 1)
{ // last in the array
// special case for root of entire tree at end of top level
if (roundNumber == baseTree->nRounds)
{
augmentedTree->superarcs[newSupernodeID] = NO_SUCH_ELEMENT;
}
else
{ // not the tree root
// retrieve the target of the superarc from the base tree (masking to strip out the ascending flag)
vtkm::Id oldTargetSuperID = maskedIndex(baseTree->superarcs[superparentOldSuperID]);
// convert to a new supernode ID
vtkm::Id newTargetSuperID = newSupernodeIDs[oldTargetSuperID];
// add the ascending flag back in and store in the array
augmentedTree->superarcs[newSupernodeID] = newTargetSuperID | (superarcAscends ? IS_ASCENDING : 0x00);
} // not the tree root
// since there's an extra entry in the firstSupernode array as a sentinel, set it
augmentedTree->firstSupernodePerIteration[roundNumber][augmentedTree->nIterations[roundNumber]] = augmentedTree->supernodes.size();
} // last in the array
else if (superparentOldSuperID != maskedIndex(superparentSet[supernodeSorter[supernode+1]]))
{ // last in the segment
// retrieve the target of the superarc from the base tree (masking to strip out the ascending flag)
vtkm::Id oldTargetSuperID = maskedIndex(baseTree->superarcs[superparentOldSuperID]);
// convert to a new supernode ID
vtkm::Id newTargetSuperID = newSupernodeIDs[oldTargetSuperID];
// add the ascending flag back in and store in the array
augmentedTree->superarcs[newSupernodeID] = newTargetSuperID | (superarcAscends ? IS_ASCENDING : 0x00);
// since we're the last in the segment, we check to see if we are at the end of an iteration
vtkm::Id iterationNumber = maskedIndex(baseTree->whichIteration[superparentOldSuperID]);
vtkm::Id iterationNumberOfNext = maskedIndex(baseTree->whichIteration[superparentOldSuperID + 1]);
if (iterationNumber != iterationNumberOfNext)
{ // boundary of iterations
// If so, we set the "firstSupernodePerIteration" for the next
augmentedTree->firstSupernodePerIteration[roundNumber][iterationNumberOfNext] = newSupernodeID + 1;
} // boundary of iterations
} // last in the segment
else
{ // not last in the segment
// the target is always the next one, so just store it with the ascending flag
augmentedTree->superarcs[newSupernodeID] = (newSupernodeID+1) | (superarcAscends ? IS_ASCENDING : 0x00);
} // not last in the segment
// set the first supernode in the first iteration to the beginning of the round
augmentedTree->firstSupernodePerIteration[roundNumber][0] = numSupernodesAlready;
// setting the hyperparent is straightforward since the hyperstructure is preserved
// we take the superparent (which is guaranteed to be in the baseTree), find it's hyperparent and use that
augmentedTree->hyperparents [newSupernodeID] = baseTree->hyperparents [superparentOldSuperID];
// similarly, the super2hypernode should carry over, but it's harder to test because of the attachment points which
// do not have valid old supernode IDs. Instead, we check their superparent's regular global ID against them: if it
// matches, then it must be the start of the superarc, in which case it does have an old ID, and we can then use the
// existing hypernode ID
vtkm::Id superparentOldRegularID = baseTree->supernodes[superparentOldSuperID];
vtkm::Id superparentGlobalID = baseTree->regularNodeGlobalIDs[superparentOldRegularID];
if (superparentGlobalID == globalRegularIDSet[supernodeSetIndex])
{
augmentedTree->super2hypernode [newSupernodeID] = baseTree->super2hypernode[superparentOldSuperID];
}
else
{
augmentedTree->super2hypernode [newSupernodeID] = NO_SUCH_ELEMENT;
}
// which round and iteration carry over
augmentedTree->whichRound [newSupernodeID] = baseTree->whichRound[superparentOldSuperID];
augmentedTree->whichIteration [newSupernodeID] = baseTree->whichIteration[superparentOldSuperID];
// now we deal with the regular-sized arrays
// copy the global regular ID and data value
augmentedTree->regularNodeGlobalIDs [newRegularID] = globalRegularIDSet[supernodeSetIndex];
augmentedTree->dataValues [newRegularID] = dataValueSet[supernodeSetIndex];
// the sort order will be dealt with later
// since all of these nodes are supernodes, they will be their own superparent, which means that:
// a. the regular2node can be set immediately
augmentedTree->regular2supernode [newRegularID] = newSupernodeID;
// b. as can the superparent
augmentedTree->superparents [newRegularID] = newSupernodeID;
} // per supernode in the set
*/
} // operator()()
private:
const vtkm::Id NumSupernodesAlready;
const vtkm::Id BaseTreeNumRounds;
const vtkm::Id AugmentedTreeNumIterations;
const vtkm::Id RoundNumber;
}; // CreateSuperarcsWorklet
} // namespace hierarchical_augmenter
} // namespace contourtree_distributed
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,210 @@
//============================================================================
// 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 (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.
//
//=============================================================================
// 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_distributed_hierarchical_augmenter_find_superparent_for_necessary_nodes_worklet_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_find_superparent_for_necessary_nodes_worklet_h
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Worklet used in HierarchicalAugmenter::CopyBaseRegularStructure for
/// finding the superparent for each node needed
class FindSuperparentForNecessaryNodesWorklet : public vtkm::worklet::WorkletMapField
{
public:
/// Control signature for the worklet
using ControlSignature = void(
FieldIn baseTreeRegularNodeGlobalIds, // input domain
FieldIn baseTreeSuperparents, // input
FieldIn baseTreeDataValues, // input
WholeArrayIn baseTreeSuperarcs, // input
WholeArrayIn newSupernodeIds, // input
// Execution objects from the AugmentedTree to use the FindRegularByGlobal
// and FindSuperArcForUnknownNode for the hierarchical tree.
ExecObject findRegularByGlobal,
ExecObject findSuperArcForUnknownNode,
// Output arrays to populate
FieldOut regularSuperparents, // output
FieldOut regularNodesNeeded // output
);
using ExecutionSignature = void(InputIndex, _1, _2, _3, _4, _5, _6, _7, _8, _9);
using InputDomain = _1;
/// Default Constructor
VTKM_EXEC_CONT
FindSuperparentForNecessaryNodesWorklet() {}
/// operator() of the workelt
template <typename InFieldPortalType,
typename FieldType,
typename ExecObjectType1,
typename ExecObjectType2>
VTKM_EXEC void operator()(
const vtkm::Id& regularNode, // InputIndex a.k.a out loop index
const vtkm::Id& globalRegularId, // same as baseTree->regularNodeGlobalIDs[regularNode];
const vtkm::Id& oldSuperparent, // same as baseTree->superparents[regularNode];
const FieldType& dataValue, // same as baseTree->dataValues[regularNode]
const InFieldPortalType& baseTreeSuperarcsPortal,
const InFieldPortalType& newSupernodeIdsPortal,
const ExecObjectType1& findRegularByGlobal, // Execution object to call FindRegularByGlobal
const ExecObjectType2&
findSuperArcForUnknownNode, // Execution object to call FindSuperArcForUnknownNode
vtkm::Id&
regularSuperparentsValue, // same as regularSuperparents[regularNode] = ... (set on output)
vtkm::Id&
regularNodesNeededValue // same as regularNodesNeeded[regularNode] = ... (set on output)
) const
{
// per regular node
// retrieve the index (globalRegularId set on input)
// first check to see if it is already present (newRegularId set on input)
vtkm::Id newRegularId = findRegularByGlobal.FindRegularByGlobal(globalRegularId);
// if it fails this test, then it's already in tree
if (vtkm::worklet::contourtree_augmented::NoSuchElement(newRegularId))
{ // not yet in tree
// since it's not in the tree, we want to find where it belongs
// to do so, we need to find an "above" and "below" node for it. Since it exists in the old tree, it belongs to a superarc, and we
// can use the ends of the superarc as above and below to do the searching
// oldSuperparent set on Input vtkm::Id oldSuperparent = baseTree->superparents[regularNode];
vtkm::Id oldSuperarc = baseTreeSuperarcsPortal.Get(oldSuperparent);
// break the superarc into the flag and the target
// NOTE that we do not test for NO_SUCH_ELEMENT as all attachment points and the root are guaranteed to be present already,
// and have therefore been excluded by the if statement already
vtkm::Id oldSuperTarget = vtkm::worklet::contourtree_augmented::MaskedIndex(oldSuperarc);
bool ascendingSuperarc = vtkm::worklet::contourtree_augmented::IsAscending(oldSuperarc);
// convert both from and to into new supernode IDs
vtkm::Id newSuperparent = newSupernodeIdsPortal.Get(oldSuperparent);
vtkm::Id newSuperTarget = newSupernodeIdsPortal.Get(oldSuperTarget);
// retrieve the data value (dataValue set on input)
// now test and retrieve, with above = target if ascending, &c.
if (ascendingSuperarc)
{
regularSuperparentsValue = findSuperArcForUnknownNode.FindSuperArcForUnknownNode(
globalRegularId, dataValue, newSuperTarget, newSuperparent);
}
else
{
regularSuperparentsValue = findSuperArcForUnknownNode.FindSuperArcForUnknownNode(
globalRegularId, dataValue, newSuperparent, newSuperTarget);
}
// either way, we set the index array to the index
regularNodesNeededValue = regularNode;
} // not yet in tree
// Set to NO_SUCH_ELEMENT by default. By doing this in the worklet we an avoid having to
// initialize the output arrays first and we can use FieldIn instead of FieldInOut
else
{
regularSuperparentsValue = vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
regularNodesNeededValue = vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
}
// In serial this worklet implements the following operation
/*
// now loop, finding the superparent for each node needed
for (vtkm::Id regularNode = 0; regularNode < baseTree->regularNodeGlobalIDs.size(); regularNode++)
{ // per regular node
// retrieve the index
vtkm::Id globalRegularID = baseTree->regularNodeGlobalIDs[regularNode];
// first check to see if it is already present
vtkm::Id newRegularID = augmentedTree->FindRegularByGlobal(globalRegularID);
// if it fails this test, then it's already in tree
if (noSuchElement(newRegularID))
{ // not yet in tree
// std::cout << "Not yet in tree" << std::endl;
// since it's not in the tree, we want to find where it belongs
// to do so, we need to find an "above" and "below" node for it. Since it exists in the old tree, it belongs to a superarc, and we
// can use the ends of the superarc as above and below to do the searching
vtkm::Id oldSuperparent = baseTree->superparents[regularNode];
vtkm::Id oldSuperarc = baseTree->superarcs[oldSuperparent];
// break the superarc into the flag and the target
// NOTE that we do not test for NO_SUCH_ELEMENT as all attachment points and the root are guaranteed to be present already,
// and have therefore been excluded by the if statement already
vtkm::Id oldSuperTarget = maskedIndex(oldSuperarc);
bool ascendingSuperarc = isAscending(oldSuperarc);
// convert both from and to into new supernode IDs
vtkm::Id newSuperparent = newSupernodeIDs[oldSuperparent];
vtkm::Id newSuperTarget = newSupernodeIDs[oldSuperTarget];
// retrieve the data value
dataType dataValue = baseTree->dataValues[regularNode];
// now test and retrieve, with above = target if ascending, &c.
if (ascendingSuperarc)
regularSuperparents[regularNode] = augmentedTree->FindSuperArcForUnknownNode(globalRegularID, dataValue, newSuperTarget, newSuperparent);
else
regularSuperparents[regularNode] = augmentedTree->FindSuperArcForUnknownNode(globalRegularID, dataValue, newSuperparent, newSuperTarget);
// either way, we set the index array to the index
regularNodesNeeded[regularNode] = regularNode;
} // not yet in tree
} // per regular node
*/
} // operator()()
}; // FindSuperparentForNecessaryNodesWorklet
} // namespace hierarchical_augmenter
} // namespace contourtree_distributed
} // namespace worklet
} // namespace vtkm
#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 (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.
//
//=============================================================================
// 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_distributed_hierarchical_augmenter_is_ascending_decorator_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_is_ascending_decorator_h
#include <vtkm/Types.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Decorator to add the Ascending flag if necessary
class IsAscendingDecorator
{
public:
template <typename PortalType1, typename PortalType2>
struct Functor
{
PortalType1 SuperparentsPortal;
PortalType2 SuperarcsPortal;
VTKM_EXEC_CONT vtkm::Id operator()(vtkm::Id i) const
{
vtkm::Id superparent = this->SuperparentsPortal.Get(i);
if (vtkm::worklet::contourtree_augmented::IsAscending(this->SuperarcsPortal.Get(superparent)))
{
superparent |= vtkm::worklet::contourtree_augmented::IS_ASCENDING;
}
return superparent;
}
};
template <typename PT1, typename PT2>
Functor<PT1, PT2> CreateFunctor(PT1 SuperparentsPortal, PT2 SuperarcsPortal) const
{
return { SuperparentsPortal, SuperarcsPortal };
}
};
} // namespace hierarchical_augmenter
} // namespace contourtree_augmented
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,143 @@
//============================================================================
// 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 (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_distributed_hierarchical_augmenter_is_attachement_point_needed_predicate_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_is_attachement_point_needed_predicate_h
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ExecutionObjectBase.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
// Implementatin of predicate used in HierarchicalAugmenter<FieldType>::PrepareOutAttachmentPoints
// to determine whether an attachement points needs to be transferred
class IsAttachementPointNeededPredicateImpl
{
public:
using IdPortalType = vtkm::worklet::contourtree_augmented::IdArrayType::ReadPortalType;
// constructor - takes vectors as parameters
VTKM_CONT
IsAttachementPointNeededPredicateImpl(
const vtkm::worklet::contourtree_augmented::IdArrayType& superparentsRounds,
const vtkm::worklet::contourtree_augmented::IdArrayType& whichRounds,
const vtkm::Id round,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
: SuperparentsRoundsPortal(superparentsRounds.PrepareForInput(device, token))
, WhichRoundsPortal(whichRounds.PrepareForInput(device, token))
, Round(round)
{ // constructor
} // constructor
// () operator - gets called to do comparison
VTKM_EXEC
bool operator()(const vtkm::Id& attachmentPoint) const
{ // operator()
return !((this->SuperparentsRoundsPortal.Get(attachmentPoint) <= this->Round) ||
(this->WhichRoundsPortal.Get(attachmentPoint) > this->Round));
} // operator()
private:
IdPortalType SuperparentsRoundsPortal;
IdPortalType WhichRoundsPortal;
const vtkm::Id Round;
}; // IsAttachementPointNeededPredicateImpl
// Predicate ExecutonObject used in HierarchicalAugmenter<FieldType>::PrepareOutAttachmentPoints
// to determine whether an attachement points needs to be transferred
class IsAttachementPointNeededPredicate : public vtkm::cont::ExecutionObjectBase
{
public:
// constructor - takes vectors as parameters
VTKM_CONT
IsAttachementPointNeededPredicate(
const vtkm::worklet::contourtree_augmented::IdArrayType& superparentsRounds,
const vtkm::worklet::contourtree_augmented::IdArrayType& whichRounds,
const vtkm::Id round)
: SuperparentsRounds(superparentsRounds)
, WhichRounds(whichRounds)
, Round(round)
{
}
VTKM_CONT IsAttachementPointNeededPredicateImpl
PrepareForExecution(vtkm::cont::DeviceAdapterId device, vtkm::cont::Token& token) const
{
return IsAttachementPointNeededPredicateImpl(
this->SuperparentsRounds, this->WhichRounds, this->Round, device, token);
}
private:
vtkm::worklet::contourtree_augmented::IdArrayType SuperparentsRounds;
vtkm::worklet::contourtree_augmented::IdArrayType WhichRounds;
const vtkm::Id Round;
}; // IsAttachementPointNeededPredicate
} // namespace hierarchical_augmenter
} // namespace contourtree_augmented
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,141 @@
//============================================================================
// 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 (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_distributed_hierarchical_augmenter_is_attachement_point_predicate_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_is_attachement_point_predicate_h
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ExecutionObjectBase.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Predicate used in HierarchicalAugmenter<FieldType>::Initalize to determine
/// whether a node is an attachement point
class IsAttachementPointPredicateImpl
{
public:
using IdPortalType = vtkm::worklet::contourtree_augmented::IdArrayType::ReadPortalType;
// constructor - takes vectors as parameters
VTKM_CONT
IsAttachementPointPredicateImpl(
const vtkm::worklet::contourtree_augmented::IdArrayType& superarcs,
const vtkm::worklet::contourtree_augmented::IdArrayType& whichRound,
const vtkm::Id numRounds,
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
: SuperarcsPortal(superarcs.PrepareForInput(device, token))
, WhichRoundPortal(whichRound.PrepareForInput(device, token))
, NumRounds(numRounds)
{ // constructor
} // constructor
// () operator - gets called to do comparison
VTKM_EXEC
bool operator()(const vtkm::Id& supernode) const
{ // operator()
return (
vtkm::worklet::contourtree_augmented::NoSuchElement(this->SuperarcsPortal.Get(supernode)) &&
(this->WhichRoundPortal.Get(supernode) < this->NumRounds));
} // operator()
private:
IdPortalType SuperarcsPortal;
IdPortalType WhichRoundPortal;
const vtkm::Id NumRounds;
}; // IsAttachementPointPredicateImpl
class IsAttachementPointPredicate : public vtkm::cont::ExecutionObjectBase
{
public:
// constructor - takes vectors as parameters
VTKM_CONT
IsAttachementPointPredicate(const vtkm::worklet::contourtree_augmented::IdArrayType& superarcs,
const vtkm::worklet::contourtree_augmented::IdArrayType& whichRound,
const vtkm::Id numRounds)
: Superarcs(superarcs)
, WhichRound(whichRound)
, NumRounds(numRounds)
{
}
VTKM_CONT IsAttachementPointPredicateImpl PrepareForExecution(vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
return IsAttachementPointPredicateImpl(
this->Superarcs, this->WhichRound, this->NumRounds, device, token);
}
private:
vtkm::worklet::contourtree_augmented::IdArrayType Superarcs;
vtkm::worklet::contourtree_augmented::IdArrayType WhichRound;
const vtkm::Id NumRounds;
}; // IsAttachementPointPredicate
} // namespace hierarchical_augmenter
} // namespace contourtree_augmented
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,89 @@
//============================================================================
// 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 (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_distributed_hierarchical_augmenter_not_no_such_element_predicate_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_not_no_such_element_predicate_h
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
//Simple functor to subset a VTKm ArrayHandle
class NotNoSuchElementPredicate
{
public:
VTKM_EXEC_CONT
NotNoSuchElementPredicate() {}
VTKM_EXEC_CONT
bool operator()(const vtkm::Id& inId) const
{
return !static_cast<bool>(vtkm::worklet::contourtree_augmented::NoSuchElement(inId));
}
private:
};
} // namespace data_set_mesh
} // namespace contourtree_distributed
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,135 @@
//============================================================================
// 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 (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.
//
//=============================================================================
// 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_distributed_hierarchical_augmenter_resize_arrays_build_new_supernode_ids_worklet_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_resize_arrays_build_new_supernode_ids_worklet_h
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Worklet used in HierarchicalAugmenter<FieldType>ResizeArrays to build the newSupernodeIds array
class ResizeArraysBuildNewSupernodeIdsWorklet : public vtkm::worklet::WorkletMapField
{
public:
/// Control signature for the worklet
using ControlSignature = void(
FieldIn supernodeIndex, // input domain ArrayHandleIndex(SupernodeSorter.GetNumberOfValues())
FieldIn
supernodeIdSetPermuted, // input supernodeIDSet permuted by supernodeSorter to allow for FieldIn
WholeArrayInOut
newSupernodeIds // output/input (both are necessary since not all valyes will be overwritten)
);
using ExecutionSignature = void(InputIndex, _1, _2, _3);
using InputDomain = _1;
// Default Constructor
VTKM_EXEC_CONT
ResizeArraysBuildNewSupernodeIdsWorklet(const vtkm::Id& numSupernodesAlready)
: NumSupernodesAlready(numSupernodesAlready)
{
}
template <typename InOutFieldPortalType>
VTKM_EXEC void operator()(
const vtkm::Id& supernode, // InputIndex of supernodeSorter
const vtkm::Id& oldSupernodeId, // same as supernodeIDSet[supernodeSetIndex];
const InOutFieldPortalType& newSupernodeIdsPortal) const
{
// per supernode
// retrieve the index from the sorting index array. supernodeSetIndex set on input
// work out the correct new supernode ID
vtkm::Id newSupernodeId = this->NumSupernodesAlready + supernode;
// retrieve the old supernode ID from the sorting array, remembering
// that if it came from another block it will be set to NO_SUCH_ELEMENT
// vtkm::Id oldSupernodeId set on input since we use ArrayHandlePermutation to
// shuffle supernodeIDSet by supernodeSorter;
// and write to the lookup array
if (!vtkm::worklet::contourtree_augmented::NoSuchElement(oldSupernodeId))
{
newSupernodeIdsPortal.Set(oldSupernodeId, newSupernodeId);
}
// In serial this worklet implements the following operation
/*
for (vtkm::Id supernode = 0; supernode < supernodeSorter.size(); supernode++)
{ // per supernode
// retrieve the index from the sorting index array
vtkm::Id supernodeSetIndex = supernodeSorter[supernode];
// work out the correct new supernode ID
vtkm::Id newSupernodeID = numSupernodesAlready + supernode;
// retrieve the old supernode ID from the sorting array, remembering that if it came from another block it will be set to NO_SUCH_ELEMENT
vtkm::Id oldSupernodeID = supernodeIDSet[supernodeSetIndex];
// and write to the lookup array
if (!noSuchElement(oldSupernodeID))
newSupernodeIDs[oldSupernodeID] = newSupernodeID;
} // per supernode
*/
} // operator()()
private:
const vtkm::Id NumSupernodesAlready;
}; // ResizeArraysBuildNewSupernodeIdsWorklet
} // namespace hierarchical_augmenter
} // namespace contourtree_distributed
} // 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 (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.
//
//=============================================================================
// 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_distributed_hierarchical_augmenter_set_first_attachment_point_in_round_worklet_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_set_first_attachment_point_in_round_worklet_h
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Worklet used in HierarchicalHyperSweeper.TransferWeights(...) to implement
/// step 7b. Now find the LHE of each group and subtract out the prior weight
class SetFirstAttachmentPointInRoundWorklet : public vtkm::worklet::WorkletMapField
{
public:
/// Control signature for the worklet
/// NOTE: we need this to be in/out because any valyes we don't set here need
/// to remain NO_SUCH_ELEMENT for further processing
using ControlSignature = void(WholeArrayIn attachmentIds, // input
WholeArrayIn superparentRounds, // input
WholeArrayInOut firstAttachmentPointInRound // input/output
);
using ExecutionSignature = void(InputIndex, _1, _2, _3);
using InputDomain = _1;
// Default Constructor
VTKM_EXEC_CONT
SetFirstAttachmentPointInRoundWorklet() {}
template <typename InFieldPortalType, typename InOutFieldPortalType>
VTKM_EXEC void operator()(const vtkm::Id& attachmentPoint,
const InFieldPortalType& attachmentIdsPortal,
const InFieldPortalType& superparentRoundsPortal,
const InOutFieldPortalType& firstAttachmentPointInRoundPortal) const
{
// per attachment point
// retrieve the ID of the attachment point
vtkm::Id attachmentPointId = attachmentIdsPortal.Get(attachmentPoint);
// the 0th element always starts a segment, so set the round's beginning
if (attachmentPoint == 0)
{
firstAttachmentPointInRoundPortal.Set(superparentRoundsPortal.Get(attachmentPointId),
static_cast<vtkm::Id>(0));
}
// otherwise, a segment begins when it's SP round is different from the next one down
else
{ // not the beginning of the array
// retrieve the two attachment point IDs
vtkm::Id previousAttachmentPointId = attachmentIdsPortal.Get(attachmentPoint - 1);
// and the corresponding superparent rounds
vtkm::Id superparentRound = superparentRoundsPortal.Get(attachmentPointId);
vtkm::Id previousSuperparentRound = superparentRoundsPortal.Get(previousAttachmentPointId);
// detect where the segment ID changes & use that to set the value
if (superparentRound != previousSuperparentRound)
{
firstAttachmentPointInRoundPortal.Set(superparentRound, attachmentPoint);
}
} // not the beginning of the array
// In serial this worklet implements the following operation
/*
for (vtkm::Id attachmentPoint = 0; attachmentPoint < attachmentIDs.size(); attachmentPoint++)
{ // per attachment point
// retrieve the ID of the attachment point
vtkm::Id attachmentPointID = attachmentIDs[attachmentPoint];
// the 0th element always starts a segment, so set the round's beginning
if (attachmentPoint == 0)
firstAttachmentPointInRound[superparentRounds[attachmentPointID]] = 0;
// otherwise, a segment begins when it's SP round is different from the next one down
else
{ // not the beginning of the array
// retrieve the two attachment point IDs
vtkm::Id previousAttachmentPointID = attachmentIDs[attachmentPoint-1];
// and the corresponding superparent rounds
vtkm::Id superparentRound = superparentRounds[attachmentPointID];
vtkm::Id previousSuperparentRound = superparentRounds[previousAttachmentPointID];
// detect where the segment ID changes & use that to set the value
if (superparentRound != previousSuperparentRound)
firstAttachmentPointInRound[superparentRound] = attachmentPoint;
} // not the beginning of the array
} // per attachment point
*/
} // operator()()
}; // SetFirstAttachmentPointInRoundWorklet
} // namespace hierarchical_augmenter
} // namespace contourtree_distributed
} // namespace worklet
} // namespace vtkm
#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 (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.
//
//=============================================================================
// 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_distributed_hierarchical_augmenter_set_superparent_set_decorator_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_set_superparent_set_decorator_h
#include <vtkm/Types.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Decorator to add the Ascending flag if necessary
class SetSuperparentSetDecorator
{
public:
template <typename PortalType1, typename PortalType2>
struct Functor
{
PortalType1 KeptSupernodesPortal;
PortalType2 BaseTreeSuperarcsPortal;
VTKM_EXEC_CONT vtkm::Id operator()(vtkm::Id i) const
{
vtkm::Id oldSupernodeId = KeptSupernodesPortal.Get(i);
return (oldSupernodeId |
(vtkm::worklet::contourtree_augmented::IsAscending(
BaseTreeSuperarcsPortal.Get(oldSupernodeId))
? vtkm::worklet::contourtree_augmented::IS_ASCENDING
: 0x00));
}
};
template <typename PT1, typename PT2>
Functor<PT1, PT2> CreateFunctor(PT1 KeptSupernodesPortal, PT2 BaseTreeSuperarcsPortal) const
{
return { KeptSupernodesPortal, BaseTreeSuperarcsPortal };
}
};
} // namespace hierarchical_augmenter
} // namespace contourtree_augmented
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,153 @@
//============================================================================
// 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 (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.
//
//=============================================================================
// 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_distributed_hierarchical_augmenter_update_hyperstructure_set_hyperarcs_and_nodes_worklet_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_update_hyperstructure_set_hyperarcs_and_nodes_worklet_h
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Worklet used in HierarchicalAugmenter::UpdateHyperstructure to set the hyperarcs and hypernodes
class UpdateHyperstructureSetHyperarcsAndNodesWorklet : public vtkm::worklet::WorkletMapField
{
public:
/// Control signature for the worklet
using ControlSignature = void(FieldIn baseTreeHypernodes, // input
FieldIn baseTreeHyperarcs, // input
WholeArrayIn newSupernodeIds, // input
FieldOut augmentedTreeHypernodes, // output
FieldOut augmentedTreeHyperarcs // output
);
using ExecutionSignature = void(_1, _2, _3, _4, _5);
using InputDomain = _1;
// Default Constructor
VTKM_EXEC_CONT
UpdateHyperstructureSetHyperarcsAndNodesWorklet() {}
template <typename InFieldPortalType>
VTKM_EXEC void operator()(
const vtkm::Id& oldHypernodeSuperId, // same as baseTree->hypernodes[hypernode]
const vtkm::Id& oldTargetSuperIdMasked, // same as baseTree->hyperarcs[hypernode]
const InFieldPortalType& newSupernodeIdsPortal,
vtkm::Id& outAugmentedTreeHypernodesValue, // same as augmentedTree->hypernodes[hypernode] = ...
vtkm::Id& outAugmentedTreeHyperarcsValue // same as augmentedTree->hyperarcs[hypernode] = ...
) const
{
// per hypernode
// retrieve existing values which are in old supernode Ids
// oldHypernodeSuperId and oldTargetSuperIdMasked are set by the worklt
// strip out the ascending flag & the flag for root hyperarc
bool isRootHyperarc =
vtkm::worklet::contourtree_augmented::NoSuchElement(oldTargetSuperIdMasked);
bool hyperarcAscends =
vtkm::worklet::contourtree_augmented::IsAscending(oldTargetSuperIdMasked);
vtkm::Id oldTargetSuperId =
vtkm::worklet::contourtree_augmented::MaskedIndex(oldTargetSuperIdMasked);
// lookup new values
vtkm::Id newHypernodeSuperId = newSupernodeIdsPortal.Get(oldHypernodeSuperId);
vtkm::Id newTargetSuperId = vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
if (!isRootHyperarc)
{ // not the root
// lookup the new ID
newTargetSuperId = newSupernodeIdsPortal.Get(oldTargetSuperId);
if (hyperarcAscends)
{
newTargetSuperId |= vtkm::worklet::contourtree_augmented::IS_ASCENDING;
}
} // not the root
// now store them
outAugmentedTreeHypernodesValue = newHypernodeSuperId;
outAugmentedTreeHyperarcsValue = newTargetSuperId;
// In serial this worklet implements the following operation
/*
for (vtkm::Id hypernode = 0; hypernode < augmentedTree->hypernodes.size(); hypernode++)
{ // per hypernode
// retrieve existing values which are in old supernode IDs
vtkm::Id oldHypernodeSuperID = baseTree->hypernodes[hypernode];
vtkm::Id oldTargetSuperID = baseTree->hyperarcs[hypernode];
// strip out the ascending flag & the flag for root hyperarc
bool isRootHyperarc = noSuchElement(oldTargetSuperID);
bool hyperarcAscends = isAscending(oldTargetSuperID);
oldTargetSuperID = maskedIndex(oldTargetSuperID);
// lookup new values
vtkm::Id newHypernodeSuperID = newSupernodeIDs[oldHypernodeSuperID];
vtkm::Id newTargetSuperID = NO_SUCH_ELEMENT;
if (!isRootHyperarc)
{ // not the root
// lookup the new ID
newTargetSuperID = newSupernodeIDs[oldTargetSuperID];
if (hyperarcAscends)
newTargetSuperID |= IS_ASCENDING;
} // not the root
// now store them
augmentedTree->hypernodes[hypernode] = newHypernodeSuperID;
augmentedTree->hyperarcs[hypernode] = newTargetSuperID;
} // per hypernode
*/
} // operator()()
}; // UpdateHyperstructureSetHyperarcsAndNodesWorklet
} // namespace hierarchical_augmenter
} // namespace contourtree_distributed
} // namespace worklet
} // namespace vtkm
#endif

@ -0,0 +1,135 @@
//============================================================================
// 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 (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.
//
//=============================================================================
// 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_distributed_hierarchical_augmenter_update_hyperstructure_set_superchildren_worklet_h
#define vtk_m_worklet_contourtree_distributed_hierarchical_augmenter_update_hyperstructure_set_superchildren_worklet_h
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/contourtree_augmented/Types.h>
namespace vtkm
{
namespace worklet
{
namespace contourtree_distributed
{
namespace hierarchical_augmenter
{
/// Worklet used in HierarchicalAugmenter::UpdateHyperstructure to set the superchildren
/// The worklet finds the number of superchildren as the delta between the super Id
/// and the next hypernode's super Id
class UpdateHyperstructureSetSuperchildrenWorklet : public vtkm::worklet::WorkletMapField
{
public:
/// Control signature for the worklet
using ControlSignature = void(
WholeArrayIn augmentedTreeHypernodes, // input (we need both this and the next value)
FieldOut augmentedTreeSuperchildren // output
);
using ExecutionSignature = void(InputIndex, _1, _2);
using InputDomain = _1;
// Default Constructor
VTKM_EXEC_CONT
UpdateHyperstructureSetSuperchildrenWorklet(const vtkm::Id& augmentedTreeNumSupernodes)
: AugmentedTreeNumSupernodes(augmentedTreeNumSupernodes)
{
}
template <typename InFieldPortalType>
VTKM_EXEC void operator()(
const vtkm::Id& hypernode,
const InFieldPortalType& augmentedTreeHypernodesPortal,
vtkm::Id&
augmentedTreeSuperchildrenValue // same as augmentedTree->superchildren[InputIndex] = ...
) const
{
// per hypernode
// retrieve the new superId
vtkm::Id superId = augmentedTreeHypernodesPortal.Get(hypernode);
// and the next one over
vtkm::Id nextSuperId;
if (hypernode == augmentedTreeHypernodesPortal.GetNumberOfValues() - 1)
{
nextSuperId = this->AugmentedTreeNumSupernodes;
}
else
{
nextSuperId = augmentedTreeHypernodesPortal.Get(hypernode + 1);
}
// the difference is the number of superchildren
augmentedTreeSuperchildrenValue = nextSuperId - superId;
// In serial this worklet implements the following operation
/*
for (vtkm::Id hypernode = 0; hypernode < augmentedTree->hypernodes.size(); hypernode++)
{ // per hypernode
// retrieve the new super ID
vtkm::Id superID = augmentedTree->hypernodes[hypernode];
// and the next one over
vtkm::Id nextSuperID;
if (hypernode == augmentedTree->hypernodes.size() - 1)
nextSuperID = augmentedTree->supernodes.size();
else
nextSuperID = augmentedTree->hypernodes[hypernode+1];
// the difference is the number of superchildren
augmentedTree->superchildren[hypernode] = nextSuperID - superID;
} // per hypernode
*/
} // operator()()
private:
const vtkm::Id AugmentedTreeNumSupernodes;
}; // UpdateHyperstructureSetSuperchildrenWorklet
} // namespace hierarchical_augmenter
} // namespace contourtree_distributed
} // namespace worklet
} // namespace vtkm
#endif