Update HierarchicalAugmenter.UpdateHyperstructure

This commit is contained in:
Oliver Ruebel 2023-12-11 03:19:27 -08:00 committed by Gunther H. Weber
parent 03c1413316
commit 3853dbe8ec
2 changed files with 62 additions and 42 deletions

@ -760,13 +760,19 @@ void HierarchicalAugmenter<FieldType>::UpdateHyperstructure(vtkm::Id roundNumber
UpdateHyperstructureSetSuperchildrenWorklet updateHyperstructureSetSuperchildrenWorklet(
this->AugmentedTree->Supernodes.GetNumberOfValues());
// As above, we need to create views of the relevant subranges of our arrays
auto augmentedTreeHypernodesView =
vtkm::cont::make_ArrayHandleView(this->AugmentedTree->Hypernodes, startIndex, selectSize);
auto augmentedTreeSuperchildrenView =
vtkm::cont::make_ArrayHandleView(this->AugmentedTree->Superchildren, startIndex, selectSize);
auto augmentedTreeSuperarcsView =
vtkm::cont::make_ArrayHandleView(this->AugmentedTree->Superarcs, startIndex, selectSize);
vtkm::Id extraSelectSize =
((startIndex + selectSize) < this->AugmentedTree->Hyperparents.GetNumberOfValues())
? selectSize + 1
: selectSize;
auto augmentedTreeHyperparentsView = vtkm::cont::make_ArrayHandleView(
this->AugmentedTree->Hyperparents, startIndex, extraSelectSize);
this->Invoke(updateHyperstructureSetSuperchildrenWorklet,
augmentedTreeHypernodesView, // input
augmentedTreeSuperchildrenView // output
this->AugmentedTree->Hypernodes, // input
augmentedTreeSuperarcsView, // input
augmentedTreeHyperparentsView, // inpu
this->AugmentedTree->Superchildren // output
);
}
} // UpdateHyperstructure()

@ -66,10 +66,12 @@ class UpdateHyperstructureSetSuperchildrenWorklet : public vtkm::worklet::Workle
public:
/// Control signature for the worklet
using ControlSignature = void(
WholeArrayIn augmentedTreeHypernodes, // input (we need both this and the next value)
FieldOut augmentedTreeSuperchildren // output
WholeArrayIn augmentedTreeHypernodes, // input (we need both this and the next value)
FieldIn augmentedTreeSuperarcs, // input
WholeArrayIn augmentedTreeHyperparents, // input
WholeArrayInOut augmentedTreeSuperchildren // output
);
using ExecutionSignature = void(InputIndex, _1, _2);
using ExecutionSignature = void(InputIndex, _1, _2, _3, _4);
using InputDomain = _1;
// Default Constructor
@ -80,46 +82,58 @@ public:
}
template <typename InFieldPortalType>
VTKM_EXEC void operator()(
const vtkm::Id& hypernode,
const InFieldPortalType& augmentedTreeHypernodesPortal,
vtkm::Id&
augmentedTreeSuperchildrenValue // same as augmentedTree->superchildren[InputIndex] = ...
) const
template <typename InFieldPortalType1, typename InFieldPortalType2, typename OutFieldPortalType>
VTKM_EXEC void operator()(const vtkm::Id& supernode,
const InFieldPortalType1& augmentedTreeHypernodesPortal,
const vtkm::Id& augmentedTreeSuperarcsValue,
const InFieldPortalType2& augmentedTreeHyperparentsPortal,
const OutFieldPortalType& augmentedTreeSuperchildrenPortal) 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)
// per supernode
// attachment points have NULL superarcs and are skipped
if (vtkm::worklet::contourtree_augmented::NoSuchElement(augmentedTreeSuperarcsValue))
{
nextSuperId = this->AugmentedTreeNumSupernodes;
return;
}
else
{
nextSuperId = augmentedTreeHypernodesPortal.Get(hypernode + 1);
}
// the difference is the number of superchildren
augmentedTreeSuperchildrenValue = nextSuperId - superId;
// we are now guaranteed to have a valid hyperparent
vtkm::Id hyperparent = augmentedTreeHyperparentsPortal.Get(supernode);
vtkm::Id hyperparentSuperId = augmentedTreeHypernodesPortal.Get(hyperparent);
// we could be at the end of the array, so test explicitly
if (supernode == this->AugmentedTreeNumSupernodes - 1)
{
// this means that we are the end of the segment and can subtract the hyperparent's super ID to get the number of superchildren
augmentedTreeSuperchildrenPortal.Set(hyperparent,
this->AugmentedTreeNumSupernodes - hyperparentSuperId);
}
// otherwise, if our hyperparent is different from our neighbor's, we are the end of the segment
else if (hyperparent != augmentedTreeHyperparentsPortal.Get(supernode + 1))
{
// again, subtract to get the number
augmentedTreeSuperchildrenPortal.Set(
hyperparent, this->AugmentedTreeNumSupernodes + 1 - hyperparentSuperId);
}
// per supernode
// 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
for (indexType supernode = augmentedTree->firstSupernodePerIteration[roundNo][0]; supernode < augmentedTree->firstSupernodePerIteration[roundNo][augmentedTree->nIterations[roundNo]]; supernode++)
{ // per supernode
// attachment points have NULL superarcs and are skipped
if (noSuchElement(augmentedTree->superarcs[supernode]))
continue;
// we are now guaranteed to have a valid hyperparent
indexType hyperparent = augmentedTree->hyperparents[supernode];
indexType hyperparentSuperID = augmentedTree->hypernodes[hyperparent];
// we could be at the end of the array, so test explicitly
if (supernode == augmentedTree->supernodes.size() - 1)
// this means that we are the end of the segment and can subtract the hyperparent's super ID to get the number of superchildren
augmentedTree->superchildren[hyperparent] = augmentedTree->supernodes.size() - hyperparentSuperID;
// otherwise, if our hyperparent is different from our neighbor's, we are the end of the segment
else if (hyperparent != augmentedTree->hyperparents[supernode + 1])
// again, subtract to get the number
augmentedTree->superchildren[hyperparent] = supernode + 1 - hyperparentSuperID;
} // per supernode
*/
} // operator()()