mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-19 18:45:43 +00:00
Updated TreeGrafter for parallel hypersweep
This commit is contained in:
parent
76d88db157
commit
7506068236
@ -66,6 +66,7 @@
|
||||
#include <vtkm/worklet/contourtree_augmented/ContourTree.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/HierarchicalContourTree.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/InteriorForest.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/tree_grafter/CalculateAttachementCounterWorklet.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/tree_grafter/CollapseRegularChainsWorklet.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/tree_grafter/CopyFirstHypernodePerIterationWorklet.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/tree_grafter/CopyFirstSupernodePerIterationWorklet.h>
|
||||
@ -354,7 +355,18 @@ void TreeGrafter<MeshType, FieldType>::GraftInteriorForests(
|
||||
// count the number of iterations
|
||||
this->NumTransferIterations = 0;
|
||||
|
||||
// Now loop to transfer one iteration at a time
|
||||
// There are several cases we need to handle properly
|
||||
// 1. We could have a round with no superarcs to add (in which case we are
|
||||
// guaranteed not to have attachment points)
|
||||
// 2. We could have a round with some superarcs but no attachment points
|
||||
// (because we attach to existing supernodes)
|
||||
// 3. We could have a round with attachment points to add
|
||||
// Attachment points are interior, so are never added to the active superarc
|
||||
// list in the first place. This means that we need to have an extra round
|
||||
// some of the time to transfer attachment points. So the logic is:
|
||||
// first we transfer all active superarcs, then we test (somehow) for having
|
||||
// attachment points to transfer
|
||||
// Loop to transfer active superarcs with a variation of the PPP transfer phase
|
||||
// We stop when all that is left are attachment points (which aren't included in the active list)
|
||||
while (this->ActiveSuperarcs.GetNumberOfValues() > 0)
|
||||
{ // loop to transfer
|
||||
@ -381,18 +393,34 @@ void TreeGrafter<MeshType, FieldType>::GraftInteriorForests(
|
||||
DebugPrint("Finished Transfer Iterations", __FILE__, __LINE__));
|
||||
#endif
|
||||
|
||||
// Now set the transfer iteration for all attachment points
|
||||
// If there were no supernodes to transfer, their types are all NO_SUCH_ELEMENT
|
||||
auto setTransferIterationWorklet = vtkm::worklet::contourtree_distributed::tree_grafter::
|
||||
GraftInteriorForestsSetTransferIterationWorklet(this->NumTransferIterations);
|
||||
this->Invoke(setTransferIterationWorklet,
|
||||
this->SupernodeType, // input
|
||||
this->HierarchicalSuperId, // input
|
||||
this->WhenTransferred // output
|
||||
// At this point, we can check to see whether all supernodes in the residue have already been transferred
|
||||
// length of the attachementCounter will be set to (this->ContourTree->Supernodes.GetNumberOfValue());
|
||||
// as a result of the worklet
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType attachmentCounter;
|
||||
vtkm::worklet::contourtree_distributed::tree_grafter::CalculateAttachementCounterWorklet
|
||||
calculateAttachementCounterWorklet;
|
||||
this->Invoke(calculateAttachementCounterWorklet, // worklet
|
||||
this->SupernodeType, // input
|
||||
this->HierarchicalSuperId, // input
|
||||
attachmentCounter // output
|
||||
);
|
||||
vtkm::Id numAttachmentPoints = vtkm::cont::Algorithm::Reduce(attachmentCounter, 0, vtkm::Sum());
|
||||
|
||||
// and increment the number of iterations
|
||||
this->NumTransferIterations++;
|
||||
// if there are any at all, we need an extra iteration
|
||||
if (numAttachmentPoints > 0)
|
||||
{ // attachment points needing transfer
|
||||
// Now set the transfer iteration for all attachment points
|
||||
// If there were no supernodes to transfer, their types are all NO_SUCH_ELEMENT
|
||||
auto setTransferIterationWorklet = vtkm::worklet::contourtree_distributed::tree_grafter::
|
||||
GraftInteriorForestsSetTransferIterationWorklet(this->NumTransferIterations);
|
||||
this->Invoke(setTransferIterationWorklet,
|
||||
this->SupernodeType, // input
|
||||
this->HierarchicalSuperId, // input
|
||||
this->WhenTransferred // output
|
||||
);
|
||||
// and increment the number of iterations
|
||||
this->NumTransferIterations++;
|
||||
} // attachment points needing transfer
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
@ -1397,8 +1425,8 @@ void TreeGrafter<MeshType, FieldType>::CopyIterationDetails(
|
||||
this->NewSupernodes.GetNumberOfValues());
|
||||
hierarchicalTree.NumHypernodesInRound.WritePortal().Set(theRound,
|
||||
this->NewHypernodes.GetNumberOfValues());
|
||||
// the -1 is because the last iteration is just setting attachment points
|
||||
hierarchicalTree.NumIterations.WritePortal().Set(theRound, this->NumTransferIterations - 1);
|
||||
// last iteration is just setting attachment points (but we are including this now) (previously added -1)
|
||||
hierarchicalTree.NumIterations.WritePortal().Set(theRound, this->NumTransferIterations);
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
@ -1424,7 +1452,7 @@ void TreeGrafter<MeshType, FieldType>::CopyIterationDetails(
|
||||
// and set the per round iteration counts. There may be smarter ways of doing this, but . . .
|
||||
this->ResizeVector<vtkm::Id>(
|
||||
hierarchicalTree.FirstSupernodePerIteration[static_cast<std::size_t>(theRound)],
|
||||
this->NumTransferIterations,
|
||||
this->NumTransferIterations + 1,
|
||||
vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT);
|
||||
{
|
||||
auto copyFirstSupernodePerIterationWorklet =
|
||||
@ -1445,11 +1473,16 @@ void TreeGrafter<MeshType, FieldType>::CopyIterationDetails(
|
||||
hierarchicalTree.DebugPrint("Supernode Iteration Counts Set", __FILE__, __LINE__));
|
||||
#endif
|
||||
|
||||
// Initalize hierarchicalTree.FirstHypernodePerIteration with NO_SUCH_ELEMENT
|
||||
// we add one so we don't need special cases when establishing subranges
|
||||
// There's a tricky case to be dealt with due to attachment points - the last (extra) iteration transfers supernodes
|
||||
// with a "virtual" superarc but no hyperarc. This can only occur in the final iteration, in which case the correct value is
|
||||
// the "off the end" sentinel. But it is also possible for there to be no attachment points, in which case the final iteration
|
||||
// will have some other value. Also, we need to set the "off the end" for the extra entry in any event.
|
||||
// THEREFORE, instead of instantiating to NO_SUCH_ELEMENT for safety, we instantiate to the hypernodes.size()
|
||||
this->ResizeVector<vtkm::Id>(
|
||||
hierarchicalTree.FirstHypernodePerIteration[static_cast<std::size_t>(theRound)],
|
||||
this->NumTransferIterations,
|
||||
vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT);
|
||||
this->NumTransferIterations + 1,
|
||||
hierarchicalTree.Hypernodes.GetNumberOfValues());
|
||||
// copy the approbriat hierarchicalTree.FirstHypernodePerIteration values
|
||||
{
|
||||
auto copyFirstHypernodePerIterationWorklet =
|
||||
@ -1466,9 +1499,9 @@ void TreeGrafter<MeshType, FieldType>::CopyIterationDetails(
|
||||
);
|
||||
}
|
||||
|
||||
// force the extra one to be one-off-the end for safety
|
||||
hierarchicalTree.FirstHypernodePerIteration[static_cast<size_t>(theRound)].WritePortal().Set(
|
||||
this->NumTransferIterations - 1, hierarchicalTree.Hypernodes.GetNumberOfValues());
|
||||
// force the extra one to be one-off-the end for safety; REMOVED - SEE ABOVE FOR LOGIC
|
||||
//hierarchicalTree.FirstHypernodePerIteration[static_cast<size_t>(theRound)].WritePortal().Set(
|
||||
// this->NumTransferIterations, hierarchicalTree.Hypernodes.GetNumberOfValues());
|
||||
|
||||
#ifdef DEBUG_PRINT
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
|
@ -32,6 +32,7 @@ set(headers
|
||||
CopyNewNodesSetSuperparentsWorklet.h
|
||||
CopyFirstSupernodePerIterationWorklet.h
|
||||
CopyFirstHypernodePerIterationWorklet.h
|
||||
CalculateAttachementCounterWorklet.h
|
||||
)
|
||||
|
||||
vtkm_declare_headers(${headers})
|
||||
|
105
vtkm/worklet/contourtree_distributed/tree_grafter/CalculateAttachementCounterWorklet.h
Normal file
105
vtkm/worklet/contourtree_distributed/tree_grafter/CalculateAttachementCounterWorklet.h
Normal file
@ -0,0 +1,105 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
// Copyright (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_tree_grafter_calculate_attachement_counter_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_tree_grafter_calculate_attachement_counter_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace tree_grafter
|
||||
{
|
||||
|
||||
// In TreeGrafter.GraftInteriorForests to compute attachmentCounter to
|
||||
// check whether additional attachement points need to be transferred
|
||||
class CalculateAttachementCounterWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn supernodeType, // input
|
||||
FieldIn hierarchicalSuperId, // input
|
||||
FieldOut attachmentCounter // output
|
||||
|
||||
);
|
||||
|
||||
using ExecutionSignature = _3(_1, _2);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
CalculateAttachementCounterWorklet() {}
|
||||
|
||||
VTKM_EXEC vtkm::Id operator()(const vtkm::Id& supernodeType,
|
||||
const vtkm::Id& hierarchicalSuperId) const
|
||||
{ // operator ()
|
||||
return (supernodeType == vtkm::worklet::contourtree_augmented::IS_ATTACHMENT) &&
|
||||
vtkm::worklet::contourtree_augmented::NoSuchElement(hierarchicalSuperId);
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType supernode = 0; supernode < contourTree->supernodes.size(); supernode++)
|
||||
attachmentCounter[supernode] = (supernodeType[supernode] == IS_ATTACHMENT) && noSuchElement(hierarchicalSuperID[supernode]);
|
||||
*/
|
||||
} // operator ()
|
||||
|
||||
}; // CalculateAttachementCounterWorklet
|
||||
|
||||
} // namespace tree_grafter
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user