mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-19 18:45:43 +00:00
Fix errors in HierarchicalAugmenter
Fix CreateSuperarcsWorklet. Use standard copy to reduce complexity of CreateSuperarcsWorklet. Fix compile errors in HierarchicalAugmenter. Some more clean-up and optimization for HierarchicalAugmenter.CreateSuperarcsWorklet.
This commit is contained in:
parent
c6ff4a5f09
commit
35a14f3129
@ -342,14 +342,18 @@ void HierarchicalAugmenter<FieldType>::PrepareOutAttachmentPoints(vtkm::Id round
|
||||
vtkm::worklet::contourtree_distributed::hierarchical_augmenter::
|
||||
IsAttachementPointNeededPredicate isAttachementPointNeededPredicate(
|
||||
this->SuperparentRounds, this->WhichRounds, round);
|
||||
auto tempAttachmentPointsIndex =
|
||||
vtkm::cont::ArrayHandleIndex(this->GlobalRegularIds.GetNumberOfValues());
|
||||
vtkm::cont::Algorithm::CopyIf(
|
||||
// 1. generate a list of all of the attachment points
|
||||
vtkm::cont::ArrayHandleIndex(this - GlobalRegularIds.GetNumberOfValues()),
|
||||
// 2. then our stencil identifies all attachment points needed
|
||||
isAttachementPointNeededPredicate,
|
||||
// 3. And the CopyIf compress the supernodes array to eliminate the non-attachement points and
|
||||
// save to this->AttachmentIds
|
||||
this->AttachmentIds);
|
||||
// 1. fancy array of all of the attachment points of which parts are copied to this->AttachmentIds
|
||||
tempAttachmentPointsIndex, // input
|
||||
// 2. stencil used with the predicate to decide which AttachementIds to keep
|
||||
tempAttachmentPointsIndex, // stencil
|
||||
// 3. CopyIf compress the supernodes array to eliminate the non-attachement
|
||||
// points and save to this->AttachmentIds
|
||||
this->AttachmentIds,
|
||||
// 4. the unary predicate uses the stencil to identify all attachment points needed
|
||||
isAttachementPointNeededPredicate);
|
||||
}
|
||||
|
||||
// 4. resize the out array
|
||||
@ -369,19 +373,19 @@ void HierarchicalAugmenter<FieldType>::PrepareOutAttachmentPoints(vtkm::Id round
|
||||
// outDataValues[outAttachmentPoint] = dataValues[attachmentPoint];
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
vtkm::cont::make_ArrayHandlePermutation(this->AttachmentIds, this->DataValues),
|
||||
this->outDataValues);
|
||||
this->OutDataValues);
|
||||
// outSupernodeIDs[outAttachmentPoint] = supernodeIDs[attachmentPoint];
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
vtkm::cont::make_ArrayHandlePermutation(this->AttachmentIds, this->SupernodeIds),
|
||||
this->OutSupernodeIds);
|
||||
// outSuperparents[outAttachmentPoint] = superparents[attachmentPoint];
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
vtkm::cont::make_ArrayHandlePermutation(this->AttachmentIds, this->superparents),
|
||||
this->outSuperparents);
|
||||
vtkm::cont::make_ArrayHandlePermutation(this->AttachmentIds, this->Superparents),
|
||||
this->OutSuperparents);
|
||||
// outSuperparentRounds[outAttachmentPoint] = superparentRounds[attachmentPoint];
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
vtkm::cont::make_ArrayHandlePermutation(this->AttachmentIds, this->SuperparentRounds),
|
||||
this->outSuperparentRounds);
|
||||
this->OutSuperparentRounds);
|
||||
// outWhichRounds[outAttachmentPoint] = whichRounds[attachmentPoint];
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
vtkm::cont::make_ArrayHandlePermutation(this->AttachmentIds, this->WhichRounds),
|
||||
@ -405,9 +409,9 @@ void HierarchicalAugmenter<FieldType>::RetrieveInAttachmentPoints(HierarchicalAu
|
||||
vtkm::Id numTotalAttachments = numAttachmentsCurrently + numIncomingAttachments;
|
||||
|
||||
// I. resize the existing arrays
|
||||
this->GlobalRegularIDs.Allocate(numTotalAttachments);
|
||||
this->GlobalRegularIds.Allocate(numTotalAttachments);
|
||||
this->DataValues.Allocate(numTotalAttachments);
|
||||
this->SupernodeIDs.Allocate(numTotalAttachments);
|
||||
this->SupernodeIds.Allocate(numTotalAttachments);
|
||||
this->Superparents.Allocate(numTotalAttachments);
|
||||
this->SuperparentRounds.Allocate(numTotalAttachments);
|
||||
this->WhichRounds.Allocate(numTotalAttachments);
|
||||
@ -417,36 +421,31 @@ void HierarchicalAugmenter<FieldType>::RetrieveInAttachmentPoints(HierarchicalAu
|
||||
// The following sequence of copy operations implements the following for from the orginal code
|
||||
// for (vtkm::Id outAttachmentPoint = 0; outAttachmentPoint < partner.outGlobalRegularIDs.size(); outAttachmentPoint++)
|
||||
// globalRegularIDs[attachmentPoint] = partner.outGlobalRegularIDs[outAttachmentPoint];
|
||||
vtkm::cont::Algorithm::Copy(partner.OutGlobalRegularIds,
|
||||
vtkm::cont::make_ArrayHandleView(this->GlobalRegularIds,
|
||||
numAttachmentsCurrently,
|
||||
numIncomingAttachments));
|
||||
auto tempGlobalRegularIdsView = vtkm::cont::make_ArrayHandleView(
|
||||
this->GlobalRegularIds, numAttachmentsCurrently, numIncomingAttachments);
|
||||
vtkm::cont::Algorithm::Copy(partner.OutGlobalRegularIds, tempGlobalRegularIdsView);
|
||||
// dataValues[attachmentPoint] = partner.outDataValues[outAttachmentPoint];
|
||||
vtkm::cont::Algorithm::Copy(partner.OutDataValues,
|
||||
vtkm::cont::make_ArrayHandleView(this->DataValues,
|
||||
numAttachmentsCurrently,
|
||||
numIncomingAttachments));
|
||||
auto tempDataValuesView = vtkm::cont::make_ArrayHandleView(
|
||||
this->DataValues, numAttachmentsCurrently, numIncomingAttachments);
|
||||
vtkm::cont::Algorithm::Copy(partner.OutDataValues, tempDataValuesView);
|
||||
// supernodeIDs[attachmentPoint] = NO_SUCH_ELEMENT;
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
vtkm::cont::make_ArrayHandleConstant(vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT,
|
||||
numIncomingAttachments),
|
||||
vtkm::cont::make_ArrayHandleView(
|
||||
this->SupernodeIds, numAttachmentsCurrently, numIncomingAttachments));
|
||||
auto tempNoSuchElementArr = vtkm::cont::make_ArrayHandleConstant(
|
||||
vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT, numIncomingAttachments);
|
||||
auto tempSupernodeIdsView = vtkm::cont::make_ArrayHandleView(
|
||||
this->SupernodeIds, numAttachmentsCurrently, numIncomingAttachments);
|
||||
vtkm::cont::Algorithm::Copy(tempNoSuchElementArr, tempSupernodeIdsView);
|
||||
// superparents[attachmentPoint] = partner.outSuperparents[outAttachmentPoint];
|
||||
vtkm::cont::Algorithm::Copy(partner.outSuperparents,
|
||||
vtkm::cont::make_ArrayHandleView(this->Superparents,
|
||||
numAttachmentsCurrently,
|
||||
numIncomingAttachments));
|
||||
auto tempSuperparentsView = vtkm::cont::make_ArrayHandleView(
|
||||
this->Superparents, numAttachmentsCurrently, numIncomingAttachments);
|
||||
vtkm::cont::Algorithm::Copy(partner.OutSuperparents, tempSuperparentsView);
|
||||
// superparentRounds[attachmentPoint] = partner.outSuperparentRounds[outAttachmentPoint];
|
||||
vtkm::cont::Algorithm::Copy(partner.outSuperparentRounds,
|
||||
vtkm::cont::make_ArrayHandleView(this->SuperparentRounds,
|
||||
numAttachmentsCurrently,
|
||||
numIncomingAttachments));
|
||||
auto tempSuperparentRoundsView = vtkm::cont::make_ArrayHandleView(
|
||||
this->SuperparentRounds, numAttachmentsCurrently, numIncomingAttachments);
|
||||
vtkm::cont::Algorithm::Copy(partner.OutSuperparentRounds, tempSuperparentRoundsView);
|
||||
// whichRounds[attachmentPoint] = partner.outWhichRounds[outAttachmentPoint];
|
||||
vtkm::cont::Algorithm::Copy(partner.OutWhichRounds,
|
||||
vtkm::cont::make_ArrayHandleView(this->WhichRounds,
|
||||
numAttachmentsCurrently,
|
||||
numIncomingAttachments));
|
||||
auto tempWhichRoundsView = vtkm::cont::make_ArrayHandleView(
|
||||
this->WhichRounds, numAttachmentsCurrently, numIncomingAttachments);
|
||||
vtkm::cont::Algorithm::Copy(partner.OutWhichRounds, tempWhichRoundsView);
|
||||
}
|
||||
} // RetrieveInAttachmentPoints()
|
||||
|
||||
@ -455,9 +454,9 @@ void HierarchicalAugmenter<FieldType>::RetrieveInAttachmentPoints(HierarchicalAu
|
||||
template <typename FieldType>
|
||||
void HierarchicalAugmenter<FieldType>::ReleaseOutArrays()
|
||||
{ // ReleaseOutArrays()
|
||||
this->OutGlobalRegularIDs.ReleaseResources();
|
||||
this->OutGlobalRegularIds.ReleaseResources();
|
||||
this->OutDataValues.ReleaseResources();
|
||||
this->OutSupernodeIDs.ReleaseResources();
|
||||
this->OutSupernodeIds.ReleaseResources();
|
||||
this->OutSuperparents.ReleaseResources();
|
||||
this->OutSuperparentRounds.ReleaseResources();
|
||||
this->OutWhichRounds.ReleaseResources();
|
||||
@ -1110,52 +1109,136 @@ void HierarchicalAugmenter<FieldType>::ResizeArrays(vtkm::Id roundNumber)
|
||||
template <typename FieldType>
|
||||
void HierarchicalAugmenter<FieldType>::CreateSuperarcs(vtkm::Id roundNumber)
|
||||
{ // CreateSuperarcs()
|
||||
// retrieve the ID number of the first supernode at this leverl
|
||||
// retrieve the ID number of the first supernode at this level
|
||||
vtkm::Id numSupernodesAlready =
|
||||
vtkm::cont::ArrayGetValue(0, this->AugmentedTree->FirstSupernodePerIteration[roundNumber]);
|
||||
|
||||
// e. Connect superarcs for the level & set hyperparents & superchildren count, whichRound, whichIteration, super2hypernode
|
||||
{
|
||||
// TODO: The CreateSuperarcsWorklet uses a lot of arrays and lots of WholeArrayTransfers. This could probably be further optimized.
|
||||
// TODO: FIX invokation of this worklet
|
||||
throw std::logic_error("Invocation of CreateSuperarcsWorklet currently broken");
|
||||
/*
|
||||
{ // START scope for e. to delete temporary variables
|
||||
// Note: The original PPP algorithm performed all operations listed in this block
|
||||
// in a single parralel for loop. Many of those operations were smart array
|
||||
// copies. So to simplfy the worklet and to make more effective use of
|
||||
// VTKm algorithm, a large number of copy operations have been extracted from
|
||||
// the loop and are performed here via combinations of fancy array handles and
|
||||
// vtkm::cont::Algorithm::Copy operations.
|
||||
|
||||
// Define the new supernode and regular Id. Both are actually the same here since we are
|
||||
// augmenting the tree here, but for clarity we define them as separate variables.
|
||||
// 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::cont::ArrayHandleCounting<vtkm::Id> newSupernodeId(
|
||||
numSupernodesAlready, // start
|
||||
static_cast<vtkm::Id>(1), // step
|
||||
this->SupernodeSorter.GetNumberOfValues() // number of values
|
||||
);
|
||||
auto newRegularId = newSupernodeId;
|
||||
// define the superparentOldSuperId
|
||||
auto permutedSuperparentSet =
|
||||
vtkm::cont::make_ArrayHandlePermutation(this->SupernodeSorter, this->SuperparentSet);
|
||||
auto superparentOldSuperId = vtkm::cont::make_ArrayHandleTransform(
|
||||
permutedSuperparentSet, vtkm::worklet::contourtree_augmented::MaskedIndexFunctor<vtkm::Id>());
|
||||
|
||||
// set the supernode's regular Id. Set: augmentedTree->supernodes[newSupernodeID] = newRegularID;
|
||||
auto permutedAugmentedTreeSupernodes =
|
||||
vtkm::cont::make_ArrayHandlePermutation(newSupernodeId, this->AugmentedTree->Supernodes);
|
||||
vtkm::cont::Algorithm::Copy(newRegularId, permutedAugmentedTreeSupernodes);
|
||||
|
||||
// Run the worklet for more complex operations
|
||||
{ // START block for CreateSuperarcsWorklet
|
||||
// create the worklet
|
||||
vtkm::worklet::contourtree_distributed::hierarchical_augmenter::CreateSuperarcsWorklet
|
||||
createSuperarcsWorklet(
|
||||
numSupernodesAlready,
|
||||
this->BaseTree->NumRounds,
|
||||
vtkm::cont::ArrayGetValue(roundNumber, this->AugmentedTree->NumIterations),
|
||||
roundNumber);
|
||||
this->Invoke(
|
||||
createSuperarcsWorklet, // the worklet
|
||||
this->SupernodeSorter, // input domain (we need access to InputIndex and InputIndex+1)
|
||||
roundNumber,
|
||||
this->AugmentedTree->Supernodes.GetNumberOfValues());
|
||||
// create fancy arrays needed to allow use of FieldIn for worklet parameters
|
||||
auto permutedGlobalRegularIdSet =
|
||||
vtkm::cont::make_ArrayHandlePermutation(this->SupernodeSorter, this->GlobalRegularIdSet);
|
||||
auto augmentedTreeSuperarcsView =
|
||||
vtkm::cont::make_ArrayHandleView(this->AugmentedTree->Superarcs,
|
||||
numSupernodesAlready,
|
||||
this->SupernodeSorter.GetNumberOfValues());
|
||||
auto augmentedTreeSuper2HypernodeView =
|
||||
vtkm::cont::make_ArrayHandleView(this->AugmentedTree->Super2Hypernode,
|
||||
numSupernodesAlready,
|
||||
this->SupernodeSorter.GetNumberOfValues());
|
||||
// invoke the worklet
|
||||
this->Invoke(createSuperarcsWorklet, // the worklet
|
||||
this->SupernodeSorter, // input domain
|
||||
this->SuperparentSet, // input
|
||||
this->BaseTree->Superarcs, // input
|
||||
this->NewSupernodeIds, // input
|
||||
this->BaseTree->Hyperparents, // input
|
||||
this->BaseTree->Supernodes, // input
|
||||
this->BaseTree->RegularNodeGlobalIds, // input
|
||||
this->GlobalRegularIdSet, // input
|
||||
permutedGlobalRegularIdSet, // input
|
||||
this->BaseTree->Super2Hypernode, // input
|
||||
this->BaseTree->WhichRound, // input
|
||||
this->BaseTree->WhichIteration, // input
|
||||
this->DataValueSet, // input
|
||||
vtkm::cont::make_ArrayHandleView(
|
||||
this->AugmentedTree->Superarcs,
|
||||
numSupernodesAlready,
|
||||
this->SupernodeSorter.GetNumberOfValues()), // output
|
||||
this->AugmentedTree->Hyperparents, // input/output
|
||||
augmentedTreeSuperarcsView, // output
|
||||
this->AugmentedTree->FirstSupernodePerIteration[roundNumber], // input/output
|
||||
this->AugmentedTree->Supernodes, // input/output
|
||||
this->AugmentedTree->Super2Hypernode, // input/ouput
|
||||
this->AugmentedTree->WhichRound, // input/ouput
|
||||
this->AugmentedTree->WhichIteration, // input/ouput
|
||||
this->AugmentedTree->RegularNodeGlobalIds, //input/ ouput
|
||||
this->AugmentedTree->DataValues, // input/ouput
|
||||
this->AugmentedTree->Regular2Supernode, // input/ouput
|
||||
this->AugmentedTree->Superparents // input/ouput
|
||||
);*/
|
||||
}
|
||||
augmentedTreeSuper2HypernodeView // output
|
||||
);
|
||||
} // END block for CreateSuperarcsWorklet
|
||||
|
||||
// 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
|
||||
// Set: augmentedTree->hyperparents[newSupernodeID] = baseTree->hyperparents[superparentOldSuperID];
|
||||
auto permutedAugmentedTreeHyperparents =
|
||||
vtkm::cont::make_ArrayHandlePermutation(newSupernodeId, this->AugmentedTree->Hyperparents);
|
||||
auto permutedBaseTreeHyperparents =
|
||||
vtkm::cont::make_ArrayHandlePermutation(superparentOldSuperId, this->BaseTree->Hyperparents);
|
||||
vtkm::cont::Algorithm::Copy(permutedBaseTreeHyperparents, permutedAugmentedTreeHyperparents);
|
||||
|
||||
// which round and iteration carry over
|
||||
// Set: augmentedTree->whichRound[newSupernodeID] = baseTree->whichRound[superparentOldSuperID];
|
||||
auto permutedAugmentedTreeWhichRound =
|
||||
vtkm::cont::make_ArrayHandlePermutation(newSupernodeId, this->AugmentedTree->WhichRound);
|
||||
auto permutedBaseTreeWhichRound =
|
||||
vtkm::cont::make_ArrayHandlePermutation(superparentOldSuperId, this->BaseTree->WhichRound);
|
||||
vtkm::cont::Algorithm::Copy(permutedBaseTreeWhichRound, permutedAugmentedTreeWhichRound);
|
||||
|
||||
// Set: augmentedTree->whichIteration[newSupernodeID] = baseTree->whichIteration[superparentOldSuperID];
|
||||
auto permutedAugmentedTreeWhichIteration =
|
||||
vtkm::cont::make_ArrayHandlePermutation(newSupernodeId, this->AugmentedTree->WhichIteration);
|
||||
auto permutedBaseTreeWhichIterationPortal = vtkm::cont::make_ArrayHandlePermutation(
|
||||
superparentOldSuperId, this->BaseTree->WhichIteration);
|
||||
vtkm::cont::Algorithm::Copy(permutedBaseTreeWhichIterationPortal,
|
||||
permutedAugmentedTreeWhichIteration);
|
||||
|
||||
// now we deal with the regular-sized arrays. In the following supernodeSetIndex is simply supernodeSorterPortal.Get(supernode);
|
||||
// copy the global regular Id and data value
|
||||
// Set: augmentedTree->regularNodeGlobalIDs[newRegularID] = globalRegularIDSet[supernodeSetIndex];
|
||||
auto permutedAugmentedTreeRegularNodeGlobalIds = vtkm::cont::make_ArrayHandlePermutation(
|
||||
newRegularId, this->AugmentedTree->RegularNodeGlobalIds);
|
||||
auto permutedGlobalRegularIdSet =
|
||||
vtkm::cont::make_ArrayHandlePermutation(this->SupernodeSorter, this->GlobalRegularIdSet);
|
||||
vtkm::cont::Algorithm::Copy(permutedGlobalRegularIdSet,
|
||||
permutedAugmentedTreeRegularNodeGlobalIds);
|
||||
// SetL augmentedTree->dataValues[newRegularID] = dataValueSet[supernodeSetIndex];
|
||||
auto permutedAugmentedTreeDataValues =
|
||||
vtkm::cont::make_ArrayHandlePermutation(newRegularId, this->AugmentedTree->DataValues);
|
||||
auto permutedDataValueSet =
|
||||
vtkm::cont::make_ArrayHandlePermutation(this->SupernodeSorter, this->DataValueSet);
|
||||
vtkm::cont::Algorithm::Copy(permutedDataValueSet, permutedAugmentedTreeDataValues);
|
||||
|
||||
// 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
|
||||
// Set: augmentedTree->regular2supernode[newRegularID] = newSupernodeID;
|
||||
auto permutedAugmentedTreeRegular2Supernode =
|
||||
vtkm::cont::make_ArrayHandlePermutation(newRegularId, this->AugmentedTree->Regular2Supernode);
|
||||
vtkm::cont::Algorithm::Copy(newSupernodeId, permutedAugmentedTreeRegular2Supernode);
|
||||
|
||||
// b. as can the superparent
|
||||
// Set: augmentedTree->superparents[newRegularID] = newSupernodeID;
|
||||
auto permutedAugmentedTreeSuperparents =
|
||||
vtkm::cont::make_ArrayHandlePermutation(newRegularId, this->AugmentedTree->Superparents);
|
||||
vtkm::cont::Algorithm::Copy(newSupernodeId, permutedAugmentedTreeSuperparents);
|
||||
} // END scope for e. to delete temporary variables
|
||||
|
||||
// We have one last bit of cleanup to do. If there were attachment points, then the round in which they transfer has been removed
|
||||
// While it is possible to turn this into a null round, it is better to reduce the iteration count by one and resize the arrays
|
||||
|
@ -64,148 +64,115 @@ namespace hierarchical_augmenter
|
||||
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: Check if augmentedTreeFirstSupernodePerIteration could be changed to WholeArrayOut or if we need the In to preserve orignal values
|
||||
|
||||
// TODO: This worklet could probably be optimized further to reduce the use of WholeArray passing
|
||||
/// Control signature for the worklet
|
||||
/// @param[in] supernodeSorter input domain. We need access to InputIndex and InputIndex+1,
|
||||
/// therefore this is a WholeArrayIn transfer.
|
||||
/// @param[in] superparentSet WholeArrayIn because we need access to superparentSet[supernodeSorter[InputIndex]]
|
||||
/// and superparentSet[supernodeSorter[InputIndex+1]].
|
||||
/// @param[in] baseTreeSuperarcs WholeArrayIn because we need access to baseTreeSuperarcsPortal.Get(superparentOldSuperId)
|
||||
/// While this could be done with fancy array magic, it would require a sequence of multiple
|
||||
/// fancy arrays and would likely not be cheaper then computing things in the worklet.
|
||||
/// @param[in] newSupernodeIds WholeArrayIn because we need to access newSupernodeIdsPortal.Get(oldTargetSuperId)
|
||||
/// where oldTargetSuperId is the unmasked baseTreeSuperarcsPortal.Get(superparentOldSuperId)
|
||||
/// @param[in] baseTreeSupernodes WholeArrayIn because we need to access baseTreeSupernodesPortal.Get(superparentOldSuperId);
|
||||
/// @param[in] baseTreeRegularNodeGlobalIds WholeArrayIn because we need to access
|
||||
/// baseTreeRegularNodeGlobalIdsPortal.Get(superparentOldSuperId);
|
||||
/// @param[in] globalRegularIdSet FieldInd. Permute globalRegularIdSet with supernodeSorter in order to allow this to be a FieldIn.
|
||||
/// @param[in] baseTreeSuper2Hypernode WholeArrayIn because we need to access
|
||||
/// baseTreeSuper2HypernodePortal.Get(superparentOldSuperId)
|
||||
/// @param[in] baseTreeWhichIteration WholeArrayIn because we need to access baseTreeWhichIterationPortal.Get(superparentOldSuperId)
|
||||
/// and baseTreeWhichIterationPortal.Get(superparentOldSuperId+1)
|
||||
/// @param[in] augmentedTreeSuperarcsView output view of this->AugmentedTree->Superarcs with
|
||||
/// vtkm::cont::make_ArrayHandleView(this->AugmentedTree->Superarcs,
|
||||
/// numSupernodesAlready, this->SupernodeSorter.GetNumberOfValues()).
|
||||
/// By using this view allows us to do this one as a FieldOut and it effectively the
|
||||
/// same as accessing the array at the newSuppernodeId location.
|
||||
/// @param[in] augmentedTreeFirstSupernodePerIteration WholeArrayInOut because we need to update multiple locations.
|
||||
/// In is used to preseve original values. Set to augmentedTree->firstSupernodePerIteration[roundNumber].
|
||||
/// @param[in] augmentedTreeSuper2hypernode FieldOut. Output view of this->AugmentedTree->Super2Hypernode
|
||||
/// vtkm::cont::make_ArrayHandleView(this->AugmentedTree->Super2Hypernode,
|
||||
/// numSupernodesAlready, this->SupernodeSorter.GetNumberOfValues()).
|
||||
/// By using this view allows us to do this one as a FieldOut and it effectively the
|
||||
/// same as accessing the array at the newSuppernodeId location.
|
||||
using ControlSignature = void(
|
||||
WholeArrayIn supernodeSorter, // input domain (we need access to InputIndex and InputIndex+1)
|
||||
WholeArrayIn supernodeSorter,
|
||||
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?
|
||||
WholeArrayIn baseTreeSupernodes, // input
|
||||
WholeArrayIn baseTreeRegularNodeGlobalIds, // input
|
||||
FieldIn globalRegularIdSet, // input
|
||||
WholeArrayIn baseTreeSuper2Hypernode, // input
|
||||
WholeArrayIn baseTreeWhichIteration, // input
|
||||
FieldOut augmentedTreeSuperarcsView, // output
|
||||
WholeArrayInOut augmentedTreeFirstSupernodePerIteration, // input/output
|
||||
FieldOut augmentedTreeSuper2hypernode // ouput
|
||||
);
|
||||
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 ExecutionSignature = void(InputIndex, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12);
|
||||
using InputDomain = _1;
|
||||
|
||||
/// Default Constructor
|
||||
/// @param[in] numSupernodesAlready Set to vtkm::cont::ArrayGetValue(0, this->AugmentedTree->FirstSupernodePerIteration[roundNumber]);
|
||||
/// @param[in] baseTreeNumRounds Set to this->BaseTree->NumRounds
|
||||
/// @param[in] augmentedTreeNumIterations Set to vtkm::cont::ArrayGetValue(roundNumber, this->AugmentedTree->NumIterations);
|
||||
/// @param[in] roundNumber Set the current round
|
||||
/// @param[in] numAugmentedTreeSupernodes Set to augmentedTreeSupernodes this->AugmentedTree->Supernodes.GetNumberOfValues();
|
||||
VTKM_EXEC_CONT
|
||||
CreateSuperarcsWorklet(
|
||||
const vtkm::Id& numSupernodesAlready,
|
||||
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)
|
||||
const vtkm::Id& augmentedTreeNumIterations,
|
||||
const vtkm::Id& roundNumber,
|
||||
const vtkm::Id& numAugmentedTreeSupernodes)
|
||||
: NumSupernodesAlready(numSupernodesAlready)
|
||||
, BaseTreeNumRounds(baseTreeNumRounds)
|
||||
, AugmentedTreeNumIterations(augmentedTreeNumIterations)
|
||||
, RoundNumber(roundNumber)
|
||||
|
||||
, NumAugmentedTreeSupernodes(numAugmentedTreeSupernodes)
|
||||
{
|
||||
}
|
||||
|
||||
/// operator() of the workelt
|
||||
template <typename InFieldPortalType,
|
||||
typename InFieldPortalType2,
|
||||
typename InOutFieldPortalType,
|
||||
typename InOutFieldPortalType2>
|
||||
template <typename InFieldPortalType, typename InOutFieldPortalType>
|
||||
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 vtkm::Id& globalRegularIdSetValue,
|
||||
const InFieldPortalType& baseTreeSuper2HypernodePortal,
|
||||
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
|
||||
vtkm::Id& augmentedTreeSuper2hypernodeValue) 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
|
||||
// work out the new supernode Id. We have this defined on the outside as a fancy array handle,
|
||||
// however, using the fancy handle here would not really make a performance differnce and
|
||||
// computing it here is more readable
|
||||
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;
|
||||
// NOTE: The newRegularId is no longer needed here since all parts
|
||||
// that used it in the worklet have been moved outside
|
||||
// vtkm::Id newRegularId = newSupernodeId;
|
||||
|
||||
// setting the supernode's regular Id is now trivial
|
||||
augmentedTreeSupernodesPortal.Set(newSupernodeId, newRegularId);
|
||||
// NOTE: This part has been moved out of the worklet and is performed using standard vtkm copy constructs
|
||||
// // 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);
|
||||
// get the ascending flag from the parent
|
||||
bool superarcAscends = vtkm::worklet::contourtree_augmented::IsAscending(superparentSetVal);
|
||||
|
||||
// strip the ascending flag from the superparent
|
||||
// strip the ascending flag from the superparent.
|
||||
vtkm::Id superparentOldSuperId =
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(superparentSetVal);
|
||||
|
||||
@ -234,8 +201,8 @@ public:
|
||||
(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());
|
||||
augmentedTreeFirstSupernodePerIterationPortal.Set(this->AugmentedTreeNumIterations,
|
||||
NumAugmentedTreeSupernodes);
|
||||
} // last in the array
|
||||
else if (superparentOldSuperId !=
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(
|
||||
@ -273,47 +240,50 @@ public:
|
||||
// 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));
|
||||
|
||||
// NOTE: This part has been moved out of the worklet and is performed using standard vtkm copy constructs
|
||||
// // 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));
|
||||
|
||||
// NOTE: This part could potentially be made a separate worklet but it does not seem necessary
|
||||
// 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))
|
||||
// Here: globalRegularIdSetValue is the same as globalRegularIdSetPortal.Get(supernodeSetIndex)
|
||||
if (superparentGlobalId == globalRegularIdSetValue)
|
||||
{
|
||||
augmentedTreeSuper2hypernodePortal.Set(
|
||||
newSupernodeId, baseTreeSuper2hypernodePortal.Get(superparentOldSuperId));
|
||||
// augmentedTreeSuper2hypernodePortal.Set(newSupernodeId, baseTreeSuper2HypernodePortal.Get(superparentOldSuperId));
|
||||
augmentedTreeSuper2hypernodeValue = baseTreeSuper2HypernodePortal.Get(superparentOldSuperId);
|
||||
}
|
||||
else
|
||||
{
|
||||
augmentedTreeSuper2hypernodePortal.Set(newSupernodeId,
|
||||
vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT);
|
||||
// augmentedTreeSuper2hypernodePortal.Set(newSupernodeId, vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT);
|
||||
augmentedTreeSuper2hypernodeValue = 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));
|
||||
// NOTE: This part has been moved out of the worklet and is performed using standard vtkm copy constructs
|
||||
// // 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));
|
||||
// NOTE: This part has been moved out of the worklet and is performed using standard vtkm copy constructs
|
||||
// // 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);
|
||||
// NOTE: This part has been moved out of the worklet and is performed using standard vtkm copy constructs
|
||||
// // 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
|
||||
/*
|
||||
@ -434,6 +404,7 @@ private:
|
||||
const vtkm::Id BaseTreeNumRounds;
|
||||
const vtkm::Id AugmentedTreeNumIterations;
|
||||
const vtkm::Id RoundNumber;
|
||||
const vtkm::Id NumAugmentedTreeSupernodes;
|
||||
|
||||
}; // CreateSuperarcsWorklet
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user