mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-05 01:49:02 +00:00
Added fixes for HierarchicalHyperSweeper for pre-simplification
This commit is contained in:
parent
3853dbe8ec
commit
2c0b127f7b
@ -153,7 +153,7 @@ inline bool NoFlagsSet(vtkm::Id flaggedIndex)
|
||||
|
||||
// Helper function: to check that the TRANSFER_TO_SUPERARC flag is set
|
||||
VTKM_EXEC_CONT
|
||||
inline bool transferToSuperarc(vtkm::Id flaggedIndex)
|
||||
inline bool TransferToSuperarc(vtkm::Id flaggedIndex)
|
||||
{ // transferToSuperarc()
|
||||
return ((flaggedIndex & TRANSFER_TO_SUPERARC) != 0);
|
||||
} // transferToSuperarc()
|
||||
|
@ -91,7 +91,9 @@
|
||||
#include <vtkm/filter/scalar_topology/worklet/contourtree_distributed/hierarchical_hyper_sweeper/InitializeIntrinsicVertexCountSubtractLowEndWorklet.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/contourtree_distributed/hierarchical_hyper_sweeper/TransferTargetComperator.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/contourtree_distributed/hierarchical_hyper_sweeper/TransferWeightsUpdateLHEWorklet.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/contourtree_distributed/hierarchical_hyper_sweeper/TransferWeightsUpdateLHEWorkletRound2.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/contourtree_distributed/hierarchical_hyper_sweeper/TransferWeightsUpdateRHEWorklet.h>
|
||||
#include <vtkm/filter/scalar_topology/worklet/contourtree_distributed/hierarchical_hyper_sweeper/TransferWeightsUpdateRHEWorkletRound2.h>
|
||||
|
||||
|
||||
namespace vtkm
|
||||
@ -530,6 +532,9 @@ void HierarchicalHyperSweeper<SweepValueType, ContourTreeFieldType>::ComputeSupe
|
||||
} // scope ComputeSuperarcTransferWeightsWorklet
|
||||
|
||||
// 5. Now we need to sort the transfer targets into contiguous segments
|
||||
// TODO / WARNING 11/07/2023
|
||||
// We have now got a flag of ATTACHMENT_POINT_TRANSFER whose effect is to separate out transfers to
|
||||
// the superarc from transfers to the supernode
|
||||
{
|
||||
// create view of superSortPermute[firstSupernode, lastSupernode) for sorting
|
||||
vtkm::cont::ArrayHandleView<vtkm::worklet::contourtree_augmented::IdArrayType>
|
||||
@ -578,6 +583,16 @@ void HierarchicalHyperSweeper<SweepValueType, ContourTreeFieldType>::TransferWei
|
||||
vtkm::Id firstSupernode,
|
||||
vtkm::Id lastSupernode)
|
||||
{ // TransferWeights()
|
||||
// TODO / WARNING 11/07/2023
|
||||
// This code was originally written on the assumption that the hierarchical tree had been augmented by the attachment points.
|
||||
// As a result, it assumed that no attachment points remained.
|
||||
// It is now being used for partially augmented versions due to pre-simplification, for which the correct treatment is to
|
||||
// transfer not as dependent weight, but as intrinsic weight. Note that this ONLY applies to attachment points: if the
|
||||
// subtree attaches at a proper supernode in the ancestor level, it should still be treated as dependent weight. The logic
|
||||
// behind this is that an attachment point is regular with respect to the superarc along which it inserts. Adding it as
|
||||
// dependent weight means that it is treated as *OUTSIDE* the superarc in the reverse sweep (or equivalent computation)
|
||||
// Treating it as dependent weight means that both ends of the superarc end up with the correct value.
|
||||
|
||||
// 7. Now perform a segmented prefix sum
|
||||
vtkm::Id numSupernodesToProcess = lastSupernode - firstSupernode;
|
||||
// Same as std::partial_sum(valuePrefixSum.begin() + firstSupernode, valuePrefixSum.begin() + lastSupernode, valuePrefixSum.begin() + firstSupernode);
|
||||
@ -602,6 +617,12 @@ void HierarchicalHyperSweeper<SweepValueType, ContourTreeFieldType>::TransferWei
|
||||
|
||||
// 7a. and 7b.
|
||||
{
|
||||
// TODO / WARNING 11/07/2023
|
||||
// Before dealing with attachment points, we just transferred by segments. We now have
|
||||
// the possibility of transferring some weight at an attachment point,
|
||||
// and some not. To avoid write conflicts, we treat this as two passes: one for attachment
|
||||
// points, one for all others. This means duplicating 7a/7b, sadly.
|
||||
|
||||
// 7a. Find the RHE of each group and transfer the prefix sum weight
|
||||
// Note that we do not compute the transfer weight separately, we add it in place instead
|
||||
// Instantiate the worklet
|
||||
@ -634,7 +655,7 @@ void HierarchicalHyperSweeper<SweepValueType, ContourTreeFieldType>::TransferWei
|
||||
auto valuePrefixSumPreviousValueView = vtkm::cont::make_ArrayHandleView(
|
||||
this->ValuePrefixSum, firstSupernode, numSupernodesToProcess - 1);
|
||||
|
||||
// 7b. Now find the LHE of each group and subtract out the prior weight
|
||||
// 7b (non-attachment). Now find the LHE of each group and subtract out the prior weight.
|
||||
vtkm::worklet::contourtree_distributed::hierarchical_hyper_sweeper::
|
||||
TransferWeightsUpdateLHEWorklet transferWeightsUpdateLHEWorklet;
|
||||
this->Invoke(transferWeightsUpdateLHEWorklet,
|
||||
@ -643,6 +664,43 @@ void HierarchicalHyperSweeper<SweepValueType, ContourTreeFieldType>::TransferWei
|
||||
valuePrefixSumPreviousValueView,
|
||||
this->DependentValues);
|
||||
}
|
||||
|
||||
// 7a (attachment). Find the RHE of each group and transfer the prefix sum weight
|
||||
// Note that we do not compute the transfer weight separately, we add it in place instead
|
||||
{
|
||||
auto supernodeIndex =
|
||||
vtkm::cont::make_ArrayHandleCounting(firstSupernode, vtkm::Id{ 1 }, numSupernodesToProcess);
|
||||
auto valuePrefixSumView = vtkm::cont::make_ArrayHandleView(
|
||||
this->ValuePrefixSum, firstSupernode, numSupernodesToProcess);
|
||||
|
||||
vtkm::worklet::contourtree_distributed::hierarchical_hyper_sweeper::
|
||||
TransferWeightsUpdateRHEWorkletRound2 transferWeightsUpdateRHEWorkletRound2(lastSupernode);
|
||||
// Invoke the worklet
|
||||
this->Invoke(transferWeightsUpdateRHEWorkletRound2, // worklet
|
||||
supernodeIndex, // input counting array [firstSupernode, lastSupernode)
|
||||
this->SortedTransferTarget,
|
||||
valuePrefixSumView, // input view of valuePrefixSum[firstSupernode, lastSupernode)
|
||||
this->IntrinsicValues,
|
||||
this->DependentValues);
|
||||
}
|
||||
// 7b (i). Now find the LHE of each group and subtract out the prior weight.
|
||||
{
|
||||
auto sortedTransferTargetView = vtkm::cont::make_ArrayHandleView(
|
||||
this->SortedTransferTarget, firstSupernode + 1, numSupernodesToProcess - 1);
|
||||
auto sortedTransferTargetShiftedView = vtkm::cont::make_ArrayHandleView(
|
||||
this->SortedTransferTarget, firstSupernode, numSupernodesToProcess - 1);
|
||||
auto valuePrefixSumPreviousValueView = vtkm::cont::make_ArrayHandleView(
|
||||
this->ValuePrefixSum, firstSupernode, numSupernodesToProcess - 1);
|
||||
|
||||
vtkm::worklet::contourtree_distributed::hierarchical_hyper_sweeper::
|
||||
TransferWeightsUpdateLHEWorkletRound2 transferWeightsUpdateLHEWorkletRound2;
|
||||
this->Invoke(transferWeightsUpdateLHEWorkletRound2,
|
||||
sortedTransferTargetView,
|
||||
sortedTransferTargetShiftedView,
|
||||
valuePrefixSumPreviousValueView,
|
||||
this->IntrinsicValues,
|
||||
this->DependentValues);
|
||||
}
|
||||
} // TransferWeights()
|
||||
|
||||
|
||||
|
@ -17,6 +17,8 @@ set(headers
|
||||
TransferTargetComperator.h
|
||||
TransferWeightsUpdateRHEWorklet.h
|
||||
TransferWeightsUpdateLHEWorklet.h
|
||||
TransferWeightsUpdateRHEWorkletRound2.h
|
||||
TransferWeightsUpdateLHEWorkletRound2.h
|
||||
)
|
||||
|
||||
vtkm_declare_headers(${headers})
|
||||
|
@ -116,7 +116,8 @@ public:
|
||||
else
|
||||
{ // attachment point
|
||||
// set the transfer target
|
||||
transferTarget = hierarchicalTreeSuperparentsPortal.Get(supernodeRegularId);
|
||||
transferTarget = hierarchicalTreeSuperparentsPortal.Get(supernodeRegularId) |
|
||||
vtkm::worklet::contourtree_augmented::TRANSFER_TO_SUPERARC;
|
||||
} // attachment point
|
||||
} // null superarc
|
||||
else
|
||||
|
@ -74,10 +74,11 @@ public:
|
||||
FieldIn sortedTransferTargetShiftedView,
|
||||
FieldIn valuePrefixSumShiftedView,
|
||||
WholeArrayInOut dependentValuesPortal);
|
||||
using ExecutionSgnature = void(_1, _2, _3, _4);
|
||||
using ExecutionSignature = void(InputIndex, _1, _2, _3, _4);
|
||||
|
||||
template <typename InOutPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& sortedTransferTargetValue,
|
||||
VTKM_EXEC void operator()(const vtkm::Id& supernode,
|
||||
const vtkm::Id& sortedTransferTargetValue,
|
||||
const vtkm::Id& sortedTransferTargetPreviousValue,
|
||||
const vtkm::Id& valuePrefixSumPreviousValue,
|
||||
InOutPortalType& dependentValuesPortal) const
|
||||
@ -88,30 +89,33 @@ public:
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (sortedTransferTargetValue != sortedTransferTargetPreviousValue)
|
||||
|
||||
// we need to separate out the flag for attachment points
|
||||
bool superarcTransfer =
|
||||
vtkm::worklet::contourtree_augmented::TransferToSuperarc(sortedTransferTargetValue);
|
||||
vtkm::Id superarcOrNodeId =
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(sortedTransferTargetValue);
|
||||
|
||||
// ignore the transfers for attachment points
|
||||
if (superarcTransfer)
|
||||
{
|
||||
auto originalValue = dependentValuesPortal.Get(sortedTransferTargetValue);
|
||||
return;
|
||||
}
|
||||
|
||||
// the LHE at 0 is special - it subtracts zero. In practice, since NO_SUCH_ELEMENT will sort low, this will never
|
||||
// occur, but let's keep the logic strict
|
||||
auto originalValue = dependentValuesPortal.Get(superarcOrNodeId);
|
||||
if (supernode ==
|
||||
0) // i.e., supernode == firstSupernode but we view the arrays when we call the worklet
|
||||
{ // LHE 0
|
||||
dependentValuesPortal.Set(superarcOrNodeId, originalValue - 0);
|
||||
}
|
||||
else if (sortedTransferTargetValue != sortedTransferTargetPreviousValue)
|
||||
{ // LHE not 0
|
||||
|
||||
dependentValuesPortal.Set(sortedTransferTargetValue,
|
||||
originalValue - valuePrefixSumPreviousValue);
|
||||
}
|
||||
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (vtkm::Id supernode = firstSupernode + 1; supernode < lastSupernode; supernode++)
|
||||
{ // per supernode
|
||||
// ignore any that point at NO_SUCH_ELEMENT
|
||||
if (noSuchElement(sortedTransferTarget[supernode]))
|
||||
continue;
|
||||
|
||||
// the LHE at 0 is special - it subtracts zero. In practice, since NO_SUCH_ELEMENT will sort low, this will never
|
||||
// occur, but let's keep the logic strict
|
||||
if (sortedTransferTarget[supernode] != sortedTransferTarget[supernode-1])
|
||||
{ // LHE not 0
|
||||
dependentValues[sortedTransferTarget[supernode]] -= valuePrefixSum[supernode-1];
|
||||
} // LHE not 0
|
||||
} // per supernode
|
||||
*/
|
||||
} // operator()()
|
||||
}; // TransferWeightsUpdateLHEWorklet
|
||||
|
||||
|
132
vtkm/filter/scalar_topology/worklet/contourtree_distributed/hierarchical_hyper_sweeper/TransferWeightsUpdateLHEWorkletRound2.h
Normal file
132
vtkm/filter/scalar_topology/worklet/contourtree_distributed/hierarchical_hyper_sweeper/TransferWeightsUpdateLHEWorkletRound2.h
Normal file
@ -0,0 +1,132 @@
|
||||
//============================================================================
|
||||
// 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_hyper_sweeper_transfer_weights_update_lhe_worklet_round2_h
|
||||
#define vtk_m_worklet_contourtree_distributed_hierarchical_hyper_sweeper_transfer_weights_update_lhe_worklet_round2_h
|
||||
|
||||
#include <vtkm/filter/scalar_topology/worklet/contourtree_augmented/Types.h>
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace hierarchical_hyper_sweeper
|
||||
{
|
||||
|
||||
/// Worklet used in HierarchicalHyperSweeper.TransferWeights(...) to implement
|
||||
/// step 7b. Now find the LHE of each group and subtract out the prior weight
|
||||
class TransferWeightsUpdateLHEWorkletRound2 : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn sortedTransferTargetPortal,
|
||||
FieldIn sortedTransferTargetShiftedView,
|
||||
FieldIn valuePrefixSumShiftedView,
|
||||
WholeArrayInOut intrinsicValues,
|
||||
WholeArrayInOut dependentValues);
|
||||
using ExecutionSignature = void(InputIndex, _1, _2, _3, _4, _5);
|
||||
|
||||
template <typename InOutPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& supernode,
|
||||
const vtkm::Id& sortedTransferTargetValue,
|
||||
const vtkm::Id& sortedTransferTargetPreviousValue,
|
||||
const vtkm::Id& valuePrefixSumPreviousValue,
|
||||
InOutPortalType& intrinsicValuesPortal,
|
||||
InOutPortalType& dependentValuesPortal) const
|
||||
{
|
||||
// per supernode
|
||||
// ignore any that point at NO_SUCH_ELEMENT
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(sortedTransferTargetValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// we need to separate out the flag for attachment points
|
||||
bool superarcTransfer =
|
||||
vtkm::worklet::contourtree_augmented::TransferToSuperarc(sortedTransferTargetValue);
|
||||
vtkm::Id superarcOrNodeId =
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(sortedTransferTargetValue);
|
||||
|
||||
// ignore the transfers for attachment points
|
||||
if (superarcTransfer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// the LHE at 0 is special - it subtracts zero. In practice, since NO_SUCH_ELEMENT will sort low, this will never
|
||||
// occur, but let's keep the logic strict
|
||||
auto originalIntrinsicValue = dependentValuesPortal.Get(superarcOrNodeId);
|
||||
auto originalDependentValue = dependentValuesPortal.Get(superarcOrNodeId);
|
||||
if (supernode ==
|
||||
0) // i.e., supernode == firstSupernode but we view the arrays when we call the worklet
|
||||
{ // LHE 0
|
||||
intrinsicValuesPortal.Set(superarcOrNodeId, originalIntrinsicValue - 0);
|
||||
dependentValuesPortal.Set(superarcOrNodeId, originalDependentValue - 0);
|
||||
}
|
||||
else if (sortedTransferTargetValue != sortedTransferTargetPreviousValue)
|
||||
{ // LHE not 0
|
||||
intrinsicValuesPortal.Set(sortedTransferTargetValue,
|
||||
originalIntrinsicValue - valuePrefixSumPreviousValue);
|
||||
dependentValuesPortal.Set(sortedTransferTargetValue,
|
||||
originalDependentValue - valuePrefixSumPreviousValue);
|
||||
}
|
||||
} // operator()()
|
||||
}; // TransferWeightsUpdateLHEWorklet
|
||||
|
||||
} // namespace hierarchical_hyper_sweeper
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
@ -100,8 +100,18 @@ public:
|
||||
if ((supernode == this->LastSupernode - 1) ||
|
||||
(transferTarget != sortedTransferTargetPortal.Get(supernode + 1)))
|
||||
{ // RHE of segment
|
||||
auto originalValue = dependentValuesPortal.Get(transferTarget);
|
||||
dependentValuesPortal.Set(transferTarget, originalValue + valuePrefixSum);
|
||||
// we need to separate out the flag for attachment points
|
||||
bool superarcTransfer =
|
||||
vtkm::worklet::contourtree_augmented::TransferToSuperarc(transferTarget);
|
||||
vtkm::Id superarcOrNodeId =
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(transferTarget);
|
||||
// we ignore attachment points
|
||||
if (superarcTransfer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto originalValue = dependentValuesPortal.Get(superarcOrNodeId);
|
||||
dependentValuesPortal.Set(superarcOrNodeId, originalValue + valuePrefixSum);
|
||||
} // RHE of segment
|
||||
}
|
||||
|
||||
@ -113,10 +123,19 @@ public:
|
||||
if (noSuchElement(sortedTransferTarget[supernode]))
|
||||
continue;
|
||||
|
||||
// the RHE of each segment transfers its weight (including all irrelevant prefixes)
|
||||
if ((supernode == lastSupernode - 1) || (sortedTransferTarget[supernode] != sortedTransferTarget[supernode+1]))
|
||||
{ // RHE of segment
|
||||
dependentValues[sortedTransferTarget[supernode]] += valuePrefixSum[supernode];
|
||||
// TODO / WARNING 11/07/2023
|
||||
// we need to separate out the flag for attachment points
|
||||
bool superarcTransfer = transferToSuperarc(sortedTransferTarget[supernode]);
|
||||
indexType superarcOrNodeID = maskedIndex(sortedTransferTarget[supernode]);
|
||||
|
||||
// we ignore attachment points
|
||||
if (superarcTransfer)
|
||||
continue;
|
||||
|
||||
// transfer as dependent weight
|
||||
dependentValues[superarcOrNodeID] += valuePrefixSum[supernode];
|
||||
} // RHE of segment
|
||||
} // per supernode
|
||||
*/
|
||||
|
161
vtkm/filter/scalar_topology/worklet/contourtree_distributed/hierarchical_hyper_sweeper/TransferWeightsUpdateRHEWorkletRound2.h
Normal file
161
vtkm/filter/scalar_topology/worklet/contourtree_distributed/hierarchical_hyper_sweeper/TransferWeightsUpdateRHEWorkletRound2.h
Normal file
@ -0,0 +1,161 @@
|
||||
//============================================================================
|
||||
// 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_hyper_sweeper_transfer_weights_update_rhe_worklet_round2_h
|
||||
#define vtk_m_worklet_contourtree_distributed_hierarchical_hyper_sweeper_transfer_weights_update_rhe_worklet_round2_h
|
||||
|
||||
#include <vtkm/filter/scalar_topology/worklet/contourtree_augmented/Types.h>
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace hierarchical_hyper_sweeper
|
||||
{
|
||||
|
||||
/// Worklet used in HierarchicalHyperSweeper.TransferWeights(...) to implement
|
||||
/// step 7a. Find the RHE of each group and transfer the prefix sum weight.
|
||||
/// Note that we do not compute the transfer weight separately, we add it in place instead
|
||||
class TransferWeightsUpdateRHEWorkletRound2 : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature =
|
||||
void(FieldIn supernodeIndex, // input counting array [firstSupernode, lastSupernode)
|
||||
WholeArrayIn sortedTransferTarget,
|
||||
FieldIn valuePrefixSumView, // input view of valuePrefixSum[firstSupernode, lastSupernode)
|
||||
WholeArrayInOut intrinsicValuesPortal,
|
||||
WholeArrayInOut dependentValuesPortal);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5);
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
TransferWeightsUpdateRHEWorkletRound2(const vtkm::Id& lastSupernode)
|
||||
: LastSupernode(lastSupernode)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename InPortalType, typename OutPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& supernode,
|
||||
const InPortalType& sortedTransferTargetPortal,
|
||||
const vtkm::Id& valuePrefixSum, // same as valuePrefixSum[supernode]
|
||||
OutPortalType& intrinsicValuesPortal,
|
||||
OutPortalType& dependentValuesPortal) const
|
||||
{
|
||||
// per supernode
|
||||
// ignore any that point at NO_SUCH_ELEMENT
|
||||
vtkm::Id transferTarget = sortedTransferTargetPortal.Get(supernode);
|
||||
if (!vtkm::worklet::contourtree_augmented::NoSuchElement(transferTarget))
|
||||
{
|
||||
// the RHE of each segment transfers its weight (including all irrelevant prefixes)
|
||||
if ((supernode == this->LastSupernode - 1) ||
|
||||
(transferTarget != sortedTransferTargetPortal.Get(supernode + 1)))
|
||||
{ // RHE of segment
|
||||
// we need to separate out the flag for attachment points
|
||||
bool superarcTransfer =
|
||||
vtkm::worklet::contourtree_augmented::TransferToSuperarc(transferTarget);
|
||||
vtkm::Id superarcOrNodeId =
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(transferTarget);
|
||||
// we ignore attachment points
|
||||
if (superarcTransfer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// we modify both intrinsic and dependent values
|
||||
// we modify both intrinsic and dependent values
|
||||
auto originalIntrinsicValue = intrinsicValuesPortal.Get(superarcOrNodeId);
|
||||
intrinsicValuesPortal.Set(superarcOrNodeId, originalIntrinsicValue + valuePrefixSum);
|
||||
auto originalDependentValue = dependentValuesPortal.Get(superarcOrNodeId);
|
||||
dependentValuesPortal.Set(superarcOrNodeId, originalDependentValue + valuePrefixSum);
|
||||
} // RHE of segment
|
||||
}
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType supernode = firstSupernode; supernode < lastSupernode; supernode++)
|
||||
{ // per supernode
|
||||
// ignore any that point at NO_SUCH_ELEMENT
|
||||
if (noSuchElement(sortedTransferTarget[supernode]))
|
||||
continue;
|
||||
|
||||
// the RHE of each segment transfers its weight (including all irrelevant prefixes)
|
||||
if ((supernode == lastSupernode - 1) || (sortedTransferTarget[supernode] != sortedTransferTarget[supernode+1]))
|
||||
{ // RHE of segment
|
||||
// we need to separate out the flag for attachment points
|
||||
bool superarcTransfer = transferToSuperarc(sortedTransferTarget[supernode]);
|
||||
indexType superarcOrNodeID = maskedIndex(sortedTransferTarget[supernode]);
|
||||
// ignore the transfers for non-attachment points
|
||||
if (!superarcTransfer)
|
||||
continue;
|
||||
|
||||
// we modify both intrinsic and dependent values
|
||||
intrinsicValues[superarcOrNodeID] += valuePrefixSum[supernode];
|
||||
dependentValues[superarcOrNodeID] += valuePrefixSum[supernode];
|
||||
} // RHE of segment
|
||||
|
||||
} // per supernode
|
||||
*/
|
||||
} // operator()()
|
||||
|
||||
private:
|
||||
const vtkm::Id LastSupernode;
|
||||
|
||||
}; // TransferWeightsUpdateRHEWorklet
|
||||
|
||||
} // namespace hierarchical_hyper_sweeper
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user