mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Add BRACT for distributed contour tree computation
This merge request is Phase 1 of several to implement the distributed parallel contour tree in VTKm. This merge requests adds the base outline for the algorithm. The implementation of the details of the algorithm in the BoundaryRestrictedAugmentedContourTree.h is currently still missing. However, these will require a substantial (~3000) lines of additional code. The goal is to stage the integration process across merge requests to make the review process simpler.
This commit is contained in:
parent
22f227a91e
commit
66c96a983f
@ -16,6 +16,7 @@ if(VTKm_ENABLE_EXAMPLES)
|
||||
add_subdirectory(clipping)
|
||||
add_subdirectory(contour_tree)
|
||||
add_subdirectory(contour_tree_augmented)
|
||||
add_subdirectory(contour_tree_distributed)
|
||||
add_subdirectory(cosmotools)
|
||||
add_subdirectory(demo)
|
||||
#add_subdirectory(game_of_life)
|
||||
|
@ -65,6 +65,7 @@ vtkm_add_target_information(ContourTree_Augmented
|
||||
DEVICE_SOURCES ContourTreeApp.cxx)
|
||||
|
||||
option (VTKM_EXAMPLE_CONTOURTREE_ENABLE_DEBUG_PRINT Off)
|
||||
mark_as_advanced(VTKM_EXAMPLE_CONTOURTREE_ENABLE_DEBUG_PRINT)
|
||||
if (VTKM_EXAMPLE_CONTOURTREE_ENABLE_DEBUG_PRINT)
|
||||
target_compile_definitions(ContourTree_Augmented PRIVATE "DEBUG_PRINT")
|
||||
endif()
|
||||
@ -85,6 +86,7 @@ if (VTKm_ENABLE_MPI)
|
||||
target_compile_definitions(ContourTree_Augmented_MPI PRIVATE "WITH_MPI")
|
||||
|
||||
option (VTKM_EXAMPLE_CONTOURTREE_ENABLE_DEBUG_PRINT Off)
|
||||
mark_as_advanced(VTKM_EXAMPLE_CONTOURTREE_ENABLE_DEBUG_PRINT)
|
||||
if (VTKM_EXAMPLE_CONTOURTREE_ENABLE_DEBUG_PRINT)
|
||||
target_compile_definitions(ContourTree_Augmented_MPI PRIVATE "DEBUG_PRINT")
|
||||
endif()
|
||||
|
@ -459,7 +459,7 @@ int main(int argc, char* argv[])
|
||||
// TODO All we should need to do to implement BOV support is to copy the values
|
||||
// in the values vector and copy the dimensions in the dims vector
|
||||
vtkm::Id nRows, nCols, nSlices;
|
||||
vtkm::filter::GetRowsColsSlices temp;
|
||||
vtkm::worklet::contourtree_augmented::GetRowsColsSlices temp;
|
||||
temp(inDataSet.GetCellSet(), nRows, nCols, nSlices);
|
||||
dims[0] = nRows;
|
||||
dims[1] = nCols;
|
||||
|
78
examples/contour_tree_distributed/CMakeLists.txt
Normal file
78
examples/contour_tree_distributed/CMakeLists.txt
Normal file
@ -0,0 +1,78 @@
|
||||
##============================================================================
|
||||
## 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)
|
||||
##==============================================================================
|
||||
cmake_minimum_required(VERSION 3.8...3.15 FATAL_ERROR)
|
||||
|
||||
# Find the VTK-m package
|
||||
find_package(VTKm REQUIRED QUIET)
|
||||
|
||||
####################################
|
||||
# MPI
|
||||
####################################
|
||||
if (VTKm_ENABLE_MPI)
|
||||
add_executable(ContourTree_Distributed ContourTreeApp.cxx)
|
||||
target_link_libraries(ContourTree_Distributed vtkm_filter)
|
||||
vtkm_add_target_information(ContourTree_Distributed
|
||||
MODIFY_CUDA_FLAGS
|
||||
DEVICE_SOURCES ContourTreeApp.cxx)
|
||||
target_compile_definitions(ContourTree_Distributed PRIVATE)
|
||||
|
||||
option (VTKM_EXAMPLE_CONTOURTREE_ENABLE_DEBUG_PRINT Off)
|
||||
mark_as_advanced(VTKM_EXAMPLE_CONTOURTREE_ENABLE_DEBUG_PRINT)
|
||||
if (VTKM_EXAMPLE_CONTOURTREE_ENABLE_DEBUG_PRINT)
|
||||
target_compile_definitions(ContourTree_Distributed PRIVATE "DEBUG_PRINT")
|
||||
endif()
|
||||
|
||||
if (TARGET vtkm::tbb)
|
||||
target_compile_definitions(ContourTree_Distributed PRIVATE "ENABLE_SET_NUM_THREADS")
|
||||
endif()
|
||||
endif()
|
573
examples/contour_tree_distributed/ContourTreeApp.cxx
Normal file
573
examples/contour_tree_distributed/ContourTreeApp.cxx
Normal file
@ -0,0 +1,573 @@
|
||||
//============================================================================
|
||||
// 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 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2014 UT-Battelle, LLC.
|
||||
// Copyright 2014 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// the U.S. Government retains certain rights in this software.
|
||||
//
|
||||
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
||||
// Laboratory (LANL), the U.S. Government retains certain rights in
|
||||
// this software.
|
||||
//============================================================================
|
||||
// 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)
|
||||
//==============================================================================
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/DataSet.h>
|
||||
#include <vtkm/cont/DataSetBuilderUniform.h>
|
||||
#include <vtkm/cont/DataSetFieldAdd.h>
|
||||
#include <vtkm/cont/Initialize.h>
|
||||
#include <vtkm/cont/RuntimeDeviceTracker.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
#include <vtkm/filter/ContourTreeUniformDistributed.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/PrintVectors.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/ProcessContourTree.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
#ifdef ENABLE_SET_NUM_THREADS
|
||||
#include "tbb/task_scheduler_init.h"
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
VTKM_THIRDPARTY_PRE_INCLUDE
|
||||
#include <vtkm/thirdparty/diy/Configure.h>
|
||||
#include <vtkm/thirdparty/diy/diy.h>
|
||||
VTKM_THIRDPARTY_POST_INCLUDE
|
||||
// clang-format on
|
||||
|
||||
#include <mpi.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using ValueType = vtkm::Float32;
|
||||
|
||||
namespace ctaug_ns = vtkm::worklet::contourtree_augmented;
|
||||
|
||||
// Simple helper class for parsing the command line options
|
||||
class ParseCL
|
||||
{
|
||||
public:
|
||||
ParseCL() {}
|
||||
|
||||
void parse(int& argc, char** argv)
|
||||
{
|
||||
mCLOptions.resize(static_cast<std::size_t>(argc));
|
||||
for (std::size_t i = 1; i < static_cast<std::size_t>(argc); ++i)
|
||||
{
|
||||
this->mCLOptions[i] = std::string(argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
vtkm::Id findOption(const std::string& option) const
|
||||
{
|
||||
auto it =
|
||||
std::find_if(this->mCLOptions.begin(),
|
||||
this->mCLOptions.end(),
|
||||
[option](const std::string& val) -> bool { return val.find(option) == 0; });
|
||||
if (it == this->mCLOptions.end())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (it - this->mCLOptions.begin());
|
||||
}
|
||||
}
|
||||
|
||||
bool hasOption(const std::string& option) const { return this->findOption(option) >= 0; }
|
||||
|
||||
std::string getOption(const std::string& option) const
|
||||
{
|
||||
std::size_t index = static_cast<std::size_t>(this->findOption(option));
|
||||
std::string val = this->mCLOptions[index];
|
||||
auto valPos = val.find("=");
|
||||
if (valPos)
|
||||
{
|
||||
return val.substr(valPos + 1);
|
||||
}
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
const std::vector<std::string>& getOptions() const { return this->mCLOptions; }
|
||||
|
||||
private:
|
||||
std::vector<std::string> mCLOptions;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Compute and render an isosurface for a uniform grid example
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// Setup the MPI environment.
|
||||
MPI_Init(&argc, &argv);
|
||||
auto comm = MPI_COMM_WORLD;
|
||||
|
||||
// Tell VTK-m which communicator it should use.
|
||||
vtkm::cont::EnvironmentTracker::SetCommunicator(vtkmdiy::mpi::communicator(comm));
|
||||
|
||||
// get the rank and size
|
||||
int rank, size;
|
||||
MPI_Comm_rank(comm, &rank);
|
||||
MPI_Comm_size(comm, &size);
|
||||
int numBlocks = size;
|
||||
int blocksPerRank = 1;
|
||||
|
||||
// initialize vtkm-m (e.g., logging via -v and device via the -d option)
|
||||
vtkm::cont::InitializeOptions vtkm_initialize_options =
|
||||
vtkm::cont::InitializeOptions::RequireDevice;
|
||||
vtkm::cont::InitializeResult vtkm_config =
|
||||
vtkm::cont::Initialize(argc, argv, vtkm_initialize_options);
|
||||
auto device = vtkm_config.Device;
|
||||
|
||||
VTKM_LOG_IF_S(vtkm::cont::LogLevel::Info, rank == 0, "Running with MPI. #ranks=" << size);
|
||||
|
||||
// Setup timing
|
||||
vtkm::Float64 prevTime = 0;
|
||||
vtkm::Float64 currTime = 0;
|
||||
vtkm::cont::Timer totalTime;
|
||||
|
||||
totalTime.Start();
|
||||
|
||||
////////////////////////////////////////////
|
||||
// Parse the command line options
|
||||
////////////////////////////////////////////
|
||||
ParseCL parser;
|
||||
parser.parse(argc, argv);
|
||||
std::string filename = parser.getOptions().back();
|
||||
bool useMarchingCubes = false;
|
||||
if (parser.hasOption("--mc"))
|
||||
useMarchingCubes = true;
|
||||
|
||||
#ifdef ENABLE_SET_NUM_THREADS
|
||||
int numThreads = tbb::task_scheduler_init::default_num_threads();
|
||||
if (parser.hasOption("--numThreads"))
|
||||
{
|
||||
bool deviceIsTBB = (device.GetName() == "TBB");
|
||||
// Set the number of threads to be used for TBB
|
||||
if (deviceIsTBB)
|
||||
{
|
||||
numThreads = std::stoi(parser.getOption("--numThreads"));
|
||||
tbb::task_scheduler_init schedulerInit(numThreads);
|
||||
}
|
||||
// Print warning about mismatch between the --numThreads and -d/--device option
|
||||
else
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Warn,
|
||||
"WARNING: Mismatch between --numThreads and -d/--device option."
|
||||
"numThreads option requires the use of TBB as device. "
|
||||
"Ignoring the numThread option.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rank == 0 && (argc < 2 || parser.hasOption("--help") || parser.hasOption("-h")))
|
||||
{
|
||||
std::cout << "ContourTreeAugmented <options> <fileName>" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "<fileName> Name of the input data file." << std::endl;
|
||||
std::cout << "The file is expected to be ASCII with either: " << std::endl;
|
||||
std::cout << " - xdim ydim integers for 2D or" << std::endl;
|
||||
std::cout << " - xdim ydim zdim integers for 3D" << std::endl;
|
||||
std::cout << "followed by vector data last dimension varying fastest" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "----------------------------- VTKM Options -----------------------------"
|
||||
<< std::endl;
|
||||
std::cout << vtkm_config.Usage << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "------------------------- Contour Tree Options -------------------------"
|
||||
<< std::endl;
|
||||
std::cout << "Options: (Bool options are give via int, i.e. =0 for False and =1 for True)"
|
||||
<< std::endl;
|
||||
std::cout << "--mc Use marching cubes interpolation for contour tree calculation. "
|
||||
"(Default=False)"
|
||||
<< std::endl;
|
||||
#ifdef ENABLE_SET_NUM_THREADS
|
||||
std::cout << "--numThreads Specifiy the number of threads to use. Available only with TBB."
|
||||
<< std::endl;
|
||||
#endif
|
||||
std::cout << std::endl;
|
||||
|
||||
MPI_Finalize();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (rank == 0)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
std::endl
|
||||
<< " ------------ Settings -----------"
|
||||
<< std::endl
|
||||
<< " filename="
|
||||
<< filename
|
||||
<< std::endl
|
||||
<< " device="
|
||||
<< device.GetName()
|
||||
<< std::endl
|
||||
<< " mc="
|
||||
<< useMarchingCubes
|
||||
<< std::endl
|
||||
#ifdef ENABLE_SET_NUM_THREADS
|
||||
<< " numThreads="
|
||||
<< numThreads
|
||||
<< std::endl
|
||||
#endif
|
||||
<< " nblocks="
|
||||
<< numBlocks
|
||||
<< std::endl);
|
||||
}
|
||||
currTime = totalTime.GetElapsedTime();
|
||||
vtkm::Float64 startUpTime = currTime - prevTime;
|
||||
prevTime = currTime;
|
||||
|
||||
// Redirect stdout to file if we are using MPI with Debugging
|
||||
#ifdef DEBUG_PRINT
|
||||
// From https://www.unix.com/302983597-post2.html
|
||||
char* cstr_filename = new char[15];
|
||||
snprintf(cstr_filename, sizeof(filename), "cout_%d.log", rank);
|
||||
int out = open(cstr_filename, O_RDWR | O_CREAT | O_APPEND, 0600);
|
||||
if (-1 == out)
|
||||
{
|
||||
perror("opening cout.log");
|
||||
return 255;
|
||||
}
|
||||
|
||||
snprintf(cstr_filename, sizeof(cstr_filename), "cerr_%d.log", rank);
|
||||
int err = open(cstr_filename, O_RDWR | O_CREAT | O_APPEND, 0600);
|
||||
if (-1 == err)
|
||||
{
|
||||
perror("opening cerr.log");
|
||||
return 255;
|
||||
}
|
||||
|
||||
int save_out = dup(fileno(stdout));
|
||||
int save_err = dup(fileno(stderr));
|
||||
|
||||
if (-1 == dup2(out, fileno(stdout)))
|
||||
{
|
||||
perror("cannot redirect stdout");
|
||||
return 255;
|
||||
}
|
||||
if (-1 == dup2(err, fileno(stderr)))
|
||||
{
|
||||
perror("cannot redirect stderr");
|
||||
return 255;
|
||||
}
|
||||
|
||||
delete[] cstr_filename;
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// Read the input data
|
||||
///////////////////////////////////////////////
|
||||
std::ifstream inFile(filename);
|
||||
if (inFile.bad())
|
||||
return 0;
|
||||
|
||||
// Read the dimensions of the mesh, i.e,. number of elementes in x, y, and z
|
||||
std::vector<std::size_t> dims;
|
||||
std::string line;
|
||||
getline(inFile, line);
|
||||
std::istringstream linestream(line);
|
||||
std::size_t dimVertices;
|
||||
while (linestream >> dimVertices)
|
||||
{
|
||||
dims.push_back(dimVertices);
|
||||
}
|
||||
|
||||
// Compute the number of vertices, i.e., xdim * ydim * zdim
|
||||
unsigned short nDims = static_cast<unsigned short>(dims.size());
|
||||
std::size_t numVertices = static_cast<std::size_t>(
|
||||
std::accumulate(dims.begin(), dims.end(), std::size_t(1), std::multiplies<std::size_t>()));
|
||||
|
||||
// Print the mesh metadata
|
||||
if (rank == 0)
|
||||
{
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
std::endl
|
||||
<< " ---------------- Input Mesh Properties --------------"
|
||||
<< std::endl
|
||||
<< " Number of dimensions: "
|
||||
<< nDims
|
||||
<< std::endl
|
||||
<< " Number of mesh vertices: "
|
||||
<< numVertices
|
||||
<< std::endl);
|
||||
}
|
||||
|
||||
// Check for fatal input errors
|
||||
// Check the the number of dimensiosn is either 2D or 3D
|
||||
bool invalidNumDimensions = (nDims < 2 || nDims > 3);
|
||||
// Check if marching cubes is enabled for non 3D data
|
||||
bool invalidMCOption = (useMarchingCubes && nDims != 3);
|
||||
// Log any errors if found on rank 0
|
||||
VTKM_LOG_IF_S(vtkm::cont::LogLevel::Error,
|
||||
invalidNumDimensions && (rank == 0),
|
||||
"The input mesh is " << nDims << "D. "
|
||||
"The input data must be either 2D or 3D.");
|
||||
VTKM_LOG_IF_S(
|
||||
vtkm::cont::LogLevel::Error,
|
||||
invalidMCOption && (rank == 0),
|
||||
"The input mesh is " << nDims << "D. "
|
||||
<< "Contour tree using marching cubes is only supported for 3D data.");
|
||||
// If we found any errors in the setttings than finalize MPI and exit the execution
|
||||
if (invalidNumDimensions || invalidMCOption)
|
||||
{
|
||||
MPI_Finalize();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Read data
|
||||
std::vector<ValueType> values(numVertices);
|
||||
for (std::size_t vertex = 0; vertex < numVertices; ++vertex)
|
||||
{
|
||||
inFile >> values[vertex];
|
||||
}
|
||||
|
||||
// finish reading the data
|
||||
inFile.close();
|
||||
|
||||
currTime = totalTime.GetElapsedTime();
|
||||
vtkm::Float64 dataReadTime = currTime - prevTime;
|
||||
prevTime = currTime;
|
||||
|
||||
vtkm::cont::DataSetBuilderUniform dsb;
|
||||
// Create a multi-block dataset for multi-block DIY-paralle processing
|
||||
vtkm::cont::PartitionedDataSet inDataSet; // Partitioned variant of the input dataset
|
||||
vtkm::Id3 blocksPerDim =
|
||||
nDims == 3 ? vtkm::Id3(1, 1, numBlocks) : vtkm::Id3(1, numBlocks, 1); // Decompose the data into
|
||||
vtkm::Id3 globalSize = nDims == 3 ? vtkm::Id3(static_cast<vtkm::Id>(dims[0]),
|
||||
static_cast<vtkm::Id>(dims[1]),
|
||||
static_cast<vtkm::Id>(dims[2]))
|
||||
: vtkm::Id3(static_cast<vtkm::Id>(dims[0]),
|
||||
static_cast<vtkm::Id>(dims[1]),
|
||||
static_cast<vtkm::Id>(0));
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockIndices;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockOrigins;
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> localBlockSizes;
|
||||
localBlockIndices.Allocate(blocksPerRank);
|
||||
localBlockOrigins.Allocate(blocksPerRank);
|
||||
localBlockSizes.Allocate(blocksPerRank);
|
||||
auto localBlockIndicesPortal = localBlockIndices.WritePortal();
|
||||
auto localBlockOriginsPortal = localBlockOrigins.WritePortal();
|
||||
auto localBlockSizesPortal = localBlockSizes.WritePortal();
|
||||
|
||||
{
|
||||
vtkm::Id lastDimSize =
|
||||
(nDims == 2) ? static_cast<vtkm::Id>(dims[1]) : static_cast<vtkm::Id>(dims[2]);
|
||||
if (size > (lastDimSize / 2.))
|
||||
{
|
||||
VTKM_LOG_IF_S(vtkm::cont::LogLevel::Error,
|
||||
rank == 0,
|
||||
"Number of ranks to large for data. Use " << lastDimSize / 2
|
||||
<< "or fewer ranks");
|
||||
MPI_Finalize();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
vtkm::Id standardBlockSize = (vtkm::Id)(lastDimSize / numBlocks);
|
||||
vtkm::Id blockSize = standardBlockSize;
|
||||
vtkm::Id blockSliceSize =
|
||||
nDims == 2 ? static_cast<vtkm::Id>(dims[0]) : static_cast<vtkm::Id>((dims[0] * dims[1]));
|
||||
vtkm::Id blockNumValues = blockSize * blockSliceSize;
|
||||
|
||||
vtkm::Id startBlock = blocksPerRank * rank;
|
||||
vtkm::Id endBlock = startBlock + blocksPerRank;
|
||||
for (vtkm::Id blockIndex = startBlock; blockIndex < endBlock; ++blockIndex)
|
||||
{
|
||||
vtkm::Id localBlockIndex = blockIndex - startBlock;
|
||||
vtkm::Id blockStart = blockIndex * blockNumValues;
|
||||
vtkm::Id blockEnd = blockStart + blockNumValues;
|
||||
if (blockIndex < (numBlocks - 1)) // add overlap between regions
|
||||
{
|
||||
blockEnd += blockSliceSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
blockEnd = lastDimSize * blockSliceSize;
|
||||
}
|
||||
vtkm::Id currBlockSize = (vtkm::Id)((blockEnd - blockStart) / blockSliceSize);
|
||||
|
||||
vtkm::cont::DataSet ds;
|
||||
|
||||
// 2D data
|
||||
if (nDims == 2)
|
||||
{
|
||||
vtkm::Id2 vdims;
|
||||
vdims[0] = static_cast<vtkm::Id>(currBlockSize);
|
||||
vdims[1] = static_cast<vtkm::Id>(dims[0]);
|
||||
vtkm::Vec<ValueType, 2> origin(0, blockIndex * blockSize);
|
||||
vtkm::Vec<ValueType, 2> spacing(1, 1);
|
||||
ds = dsb.Create(vdims, origin, spacing);
|
||||
|
||||
localBlockIndicesPortal.Set(localBlockIndex, vtkm::Id3(blockIndex, 0, 0));
|
||||
localBlockOriginsPortal.Set(localBlockIndex,
|
||||
vtkm::Id3((blockStart / blockSliceSize), 0, 0));
|
||||
localBlockSizesPortal.Set(localBlockIndex,
|
||||
vtkm::Id3(currBlockSize, static_cast<vtkm::Id>(dims[0]), 0));
|
||||
}
|
||||
// 3D data
|
||||
else
|
||||
{
|
||||
vtkm::Id3 vdims;
|
||||
vdims[0] = static_cast<vtkm::Id>(dims[0]);
|
||||
vdims[1] = static_cast<vtkm::Id>(dims[1]);
|
||||
vdims[2] = static_cast<vtkm::Id>(currBlockSize);
|
||||
vtkm::Vec<ValueType, 3> origin(0, 0, (blockIndex * blockSize));
|
||||
vtkm::Vec<ValueType, 3> spacing(1, 1, 1);
|
||||
ds = dsb.Create(vdims, origin, spacing);
|
||||
|
||||
localBlockIndicesPortal.Set(localBlockIndex, vtkm::Id3(0, 0, blockIndex));
|
||||
localBlockOriginsPortal.Set(localBlockIndex,
|
||||
vtkm::Id3(0, 0, (blockStart / blockSliceSize)));
|
||||
localBlockSizesPortal.Set(
|
||||
localBlockIndex,
|
||||
vtkm::Id3(static_cast<vtkm::Id>(dims[0]), static_cast<vtkm::Id>(dims[1]), currBlockSize));
|
||||
}
|
||||
|
||||
std::vector<vtkm::Float32> subValues((values.begin() + blockStart),
|
||||
(values.begin() + blockEnd));
|
||||
|
||||
//vtkm::cont::DataSetFieldAdd dsf;
|
||||
ds.AddPointField("values", subValues);
|
||||
inDataSet.AppendPartition(ds);
|
||||
}
|
||||
}
|
||||
|
||||
currTime = totalTime.GetElapsedTime();
|
||||
vtkm::Float64 buildDatasetTime = currTime - prevTime;
|
||||
prevTime = currTime;
|
||||
|
||||
// Convert the mesh of values into contour tree, pairs of vertex ids
|
||||
vtkm::filter::ContourTreeUniformDistributed filter(useMarchingCubes);
|
||||
|
||||
filter.SetSpatialDecomposition(
|
||||
blocksPerDim, globalSize, localBlockIndices, localBlockOrigins, localBlockSizes);
|
||||
filter.SetActiveField("values");
|
||||
|
||||
// Execute the contour tree analysis. NOTE: If MPI is used the result will be
|
||||
// a vtkm::cont::PartitionedDataSet instead of a vtkm::cont::DataSet
|
||||
auto result = filter.Execute(inDataSet);
|
||||
|
||||
currTime = totalTime.GetElapsedTime();
|
||||
vtkm::Float64 computeContourTreeTime = currTime - prevTime;
|
||||
prevTime = currTime;
|
||||
|
||||
// Force a simple round-robin on the ranks for the summary prints. Its not perfect for MPI but
|
||||
// it works well enough to sort the summaries from the ranks for small-scale debugging.
|
||||
if (rank > 0)
|
||||
{
|
||||
int temp;
|
||||
MPI_Status status;
|
||||
MPI_Recv(&temp, 1, MPI_INT, (rank - 1), 0, comm, &status);
|
||||
}
|
||||
currTime = totalTime.GetElapsedTime();
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
std::endl
|
||||
<< " -------------------------- Totals "
|
||||
<< rank
|
||||
<< " -----------------------------"
|
||||
<< std::endl
|
||||
<< std::setw(42)
|
||||
<< std::left
|
||||
<< " Start-up"
|
||||
<< ": "
|
||||
<< startUpTime
|
||||
<< " seconds"
|
||||
<< std::endl
|
||||
<< std::setw(42)
|
||||
<< std::left
|
||||
<< " Data Read"
|
||||
<< ": "
|
||||
<< dataReadTime
|
||||
<< " seconds"
|
||||
<< std::endl
|
||||
<< std::setw(42)
|
||||
<< std::left
|
||||
<< " Build VTKM Dataset"
|
||||
<< ": "
|
||||
<< buildDatasetTime
|
||||
<< " seconds"
|
||||
<< std::endl
|
||||
<< std::setw(42)
|
||||
<< std::left
|
||||
<< " Compute Contour Tree"
|
||||
<< ": "
|
||||
<< computeContourTreeTime
|
||||
<< " seconds"
|
||||
<< std::endl
|
||||
<< std::setw(42)
|
||||
<< std::left
|
||||
<< " Total Time"
|
||||
<< ": "
|
||||
<< currTime
|
||||
<< " seconds");
|
||||
|
||||
// Flush ouput streams just to make sure everything has been logged (in particular when using MPI)
|
||||
std::cout << std::flush;
|
||||
std::cerr << std::flush;
|
||||
|
||||
// Let the next rank know that it is time to print their summary.
|
||||
if (rank < (size - 1))
|
||||
{
|
||||
int message = 1;
|
||||
MPI_Send(&message, 1, MPI_INT, (rank + 1), 0, comm);
|
||||
}
|
||||
MPI_Finalize();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -19,6 +19,7 @@ set(headers
|
||||
Contour.h
|
||||
ContourTreeUniform.h
|
||||
ContourTreeUniformAugmented.h
|
||||
ContourTreeUniformDistributed.h
|
||||
CoordinateSystemTransform.h
|
||||
CreateResult.h
|
||||
CrossProduct.h
|
||||
@ -92,6 +93,7 @@ set(header_template_sources
|
||||
Contour.hxx
|
||||
ContourTreeUniform.hxx
|
||||
ContourTreeUniformAugmented.hxx
|
||||
ContourTreeUniformDistributed.hxx
|
||||
CoordinateSystemTransform.hxx
|
||||
CrossProduct.hxx
|
||||
DotProduct.hxx
|
||||
|
@ -57,23 +57,17 @@
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/ContourTree.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/MultiBlockContourTreeHelper.h>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <vtkm/Bounds.h>
|
||||
#include <vtkm/filter/FilterCell.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
class MultiBlockContourTreeHelper;
|
||||
} // namespace detail
|
||||
|
||||
/// \brief Construct the Contour Tree for a 2D or 3D regular mesh
|
||||
///
|
||||
/// This filter implements the parallel peak pruning algorithm. In contrast to
|
||||
@ -185,52 +179,8 @@ private:
|
||||
/// Array with the sorted order of the mesh vertices
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType MeshSortOrder;
|
||||
/// Helper object to help with the parallel merge when running with DIY in parallel with MulitBlock data
|
||||
detail::MultiBlockContourTreeHelper* MultiBlockTreeHelper;
|
||||
};
|
||||
|
||||
///
|
||||
/// Helper struct to collect sizing information from the dataset
|
||||
///
|
||||
struct GetRowsColsSlices
|
||||
{
|
||||
//@{
|
||||
/// Get the number of rows, cols, and slices of a vtkm::cont::CellSetStructured
|
||||
/// @param[in] cells The input vtkm::cont::CellSetStructured
|
||||
/// @param[out] nRows Number of rows (x) in the cell set
|
||||
/// @param[out] nCols Number of columns (y) in the cell set
|
||||
/// @param[out] nSlices Number of slices (z) in the cell set
|
||||
void operator()(const vtkm::cont::CellSetStructured<2>& cells,
|
||||
vtkm::Id& nRows,
|
||||
vtkm::Id& nCols,
|
||||
vtkm::Id& nSlices) const
|
||||
{
|
||||
vtkm::Id2 pointDimensions = cells.GetPointDimensions();
|
||||
nRows = pointDimensions[0];
|
||||
nCols = pointDimensions[1];
|
||||
nSlices = 1;
|
||||
}
|
||||
void operator()(const vtkm::cont::CellSetStructured<3>& cells,
|
||||
vtkm::Id& nRows,
|
||||
vtkm::Id& nCols,
|
||||
vtkm::Id& nSlices) const
|
||||
{
|
||||
vtkm::Id3 pointDimensions = cells.GetPointDimensions();
|
||||
nRows = pointDimensions[0];
|
||||
nCols = pointDimensions[1];
|
||||
nSlices = pointDimensions[2];
|
||||
}
|
||||
//@}
|
||||
|
||||
/// Raise ErrorBadValue if the input cell set is not a vtkm::cont::CellSetStructured<2> or <3>
|
||||
template <typename T>
|
||||
void operator()(const T& cells, vtkm::Id& nRows, vtkm::Id& nCols, vtkm::Id& nSlices) const
|
||||
{
|
||||
(void)nRows;
|
||||
(void)nCols;
|
||||
(void)nSlices;
|
||||
(void)cells;
|
||||
throw vtkm::cont::ErrorBadValue("Expected 2D or 3D structured cell cet! ");
|
||||
}
|
||||
std::unique_ptr<vtkm::worklet::contourtree_distributed::MultiBlockContourTreeHelper>
|
||||
MultiBlockTreeHelper;
|
||||
};
|
||||
|
||||
} // namespace filter
|
||||
|
@ -53,23 +53,12 @@
|
||||
#ifndef vtk_m_filter_ContourTreeUniformAugmented_hxx
|
||||
#define vtk_m_filter_ContourTreeUniformAugmented_hxx
|
||||
|
||||
#include <vtkm/cont/ErrorBadValue.h>
|
||||
#include <vtkm/cont/Timer.h>
|
||||
|
||||
#include <vtkm/filter/ContourTreeUniformAugmented.h>
|
||||
|
||||
#include <vtkm/worklet/ContourTreeUniformAugmented.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/ProcessContourTree.h>
|
||||
|
||||
#include <vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/ContourTreeMesh.h>
|
||||
|
||||
#include <vtkm/cont/ArrayCopy.h>
|
||||
//#include <vtkm/cont/DeviceAdapter.h>
|
||||
#include <vtkm/cont/AssignerPartitionedDataSet.h>
|
||||
#include <vtkm/cont/BoundsCompute.h>
|
||||
#include <vtkm/cont/BoundsGlobalCompute.h>
|
||||
#include <vtkm/cont/EnvironmentTracker.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem/IdRelabler.h>
|
||||
// clang-format off
|
||||
VTKM_THIRDPARTY_PRE_INCLUDE
|
||||
#include <vtkm/thirdparty/diy/Configure.h>
|
||||
@ -77,83 +66,11 @@ VTKM_THIRDPARTY_PRE_INCLUDE
|
||||
VTKM_THIRDPARTY_POST_INCLUDE
|
||||
// clang-format on
|
||||
|
||||
#include <vtkm/worklet/contourtree_distributed/ContourTreeBlockData.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/SpatialDecomposition.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/MergeBlockFunctor.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <typename FieldType>
|
||||
struct ContourTreeBlockData
|
||||
{
|
||||
static void* create() { return new ContourTreeBlockData<FieldType>; }
|
||||
static void destroy(void* b) { delete static_cast<ContourTreeBlockData<FieldType>*>(b); }
|
||||
|
||||
// ContourTreeMesh data
|
||||
vtkm::Id NumVertices;
|
||||
// TODO Should be able to remove sortOrder here, but we need to figure out what to return in the worklet instead
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType SortOrder;
|
||||
vtkm::cont::ArrayHandle<FieldType> SortedValue;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType GlobalMeshIndex;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType Neighbours;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType FirstNeighbour;
|
||||
vtkm::Id MaxNeighbours;
|
||||
|
||||
// Block metadata
|
||||
vtkm::Id3 BlockOrigin; // Origin of the data block
|
||||
vtkm::Id3 BlockSize; // Extends of the data block
|
||||
vtkm::Id3 GlobalSize; // Extends of the global mesh
|
||||
unsigned int ComputeRegularStructure; // pass through augmentation setting
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace filter
|
||||
} // namespace vtkm
|
||||
|
||||
|
||||
|
||||
namespace vtkmdiy
|
||||
{
|
||||
|
||||
// Struct to serialize ContourBlockData objects (i.e., load/save) needed in parralle for DIY
|
||||
template <typename FieldType>
|
||||
struct Serialization<vtkm::filter::detail::ContourTreeBlockData<FieldType>>
|
||||
{
|
||||
static void save(vtkmdiy::BinaryBuffer& bb,
|
||||
const vtkm::filter::detail::ContourTreeBlockData<FieldType>& block)
|
||||
{
|
||||
vtkmdiy::save(bb, block.NumVertices);
|
||||
vtkmdiy::save(bb, block.SortOrder);
|
||||
vtkmdiy::save(bb, block.SortedValue);
|
||||
vtkmdiy::save(bb, block.GlobalMeshIndex);
|
||||
vtkmdiy::save(bb, block.Neighbours);
|
||||
vtkmdiy::save(bb, block.FirstNeighbour);
|
||||
vtkmdiy::save(bb, block.MaxNeighbours);
|
||||
vtkmdiy::save(bb, block.BlockOrigin);
|
||||
vtkmdiy::save(bb, block.BlockSize);
|
||||
vtkmdiy::save(bb, block.GlobalSize);
|
||||
vtkmdiy::save(bb, block.ComputeRegularStructure);
|
||||
}
|
||||
|
||||
static void load(vtkmdiy::BinaryBuffer& bb,
|
||||
vtkm::filter::detail::ContourTreeBlockData<FieldType>& block)
|
||||
{
|
||||
vtkmdiy::load(bb, block.NumVertices);
|
||||
vtkmdiy::load(bb, block.SortOrder);
|
||||
vtkmdiy::load(bb, block.SortedValue);
|
||||
vtkmdiy::load(bb, block.GlobalMeshIndex);
|
||||
vtkmdiy::load(bb, block.Neighbours);
|
||||
vtkmdiy::load(bb, block.FirstNeighbour);
|
||||
vtkmdiy::load(bb, block.MaxNeighbours);
|
||||
vtkmdiy::load(bb, block.BlockOrigin);
|
||||
vtkmdiy::load(bb, block.BlockSize);
|
||||
vtkmdiy::load(bb, block.GlobalSize);
|
||||
vtkmdiy::load(bb, block.ComputeRegularStructure);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mangled_vtkmdiy_namespace
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -179,379 +96,6 @@ struct PostExecuteCaller
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// --- Helper class to store the spatial decomposition defined by the PartitionedDataSet input data
|
||||
class SpatialDecomposition
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
SpatialDecomposition(vtkm::Id3 blocksPerDim,
|
||||
vtkm::Id3 globalSize,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockOrigins,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockSizes)
|
||||
: BlocksPerDimension(blocksPerDim)
|
||||
, GlobalSize(globalSize)
|
||||
, LocalBlockIndices(localBlockIndices)
|
||||
, LocalBlockOrigins(localBlockOrigins)
|
||||
, LocalBlockSizes(localBlockSizes)
|
||||
{
|
||||
}
|
||||
|
||||
inline vtkmdiy::DiscreteBounds GetVTKmDIYBounds() const
|
||||
{
|
||||
if (this->NumberOfDimensions() == 2)
|
||||
{
|
||||
vtkmdiy::DiscreteBounds domain(2);
|
||||
domain.min[0] = domain.min[1] = 0;
|
||||
domain.max[0] = static_cast<int>(this->GlobalSize[0]);
|
||||
domain.max[1] = static_cast<int>(this->GlobalSize[1]);
|
||||
return domain;
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkmdiy::DiscreteBounds domain(3);
|
||||
domain.min[0] = domain.min[1] = domain.min[2] = 0;
|
||||
domain.max[0] = static_cast<int>(this->GlobalSize[0]);
|
||||
domain.max[1] = static_cast<int>(this->GlobalSize[1]);
|
||||
domain.max[2] = static_cast<int>(this->GlobalSize[2]);
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
|
||||
inline vtkm::Id NumberOfDimensions() const { return GlobalSize[2] > 1 ? 3 : 2; }
|
||||
|
||||
inline vtkm::Id GetGlobalNumberOfBlocks() const
|
||||
{
|
||||
return BlocksPerDimension[0] * BlocksPerDimension[1] * BlocksPerDimension[2];
|
||||
}
|
||||
|
||||
inline vtkm::Id GetLocalNumberOfBlocks() const { return LocalBlockSizes.GetNumberOfValues(); }
|
||||
|
||||
// Number of blocks along each dimension
|
||||
vtkm::Id3 BlocksPerDimension;
|
||||
// Size of the global mesh
|
||||
vtkm::Id3 GlobalSize;
|
||||
// Index of the local blocks in x,y,z, i.e., in i,j,k mesh coordinates
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> LocalBlockIndices;
|
||||
// Origin of the local blocks in mesh index space
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> LocalBlockOrigins;
|
||||
// Size of each local block in x, y,z
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> LocalBlockSizes;
|
||||
};
|
||||
|
||||
|
||||
//--- Helper class to help with the contstuction of the GlobalContourTree
|
||||
class MultiBlockContourTreeHelper
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
MultiBlockContourTreeHelper(vtkm::Id3 blocksPerDim,
|
||||
vtkm::Id3 globalSize,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockOrigins,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockSizes)
|
||||
: MultiBlockSpatialDecomposition(blocksPerDim,
|
||||
globalSize,
|
||||
localBlockIndices,
|
||||
localBlockOrigins,
|
||||
localBlockSizes)
|
||||
{
|
||||
vtkm::Id localNumBlocks = this->GetLocalNumberOfBlocks();
|
||||
LocalContourTrees.resize(static_cast<std::size_t>(localNumBlocks));
|
||||
LocalSortOrders.resize(static_cast<std::size_t>(localNumBlocks));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
~MultiBlockContourTreeHelper(void)
|
||||
{
|
||||
LocalContourTrees.clear();
|
||||
LocalSortOrders.clear();
|
||||
}
|
||||
|
||||
inline static vtkm::Bounds GetGlobalBounds(const vtkm::cont::PartitionedDataSet& input)
|
||||
{
|
||||
// Get the spatial bounds of a multi -block data set
|
||||
vtkm::Bounds bounds = vtkm::cont::BoundsGlobalCompute(input);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
inline static vtkm::Bounds GetLocalBounds(const vtkm::cont::PartitionedDataSet& input)
|
||||
{
|
||||
// Get the spatial bounds of a multi -block data set
|
||||
vtkm::Bounds bounds = vtkm::cont::BoundsCompute(input);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
inline vtkm::Id GetLocalNumberOfBlocks() const
|
||||
{
|
||||
return this->MultiBlockSpatialDecomposition.GetLocalNumberOfBlocks();
|
||||
}
|
||||
|
||||
inline vtkm::Id GetGlobalNumberOfBlocks() const
|
||||
{
|
||||
return this->MultiBlockSpatialDecomposition.GetGlobalNumberOfBlocks();
|
||||
}
|
||||
|
||||
inline static vtkm::Id GetGlobalNumberOfBlocks(const vtkm::cont::PartitionedDataSet& input)
|
||||
{
|
||||
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
|
||||
vtkm::Id localSize = input.GetNumberOfPartitions();
|
||||
vtkm::Id globalSize = 0;
|
||||
#ifdef VTKM_ENABLE_MPI
|
||||
vtkmdiy::mpi::all_reduce(comm, localSize, globalSize, std::plus<vtkm::Id>{});
|
||||
#else
|
||||
globalSize = localSize;
|
||||
#endif
|
||||
return globalSize;
|
||||
}
|
||||
|
||||
// Used to compute the local contour tree mesh in after DoExecute. I.e., the function is
|
||||
// used in PostExecute to construct the initial set of local ContourTreeMesh blocks for
|
||||
// DIY. Subsequent construction of updated ContourTreeMeshes is handled separately.
|
||||
template <typename T>
|
||||
inline static vtkm::worklet::contourtree_augmented::ContourTreeMesh<T>*
|
||||
ComputeLocalContourTreeMesh(const vtkm::Id3 localBlockOrigin,
|
||||
const vtkm::Id3 localBlockSize,
|
||||
const vtkm::Id3 globalSize,
|
||||
const vtkm::cont::ArrayHandle<T>& field,
|
||||
const vtkm::worklet::contourtree_augmented::ContourTree& contourTree,
|
||||
const vtkm::worklet::contourtree_augmented::IdArrayType& sortOrder,
|
||||
unsigned int computeRegularStructure)
|
||||
|
||||
{
|
||||
vtkm::Id startRow = localBlockOrigin[0];
|
||||
vtkm::Id startCol = localBlockOrigin[1];
|
||||
vtkm::Id startSlice = localBlockOrigin[2];
|
||||
vtkm::Id numRows = localBlockSize[0];
|
||||
vtkm::Id numCols = localBlockSize[1];
|
||||
vtkm::Id totalNumRows = globalSize[0];
|
||||
vtkm::Id totalNumCols = globalSize[1];
|
||||
// compute the global mesh index and initalize the local contour tree mesh
|
||||
if (computeRegularStructure == 1)
|
||||
{
|
||||
// Compute the global mesh index
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType localGlobalMeshIndex;
|
||||
auto transformedIndex = vtkm::cont::ArrayHandleTransform<
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType,
|
||||
vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabler>(
|
||||
sortOrder,
|
||||
vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabler(
|
||||
startRow, startCol, startSlice, numRows, numCols, totalNumRows, totalNumCols));
|
||||
vtkm::cont::Algorithm::Copy(transformedIndex, localGlobalMeshIndex);
|
||||
// Compute the local contour tree mesh
|
||||
auto localContourTreeMesh = new vtkm::worklet::contourtree_augmented::ContourTreeMesh<T>(
|
||||
contourTree.Arcs, sortOrder, field, localGlobalMeshIndex);
|
||||
return localContourTreeMesh;
|
||||
}
|
||||
else if (computeRegularStructure == 2)
|
||||
{
|
||||
// Compute the global mesh index for the partially augmented contour tree. I.e., here we
|
||||
// don't need the global mesh index for all nodes, but only for the augmented nodes from the
|
||||
// tree. We, hence, permute the sortOrder by contourTree.augmentednodes and then compute the
|
||||
// GlobalMeshIndex by tranforming those indices with our IdRelabler
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType localGlobalMeshIndex;
|
||||
vtkm::cont::ArrayHandlePermutation<vtkm::worklet::contourtree_augmented::IdArrayType,
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType>
|
||||
permutedSortOrder(contourTree.Augmentnodes, sortOrder);
|
||||
auto transformedIndex = vtkm::cont::make_ArrayHandleTransform(
|
||||
permutedSortOrder,
|
||||
vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabler(
|
||||
startRow, startCol, startSlice, numRows, numCols, totalNumRows, totalNumCols));
|
||||
vtkm::cont::Algorithm::Copy(transformedIndex, localGlobalMeshIndex);
|
||||
// Compute the local contour tree mesh
|
||||
auto localContourTreeMesh = new vtkm::worklet::contourtree_augmented::ContourTreeMesh<T>(
|
||||
contourTree.Augmentnodes, contourTree.Augmentarcs, sortOrder, field, localGlobalMeshIndex);
|
||||
return localContourTreeMesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We should not be able to get here
|
||||
throw vtkm::cont::ErrorFilterExecution(
|
||||
"Parallel contour tree requires at least parial boundary augmentation");
|
||||
}
|
||||
}
|
||||
|
||||
SpatialDecomposition MultiBlockSpatialDecomposition;
|
||||
std::vector<vtkm::worklet::contourtree_augmented::ContourTree> LocalContourTrees;
|
||||
std::vector<vtkm::worklet::contourtree_augmented::IdArrayType> LocalSortOrders;
|
||||
|
||||
}; // end MultiBlockContourTreeHelper
|
||||
|
||||
// Functor needed so we can discover the FieldType and DeviceAdapter template parameters to call MergeWith
|
||||
struct MergeFunctor
|
||||
{
|
||||
template <typename DeviceAdapterTag, typename FieldType>
|
||||
bool operator()(DeviceAdapterTag,
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>& in,
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>& out) const
|
||||
{
|
||||
out.template MergeWith<DeviceAdapterTag>(in);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Functor used by DIY reduce the merge data blocks in parallel
|
||||
template <typename FieldType>
|
||||
void MergeBlockFunctor(
|
||||
ContourTreeBlockData<FieldType>* block, // local Block.
|
||||
const vtkmdiy::ReduceProxy& rp, // communication proxy
|
||||
const vtkmdiy::RegularMergePartners& partners // partners of the current block
|
||||
)
|
||||
{ //MergeBlockFunctor
|
||||
(void)partners; // Avoid unused parameter warning
|
||||
|
||||
const auto selfid = rp.gid();
|
||||
|
||||
// TODO This should be changed so that we have the ContourTree itself as the block and then the
|
||||
// ContourTreeMesh would still be used for exchange. In this case we would need to compute
|
||||
// the ContourTreeMesh at the beginning of the function for the current block every time
|
||||
// but then we would not need to compute those meshes when we initialize vtkmdiy
|
||||
// and we don't need to have the special case for rank 0.
|
||||
|
||||
// Here we do the deque first before the send due to the way the iteration is handled in DIY, i.e., in each iteration
|
||||
// A block needs to first collect the data from its neighours and then send the combined block to its neighbours
|
||||
// for the next iteration.
|
||||
// 1. dequeue the block and compute the new contour tree and contour tree mesh for the block if we have the hight GID
|
||||
std::vector<int> incoming;
|
||||
rp.incoming(incoming);
|
||||
for (const int ingid : incoming)
|
||||
{
|
||||
if (ingid != selfid)
|
||||
{
|
||||
ContourTreeBlockData<FieldType> recvblock;
|
||||
rp.dequeue(ingid, recvblock);
|
||||
|
||||
// Construct the two contour tree mesh by assignign the block data
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType> contourTreeMeshIn;
|
||||
contourTreeMeshIn.NumVertices = recvblock.NumVertices;
|
||||
contourTreeMeshIn.SortOrder = recvblock.SortOrder;
|
||||
contourTreeMeshIn.SortedValues = recvblock.SortedValue;
|
||||
contourTreeMeshIn.GlobalMeshIndex = recvblock.GlobalMeshIndex;
|
||||
contourTreeMeshIn.Neighbours = recvblock.Neighbours;
|
||||
contourTreeMeshIn.FirstNeighbour = recvblock.FirstNeighbour;
|
||||
contourTreeMeshIn.MaxNeighbours = recvblock.MaxNeighbours;
|
||||
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType> contourTreeMeshOut;
|
||||
contourTreeMeshOut.NumVertices = block->NumVertices;
|
||||
contourTreeMeshOut.SortOrder = block->SortOrder;
|
||||
contourTreeMeshOut.SortedValues = block->SortedValue;
|
||||
contourTreeMeshOut.GlobalMeshIndex = block->GlobalMeshIndex;
|
||||
contourTreeMeshOut.Neighbours = block->Neighbours;
|
||||
contourTreeMeshOut.FirstNeighbour = block->FirstNeighbour;
|
||||
contourTreeMeshOut.MaxNeighbours = block->MaxNeighbours;
|
||||
// Merge the two contour tree meshes
|
||||
vtkm::cont::TryExecute(MergeFunctor{}, contourTreeMeshIn, contourTreeMeshOut);
|
||||
|
||||
// Compute the origin and size of the new block
|
||||
vtkm::Id3 globalSize = block->GlobalSize;
|
||||
vtkm::Id3 currBlockOrigin;
|
||||
currBlockOrigin[0] = std::min(recvblock.BlockOrigin[0], block->BlockOrigin[0]);
|
||||
currBlockOrigin[1] = std::min(recvblock.BlockOrigin[1], block->BlockOrigin[1]);
|
||||
currBlockOrigin[2] = std::min(recvblock.BlockOrigin[2], block->BlockOrigin[2]);
|
||||
vtkm::Id3 currBlockMaxIndex; // Needed only to compute the block size
|
||||
currBlockMaxIndex[0] = std::max(recvblock.BlockOrigin[0] + recvblock.BlockSize[0],
|
||||
block->BlockOrigin[0] + block->BlockSize[0]);
|
||||
currBlockMaxIndex[1] = std::max(recvblock.BlockOrigin[1] + recvblock.BlockSize[1],
|
||||
block->BlockOrigin[1] + block->BlockSize[1]);
|
||||
currBlockMaxIndex[2] = std::max(recvblock.BlockOrigin[2] + recvblock.BlockSize[2],
|
||||
block->BlockOrigin[2] + block->BlockSize[2]);
|
||||
vtkm::Id3 currBlockSize;
|
||||
currBlockSize[0] = currBlockMaxIndex[0] - currBlockOrigin[0];
|
||||
currBlockSize[1] = currBlockMaxIndex[1] - currBlockOrigin[1];
|
||||
currBlockSize[2] = currBlockMaxIndex[2] - currBlockOrigin[2];
|
||||
|
||||
// On rank 0 we compute the contour tree at the end when the merge is done, so we don't need to do it here
|
||||
if (selfid == 0)
|
||||
{
|
||||
// Save the data from our block for the next iteration
|
||||
block->NumVertices = contourTreeMeshOut.NumVertices;
|
||||
block->SortOrder = contourTreeMeshOut.SortOrder;
|
||||
block->SortedValue = contourTreeMeshOut.SortedValues;
|
||||
block->GlobalMeshIndex = contourTreeMeshOut.GlobalMeshIndex;
|
||||
block->Neighbours = contourTreeMeshOut.Neighbours;
|
||||
block->FirstNeighbour = contourTreeMeshOut.FirstNeighbour;
|
||||
block->MaxNeighbours = contourTreeMeshOut.MaxNeighbours;
|
||||
block->BlockOrigin = currBlockOrigin;
|
||||
block->BlockSize = currBlockSize;
|
||||
block->GlobalSize = globalSize;
|
||||
}
|
||||
else // If we are a block that will continue to be merged then we need compute the contour tree here
|
||||
{
|
||||
// Compute the contour tree from our merged mesh
|
||||
vtkm::Id currNumIterations;
|
||||
vtkm::worklet::contourtree_augmented::ContourTree currContourTree;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType currSortOrder;
|
||||
vtkm::worklet::ContourTreeAugmented worklet;
|
||||
vtkm::cont::ArrayHandle<FieldType> currField;
|
||||
vtkm::Id3 maxIdx(currBlockOrigin[0] + currBlockSize[0] - 1,
|
||||
currBlockOrigin[1] + currBlockSize[1] - 1,
|
||||
currBlockOrigin[2] + currBlockSize[2] - 1);
|
||||
auto meshBoundaryExecObj =
|
||||
contourTreeMeshOut.GetMeshBoundaryExecutionObject(globalSize[0], // totalNRows
|
||||
globalSize[1], // totalNCols
|
||||
currBlockOrigin, // minIdx
|
||||
maxIdx // maxIdx
|
||||
);
|
||||
worklet.Run(
|
||||
contourTreeMeshOut.SortedValues, // Unused param. Provide something to keep the API happy
|
||||
contourTreeMeshOut,
|
||||
currContourTree,
|
||||
currSortOrder,
|
||||
currNumIterations,
|
||||
block->ComputeRegularStructure,
|
||||
meshBoundaryExecObj);
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>* newContourTreeMesh =
|
||||
nullptr;
|
||||
if (block->ComputeRegularStructure == 1)
|
||||
{
|
||||
// If we have the fully augmented contour tree
|
||||
newContourTreeMesh = new vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>(
|
||||
currContourTree.Arcs, contourTreeMeshOut);
|
||||
}
|
||||
else if (block->ComputeRegularStructure == 2)
|
||||
{
|
||||
// If we have the partially augmented (e.g., boundary augmented) contour tree
|
||||
newContourTreeMesh = new vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>(
|
||||
currContourTree.Augmentnodes, currContourTree.Augmentarcs, contourTreeMeshOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We should not be able to get here
|
||||
throw vtkm::cont::ErrorFilterExecution(
|
||||
"Parallel contour tree requires at least parial boundary augmentation");
|
||||
}
|
||||
|
||||
// Copy the data from newContourTreeMesh into block
|
||||
block->NumVertices = newContourTreeMesh->NumVertices;
|
||||
block->SortOrder = newContourTreeMesh->SortOrder;
|
||||
block->SortedValue = newContourTreeMesh->SortedValues;
|
||||
block->GlobalMeshIndex = newContourTreeMesh->GlobalMeshIndex;
|
||||
block->Neighbours = newContourTreeMesh->Neighbours;
|
||||
block->FirstNeighbour = newContourTreeMesh->FirstNeighbour;
|
||||
block->MaxNeighbours = newContourTreeMesh->MaxNeighbours;
|
||||
block->BlockOrigin = currBlockOrigin;
|
||||
block->BlockSize = currBlockSize;
|
||||
block->GlobalSize = globalSize;
|
||||
|
||||
// VTKm keeps track of the arrays for us, so we can savely delete the ContourTreeMesh
|
||||
// as all data has been transferred into our data block
|
||||
delete newContourTreeMesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Send our current block (which is either our original block or the one we just combined from the ones we received) to our next neighbour.
|
||||
// Once a rank has send his block (either in its orignal or merged form) it is done with the reduce
|
||||
for (int cc = 0; cc < rp.out_link().size(); ++cc)
|
||||
{
|
||||
auto target = rp.out_link().target(cc);
|
||||
if (target.gid != selfid)
|
||||
{
|
||||
rp.enqueue(target, *block);
|
||||
}
|
||||
}
|
||||
} //end MergeBlockFunctor
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
|
||||
@ -576,11 +120,12 @@ void ContourTreeAugmented::SetSpatialDecomposition(
|
||||
{
|
||||
if (this->MultiBlockTreeHelper)
|
||||
{
|
||||
delete this->MultiBlockTreeHelper;
|
||||
this->MultiBlockTreeHelper = nullptr;
|
||||
this->MultiBlockTreeHelper.reset();
|
||||
}
|
||||
this->MultiBlockTreeHelper = new detail::MultiBlockContourTreeHelper(
|
||||
blocksPerDim, globalSize, localBlockIndices, localBlockOrigins, localBlockSizes);
|
||||
this->MultiBlockTreeHelper =
|
||||
std::unique_ptr<vtkm::worklet::contourtree_distributed::MultiBlockContourTreeHelper>(
|
||||
new vtkm::worklet::contourtree_distributed::MultiBlockContourTreeHelper(
|
||||
blocksPerDim, globalSize, localBlockIndices, localBlockOrigins, localBlockSizes));
|
||||
}
|
||||
|
||||
const vtkm::worklet::contourtree_augmented::ContourTree& ContourTreeAugmented::GetContourTree()
|
||||
@ -623,7 +168,7 @@ vtkm::cont::DataSet ContourTreeAugmented::DoExecute(
|
||||
vtkm::Id nSlices = 1;
|
||||
const auto& cells = input.GetCellSet();
|
||||
vtkm::filter::ApplyPolicyCellSet(cells, policy, *this)
|
||||
.CastAndCall(GetRowsColsSlices(), nRows, nCols, nSlices);
|
||||
.CastAndCall(vtkm::worklet::contourtree_augmented::GetRowsColsSlices(), nRows, nCols, nSlices);
|
||||
// TODO blockIndex needs to change if we have multiple blocks per MPI rank and DoExecute is called for multiple blocks
|
||||
std::size_t blockIndex = 0;
|
||||
|
||||
@ -677,7 +222,7 @@ vtkm::cont::DataSet ContourTreeAugmented::DoExecute(
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Perf,
|
||||
std::endl
|
||||
<< " "
|
||||
<< std::setw(38)
|
||||
@ -742,7 +287,7 @@ VTKM_CONT void ContourTreeAugmented::DoPostExecute(
|
||||
std::vector<vtkm::worklet::contourtree_augmented::ContourTreeMesh<T>*> localContourTreeMeshes;
|
||||
localContourTreeMeshes.resize(static_cast<std::size_t>(input.GetNumberOfPartitions()));
|
||||
// TODO need to allocate and free these ourselves. May need to update detail::MultiBlockContourTreeHelper::ComputeLocalContourTreeMesh
|
||||
std::vector<vtkm::filter::detail::ContourTreeBlockData<T>*> localDataBlocks;
|
||||
std::vector<vtkm::worklet::contourtree_distributed::ContourTreeBlockData<T>*> localDataBlocks;
|
||||
localDataBlocks.resize(static_cast<size_t>(input.GetNumberOfPartitions()));
|
||||
std::vector<vtkmdiy::Link*> localLinks; // dummy links needed to make DIY happy
|
||||
localLinks.resize(static_cast<size_t>(input.GetNumberOfPartitions()));
|
||||
@ -764,10 +309,12 @@ VTKM_CONT void ContourTreeAugmented::DoPostExecute(
|
||||
//const vtkm::cont::ArrayHandle<T,StorageType> &fieldData = currField.GetData().Cast<vtkm::cont::ArrayHandle<T,StorageType> >();
|
||||
vtkm::cont::ArrayHandle<T> fieldData;
|
||||
vtkm::cont::ArrayCopy(currField.GetData().template AsVirtual<T>(), fieldData);
|
||||
auto currContourTreeMesh =
|
||||
vtkm::filter::detail::MultiBlockContourTreeHelper::ComputeLocalContourTreeMesh<T>(
|
||||
localBlocksOriginPortal.Get(static_cast<vtkm::Id>(bi)),
|
||||
localBlocksSizesPortal.Get(static_cast<vtkm::Id>(bi)),
|
||||
auto currContourTreeMesh = vtkm::worklet::contourtree_distributed::MultiBlockContourTreeHelper::
|
||||
ComputeLocalContourTreeMesh<T>(
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.LocalBlockOrigins.ReadPortal()
|
||||
.Get(static_cast<vtkm::Id>(bi)),
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.LocalBlockSizes.ReadPortal().Get(
|
||||
static_cast<vtkm::Id>(bi)),
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize,
|
||||
fieldData,
|
||||
MultiBlockTreeHelper->LocalContourTrees[bi],
|
||||
@ -775,7 +322,7 @@ VTKM_CONT void ContourTreeAugmented::DoPostExecute(
|
||||
compRegularStruct);
|
||||
localContourTreeMeshes[bi] = currContourTreeMesh;
|
||||
// create the local data block structure
|
||||
localDataBlocks[bi] = new vtkm::filter::detail::ContourTreeBlockData<T>();
|
||||
localDataBlocks[bi] = new vtkm::worklet::contourtree_distributed::ContourTreeBlockData<T>();
|
||||
localDataBlocks[bi]->NumVertices = currContourTreeMesh->NumVertices;
|
||||
localDataBlocks[bi]->SortOrder = currContourTreeMesh->SortOrder;
|
||||
localDataBlocks[bi]->SortedValue = currContourTreeMesh->SortedValues;
|
||||
@ -799,7 +346,7 @@ VTKM_CONT void ContourTreeAugmented::DoPostExecute(
|
||||
);
|
||||
|
||||
// Compute the gids for our local blocks
|
||||
const detail::SpatialDecomposition& spatialDecomp =
|
||||
const vtkm::worklet::contourtree_distributed::SpatialDecomposition& spatialDecomp =
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition;
|
||||
auto localBlockIndicesPortal = spatialDecomp.LocalBlockIndices.ReadPortal();
|
||||
std::vector<vtkm::Id> vtkmdiyLocalBlockGids(static_cast<size_t>(input.GetNumberOfPartitions()));
|
||||
@ -853,7 +400,8 @@ VTKM_CONT void ContourTreeAugmented::DoPostExecute(
|
||||
true // contiguous: true=distance doubling , false=distnace halving TODO check this value
|
||||
);
|
||||
// reduction
|
||||
vtkmdiy::reduce(master, assigner, partners, &detail::MergeBlockFunctor<T>);
|
||||
vtkmdiy::reduce(
|
||||
master, assigner, partners, &vtkm::worklet::contourtree_distributed::MergeBlockFunctor<T>);
|
||||
|
||||
comm.barrier(); // Be safe!
|
||||
|
||||
@ -957,9 +505,8 @@ inline VTKM_CONT void ContourTreeAugmented::PostExecute(
|
||||
metaData,
|
||||
policy);
|
||||
|
||||
delete this->MultiBlockTreeHelper;
|
||||
this->MultiBlockTreeHelper = nullptr;
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
this->MultiBlockTreeHelper.reset();
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Perf,
|
||||
std::endl
|
||||
<< " "
|
||||
<< std::setw(38)
|
||||
|
172
vtkm/filter/ContourTreeUniformDistributed.h
Normal file
172
vtkm/filter/ContourTreeUniformDistributed.h
Normal file
@ -0,0 +1,172 @@
|
||||
//============================================================================
|
||||
// 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_filter_ContourTreeUniformDistributed_h
|
||||
#define vtk_m_filter_ContourTreeUniformDistributed_h
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/ContourTree.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/MultiBlockContourTreeHelper.h>
|
||||
|
||||
#include <vtkm/filter/FilterCell.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
|
||||
/// \brief Construct the Contour Tree for a 2D or 3D regular mesh
|
||||
///
|
||||
/// This filter implements the parallel peak pruning algorithm. In contrast to
|
||||
/// the ContourTreeUniform filter, this filter is optimized to allow for the
|
||||
/// computation of the augmented contour tree, i.e., the contour tree including
|
||||
/// all regular mesh vertices. Augmentation with regular vertices is used in
|
||||
/// practice to compute statistics (e.g., volume), to segment the input mesh,
|
||||
/// facilitate iso-value selection, enable localization of all verticies of a
|
||||
/// mesh in the tree among others.
|
||||
///
|
||||
/// In addition to single-block computation, the filter also supports multi-block
|
||||
/// regular grids. The blocks are processed in parallel using DIY and then the
|
||||
/// tree are merged progressively using a binary-reduction scheme to compute the
|
||||
/// final contour tree. I.e., in the multi-block context, the final tree is
|
||||
/// constructed on rank 0.
|
||||
class ContourTreeUniformDistributed : public vtkm::filter::FilterCell<ContourTreeUniformDistributed>
|
||||
{
|
||||
public:
|
||||
using SupportedTypes = vtkm::TypeListScalarAll;
|
||||
///
|
||||
/// Create the contour tree filter
|
||||
/// @param[in] useMarchingCubes Boolean indicating whether marching cubes (true) or freudenthal (false)
|
||||
/// connectivity should be used. Valid only for 3D input data. Default is false.
|
||||
VTKM_CONT
|
||||
ContourTreeUniformDistributed(bool useMarchingCubes = false);
|
||||
|
||||
///
|
||||
/// Define the spatial decomposition of the data in case we run in parallel with a multi-block dataset
|
||||
///
|
||||
/// Note: Only used when running on a multi-block dataset.
|
||||
/// @param[in] blocksPerDim Number of data blocks used in each data dimension
|
||||
/// @param[in] globalSize Global extends of the input mesh (i.e., number of mesh points in each dimension)
|
||||
/// @param[in] localBlockIndices Array with the (x,y,z) index of each local data block with
|
||||
/// with respect to blocksPerDim
|
||||
/// @param[in] localBlockOrigins Array with the (x,y,z) origin (with regard to mesh index) of each
|
||||
/// local data block
|
||||
/// @param[in] localBlockSizes Array with the sizes (i.e., extends in number of mesh points) of each
|
||||
/// local data block
|
||||
VTKM_CONT
|
||||
void SetSpatialDecomposition(vtkm::Id3 blocksPerDim,
|
||||
vtkm::Id3 globalSize,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockOrigins,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockSizes);
|
||||
|
||||
/// Output field "saddlePeak" wich is pairs of vertex ids indicating saddle and peak of contour
|
||||
template <typename T, typename StorageType, typename DerivedPolicy>
|
||||
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>& field,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
vtkm::filter::PolicyBase<DerivedPolicy> policy);
|
||||
|
||||
//@{
|
||||
/// when operating on vtkm::cont::MultiBlock we want to
|
||||
/// do processing across ranks as well. Just adding pre/post handles
|
||||
/// for the same does the trick.
|
||||
template <typename DerivedPolicy>
|
||||
VTKM_CONT void PreExecute(const vtkm::cont::PartitionedDataSet& input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
|
||||
|
||||
template <typename DerivedPolicy>
|
||||
VTKM_CONT void PostExecute(const vtkm::cont::PartitionedDataSet& input,
|
||||
vtkm::cont::PartitionedDataSet& output,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&);
|
||||
|
||||
|
||||
///
|
||||
/// Internal helper function that implements the actual functionality of PostExecute
|
||||
///
|
||||
/// In the case we operate on vtkm::cont::MultiBlock we need to merge the trees
|
||||
/// computed on the block to compute the final contour tree.
|
||||
template <typename T, typename StorageType, typename DerivedPolicy>
|
||||
VTKM_CONT void DoPostExecute(
|
||||
const vtkm::cont::PartitionedDataSet& input,
|
||||
vtkm::cont::PartitionedDataSet& output,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>&, // dummy parameter to get the type
|
||||
vtkm::filter::PolicyBase<DerivedPolicy> policy);
|
||||
//@}
|
||||
|
||||
private:
|
||||
/// Use marching cubes connectivity for computing the contour tree
|
||||
bool UseMarchingCubes;
|
||||
|
||||
/// The contour tree computed by the filter
|
||||
vtkm::worklet::contourtree_augmented::ContourTree ContourTreeData;
|
||||
/// Number of iterations used to compute the contour tree
|
||||
vtkm::Id NumIterations;
|
||||
/// Array with the sorted order of the mesh vertices
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType MeshSortOrder;
|
||||
|
||||
/// Helper object to help with the parallel merge when running with DIY in parallel with MulitBlock data
|
||||
std::unique_ptr<vtkm::worklet::contourtree_distributed::MultiBlockContourTreeHelper>
|
||||
MultiBlockTreeHelper;
|
||||
};
|
||||
|
||||
} // namespace filter
|
||||
} // namespace vtkm
|
||||
|
||||
#include <vtkm/filter/ContourTreeUniformDistributed.hxx>
|
||||
|
||||
#endif // vtk_m_filter_ContourTreeUniformAugmented_h
|
491
vtkm/filter/ContourTreeUniformDistributed.hxx
Normal file
491
vtkm/filter/ContourTreeUniformDistributed.hxx
Normal file
@ -0,0 +1,491 @@
|
||||
//============================================================================
|
||||
// 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_filter_ContourTreeUniformDistributed_hxx
|
||||
#define vtk_m_filter_ContourTreeUniformDistributed_hxx
|
||||
|
||||
// vtkm includes
|
||||
#include <vtkm/cont/Timer.h>
|
||||
|
||||
// single-node augmented contour tree includes
|
||||
#include <vtkm/filter/ContourTreeUniformDistributed.h>
|
||||
#include <vtkm/worklet/ContourTreeUniformAugmented.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/ContourTreeMesh.h>
|
||||
|
||||
// distributed contour tree includes
|
||||
#include <vtkm/worklet/contourtree_distributed/BoundaryRestrictedAugmentedContourTree.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/BoundaryRestrictedAugmentedContourTreeMaker.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/ContourTreeBlockData.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/MergeBlockFunctor.h>
|
||||
#include <vtkm/worklet/contourtree_distributed/SpatialDecomposition.h>
|
||||
|
||||
// DIY includes
|
||||
// clang-format off
|
||||
VTKM_THIRDPARTY_PRE_INCLUDE
|
||||
#include <vtkm/thirdparty/diy/Configure.h>
|
||||
#include <vtkm/thirdparty/diy/diy.h>
|
||||
VTKM_THIRDPARTY_POST_INCLUDE
|
||||
// clang-format on
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
namespace contourtree_distributed_detail
|
||||
{
|
||||
//----Helper struct to call DoPostExecute. This is used to be able to
|
||||
// wrap the PostExecute work in a functor so that we can use VTK-M's
|
||||
// vtkm::cont::CastAndCall to infer the FieldType template parameters
|
||||
struct PostExecuteCaller
|
||||
{
|
||||
template <typename T, typename S, typename DerivedPolicy>
|
||||
VTKM_CONT void operator()(const vtkm::cont::ArrayHandle<T, S>&,
|
||||
ContourTreeUniformDistributed* self,
|
||||
const vtkm::cont::PartitionedDataSet& input,
|
||||
vtkm::cont::PartitionedDataSet& output,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
vtkm::filter::PolicyBase<DerivedPolicy> policy) const
|
||||
{
|
||||
vtkm::cont::ArrayHandle<T, S> dummy;
|
||||
self->DoPostExecute(input, output, fieldMeta, dummy, policy);
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace contourtree_distributed_detail
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ContourTreeUniformDistributed::ContourTreeUniformDistributed(bool useMarchingCubes)
|
||||
: vtkm::filter::FilterCell<ContourTreeUniformDistributed>()
|
||||
, UseMarchingCubes(useMarchingCubes)
|
||||
, MultiBlockTreeHelper(nullptr)
|
||||
{
|
||||
this->SetOutputFieldName("resultData");
|
||||
}
|
||||
|
||||
void ContourTreeUniformDistributed::SetSpatialDecomposition(
|
||||
vtkm::Id3 blocksPerDim,
|
||||
vtkm::Id3 globalSize,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockOrigins,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockSizes)
|
||||
{
|
||||
if (this->MultiBlockTreeHelper)
|
||||
{
|
||||
this->MultiBlockTreeHelper.reset();
|
||||
}
|
||||
this->MultiBlockTreeHelper =
|
||||
std::unique_ptr<vtkm::worklet::contourtree_distributed::MultiBlockContourTreeHelper>(
|
||||
new vtkm::worklet::contourtree_distributed::MultiBlockContourTreeHelper(
|
||||
blocksPerDim, globalSize, localBlockIndices, localBlockOrigins, localBlockSizes));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T, typename StorageType, typename DerivedPolicy>
|
||||
vtkm::cont::DataSet ContourTreeUniformDistributed::DoExecute(
|
||||
const vtkm::cont::DataSet& input,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>& field,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
vtkm::filter::PolicyBase<DerivedPolicy> policy)
|
||||
{
|
||||
vtkm::cont::Timer timer;
|
||||
timer.Start();
|
||||
|
||||
// Check that the field is Ok
|
||||
if (fieldMeta.IsPointField() == false)
|
||||
{
|
||||
throw vtkm::cont::ErrorFilterExecution("Point field expected.");
|
||||
}
|
||||
|
||||
// Use the GetRowsColsSlices struct defined in the header to collect the nRows, nCols, and nSlices information
|
||||
vtkm::worklet::ContourTreeAugmented worklet;
|
||||
vtkm::Id nRows;
|
||||
vtkm::Id nCols;
|
||||
vtkm::Id nSlices = 1;
|
||||
const auto& cells = input.GetCellSet();
|
||||
vtkm::filter::ApplyPolicyCellSet(cells, policy, *this)
|
||||
.CastAndCall(vtkm::worklet::contourtree_augmented::GetRowsColsSlices(), nRows, nCols, nSlices);
|
||||
// TODO blockIndex needs to change if we have multiple blocks per MPI rank and DoExecute is called for multiple blocks
|
||||
std::size_t blockIndex = 0;
|
||||
|
||||
// We always need to compute the fully augemented contour tree for our local data block
|
||||
unsigned int compRegularStruct = 1;
|
||||
|
||||
// Run the worklet
|
||||
worklet.Run(field,
|
||||
MultiBlockTreeHelper ? MultiBlockTreeHelper->LocalContourTrees[blockIndex]
|
||||
: this->ContourTreeData,
|
||||
MultiBlockTreeHelper ? MultiBlockTreeHelper->LocalSortOrders[blockIndex]
|
||||
: this->MeshSortOrder,
|
||||
this->NumIterations,
|
||||
nRows,
|
||||
nCols,
|
||||
nSlices,
|
||||
this->UseMarchingCubes,
|
||||
compRegularStruct);
|
||||
|
||||
// If we run in parallel but with only one global block, then we need set our outputs correctly
|
||||
// here to match the expected behavior in parallel
|
||||
if (this->MultiBlockTreeHelper)
|
||||
{
|
||||
if (this->MultiBlockTreeHelper->GetGlobalNumberOfBlocks() == 1)
|
||||
{
|
||||
// Copy the contour tree and mesh sort order to the output
|
||||
this->ContourTreeData = this->MultiBlockTreeHelper->LocalContourTrees[0];
|
||||
this->MeshSortOrder = this->MultiBlockTreeHelper->LocalSortOrders[0];
|
||||
// In parallel we need the sorted values as output resulti
|
||||
// Construct the sorted values by permutting the input field
|
||||
auto fieldPermutted = vtkm::cont::make_ArrayHandlePermutation(this->MeshSortOrder, field);
|
||||
vtkm::cont::ArrayHandle<T> sortedValues;
|
||||
vtkm::cont::Algorithm::Copy(fieldPermutted, sortedValues);
|
||||
// Create the result object
|
||||
vtkm::cont::DataSet result;
|
||||
vtkm::cont::Field rfield(
|
||||
this->GetOutputFieldName(), vtkm::cont::Field::Association::WHOLE_MESH, sortedValues);
|
||||
result.AddField(rfield);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Perf,
|
||||
std::endl
|
||||
<< " "
|
||||
<< std::setw(38)
|
||||
<< std::left
|
||||
<< "Contour Tree Filter DoExecute"
|
||||
<< ": "
|
||||
<< timer.GetElapsedTime()
|
||||
<< " seconds");
|
||||
|
||||
// Construct the expected result for serial execution. Note, in serial the result currently
|
||||
// not actually being used, but in parallel we need the sorted mesh values as output
|
||||
// This part is being hit when we run in serial or parallel with more then one rank
|
||||
return CreateResultFieldPoint(input, ContourTreeData.Arcs, this->GetOutputFieldName());
|
||||
} // ContourTreeUniformDistributed::DoExecute
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename DerivedPolicy>
|
||||
inline VTKM_CONT void ContourTreeUniformDistributed::PreExecute(
|
||||
const vtkm::cont::PartitionedDataSet& input,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>&)
|
||||
{
|
||||
if (this->MultiBlockTreeHelper)
|
||||
{
|
||||
if (this->MultiBlockTreeHelper->GetGlobalNumberOfBlocks(input) !=
|
||||
this->MultiBlockTreeHelper->GetGlobalNumberOfBlocks())
|
||||
{
|
||||
throw vtkm::cont::ErrorFilterExecution(
|
||||
"Global number of block in MultiBlock dataset does not match the SpatialDecomposition");
|
||||
}
|
||||
if (this->MultiBlockTreeHelper->GetLocalNumberOfBlocks() != input.GetNumberOfPartitions())
|
||||
{
|
||||
throw vtkm::cont::ErrorFilterExecution(
|
||||
"Global number of block in MultiBlock dataset does not match the SpatialDecomposition");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename T, typename StorageType, typename DerivedPolicy>
|
||||
VTKM_CONT void ContourTreeUniformDistributed::DoPostExecute(
|
||||
const vtkm::cont::PartitionedDataSet& input,
|
||||
vtkm::cont::PartitionedDataSet& output,
|
||||
const vtkm::filter::FieldMetadata& fieldMeta,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>&, // dummy parameter to get the type
|
||||
vtkm::filter::PolicyBase<DerivedPolicy> policy)
|
||||
{
|
||||
(void)fieldMeta; // avoid unused parameter warning
|
||||
(void)policy; // avoid unused parameter warning
|
||||
|
||||
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
|
||||
vtkm::Id size = comm.size();
|
||||
vtkm::Id rank = comm.rank();
|
||||
|
||||
std::vector<vtkm::worklet::contourtree_augmented::ContourTreeMesh<T>*> localContourTreeMeshes;
|
||||
localContourTreeMeshes.resize(static_cast<std::size_t>(input.GetNumberOfPartitions()));
|
||||
// TODO need to allocate and free these ourselves. May need to update detail::MultiBlockContourTreeHelper::ComputeLocalContourTreeMesh
|
||||
std::vector<vtkm::worklet::contourtree_distributed::ContourTreeBlockData<T>*> localDataBlocks;
|
||||
localDataBlocks.resize(static_cast<size_t>(input.GetNumberOfPartitions()));
|
||||
std::vector<vtkmdiy::Link*> localLinks; // dummy links needed to make DIY happy
|
||||
localLinks.resize(static_cast<size_t>(input.GetNumberOfPartitions()));
|
||||
// TODO Check setting. In parallel we should need to augment the tree in order to be able to do the merging
|
||||
unsigned int compRegularStruct = 1;
|
||||
for (std::size_t bi = 0; bi < static_cast<std::size_t>(input.GetNumberOfPartitions()); bi++)
|
||||
{
|
||||
// create the local contour tree mesh
|
||||
localLinks[bi] = new vtkmdiy::Link;
|
||||
auto currBlock = input.GetPartition(static_cast<vtkm::Id>(bi));
|
||||
auto currField =
|
||||
currBlock.GetField(this->GetActiveFieldName(), this->GetActiveFieldAssociation());
|
||||
//const vtkm::cont::ArrayHandle<T,StorageType> &fieldData = currField.GetData().Cast<vtkm::cont::ArrayHandle<T,StorageType> >();
|
||||
vtkm::cont::ArrayHandle<T> fieldData;
|
||||
vtkm::cont::ArrayCopy(currField.GetData().AsVirtual<T>(), fieldData);
|
||||
auto currContourTreeMesh = vtkm::worklet::contourtree_distributed::MultiBlockContourTreeHelper::
|
||||
ComputeLocalContourTreeMesh<T>(
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.LocalBlockOrigins.ReadPortal()
|
||||
.Get(static_cast<vtkm::Id>(bi)),
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.LocalBlockSizes.ReadPortal().Get(
|
||||
static_cast<vtkm::Id>(bi)),
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize,
|
||||
fieldData,
|
||||
MultiBlockTreeHelper->LocalContourTrees[bi],
|
||||
MultiBlockTreeHelper->LocalSortOrders[bi],
|
||||
compRegularStruct);
|
||||
localContourTreeMeshes[bi] = currContourTreeMesh;
|
||||
// create the local data block structure
|
||||
localDataBlocks[bi] = new vtkm::worklet::contourtree_distributed::ContourTreeBlockData<T>();
|
||||
localDataBlocks[bi]->NumVertices = currContourTreeMesh->NumVertices;
|
||||
localDataBlocks[bi]->SortOrder = currContourTreeMesh->SortOrder;
|
||||
localDataBlocks[bi]->SortedValue = currContourTreeMesh->SortedValues;
|
||||
localDataBlocks[bi]->GlobalMeshIndex = currContourTreeMesh->GlobalMeshIndex;
|
||||
localDataBlocks[bi]->Neighbours = currContourTreeMesh->Neighbours;
|
||||
localDataBlocks[bi]->FirstNeighbour = currContourTreeMesh->FirstNeighbour;
|
||||
localDataBlocks[bi]->MaxNeighbours = currContourTreeMesh->MaxNeighbours;
|
||||
localDataBlocks[bi]->BlockOrigin =
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.LocalBlockOrigins.ReadPortal().Get(
|
||||
static_cast<vtkm::Id>(bi));
|
||||
localDataBlocks[bi]->BlockSize =
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.LocalBlockSizes.ReadPortal().Get(
|
||||
static_cast<vtkm::Id>(bi));
|
||||
localDataBlocks[bi]->GlobalSize =
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize;
|
||||
// We need to augment at least with the boundary vertices when running in parallel
|
||||
localDataBlocks[bi]->ComputeRegularStructure = compRegularStruct;
|
||||
}
|
||||
// Setup vtkmdiy to do global binary reduction of neighbouring blocks. See also RecuctionOperation struct for example
|
||||
|
||||
// Create the vtkmdiy master
|
||||
vtkmdiy::Master master(comm,
|
||||
1, // Use 1 thread, VTK-M will do the treading
|
||||
-1 // All block in memory
|
||||
);
|
||||
|
||||
// Compute the gids for our local blocks
|
||||
const vtkm::worklet::contourtree_distributed::SpatialDecomposition& spatialDecomp =
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition;
|
||||
auto localBlockIndicesPortal = spatialDecomp.LocalBlockIndices.ReadPortal();
|
||||
std::vector<vtkm::Id> vtkmdiyLocalBlockGids(static_cast<size_t>(input.GetNumberOfPartitions()));
|
||||
for (vtkm::Id bi = 0; bi < input.GetNumberOfPartitions(); bi++)
|
||||
{
|
||||
std::vector<int> tempCoords; // DivisionsVector type in DIY
|
||||
std::vector<int> tempDivisions; // DivisionsVector type in DIY
|
||||
tempCoords.resize(static_cast<size_t>(spatialDecomp.NumberOfDimensions()));
|
||||
tempDivisions.resize(static_cast<size_t>(spatialDecomp.NumberOfDimensions()));
|
||||
auto currentCoords = localBlockIndicesPortal.Get(bi);
|
||||
for (std::size_t di = 0; di < static_cast<size_t>(spatialDecomp.NumberOfDimensions()); di++)
|
||||
{
|
||||
tempCoords[di] = static_cast<int>(currentCoords[static_cast<vtkm::IdComponent>(di)]);
|
||||
tempDivisions[di] =
|
||||
static_cast<int>(spatialDecomp.BlocksPerDimension[static_cast<vtkm::IdComponent>(di)]);
|
||||
}
|
||||
vtkmdiyLocalBlockGids[static_cast<size_t>(bi)] =
|
||||
vtkmdiy::RegularDecomposer<vtkmdiy::DiscreteBounds>::coords_to_gid(tempCoords, tempDivisions);
|
||||
}
|
||||
|
||||
// Add my local blocks to the vtkmdiy master.
|
||||
for (std::size_t bi = 0; bi < static_cast<std::size_t>(input.GetNumberOfPartitions()); bi++)
|
||||
{
|
||||
master.add(static_cast<int>(vtkmdiyLocalBlockGids[bi]), // block id
|
||||
localDataBlocks[bi],
|
||||
localLinks[bi]);
|
||||
}
|
||||
|
||||
// Define the decomposition of the domain into regular blocks
|
||||
vtkmdiy::RegularDecomposer<vtkmdiy::DiscreteBounds> decomposer(
|
||||
static_cast<int>(spatialDecomp.NumberOfDimensions()), // number of dims
|
||||
spatialDecomp.GetVTKmDIYBounds(),
|
||||
static_cast<int>(spatialDecomp.GetGlobalNumberOfBlocks()));
|
||||
|
||||
// Define which blocks live on which rank so that vtkmdiy can manage them
|
||||
vtkmdiy::DynamicAssigner assigner(
|
||||
comm, static_cast<int>(size), static_cast<int>(spatialDecomp.GetGlobalNumberOfBlocks()));
|
||||
for (vtkm::Id bi = 0; bi < input.GetNumberOfPartitions(); bi++)
|
||||
{
|
||||
assigner.set_rank(static_cast<int>(rank),
|
||||
static_cast<int>(vtkmdiyLocalBlockGids[static_cast<size_t>(bi)]));
|
||||
}
|
||||
|
||||
// Fix the vtkmdiy links. TODO Remove changes to the vtkmdiy in VTKM when we update to the new VTK-M
|
||||
vtkmdiy::fix_links(master, assigner);
|
||||
|
||||
// partners for merge over regular block grid
|
||||
vtkmdiy::RegularMergePartners partners(
|
||||
decomposer, // domain decomposition
|
||||
2, // raix of k-ary reduction. TODO check this value
|
||||
true // contiguous: true=distance doubling , false=distnace halving TODO check this value
|
||||
);
|
||||
// reduction
|
||||
vtkmdiy::reduce(
|
||||
master, assigner, partners, &vtkm::worklet::contourtree_distributed::MergeBlockFunctor<T>);
|
||||
|
||||
comm.barrier(); // Be safe!
|
||||
|
||||
if (rank == 0)
|
||||
{
|
||||
// Now run the contour tree algorithm on the last block to compute the final tree
|
||||
vtkm::Id currNumIterations;
|
||||
vtkm::worklet::contourtree_augmented::ContourTree currContourTree;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType currSortOrder;
|
||||
vtkm::worklet::ContourTreeAugmented worklet;
|
||||
vtkm::cont::ArrayHandle<T> currField;
|
||||
// Construct the contour tree mesh from the last block
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<T> contourTreeMeshOut;
|
||||
contourTreeMeshOut.NumVertices = localDataBlocks[0]->NumVertices;
|
||||
contourTreeMeshOut.SortOrder = localDataBlocks[0]->SortOrder;
|
||||
contourTreeMeshOut.SortedValues = localDataBlocks[0]->SortedValue;
|
||||
contourTreeMeshOut.GlobalMeshIndex = localDataBlocks[0]->GlobalMeshIndex;
|
||||
contourTreeMeshOut.Neighbours = localDataBlocks[0]->Neighbours;
|
||||
contourTreeMeshOut.FirstNeighbour = localDataBlocks[0]->FirstNeighbour;
|
||||
contourTreeMeshOut.MaxNeighbours = localDataBlocks[0]->MaxNeighbours;
|
||||
// Construct the mesh boundary exectuion object needed for boundary augmentation
|
||||
vtkm::Id3 minIdx(0, 0, 0);
|
||||
vtkm::Id3 maxIdx = this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize;
|
||||
maxIdx[0] = maxIdx[0] - 1;
|
||||
maxIdx[1] = maxIdx[1] - 1;
|
||||
maxIdx[2] = maxIdx[2] > 0 ? (maxIdx[2] - 1) : 0;
|
||||
auto meshBoundaryExecObj = contourTreeMeshOut.GetMeshBoundaryExecutionObject(
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize[0],
|
||||
this->MultiBlockTreeHelper->MultiBlockSpatialDecomposition.GlobalSize[1],
|
||||
minIdx,
|
||||
maxIdx);
|
||||
// Run the worklet to compute the final contour tree
|
||||
worklet.Run(
|
||||
contourTreeMeshOut.SortedValues, // Unused param. Provide something to keep API happy
|
||||
contourTreeMeshOut,
|
||||
this->ContourTreeData,
|
||||
this->MeshSortOrder,
|
||||
currNumIterations,
|
||||
compRegularStruct,
|
||||
meshBoundaryExecObj);
|
||||
|
||||
// Set the final mesh sort order we need to use
|
||||
this->MeshSortOrder = contourTreeMeshOut.GlobalMeshIndex;
|
||||
// Remeber the number of iterations for the output
|
||||
this->NumIterations = currNumIterations;
|
||||
|
||||
// Return the sorted values of the contour tree as the result
|
||||
// TODO the result we return for the parallel and serial case are different right now. This should be made consistent. However, only in the parallel case are we useing the result output
|
||||
vtkm::cont::DataSet temp;
|
||||
vtkm::cont::Field rfield(this->GetOutputFieldName(),
|
||||
vtkm::cont::Field::Association::WHOLE_MESH,
|
||||
contourTreeMeshOut.SortedValues);
|
||||
temp.AddField(rfield);
|
||||
output = vtkm::cont::PartitionedDataSet(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ContourTreeData = MultiBlockTreeHelper->LocalContourTrees[0];
|
||||
this->MeshSortOrder = MultiBlockTreeHelper->LocalSortOrders[0];
|
||||
|
||||
// Free allocated temporary pointers
|
||||
for (std::size_t bi = 0; bi < static_cast<std::size_t>(input.GetNumberOfPartitions()); bi++)
|
||||
{
|
||||
delete localContourTreeMeshes[bi];
|
||||
delete localDataBlocks[bi];
|
||||
// delete localLinks[bi];
|
||||
}
|
||||
}
|
||||
localContourTreeMeshes.clear();
|
||||
localDataBlocks.clear();
|
||||
localLinks.clear();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
template <typename DerivedPolicy>
|
||||
inline VTKM_CONT void ContourTreeUniformDistributed::PostExecute(
|
||||
const vtkm::cont::PartitionedDataSet& input,
|
||||
vtkm::cont::PartitionedDataSet& result,
|
||||
const vtkm::filter::PolicyBase<DerivedPolicy>& policy)
|
||||
{
|
||||
if (this->MultiBlockTreeHelper)
|
||||
{
|
||||
vtkm::cont::Timer timer;
|
||||
timer.Start();
|
||||
// We are running in parallel and need to merge the contour tree in PostExecute
|
||||
if (MultiBlockTreeHelper->GetGlobalNumberOfBlocks() == 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
auto field =
|
||||
input.GetPartition(0).GetField(this->GetActiveFieldName(), this->GetActiveFieldAssociation());
|
||||
vtkm::filter::FieldMetadata metaData(field);
|
||||
|
||||
vtkm::filter::FilterTraits<ContourTreeUniformDistributed> traits;
|
||||
vtkm::cont::CastAndCall(vtkm::filter::ApplyPolicyFieldActive(field, policy, traits),
|
||||
vtkm::filter::contourtree_distributed_detail::PostExecuteCaller{},
|
||||
this,
|
||||
input,
|
||||
result,
|
||||
metaData,
|
||||
policy);
|
||||
|
||||
this->MultiBlockTreeHelper.reset();
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Perf,
|
||||
std::endl
|
||||
<< " "
|
||||
<< std::setw(38)
|
||||
<< std::left
|
||||
<< "Contour Tree Filter PostExecute"
|
||||
<< ": "
|
||||
<< timer.GetElapsedTime()
|
||||
<< " seconds");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace filter
|
||||
} // namespace vtkm::filter
|
||||
|
||||
#endif
|
@ -124,6 +124,7 @@ add_subdirectory(connectivities)
|
||||
add_subdirectory(contour)
|
||||
add_subdirectory(contourtree)
|
||||
add_subdirectory(contourtree_augmented)
|
||||
add_subdirectory(contourtree_distributed)
|
||||
add_subdirectory(cosmotools)
|
||||
add_subdirectory(gradient)
|
||||
add_subdirectory(histogram)
|
||||
|
@ -76,7 +76,9 @@
|
||||
#include <vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/ContourTreeMesh.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshBoundary.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary2D.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary3D.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundaryContourTreeMesh.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -352,14 +354,14 @@ private:
|
||||
timer.Start();
|
||||
|
||||
// Collect the output data
|
||||
nIterations = treeMaker.NumIterations;
|
||||
nIterations = treeMaker.ContourTreeResult.NumIterations;
|
||||
sortOrder = mesh.SortOrder;
|
||||
// ProcessContourTree::CollectSortedSuperarcs<DeviceAdapter>(contourTree, mesh.SortOrder, saddlePeak);
|
||||
// contourTree.SortedArcPrint(mesh.SortOrder);
|
||||
// contourTree.PrintDotSuperStructure();
|
||||
|
||||
// Log the collected timing results in one coherent log entry
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info, timingsStream.str());
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Perf, timingsStream.str());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -148,11 +148,14 @@ public:
|
||||
// because not all Hyperarcs lead to hypernodes
|
||||
IdArrayType Hyperarcs;
|
||||
|
||||
// counter for the number of iterations it took to construct the tree
|
||||
// this is also used for hypersweep computations
|
||||
vtkm::Id NumIterations;
|
||||
|
||||
// vectors tracking the segments used in each iteration of the hypersweep
|
||||
IdArrayType FirstSupernodePerIteration;
|
||||
IdArrayType FirstHypernodePerIteration;
|
||||
|
||||
// THIS ONE HAS BEEN DELETED BECAUSE IT'S THE SAME AS THE HYPERNODE ID
|
||||
// ALTHOUGH THIS IS NOT NECESSARY, IT'S THE RESULT OF THE CONSTRUCTION
|
||||
// vector to find the first child superarc
|
||||
// IdArrayType FirstSuperchild;
|
||||
|
||||
// ROUTINES
|
||||
|
||||
@ -216,6 +219,11 @@ inline void ContourTree::PrintContent() const
|
||||
PrintHeader(Augmentnodes.GetNumberOfValues());
|
||||
PrintIndices("Augmentnodes", Augmentnodes);
|
||||
PrintIndices("Augmentarcs", this->Augmentarcs);
|
||||
std::cout << std::endl;
|
||||
std::cout << "NumIterations: " << this->NumIterations << std::endl;
|
||||
PrintHeader(this->FirstSupernodePerIteration.GetNumberOfValues());
|
||||
PrintIndices("First SN Per Iter", this->FirstSupernodePerIteration);
|
||||
PrintIndices("First HN Per Iter", this->FirstHypernodePerIteration);
|
||||
}
|
||||
|
||||
void ContourTree::DebugPrint(const char* message, const char* fileName, long lineNum) const
|
||||
|
@ -71,6 +71,7 @@
|
||||
#include <vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeHyperAndSuperStructure_HypernodesSetFirstSuperchild.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeHyperAndSuperStructure_PermuteArcs.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeHyperAndSuperStructure_ResetHyperparentsId.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeHyperAndSuperStructure_SetFirstSupernodePerIterationWorklet.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeHyperAndSuperStructure_SetNewHypernodesAndArcs.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeRegularStructure_LocateSuperarcs.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeRegularStructure_SetArcs.h>
|
||||
@ -132,9 +133,6 @@ public:
|
||||
// vector for the active set of supernodes
|
||||
IdArrayType ActiveSupernodes;
|
||||
|
||||
// counter for the number of iterations it took
|
||||
vtkm::Id NumIterations;
|
||||
|
||||
// constructor does the real work does the real work but mostly, it just calls the following two routines
|
||||
ContourTreeMaker(ContourTree& theContourTree, MergeTree& joinTree, MergeTree& splitTree);
|
||||
|
||||
@ -186,7 +184,6 @@ ContourTreeMaker::ContourTreeMaker(ContourTree& contourTree,
|
||||
, AugmentedJoinSuperarcs()
|
||||
, AugmentedSplitSuperarcs()
|
||||
, ActiveSupernodes()
|
||||
, NumIterations(0)
|
||||
{ // constructor
|
||||
} //MakeContourTree()
|
||||
|
||||
@ -198,7 +195,7 @@ void ContourTreeMaker::ComputeHyperAndSuperStructure()
|
||||
AugmentMergeTrees();
|
||||
|
||||
// track how many iterations it takes
|
||||
this->NumIterations = 0;
|
||||
this->ContourTreeResult.NumIterations = 0;
|
||||
|
||||
// loop until no arcs remaining to be found
|
||||
// tree can end with either 0 or 1 vertices unprocessed
|
||||
@ -210,7 +207,7 @@ void ContourTreeMaker::ComputeHyperAndSuperStructure()
|
||||
FindDegrees();
|
||||
|
||||
// alternate iterations between upper & lower
|
||||
if (this->NumIterations % 2 == 0)
|
||||
if (this->ContourTreeResult.NumIterations % 2 == 0)
|
||||
TransferLeafChains(true);
|
||||
else
|
||||
TransferLeafChains(false);
|
||||
@ -219,7 +216,7 @@ void ContourTreeMaker::ComputeHyperAndSuperStructure()
|
||||
CompressTrees();
|
||||
// compress the active list of supernodes
|
||||
CompressActiveSupernodes();
|
||||
this->NumIterations++;
|
||||
this->ContourTreeResult.NumIterations++;
|
||||
} // loop until no active vertices remaining
|
||||
|
||||
// test for final edges meeting
|
||||
@ -231,8 +228,8 @@ void ContourTreeMaker::ComputeHyperAndSuperStructure()
|
||||
this->ContourTreeResult.Hyperarcs.WritePortal().Set(superID,
|
||||
static_cast<vtkm::Id>(NO_SUCH_ELEMENT));
|
||||
this->ContourTreeResult.Hyperparents.WritePortal().Set(superID, superID);
|
||||
this->ContourTreeResult.WhenTransferred.WritePortal().Set(superID,
|
||||
this->NumIterations | IS_HYPERNODE);
|
||||
this->ContourTreeResult.WhenTransferred.WritePortal().Set(
|
||||
superID, this->ContourTreeResult.NumIterations | IS_HYPERNODE);
|
||||
} // meet at a vertex
|
||||
DebugPrint("Contour Tree Constructed. Now Swizzling", __FILE__, __LINE__);
|
||||
|
||||
@ -385,6 +382,66 @@ void ContourTreeMaker::ComputeHyperAndSuperStructure()
|
||||
resetHyperparentsIdWorklet;
|
||||
this->Invoke(resetHyperparentsIdWorklet, superSortIndex, this->ContourTreeResult.Hyperparents);
|
||||
|
||||
// set up the array which tracks which supernodes to deal with on which iteration:
|
||||
// it's plus 2 because there's an "extra" iteration for the root
|
||||
// and it's useful to store the size as one beyond that
|
||||
// initalize with 0's to be safe
|
||||
vtkm::cont::Algorithm::Copy(
|
||||
vtkm::cont::ArrayHandleConstant<vtkm::Id>(0, this->ContourTreeResult.NumIterations + 2),
|
||||
this->ContourTreeResult.FirstSupernodePerIteration);
|
||||
{
|
||||
contourtree_maker_inc_ns::ComputeHyperAndSuperStructure_SetFirstSupernodePerIterationWorklet
|
||||
setFirstSupernodePerIterationWorklet;
|
||||
auto tempSupernodesIndex =
|
||||
vtkm::cont::ArrayHandleIndex(this->ContourTreeResult.Supernodes.GetNumberOfValues());
|
||||
this->Invoke(setFirstSupernodePerIterationWorklet,
|
||||
tempSupernodesIndex, // loopindex
|
||||
this->ContourTreeResult.WhenTransferred, // input
|
||||
this->ContourTreeResult.FirstSupernodePerIteration // output
|
||||
);
|
||||
}
|
||||
|
||||
// TODO The following loop should be safe in parallel since there should never be two zeros in sequence, i.e., the next
|
||||
// entry after a zero will always be valid, regardless of execution order. Because this is safe if could be implemented
|
||||
// as a worklet. The number of iterations in the loop is small, so it may not be necessary for performance.
|
||||
auto firstSupernodePerIterationPortal =
|
||||
this->ContourTreeResult.FirstSupernodePerIteration.WritePortal();
|
||||
for (vtkm::Id iteration = 1; iteration < this->ContourTreeResult.NumIterations; ++iteration)
|
||||
{
|
||||
if (firstSupernodePerIterationPortal.Get(iteration) == 0)
|
||||
{
|
||||
firstSupernodePerIterationPortal.Set(iteration,
|
||||
firstSupernodePerIterationPortal.Get(iteration + 1));
|
||||
}
|
||||
}
|
||||
// set the sentinels at the end of the array
|
||||
firstSupernodePerIterationPortal.Set(this->ContourTreeResult.NumIterations,
|
||||
this->ContourTreeResult.Supernodes.GetNumberOfValues() - 1);
|
||||
firstSupernodePerIterationPortal.Set(this->ContourTreeResult.NumIterations + 1,
|
||||
this->ContourTreeResult.Supernodes.GetNumberOfValues());
|
||||
|
||||
// now use that array to construct a similar array for hypernodes: it's plus 2 because there's an "extra" iteration for the root
|
||||
// and it's useful to store the size as one beyond that
|
||||
this->ContourTreeResult.FirstHypernodePerIteration.Allocate(
|
||||
this->ContourTreeResult.NumIterations + 2);
|
||||
{
|
||||
// permute the ContourTree.Hyperpartens by the ContourTreeFirstSupernodePerIteration
|
||||
auto tempContourTreeHyperparentsPermuted = vtkm::cont::make_ArrayHandlePermutation(
|
||||
this->ContourTreeResult.FirstSupernodePerIteration, this->ContourTreeResult.Hyperparents);
|
||||
vtkm::cont::Algorithm::CopySubRange(tempContourTreeHyperparentsPermuted,
|
||||
0, // start index
|
||||
this->ContourTreeResult.NumIterations, // stop index
|
||||
this->ContourTreeResult.FirstHypernodePerIteration // target
|
||||
);
|
||||
}
|
||||
|
||||
this->ContourTreeResult.FirstHypernodePerIteration.WritePortal().Set(
|
||||
this->ContourTreeResult.NumIterations,
|
||||
this->ContourTreeResult.Hypernodes.GetNumberOfValues() - 1);
|
||||
this->ContourTreeResult.FirstHypernodePerIteration.WritePortal().Set(
|
||||
this->ContourTreeResult.NumIterations + 1,
|
||||
this->ContourTreeResult.Hypernodes.GetNumberOfValues());
|
||||
|
||||
DebugPrint("Contour Tree Super Structure Constructed", __FILE__, __LINE__);
|
||||
} // ComputeHyperAndSuperStructure()
|
||||
|
||||
@ -829,7 +886,7 @@ void ContourTreeMaker::TransferLeafChains(bool isJoin)
|
||||
|
||||
|
||||
// loop through the active vertices
|
||||
details::LeafChainsToContourTree task(this->NumIterations, // (input)
|
||||
details::LeafChainsToContourTree task(this->ContourTreeResult.NumIterations, // (input)
|
||||
isJoin, // (input)
|
||||
outdegree, // (input)
|
||||
indegree, // (input)
|
||||
@ -1010,7 +1067,7 @@ void ContourTreeMaker::DebugPrint(const char* message, const char* fileName, lon
|
||||
std::cout << std::left << std::string(message) << std::endl;
|
||||
std::cout << "Contour Tree Maker Contains: " << std::endl;
|
||||
std::cout << "------------------------------------------------------" << std::endl;
|
||||
std::cout << "NumIterations: " << this->NumIterations << std::endl;
|
||||
std::cout << "NumIterations: " << this->ContourTreeResult.NumIterations << std::endl;
|
||||
|
||||
PrintHeader(this->Updegree.GetNumberOfValues());
|
||||
PrintIndices("Updegree", this->Updegree);
|
||||
|
@ -241,7 +241,7 @@ inline void MergeTree::DebugPrintTree(const char* message,
|
||||
for (vtkm::Id entry = 0; entry < mesh.NumVertices; entry++)
|
||||
{
|
||||
vtkm::Id sortIndex = mesh.SortIndices.ReadPortal().Get(entry);
|
||||
vtkm::Id arc = this->arcs.ReadPortal().Get(sortIndex);
|
||||
vtkm::Id arc = this->Arcs.ReadPortal().Get(sortIndex);
|
||||
if (NoSuchElement(arc))
|
||||
{
|
||||
std::cout << "-1" << std::endl;
|
||||
@ -259,7 +259,7 @@ inline void MergeTree::DebugPrintTree(const char* message,
|
||||
}
|
||||
else if (mesh.NumDims == 3)
|
||||
{
|
||||
if ((entry % (mesh.NumColumns * mesh.NumRows)) == (mesh.nCols * mesh.NumRows - 1))
|
||||
if ((entry % (mesh.NumColumns * mesh.NumRows)) == (mesh.NumColumns * mesh.NumRows - 1))
|
||||
{
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
@ -82,7 +82,6 @@
|
||||
|
||||
#include <vtkm/worklet/contourtree_augmented/PrintVectors.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem/IdRelabler.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem/SimulatedSimplicityComperator.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem/SortIndices.h>
|
||||
|
||||
|
@ -83,73 +83,76 @@ constexpr int PREFIX_WIDTH = 24;
|
||||
template <typename T, typename StorageType>
|
||||
void PrintValues(std::string label,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>& dVec,
|
||||
vtkm::Id nValues = -1);
|
||||
vtkm::Id nValues = -1,
|
||||
std::ostream& outStream = std::cout);
|
||||
void PrintIndices(std::string label,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& iVec,
|
||||
vtkm::Id nIndices = -1);
|
||||
vtkm::Id nIndices = -1,
|
||||
std::ostream& outStream = std::cout);
|
||||
template <typename T, typename StorageType>
|
||||
void PrintSortedValues(std::string label,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>& dVec,
|
||||
IdArrayType& sortVec,
|
||||
vtkm::Id nValues = -1);
|
||||
vtkm::Id nValues = -1,
|
||||
std::ostream& outStream = std::cout);
|
||||
|
||||
// base routines for printing label & prefix bars
|
||||
inline void PrintLabel(std::string label)
|
||||
inline void PrintLabel(std::string label, std::ostream& outStream = std::cout)
|
||||
{ // PrintLabel()
|
||||
// print out the front end
|
||||
std::cout << std::setw(PREFIX_WIDTH) << std::left << label;
|
||||
outStream << std::setw(PREFIX_WIDTH) << std::left << label;
|
||||
// print out the vertical line
|
||||
std::cout << std::right << "|";
|
||||
outStream << std::right << "|";
|
||||
} // PrintLabel()
|
||||
|
||||
|
||||
inline void PrintSeparatingBar(vtkm::Id howMany)
|
||||
inline void PrintSeparatingBar(vtkm::Id howMany, std::ostream& outStream = std::cout)
|
||||
{ // PrintSeparatingBar()
|
||||
// print out the front end
|
||||
std::cout << std::setw(PREFIX_WIDTH) << std::setfill('-') << "";
|
||||
outStream << std::setw(PREFIX_WIDTH) << std::setfill('-') << "";
|
||||
// now the + at the vertical line
|
||||
std::cout << "+";
|
||||
outStream << "+";
|
||||
// now print out the tail end - fixed number of spaces per entry
|
||||
for (vtkm::Id block = 0; block < howMany; block++)
|
||||
{
|
||||
std::cout << std::setw(PRINT_WIDTH) << std::setfill('-') << "";
|
||||
outStream << std::setw(PRINT_WIDTH) << std::setfill('-') << "";
|
||||
}
|
||||
// now the std::endl, resetting the fill character
|
||||
std::cout << std::setfill(' ') << std::endl;
|
||||
outStream << std::setfill(' ') << std::endl;
|
||||
} // PrintSeparatingBar()
|
||||
|
||||
|
||||
// routine to print out a single value
|
||||
template <typename T>
|
||||
inline void PrintDataType(T value)
|
||||
inline void PrintDataType(T value, std::ostream& outStream = std::cout)
|
||||
{ // PrintDataType
|
||||
std::cout << std::setw(PRINT_WIDTH) << value;
|
||||
outStream << std::setw(PRINT_WIDTH) << value;
|
||||
} // PrintDataType
|
||||
|
||||
|
||||
// routine to print out a single index
|
||||
inline void PrintIndexType(vtkm::Id index)
|
||||
inline void PrintIndexType(vtkm::Id index, std::ostream& outStream = std::cout)
|
||||
{ // PrintIndexType
|
||||
std::cout << std::setw(PRINT_WIDTH - 6) << MaskedIndex(index) << " " << FlagString(index);
|
||||
outStream << std::setw(PRINT_WIDTH - 6) << MaskedIndex(index) << " " << FlagString(index);
|
||||
} // PrintIndexType
|
||||
|
||||
|
||||
// header line
|
||||
inline void PrintHeader(vtkm::Id howMany)
|
||||
inline void PrintHeader(vtkm::Id howMany, std::ostream& outStream = std::cout)
|
||||
{ // PrintHeader()
|
||||
// print out a separating bar
|
||||
PrintSeparatingBar(howMany);
|
||||
PrintSeparatingBar(howMany, outStream);
|
||||
// print out a label
|
||||
PrintLabel("ID");
|
||||
PrintLabel("ID", outStream);
|
||||
// print out the ID numbers
|
||||
for (vtkm::Id entry = 0; entry < howMany; entry++)
|
||||
{
|
||||
PrintIndexType(entry);
|
||||
PrintIndexType(entry, outStream);
|
||||
}
|
||||
// and an std::endl
|
||||
std::cout << std::endl;
|
||||
outStream << std::endl;
|
||||
// print out another separating bar
|
||||
PrintSeparatingBar(howMany);
|
||||
PrintSeparatingBar(howMany, outStream);
|
||||
} // PrintHeader()
|
||||
|
||||
|
||||
@ -157,7 +160,8 @@ inline void PrintHeader(vtkm::Id howMany)
|
||||
template <typename T, typename StorageType>
|
||||
inline void PrintValues(std::string label,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>& dVec,
|
||||
vtkm::Id nValues)
|
||||
vtkm::Id nValues,
|
||||
std::ostream& outStream)
|
||||
{ // PrintValues()
|
||||
// -1 means full size
|
||||
if (nValues == -1)
|
||||
@ -166,16 +170,16 @@ inline void PrintValues(std::string label,
|
||||
}
|
||||
|
||||
// print the label
|
||||
PrintLabel(label);
|
||||
PrintLabel(label, outStream);
|
||||
|
||||
// now print the data
|
||||
auto portal = dVec.ReadPortal();
|
||||
for (vtkm::Id entry = 0; entry < nValues; entry++)
|
||||
{
|
||||
PrintDataType(portal.Get(entry));
|
||||
PrintDataType(portal.Get(entry), outStream);
|
||||
}
|
||||
// and an std::endl
|
||||
std::cout << std::endl;
|
||||
outStream << std::endl;
|
||||
} // PrintValues()
|
||||
|
||||
|
||||
@ -184,7 +188,8 @@ template <typename T, typename StorageType>
|
||||
inline void PrintSortedValues(std::string label,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>& dVec,
|
||||
IdArrayType& sortVec,
|
||||
vtkm::Id nValues)
|
||||
vtkm::Id nValues,
|
||||
std::ostream& outStream)
|
||||
{ // PrintSortedValues()
|
||||
// -1 means full size
|
||||
if (nValues == -1)
|
||||
@ -193,24 +198,25 @@ inline void PrintSortedValues(std::string label,
|
||||
}
|
||||
|
||||
// print the label
|
||||
PrintLabel(label);
|
||||
PrintLabel(label, outStream);
|
||||
|
||||
// now print the data
|
||||
auto dportal = dVec.ReadPortal();
|
||||
auto sortPortal = sortVec.ReadPortal();
|
||||
for (vtkm::Id entry = 0; entry < nValues; entry++)
|
||||
{
|
||||
PrintDataType(dportal.Get(sortPortal.Get(entry)));
|
||||
PrintDataType(dportal.Get(sortPortal.Get(entry)), outStream);
|
||||
}
|
||||
// and an std::endl
|
||||
std::cout << std::endl;
|
||||
outStream << std::endl;
|
||||
} // PrintSortedValues()
|
||||
|
||||
|
||||
// routine for printing index arrays
|
||||
inline void PrintIndices(std::string label,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id>& iVec,
|
||||
vtkm::Id nIndices)
|
||||
vtkm::Id nIndices,
|
||||
std::ostream& outStream)
|
||||
{ // PrintIndices()
|
||||
// -1 means full size
|
||||
if (nIndices == -1)
|
||||
@ -219,53 +225,55 @@ inline void PrintIndices(std::string label,
|
||||
}
|
||||
|
||||
// print the label
|
||||
PrintLabel(label);
|
||||
PrintLabel(label, outStream);
|
||||
|
||||
auto portal = iVec.ReadPortal();
|
||||
for (vtkm::Id entry = 0; entry < nIndices; entry++)
|
||||
PrintIndexType(portal.Get(entry));
|
||||
PrintIndexType(portal.Get(entry), outStream);
|
||||
|
||||
// and the std::endl
|
||||
std::cout << std::endl;
|
||||
outStream << std::endl;
|
||||
} // PrintIndices()
|
||||
|
||||
|
||||
template <typename T, typename StorageType>
|
||||
inline void PrintLabelledDataBlock(std::string label,
|
||||
const vtkm::cont::ArrayHandle<T, StorageType>& dVec,
|
||||
vtkm::Id nColumns)
|
||||
vtkm::Id nColumns,
|
||||
std::ostream& outStream = std::cout)
|
||||
{ // PrintLabelledDataBlock()
|
||||
// start with a header
|
||||
PrintHeader(nColumns);
|
||||
PrintHeader(nColumns, outStream);
|
||||
// loop control variable
|
||||
vtkm::Id entry = 0;
|
||||
// per row
|
||||
auto portal = dVec.ReadPortal();
|
||||
for (vtkm::Id row = 0; entry < portal.GetNumberOfValues(); row++)
|
||||
{ // per row
|
||||
PrintLabel(label + "[" + std::to_string(row) + "]");
|
||||
PrintLabel(label + "[" + std::to_string(row) + "]", outStream);
|
||||
// now print the data
|
||||
for (vtkm::Id col = 0; col < nColumns; col++, entry++)
|
||||
{
|
||||
PrintDataType(portal.Get(entry));
|
||||
PrintDataType(portal.Get(entry), outStream);
|
||||
}
|
||||
std::cout << std::endl;
|
||||
outStream << std::endl;
|
||||
} // per row
|
||||
// and a final std::endl
|
||||
std::cout << std::endl;
|
||||
outStream << std::endl;
|
||||
} // PrintLabelledDataBlock()
|
||||
|
||||
|
||||
// routine for printing list of edge pairs. Used, e.g., to print the sorted list of saddle peaks from the ContourTree
|
||||
inline void PrintEdgePairArray(const EdgePairArray& edgePairArray)
|
||||
inline void PrintEdgePairArray(const EdgePairArray& edgePairArray,
|
||||
std::ostream& outStream = std::cout)
|
||||
{ // PrintEdgePairArray()
|
||||
// now print them out
|
||||
auto edgePairArrayConstPortal = edgePairArray.ReadPortal();
|
||||
for (vtkm::Id superarc = 0; superarc < edgePairArray.GetNumberOfValues(); superarc++)
|
||||
{ // per superarc
|
||||
std::cout << std::right << std::setw(PRINT_WIDTH)
|
||||
outStream << std::right << std::setw(PRINT_WIDTH)
|
||||
<< edgePairArrayConstPortal.Get(superarc).first << " ";
|
||||
std::cout << std::right << std::setw(PRINT_WIDTH)
|
||||
outStream << std::right << std::setw(PRINT_WIDTH)
|
||||
<< edgePairArrayConstPortal.Get(superarc).second << std::endl;
|
||||
} // per superarc
|
||||
} // PrintEdgePairArray()
|
||||
|
@ -262,7 +262,13 @@ public:
|
||||
hyperarcDependentWeight);
|
||||
|
||||
// set up the array which tracks which supernodes to deal with on which iteration
|
||||
IdArrayType firstSupernodePerIteration;
|
||||
auto firstSupernodePerIterationPortal = contourTree.FirstSupernodePerIteration.ReadPortal();
|
||||
auto firstHypernodePerIterationPortal = contourTree.FirstHypernodePerIteration.ReadPortal();
|
||||
auto supernodeTransferWeightPortal = supernodeTransferWeight.WritePortal();
|
||||
auto superarcDependentWeightPortal = superarcDependentWeight.WritePortal();
|
||||
auto hyperarcDependentWeightPortal = hyperarcDependentWeight.WritePortal();
|
||||
|
||||
/*
|
||||
vtkm::cont::ArrayCopy(vtkm::cont::ArrayHandleConstant<vtkm::Id>(0, nIterations + 1),
|
||||
firstSupernodePerIteration);
|
||||
auto firstSupernodePerIterationPortal = firstSupernodePerIteration.WritePortal();
|
||||
@ -298,6 +304,7 @@ public:
|
||||
firstHypernodePerIterationPortal.Set(
|
||||
iteration, hyperparentsPortal.Get(firstSupernodePerIterationPortal.Get(iteration)));
|
||||
firstHypernodePerIterationPortal.Set(nIterations, contourTree.Hypernodes.GetNumberOfValues());
|
||||
*/
|
||||
|
||||
// now iterate, propagating weights inwards
|
||||
for (vtkm::Id iteration = 0; iteration < nIterations; iteration++)
|
||||
|
@ -56,6 +56,7 @@
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/CellSetStructured.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -73,6 +74,7 @@ constexpr vtkm::Id IS_HYPERNODE = std::numeric_limits<vtkm::Id>::max() / 8 + 1;
|
||||
constexpr vtkm::Id IS_ASCENDING = std::numeric_limits<vtkm::Id>::max() / 16 + 1; //0x08000000 || 0x0800000000000000
|
||||
constexpr vtkm::Id INDEX_MASK = std::numeric_limits<vtkm::Id>::max() / 16; //0x07FFFFFF || 0x07FFFFFFFFFFFFFF
|
||||
constexpr vtkm::Id CV_OTHER_FLAG = std::numeric_limits<vtkm::Id>::max() / 8 + 1; //0x10000000 || 0x1000000000000000
|
||||
constexpr vtkm::Id ELEMENT_EXISTS = std::numeric_limits<vtkm::Id>::max() / 4 + 1; //0x20000000 || 0x2000000000000000 , same as IS_SUPERNODE
|
||||
// clang-format on
|
||||
|
||||
using IdArrayType = vtkm::cont::ArrayHandle<vtkm::Id>;
|
||||
@ -147,6 +149,53 @@ inline std::string FlagString(vtkm::Id flaggedIndex)
|
||||
} // FlagString()
|
||||
|
||||
|
||||
///
|
||||
/// Helper struct to collect sizing information from a dataset.
|
||||
/// The struct is used in the contour tree filter implementation
|
||||
/// to determine the rows, cols, slices parameters from the
|
||||
/// datasets so we can call the contour tree worklet properly.
|
||||
///
|
||||
struct GetRowsColsSlices
|
||||
{
|
||||
//@{
|
||||
/// Get the number of rows, cols, and slices of a vtkm::cont::CellSetStructured
|
||||
/// @param[in] cells The input vtkm::cont::CellSetStructured
|
||||
/// @param[out] nRows Number of rows (x) in the cell set
|
||||
/// @param[out[ nCols Number of columns (y) in the cell set
|
||||
/// @param[out] nSlices Number of slices (z) in the cell set
|
||||
void operator()(const vtkm::cont::CellSetStructured<2>& cells,
|
||||
vtkm::Id& nRows,
|
||||
vtkm::Id& nCols,
|
||||
vtkm::Id& nSlices) const
|
||||
{
|
||||
vtkm::Id2 pointDimensions = cells.GetPointDimensions();
|
||||
nRows = pointDimensions[0];
|
||||
nCols = pointDimensions[1];
|
||||
nSlices = 1;
|
||||
}
|
||||
void operator()(const vtkm::cont::CellSetStructured<3>& cells,
|
||||
vtkm::Id& nRows,
|
||||
vtkm::Id& nCols,
|
||||
vtkm::Id& nSlices) const
|
||||
{
|
||||
vtkm::Id3 pointDimensions = cells.GetPointDimensions();
|
||||
nRows = pointDimensions[0];
|
||||
nCols = pointDimensions[1];
|
||||
nSlices = pointDimensions[2];
|
||||
}
|
||||
//@}
|
||||
|
||||
/// Raise ErrorBadValue if the input cell set is not a vtkm::cont::CellSetStructured<2> or <3>
|
||||
template <typename T>
|
||||
void operator()(const T& cells, vtkm::Id& nRows, vtkm::Id& nCols, vtkm::Id& nSlices) const
|
||||
{
|
||||
(void)nRows;
|
||||
(void)nCols;
|
||||
(void)nSlices;
|
||||
(void)cells;
|
||||
throw vtkm::cont::ErrorBadValue("Expected 2D or 3D structured cell cet! ");
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace contourtree_augmented
|
||||
} // worklet
|
||||
|
@ -16,6 +16,7 @@ set(headers
|
||||
ComputeHyperAndSuperStructure_PermuteArcs.h
|
||||
ComputeHyperAndSuperStructure_ResetHyperparentsId.h
|
||||
ComputeHyperAndSuperStructure_SetNewHypernodesAndArcs.h
|
||||
ComputeHyperAndSuperStructure_SetFirstSupernodePerIterationWorklet.h
|
||||
ComputeRegularStructure_LocateSuperarcs.h
|
||||
ComputeRegularStructure_SetArcs.h
|
||||
ContourTreeSuperNodeComparator.h
|
||||
|
128
vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeHyperAndSuperStructure_SetFirstSupernodePerIterationWorklet.h
Normal file
128
vtkm/worklet/contourtree_augmented/contourtreemaker/ComputeHyperAndSuperStructure_SetFirstSupernodePerIterationWorklet.h
Normal file
@ -0,0 +1,128 @@
|
||||
//============================================================================
|
||||
// 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_augmented_contourtree_maker_inc_compute_hyper_and_super_structure_set_first_supernode_per_iteration_worklet_h
|
||||
#define vtk_m_worklet_contourtree_augmented_contourtree_maker_inc_compute_hyper_and_super_structure_set_first_supernode_per_iteration_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_augmented
|
||||
{
|
||||
namespace contourtree_maker_inc
|
||||
{
|
||||
|
||||
// Worklet for settubg the super/hyperarcs fromm the permuted super/hyperarcs vector
|
||||
class ComputeHyperAndSuperStructure_SetFirstSupernodePerIterationWorklet
|
||||
: public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn supernodeIndex, // (input) active super/hyperarcs
|
||||
WholeArrayIn whenTransferred, // (input)
|
||||
WholeArrayOut firstSupernodePerIteration); // (output)
|
||||
typedef void ExecutionSignature(_1, _2, _3);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
ComputeHyperAndSuperStructure_SetFirstSupernodePerIterationWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType, typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& supernode,
|
||||
const InFieldPortalType& whenTransferredPortal,
|
||||
const OutFieldPortalType& firstSupernodePerIterationPortal) const
|
||||
{
|
||||
// per supernode
|
||||
vtkm::Id when =
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(whenTransferredPortal.Get(supernode));
|
||||
if (supernode == 0)
|
||||
{ // zeroth supernode
|
||||
firstSupernodePerIterationPortal.Set(when, supernode);
|
||||
} // zeroth supernode
|
||||
else
|
||||
{
|
||||
vtkm::Id prevWhen =
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(whenTransferredPortal.Get(supernode - 1));
|
||||
if (when != prevWhen)
|
||||
{ // non-matching supernode
|
||||
firstSupernodePerIterationPortal.Set(when, supernode);
|
||||
} // non-matching supernode
|
||||
}
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType supernode = 0; supernode < contourTree.supernodes.size(); supernode++)
|
||||
{ // per supernode
|
||||
indexType when = maskedIndex(contourTree.whenTransferred[supernode]);
|
||||
if (supernode == 0)
|
||||
{ // zeroth supernode
|
||||
contourTree.firstSupernodePerIteration[when] = supernode;
|
||||
} // zeroth supernode
|
||||
else if (when != maskedIndex(contourTree.whenTransferred[supernode-1]))
|
||||
{ // non-matching supernode
|
||||
contourTree.firstSupernodePerIteration[when] = supernode;
|
||||
} // non-matching supernode
|
||||
} // per supernode
|
||||
*/
|
||||
}
|
||||
|
||||
}; // ComputeHyperAndSuperStructure_SetFirstSupernodePerIterationWorklet
|
||||
|
||||
} // namespace contourtree_maker_inc
|
||||
} // namespace contourtree_augmented
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
@ -12,7 +12,7 @@ set(headers
|
||||
MeshStructure3D.h
|
||||
SimulatedSimplicityComperator.h
|
||||
SortIndices.h
|
||||
IdRelabler.h
|
||||
IdRelabeler.h
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
@ -60,8 +60,8 @@
|
||||
// Oliver Ruebel (LBNL)
|
||||
//==============================================================================
|
||||
|
||||
#ifndef vtk_m_worklet_contourtree_ppp2_contourtree_mesh_inc_id_relabler_h
|
||||
#define vtk_m_worklet_contourtree_ppp2_contourtree_mesh_inc_id_relabler_h
|
||||
#ifndef vtk_m_worklet_contourtree_ppp2_contourtree_mesh_inc_id_relabeler_h
|
||||
#define vtk_m_worklet_contourtree_ppp2_contourtree_mesh_inc_id_relabeler_h
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
@ -76,11 +76,11 @@ namespace mesh_dem
|
||||
{
|
||||
|
||||
|
||||
class IdRelabler
|
||||
class IdRelabeler
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT
|
||||
IdRelabler()
|
||||
IdRelabeler()
|
||||
: InputStartRow(0)
|
||||
, InputStartCol(0)
|
||||
, InputStartSlice(0)
|
||||
@ -92,7 +92,7 @@ public:
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
IdRelabler(vtkm::Id iSR,
|
||||
IdRelabeler(vtkm::Id iSR,
|
||||
vtkm::Id iSC,
|
||||
vtkm::Id iSS,
|
||||
vtkm::Id iNR,
|
@ -16,11 +16,11 @@ set(headers
|
||||
MeshStructureFreudenthal3D.h
|
||||
MeshStructureMarchingCubes.h
|
||||
MeshStructureContourTreeMesh.h
|
||||
MeshBoundary.h
|
||||
)
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
add_subdirectory(contourtreemesh)
|
||||
add_subdirectory(mesh_boundary)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
vtkm_declare_headers(${headers})
|
||||
|
@ -74,7 +74,6 @@
|
||||
#include <vtkm/cont/EnvironmentTracker.h>
|
||||
#include <vtkm/worklet/DispatcherMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/ArrayTransforms.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshBoundary.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureContourTreeMesh.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/ArcComparator.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/CombinedOtherStartIndexNNeighboursWorklet.h>
|
||||
@ -89,6 +88,9 @@
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/ReplaceArcNumWithToVertexWorklet.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/SubtractAssignWorklet.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/UpdateCombinedNeighboursWorklet.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundaryContourTreeMesh.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundaryContourTreeMesh.h>
|
||||
|
||||
|
||||
#include <vtkm/worklet/contourtree_augmented/PrintVectors.h> // TODO remove should not be needed
|
||||
|
||||
@ -209,6 +211,11 @@ public:
|
||||
vtkm::Id3 minIdx,
|
||||
vtkm::Id3 maxIdx) const;
|
||||
|
||||
void GetBoundaryVertices(IdArrayType& boundaryVertexArray, // output
|
||||
IdArrayType& boundarySortIndexArray, // output
|
||||
MeshBoundaryContourTreeMeshExec* meshBoundaryExecObj //input
|
||||
) const;
|
||||
|
||||
private:
|
||||
vtkm::cont::Invoker Invoke;
|
||||
|
||||
@ -793,6 +800,31 @@ MeshBoundaryContourTreeMeshExec ContourTreeMesh<FieldType>::GetMeshBoundaryExecu
|
||||
this->GlobalMeshIndex, totalNRows, totalNCols, minIdx, maxIdx);
|
||||
}
|
||||
|
||||
template <typename FieldType>
|
||||
void ContourTreeMesh<FieldType>::GetBoundaryVertices(
|
||||
IdArrayType& boundaryVertexArray, // output
|
||||
IdArrayType& boundarySortIndexArray, // output
|
||||
MeshBoundaryContourTreeMeshExec* meshBoundaryExecObj //input
|
||||
) const
|
||||
{
|
||||
// start by generating a temporary array of indices
|
||||
auto indexArray = vtkm::cont::ArrayHandleIndex(this->GlobalMeshIndex.GetNumberOfValues());
|
||||
// compute the boolean array indicating which values lie on the boundary
|
||||
vtkm::cont::ArrayHandle<bool> isOnBoundary;
|
||||
ComputeMeshBoundaryContourTreeMesh computeMeshBoundaryContourTreeMeshWorklet;
|
||||
this->Invoke(computeMeshBoundaryContourTreeMeshWorklet,
|
||||
indexArray, // input
|
||||
*meshBoundaryExecObj, // input
|
||||
isOnBoundary // outut
|
||||
);
|
||||
|
||||
// we will conditionally copy the boundary vertices' indices, capturing the end iterator to compute the # of boundary vertices
|
||||
vtkm::cont::Algorithm::CopyIf(indexArray, isOnBoundary, boundaryVertexArray);
|
||||
// duplicate these into the index array, since the BRACT uses indices into the underlying mesh anyway
|
||||
vtkm::cont::Algorithm::Copy(boundaryVertexArray, boundarySortIndexArray);
|
||||
}
|
||||
|
||||
|
||||
} // namespace contourtree_augmented
|
||||
} // worklet
|
||||
} // vtkm
|
||||
|
@ -57,8 +57,9 @@
|
||||
#include <vtkm/Types.h>
|
||||
|
||||
#include <vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshBoundary.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureFreudenthal2D.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary2D.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary2D.h>
|
||||
|
||||
#include <vtkm/cont/ExecutionObjectBase.h>
|
||||
|
||||
@ -88,6 +89,12 @@ public:
|
||||
|
||||
MeshBoundary2DExec GetMeshBoundaryExecutionObject() const;
|
||||
|
||||
void GetBoundaryVertices(IdArrayType& boundaryVertexArray, // output
|
||||
IdArrayType& boundarySortIndexArray, // output
|
||||
MeshBoundary2DExec* meshBoundaryExecObj =
|
||||
NULL // optional input, included for consistency with ContourTreeMesh
|
||||
) const;
|
||||
|
||||
private:
|
||||
bool UseGetMax; // Define the behavior ofr the PrepareForExecution function
|
||||
}; // class Mesh_DEM_Triangulation
|
||||
@ -136,6 +143,29 @@ Mesh_DEM_Triangulation_2D_Freudenthal<T, StorageType>::GetMeshBoundaryExecutionO
|
||||
return MeshBoundary2DExec(this->NumColumns, this->NumRows, this->SortOrder);
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename StorageType>
|
||||
void Mesh_DEM_Triangulation_2D_Freudenthal<T, StorageType>::GetBoundaryVertices(
|
||||
IdArrayType& boundaryVertexArray, // output
|
||||
IdArrayType& boundarySortIndexArray, // output
|
||||
MeshBoundary2DExec*
|
||||
meshBoundaryExecObj // optional input, included for consistency with ContourTreeMesh
|
||||
) const
|
||||
{
|
||||
vtkm::Id numBoundary = 2 * this->NumRows + 2 * this->NumColumns - 4;
|
||||
auto boundaryId = vtkm::cont::ArrayHandleIndex(numBoundary);
|
||||
ComputeMeshBoundary2D computeMeshBoundary2dWorklet;
|
||||
this->Invoke(computeMeshBoundary2dWorklet,
|
||||
boundaryId, // input
|
||||
this->SortIndices, // input
|
||||
(meshBoundaryExecObj == NULL) ? this->GetMeshBoundaryExecutionObject()
|
||||
: *meshBoundaryExecObj, // input
|
||||
boundaryVertexArray, // output
|
||||
boundarySortIndexArray // output
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
} // namespace contourtree_augmented
|
||||
} // worklet
|
||||
} // vtkm
|
||||
|
@ -61,9 +61,10 @@
|
||||
|
||||
#include <vtkm/cont/ExecutionObjectBase.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshBoundary.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureFreudenthal3D.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/freudenthal_3D/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary3D.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary3D.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -93,6 +94,12 @@ public:
|
||||
|
||||
MeshBoundary3DExec GetMeshBoundaryExecutionObject() const;
|
||||
|
||||
void GetBoundaryVertices(IdArrayType& boundaryVertexArray, // output
|
||||
IdArrayType& boundarySortIndexArray, // output
|
||||
MeshBoundary3DExec* meshBoundaryExecObj =
|
||||
NULL // optional input, included for consistency with ContourTreeMesh
|
||||
) const;
|
||||
|
||||
private:
|
||||
bool UseGetMax; // Define the behavior ofr the PrepareForExecution function
|
||||
}; // class Mesh_DEM_Triangulation
|
||||
@ -152,6 +159,28 @@ Mesh_DEM_Triangulation_3D_Freudenthal<T, StorageType>::GetMeshBoundaryExecutionO
|
||||
return MeshBoundary3DExec(this->NumColumns, this->NumRows, this->NumSlices, this->SortOrder);
|
||||
}
|
||||
|
||||
template <typename T, typename StorageType>
|
||||
void Mesh_DEM_Triangulation_3D_Freudenthal<T, StorageType>::GetBoundaryVertices(
|
||||
IdArrayType& boundaryVertexArray, // output
|
||||
IdArrayType& boundarySortIndexArray, // output
|
||||
MeshBoundary3DExec* meshBoundaryExecObj // input
|
||||
) const
|
||||
{
|
||||
vtkm::Id numBoundary = 2 * this->NumRows * this->NumColumns // xy faces
|
||||
+ 2 * this->NumRows * (this->NumSlices - 2) // yz faces - excluding vertices on xy
|
||||
+ 2 * (this->NumColumns - 2) * (this->NumSlices - 2); // xz face interiors
|
||||
auto boundaryId = vtkm::cont::ArrayHandleIndex(numBoundary);
|
||||
ComputeMeshBoundary3D computeMeshBoundary3dWorklet;
|
||||
this->Invoke(computeMeshBoundary3dWorklet,
|
||||
boundaryId, // input
|
||||
this->SortIndices, // input
|
||||
(meshBoundaryExecObj == NULL) ? this->GetMeshBoundaryExecutionObject()
|
||||
: *meshBoundaryExecObj, // input
|
||||
boundaryVertexArray, // output
|
||||
boundarySortIndexArray // output
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace contourtree_augmented
|
||||
} // worklet
|
||||
} // vtkm
|
||||
|
@ -61,9 +61,10 @@
|
||||
#include <vtkm/cont/ExecutionObjectBase.h>
|
||||
|
||||
#include <vtkm/worklet/contourtree_augmented/Mesh_DEM_Triangulation.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshBoundary.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/MeshStructureMarchingCubes.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/marchingcubes_3D/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary3D.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary3D.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -97,6 +98,12 @@ public:
|
||||
|
||||
MeshBoundary3DExec GetMeshBoundaryExecutionObject() const;
|
||||
|
||||
void GetBoundaryVertices(IdArrayType& boundaryVertexArray, // output
|
||||
IdArrayType& boundarySortIndexArray, // output
|
||||
MeshBoundary3DExec* meshBoundaryExecObj =
|
||||
NULL // optional input, included for consistency with ContourTreeMesh
|
||||
) const;
|
||||
|
||||
private:
|
||||
bool UseGetMax; // Define the behavior ofr the PrepareForExecution function
|
||||
}; // class Mesh_DEM_Triangulation
|
||||
@ -181,6 +188,28 @@ Mesh_DEM_Triangulation_3D_MarchingCubes<T, StorageType>::GetMeshBoundaryExecutio
|
||||
return MeshBoundary3DExec(this->NumColumns, this->NumRows, this->NumSlices, this->SortOrder);
|
||||
}
|
||||
|
||||
template <typename T, typename StorageType>
|
||||
void Mesh_DEM_Triangulation_3D_MarchingCubes<T, StorageType>::GetBoundaryVertices(
|
||||
IdArrayType& boundaryVertexArray, // output
|
||||
IdArrayType& boundarySortIndexArray, // output
|
||||
MeshBoundary3DExec* meshBoundaryExecObj // input
|
||||
) const
|
||||
{
|
||||
vtkm::Id numBoundary = 2 * this->NumRows * this->NumColumns // xy faces
|
||||
+ 2 * this->NumRows * (this->NumSlices - 2) // yz faces - excluding vertices on xy
|
||||
+ 2 * (this->NumColumns - 2) * (this->NumSlices - 2); // xz face interiors
|
||||
auto boundaryId = vtkm::cont::ArrayHandleIndex(numBoundary);
|
||||
ComputeMeshBoundary3D computeMeshBoundary3dWorklet;
|
||||
this->Invoke(computeMeshBoundary3dWorklet,
|
||||
boundaryId, // input
|
||||
this->SortIndices, // input
|
||||
(meshBoundaryExecObj == NULL) ? this->GetMeshBoundaryExecutionObject()
|
||||
: *meshBoundaryExecObj, // input
|
||||
boundaryVertexArray, // output
|
||||
boundarySortIndexArray // output
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace contourtree_augmented
|
||||
} // worklet
|
||||
} // vtkm
|
||||
|
@ -105,7 +105,6 @@ public:
|
||||
nneighboursVal);
|
||||
|
||||
// Implements in reference code
|
||||
// #pragma omp parallel for
|
||||
// The following is save since each global index is only written by one entry
|
||||
// for (indexVector::size_type vtx = 0; vtx < nNeighbours.size(); ++vtx)
|
||||
// {
|
||||
|
@ -102,7 +102,6 @@ public:
|
||||
}
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
// #pragma omp parallel for
|
||||
// for (indexVector::size_type from = 0; from < arcs.size(); ++from)
|
||||
// {
|
||||
// indexType to = arcs[from];
|
||||
|
1
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/ComputeMaxNeighboursWorklet.h
1
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/contourtreemesh/ComputeMaxNeighboursWorklet.h
@ -110,7 +110,6 @@ public:
|
||||
}
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
// #pragma omp parallel for
|
||||
// for (indexVector::size_type startVtxNo = 0; startVtxNo < firstNeighbour.size()-1; ++startVtxNo)
|
||||
// {
|
||||
// nNeighbours[startVtxNo] = firstNeighbour[startVtxNo+1] - firstNeighbour[startVtxNo];
|
||||
|
@ -114,7 +114,6 @@ public:
|
||||
}
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
// #pragma omp parallel for
|
||||
// for (indexVector::size_type sortedArcNo = 1; sortedArcNo < neighbours.size(); ++sortedArcNo)
|
||||
// {
|
||||
// indexType prevFrom = (neighbours[sortedArcNo-1] % 2 == 0) ? neighbours[sortedArcNo-1]/2 : MaskedIndex(arcs[neighbours[sortedArcNo-1]/2]);
|
||||
|
@ -125,8 +125,6 @@ public:
|
||||
}
|
||||
|
||||
/* Reference code implemented by this worklet
|
||||
|
||||
#pragma omp parallel for
|
||||
for (indexVector::size_type vtx = 0; vtx < combinedFirstNeighbour.size(); ++vtx)
|
||||
{
|
||||
if (combinedOtherStartIndex[vtx]) // Needs merge
|
||||
|
@ -122,7 +122,6 @@ public:
|
||||
This worklet implemnts the following two loops from the original OpenMP code
|
||||
The two loops are the same but the arrays required are different
|
||||
|
||||
#pragma omp parallel for
|
||||
for (indexVector::size_type vtx = 0; vtx < firstNeighbour.size(); ++vtx)
|
||||
{
|
||||
indexType numNeighbours = (vtx < GetNumberOfVertices() - 1) ? firstNeighbour[vtx+1] - firstNeighbour[vtx] : neighbours.size() - firstNeighbour[vtx];
|
||||
@ -133,7 +132,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
#pragma omp parallel for
|
||||
for (indexVector::size_type vtx = 0; vtx < other.firstNeighbour.size(); ++vtx)
|
||||
{
|
||||
indexType numNeighbours = (vtx < other.GetNumberOfVertices() - 1) ? other.firstNeighbour[vtx+1] - other.firstNeighbour[vtx] : other.neighbours.size() - other.firstNeighbour[vtx];
|
||||
|
@ -0,0 +1,20 @@
|
||||
##============================================================================
|
||||
## 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
|
||||
MeshBoundary2D.h
|
||||
MeshBoundary3D.h
|
||||
MeshBoundaryContourTreeMesh.h
|
||||
ComputeMeshBoundary2D.h
|
||||
ComputeMeshBoundary3D.h
|
||||
ComputeMeshBoundaryContourTreeMesh.h
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
vtkm_declare_headers(${headers})
|
155
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary2D.h
Normal file
155
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary2D.h
Normal file
@ -0,0 +1,155 @@
|
||||
//============================================================================
|
||||
// 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_augmented_mesh_dem_mesh_types_mesh_boundary_compute_mesh_boundary_2D_h
|
||||
#define vtk_m_worklet_contourtree_augmented_mesh_dem_mesh_types_mesh_boundary_compute_mesh_boundary_2D_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_augmented
|
||||
{
|
||||
|
||||
// Worklet to collapse past regular vertices by updating inbound and outbound as part
|
||||
// loop to find the now-regular vertices and collapse past them without altering
|
||||
// the existing join & split arcs
|
||||
class ComputeMeshBoundary2D : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn boundaryId, // (input)
|
||||
WholeArrayIn sortIndices, // (input)
|
||||
ExecObject meshBoundary, // (input)
|
||||
FieldOut boundaryVertexArray, // output
|
||||
FieldOut boundarySortIndexArray // output
|
||||
);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4, _5);
|
||||
using InputDomain = _1;
|
||||
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
ComputeMeshBoundary2D() {}
|
||||
|
||||
template <typename InFieldPortalType, typename MeshBoundaryType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& boundaryId,
|
||||
const InFieldPortalType sortIndicesPortal,
|
||||
const MeshBoundaryType& meshBoundary,
|
||||
vtkm::Id& boundaryVertex,
|
||||
vtkm::Id& boundarySortIndex)
|
||||
{
|
||||
auto meshStructure2D = meshBoundary.GetMeshStructure();
|
||||
vtkm::Id numBoundary = 2 * meshStructure2D.NumRows + 2 * meshStructure2D.NumColumns - 4;
|
||||
|
||||
// Define the boundaryVertex result
|
||||
if (boundaryId < meshStructure2D->NumColumns)
|
||||
{
|
||||
boundaryVertex = meshStructure2D.VertexId(0, boundaryId);
|
||||
}
|
||||
// then bottom row
|
||||
else if (boundaryId > numBoundary - meshStructure2D.NumColumns - 1)
|
||||
{
|
||||
boundaryVertex = meshStructure2D.VertexId(
|
||||
meshStructure2D.NumRows - 1, boundaryId + meshStructure2D.NumColumns - numBoundary);
|
||||
}
|
||||
// then the row ends
|
||||
else
|
||||
{ // row ends
|
||||
vtkm::Id row = ((boundaryId - meshStructure2D.NumColumns) / 2) + 1;
|
||||
vtkm::Id col =
|
||||
((boundaryId - meshStructure2D.NumColumns) % 2) ? (meshStructure2D.NumColumnsn - 1) : 0;
|
||||
boundaryVertex = meshStructure2D.VertexId(row, col);
|
||||
} // row ends
|
||||
// and fill in the sort index array as well
|
||||
boundarySortIndex = sortIndicesPortal.Get(boundaryVertex);
|
||||
|
||||
/*
|
||||
// compute how many elements are needed
|
||||
indexType nBoundary = 2 * nRows + 2 * nCols - 4;
|
||||
|
||||
boundaryVertexArray.resize(nBoundary);
|
||||
boundarySortIndexArray.resize(nBoundary);
|
||||
|
||||
// loop to add in the vertices
|
||||
// NB: the arithmetic here is chosen to guarantee that the vertex indices
|
||||
// are in sorted order in the output - I'm not sure that this is necessary, but . . .
|
||||
for (indexType boundaryId = 0; boundaryId < nBoundary; boundaryId++)
|
||||
{ // loop through indices
|
||||
// do top row first
|
||||
if (boundaryId < nCols)
|
||||
boundaryVertexArray[boundaryId] = vertexId(0, boundaryId);
|
||||
// then bottom row
|
||||
else if (boundaryId > nBoundary - nCols - 1)
|
||||
boundaryVertexArray[boundaryId] = vertexId(nRows - 1, boundaryId + nCols - nBoundary);
|
||||
// then the row ends
|
||||
else
|
||||
{ // row ends
|
||||
indexType row = ((boundaryId - nCols) / 2) + 1;
|
||||
indexType col = ((boundaryId - nCols) % 2) ? (nCols - 1) : 0;
|
||||
boundaryVertexArray[boundaryId] = vertexId(row, col);
|
||||
} // row ends
|
||||
// and fill in the index array as well
|
||||
boundarySortIndexArray[boundaryId] = sortIndices[boundaryVertexArray[boundaryId]];
|
||||
} // loop through indices
|
||||
*/
|
||||
}
|
||||
|
||||
}; // ComputeMeshBoundary2D
|
||||
|
||||
} // namespace contourtree_augmented
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
223
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary3D.h
Normal file
223
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundary3D.h
Normal file
@ -0,0 +1,223 @@
|
||||
//============================================================================
|
||||
// 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_augmented_mesh_dem_mesh_types_mesh_boundary_compute_mesh_boundary_3D_h
|
||||
#define vtk_m_worklet_contourtree_augmented_mesh_dem_mesh_types_mesh_boundary_compute_mesh_boundary_3D_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_augmented
|
||||
{
|
||||
|
||||
// Worklet to collapse past regular vertices by updating inbound and outbound as part
|
||||
// loop to find the now-regular vertices and collapse past them without altering
|
||||
// the existing join & split arcs
|
||||
class ComputeMeshBoundary3D : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn boundaryId, // (input)
|
||||
WholeArrayIn sortIndices, // (input)
|
||||
ExecObject meshBoundary, // (input)
|
||||
FieldOut boundaryVertexArray, // output
|
||||
FieldOut boundarySortIndexArray // output
|
||||
);
|
||||
typedef void ExecutionSignature(_1, _2, _3, _4, _5);
|
||||
using InputDomain = _1;
|
||||
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
ComputeMeshBoundary3D() {}
|
||||
|
||||
template <typename InFieldPortalType, typename MeshBoundaryType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& boundaryId,
|
||||
const InFieldPortalType sortIndicesPortal,
|
||||
const MeshBoundaryType& meshBoundary,
|
||||
vtkm::Id& boundaryVertex,
|
||||
vtkm::Id& boundarySortIndex)
|
||||
{
|
||||
auto meshStructure3D = meshBoundary.GetMeshStructure();
|
||||
vtkm::Id nRows = meshStructure3D.NumRows;
|
||||
vtkm::Id nCols = meshStructure3D.NumCols;
|
||||
vtkm::Id nSlices = meshStructure3D.NumSlices;
|
||||
// calculate the number of boundary elements - all of the two xy faces
|
||||
vtkm::Id nBoundary = 2 * nRows * nCols // xy faces
|
||||
+ 2 * nRows * (nSlices - 2) // yz faces - excluding vertices on xy
|
||||
+ 2 * (nCols - 2) * (nSlices - 2); // xz face interiors
|
||||
|
||||
vtkm::Id row = 0, col = 0, slice = 0;
|
||||
vtkm::Id sliceSize = nRows * nCols;
|
||||
vtkm::Id sliceBoundarySize = 2 * nRows + 2 * nCols - 4;
|
||||
// do top plane first
|
||||
if (boundaryId < sliceSize)
|
||||
{ // top plane
|
||||
row = boundaryId / nCols;
|
||||
col = boundaryId % nCols;
|
||||
slice = 0;
|
||||
} // top plane
|
||||
// then bottom plane
|
||||
else if (boundaryId >= nBoundary - sliceSize)
|
||||
{ // bottom plane
|
||||
row = (boundaryId - (nBoundary - sliceSize)) / nCols;
|
||||
col = (boundaryId - (nBoundary - sliceSize)) % nCols;
|
||||
slice = nSlices - 1;
|
||||
} // bottom plane
|
||||
// now we have to deal with the exterior of the remaining slices
|
||||
else
|
||||
{ // slice exteriors
|
||||
// first we subtract the size of the first slice
|
||||
vtkm::Id offsetBoundaryid = boundaryId - sliceSize;
|
||||
// now we can compute the slice id
|
||||
slice = 1 + offsetBoundaryid / sliceBoundarySize;
|
||||
// compute the local id on the slice
|
||||
vtkm::Id sliceBoundaryid = offsetBoundaryid % sliceBoundarySize;
|
||||
// now test for the first and last row
|
||||
if (sliceBoundaryid < nCols)
|
||||
{ // first row
|
||||
row = 0;
|
||||
col = sliceBoundaryid;
|
||||
} // first row
|
||||
else if (sliceBoundaryid >= (sliceBoundarySize - nCols))
|
||||
{ // last row
|
||||
row = nRows - 1;
|
||||
col = sliceBoundaryid - (sliceBoundarySize - nCols);
|
||||
} // last row
|
||||
else
|
||||
{ // any other row
|
||||
row = ((sliceBoundaryid - nCols) / 2) + 1;
|
||||
col = ((sliceBoundaryid - nCols) % 2) ? (nCols - 1) : 0;
|
||||
} // any other row
|
||||
} // slice exteriors
|
||||
// now we have row, col, slice all set, compute the actual ID
|
||||
boundaryVertex = meshStructure3D.VertexId(slice, row, col);
|
||||
// and fill in the index array as well
|
||||
boundarySortIndex = sortIndicesPortal.Get(boundaryVertex);
|
||||
|
||||
/*
|
||||
{ // GetBoundaryVertices()
|
||||
// calculate the number of boundary elements - all of the two xy faces
|
||||
indexType nBoundary = 2 * nRows * nCols // xy faces
|
||||
+ 2 * nRows * (nSlices - 2) // yz faces - excluding vertices on xy
|
||||
+ 2 * (nCols - 2) * (nSlices - 2) // xz face interiors
|
||||
;
|
||||
|
||||
// resize the arrays accordingly
|
||||
boundaryVertexArray.resize(nBoundary);
|
||||
boundarySortIndexArray.resize(nBoundary);
|
||||
|
||||
// loop to add in the vertices
|
||||
for (indexType boundaryID = 0; boundaryID < nBoundary; boundaryID++)
|
||||
{ // loop through indices
|
||||
indexType row = 0, col = 0, slice = 0;
|
||||
indexType sliceSize = nRows * nCols;
|
||||
indexType sliceBoundarySize = 2 * nRows + 2 * nCols - 4;
|
||||
// do top plane first
|
||||
if (boundaryID < sliceSize)
|
||||
{ // top plane
|
||||
row = boundaryID / nCols;
|
||||
col = boundaryID % nCols;
|
||||
slice = 0;
|
||||
} // top plane
|
||||
// then bottom plane
|
||||
else if (boundaryID >= nBoundary - sliceSize)
|
||||
{ // bottom plane
|
||||
row = (boundaryID - (nBoundary - sliceSize)) / nCols;
|
||||
col = (boundaryID - (nBoundary - sliceSize)) % nCols;
|
||||
slice = nSlices - 1;
|
||||
} // bottom plane
|
||||
// now we have to deal with the exterior of the remaining slices
|
||||
else
|
||||
{ // slice exteriors
|
||||
// first we subtract the size of the first slice
|
||||
indexType offsetBoundaryID = boundaryID - sliceSize;
|
||||
// now we can compute the slice ID
|
||||
slice = 1 + offsetBoundaryID / sliceBoundarySize;
|
||||
// compute the local ID on the slice
|
||||
indexType sliceBoundaryID = offsetBoundaryID % sliceBoundarySize;
|
||||
// now test for the first and last row
|
||||
if (sliceBoundaryID < nCols)
|
||||
{ // first row
|
||||
row = 0;
|
||||
col = sliceBoundaryID;
|
||||
} // first row
|
||||
else if (sliceBoundaryID >= (sliceBoundarySize - nCols))
|
||||
{ // last row
|
||||
row = nRows - 1;
|
||||
col = sliceBoundaryID - (sliceBoundarySize - nCols);
|
||||
} // last row
|
||||
else
|
||||
{ // any other row
|
||||
row = ((sliceBoundaryID - nCols) / 2) + 1;
|
||||
col = ((sliceBoundaryID - nCols) % 2) ? (nCols - 1) : 0;
|
||||
} // any other row
|
||||
} // slice exteriors
|
||||
// now we have row, col, slice all set, compute the actual ID
|
||||
boundaryVertexArray[boundaryID] = vertexId(slice, row, col);
|
||||
// and fill in the index array as well
|
||||
boundarySortIndexArray[boundaryID] = sortIndices[boundaryVertexArray[boundaryID]];
|
||||
} // loop through indices
|
||||
} // GetBoundaryVertices()
|
||||
*/
|
||||
}
|
||||
|
||||
}; // ComputeMeshBoundary3D
|
||||
|
||||
} // namespace contourtree_augmented
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
103
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundaryContourTreeMesh.h
Normal file
103
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/ComputeMeshBoundaryContourTreeMesh.h
Normal file
@ -0,0 +1,103 @@
|
||||
//============================================================================
|
||||
// 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_augmented_mesh_dem_mesh_types_mesh_boundary_compute_mesh_boundary_contour_tree_mesh_h
|
||||
#define vtk_m_worklet_contourtree_augmented_mesh_dem_mesh_types_mesh_boundary_compute_mesh_boundary_contour_tree_mesh_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_augmented
|
||||
{
|
||||
|
||||
// Worklet to collapse past regular vertices by updating inbound and outbound as part
|
||||
// loop to find the now-regular vertices and collapse past them without altering
|
||||
// the existing join & split arcs
|
||||
class ComputeMeshBoundaryContourTreeMesh : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
typedef void ControlSignature(FieldIn nodeIndex, // (input)
|
||||
ExecObject meshBoundary, // (input)
|
||||
FieldOut isOnBoundary // (output)
|
||||
);
|
||||
typedef void ExecutionSignature(_1, _2, _3);
|
||||
using InputDomain = _1;
|
||||
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
ComputeMeshBoundaryContourTreeMesh() {}
|
||||
|
||||
template <typename InFieldPortalType, typename MeshBoundaryType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& nodeIndex,
|
||||
const MeshBoundaryType& meshBoundary,
|
||||
vtkm::Id& isOnBoundary)
|
||||
{
|
||||
isOnBoundary = meshBoundary.liesOnBoundary(nodeIndex);
|
||||
/*
|
||||
indexVector isOnBoundary(globalMeshIndex.size());
|
||||
for (indexType node = 0; node < globalMeshIndex.size(); node++)
|
||||
isOnBoundary[node] = liesOnBoundary(node);
|
||||
*/
|
||||
}
|
||||
|
||||
}; // ComputeMeshBoundaryContourTreeMesh
|
||||
|
||||
} // namespace contourtree_augmented
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
153
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary2D.h
Normal file
153
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary2D.h
Normal file
@ -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.
|
||||
//
|
||||
//=============================================================================
|
||||
//
|
||||
// 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)
|
||||
//==============================================================================
|
||||
|
||||
// This header contains a collection of classes used to describe the boundary
|
||||
// of a mesh, for each main mesh type (i.e., 2D, 3D, and ContourTreeMesh).
|
||||
// For each mesh type, there are two classes, the actual boundary desriptor
|
||||
// class and an ExectionObject class with the PrepareForInput function that
|
||||
// VTKm expects to generate the object for the execution environment.
|
||||
|
||||
#ifndef vtk_m_worklet_contourtree_augmented_mesh_boundary_mesh_boundary_2d_h
|
||||
#define vtk_m_worklet_contourtree_augmented_mesh_boundary_mesh_boundary_2d_h
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem/MeshStructure2D.h>
|
||||
|
||||
#include <vtkm/cont/ExecutionObjectBase.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_augmented
|
||||
{
|
||||
|
||||
|
||||
template <typename DeviceTag>
|
||||
class MeshBoundary2D
|
||||
{
|
||||
public:
|
||||
// Sort indicies types
|
||||
using SortOrderPortalType = typename IdArrayType::template ExecutionTypes<DeviceTag>::PortalConst;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
MeshBoundary2D()
|
||||
: MeshStructure(mesh_dem::MeshStructure2D<DeviceTag>(0, 0))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
MeshBoundary2D(vtkm::Id nrows,
|
||||
vtkm::Id ncols,
|
||||
const IdArrayType& sortOrder,
|
||||
vtkm::cont::Token& token)
|
||||
: MeshStructure(mesh_dem::MeshStructure2D<DeviceTag>(nrows, ncols))
|
||||
{
|
||||
this->SortOrderPortal = sortOrder.PrepareForInput(DeviceTag(), token);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
bool liesOnBoundary(const vtkm::Id index) const
|
||||
{
|
||||
vtkm::Id meshSortOrderValue = this->SortOrderPortal.Get(index);
|
||||
const vtkm::Id row = this->MeshStructure.VertexRow(meshSortOrderValue);
|
||||
const vtkm::Id col = this->MeshStructure.VertexColumn(meshSortOrderValue);
|
||||
|
||||
return (row == 0) || (col == 0) || (row == this->MeshStructure.NumRows - 1) ||
|
||||
(col == this->MeshStructure.NumColumns - 1);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
const mesh_dem::MeshStructure2D<DeviceTag>& GetMeshStructure() const
|
||||
{
|
||||
return this->MeshStructure;
|
||||
}
|
||||
|
||||
private:
|
||||
// 2D Mesh size parameters
|
||||
mesh_dem::MeshStructure2D<DeviceTag> MeshStructure;
|
||||
SortOrderPortalType SortOrderPortal;
|
||||
};
|
||||
|
||||
class MeshBoundary2DExec : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT
|
||||
MeshBoundary2DExec(vtkm::Id nrows, vtkm::Id ncols, const IdArrayType& inSortOrder)
|
||||
: NumRows(nrows)
|
||||
, NumColumns(ncols)
|
||||
, SortOrder(inSortOrder)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
template <typename DeviceTag>
|
||||
MeshBoundary2D<DeviceTag> PrepareForExecution(DeviceTag, vtkm::cont::Token& token) const
|
||||
{
|
||||
return MeshBoundary2D<DeviceTag>(this->NumRows, this->NumColumns, this->SortOrder, token);
|
||||
}
|
||||
|
||||
private:
|
||||
// 2D Mesh size parameters
|
||||
vtkm::Id NumRows;
|
||||
vtkm::Id NumColumns;
|
||||
const IdArrayType& SortOrder;
|
||||
};
|
||||
|
||||
|
||||
} // namespace contourtree_augmented
|
||||
} // worklet
|
||||
} // vtkm
|
||||
|
||||
#endif
|
154
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary3D.h
Normal file
154
vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/mesh_boundary/MeshBoundary3D.h
Normal file
@ -0,0 +1,154 @@
|
||||
//============================================================================
|
||||
// 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)
|
||||
//==============================================================================
|
||||
|
||||
// This header contains a collection of classes used to describe the boundary
|
||||
// of a mesh, for each main mesh type (i.e., 2D, 3D, and ContourTreeMesh).
|
||||
// For each mesh type, there are two classes, the actual boundary desriptor
|
||||
// class and an ExectionObject class with the PrepareForInput function that
|
||||
// VTKm expects to generate the object for the execution environment.
|
||||
|
||||
#ifndef vtk_m_worklet_contourtree_augmented_mesh_boundary_mesh_boundary_3d_h
|
||||
#define vtk_m_worklet_contourtree_augmented_mesh_boundary_mesh_boundary_3d_h
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem/MeshStructure3D.h>
|
||||
|
||||
#include <vtkm/cont/ExecutionObjectBase.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_augmented
|
||||
{
|
||||
|
||||
template <typename DeviceTag>
|
||||
class MeshBoundary3D : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
// Sort indicies types
|
||||
using SortOrderPortalType = typename IdArrayType::template ExecutionTypes<DeviceTag>::PortalConst;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
MeshBoundary3D()
|
||||
: MeshStructure(mesh_dem::MeshStructure3D<DeviceTag>(0, 0, 0))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
MeshBoundary3D(vtkm::Id nrows,
|
||||
vtkm::Id ncols,
|
||||
vtkm::Id nslices,
|
||||
const IdArrayType& sortOrder,
|
||||
vtkm::cont::Token& token)
|
||||
: MeshStructure(mesh_dem::MeshStructure3D<DeviceTag>(nrows, ncols, nslices))
|
||||
{
|
||||
this->SortOrderPortal = sortOrder.PrepareForInput(DeviceTag(), token);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
bool liesOnBoundary(const vtkm::Id index) const
|
||||
{
|
||||
vtkm::Id meshSortOrderValue = this->SortOrderPortal.Get(index);
|
||||
const vtkm::Id row = this->MeshStructure.VertexRow(meshSortOrderValue);
|
||||
const vtkm::Id col = this->MeshStructure.VertexColumn(meshSortOrderValue);
|
||||
const vtkm::Id sli = this->MeshStructure.VertexSlice(meshSortOrderValue);
|
||||
return (row == 0) || (col == 0) || (sli == 0) || (row == this->MeshStructure.NumRows - 1) ||
|
||||
(col == this->MeshStructure.NumColumns - 1) || (sli == this->MeshStructure.NumSlices - 1);
|
||||
}
|
||||
|
||||
protected:
|
||||
// 3D Mesh size parameters
|
||||
mesh_dem::MeshStructure3D<DeviceTag> MeshStructure;
|
||||
SortOrderPortalType SortOrderPortal;
|
||||
};
|
||||
|
||||
|
||||
class MeshBoundary3DExec : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT
|
||||
MeshBoundary3DExec(vtkm::Id nrows,
|
||||
vtkm::Id ncols,
|
||||
vtkm::Id nslices,
|
||||
const IdArrayType& inSortOrder)
|
||||
: NumRows(nrows)
|
||||
, NumColumns(ncols)
|
||||
, NumSlices(nslices)
|
||||
, SortOrder(inSortOrder)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
template <typename DeviceTag>
|
||||
MeshBoundary3D<DeviceTag> PrepareForExecution(DeviceTag, vtkm::cont::Token& token) const
|
||||
{
|
||||
return MeshBoundary3D<DeviceTag>(
|
||||
this->NumRows, this->NumColumns, this->NumSlices, this->SortOrder, token);
|
||||
}
|
||||
|
||||
protected:
|
||||
// 3D Mesh size parameters
|
||||
vtkm::Id NumRows;
|
||||
vtkm::Id NumColumns;
|
||||
vtkm::Id NumSlices;
|
||||
const IdArrayType& SortOrder;
|
||||
};
|
||||
|
||||
|
||||
} // namespace contourtree_augmented
|
||||
} // worklet
|
||||
} // vtkm
|
||||
|
||||
#endif
|
@ -56,16 +56,13 @@
|
||||
// class and an ExectionObject class with the PrepareForInput function that
|
||||
// VTKm expects to generate the object for the execution environment.
|
||||
|
||||
#ifndef vtk_m_worklet_contourtree_augmented_mesh_boundary_h
|
||||
#define vtk_m_worklet_contourtree_augmented_mesh_boundary_h
|
||||
#ifndef vtk_m_worklet_contourtree_augmented_mesh_boundary_mesh_boundary_contour_tree_mesh_h
|
||||
#define vtk_m_worklet_contourtree_augmented_mesh_boundary_mesh_boundary_contour_tree_mesh_h
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem/MeshStructure2D.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem/MeshStructure3D.h>
|
||||
|
||||
#include <vtkm/cont/ExecutionObjectBase.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -75,145 +72,6 @@ namespace contourtree_augmented
|
||||
{
|
||||
|
||||
|
||||
template <typename DeviceTag>
|
||||
class MeshBoundary2D
|
||||
{
|
||||
public:
|
||||
// Sort indicies types
|
||||
using SortOrderPortalType = typename IdArrayType::template ExecutionTypes<DeviceTag>::PortalConst;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
MeshBoundary2D()
|
||||
: MeshStructure(mesh_dem::MeshStructure2D<DeviceTag>(0, 0))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
MeshBoundary2D(vtkm::Id nrows,
|
||||
vtkm::Id ncols,
|
||||
const IdArrayType& sortOrder,
|
||||
vtkm::cont::Token& token)
|
||||
: MeshStructure(mesh_dem::MeshStructure2D<DeviceTag>(nrows, ncols))
|
||||
{
|
||||
this->SortOrderPortal = sortOrder.PrepareForInput(DeviceTag(), token);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
bool liesOnBoundary(const vtkm::Id index) const
|
||||
{
|
||||
vtkm::Id meshSortOrderValue = this->SortOrderPortal.Get(index);
|
||||
const vtkm::Id row = this->MeshStructure.VertexRow(meshSortOrderValue);
|
||||
const vtkm::Id col = this->MeshStructure.VertexColumn(meshSortOrderValue);
|
||||
|
||||
return (row == 0) || (col == 0) || (row == this->MeshStructure.NumRows - 1) ||
|
||||
(col == this->MeshStructure.NumColumns - 1);
|
||||
}
|
||||
|
||||
private:
|
||||
// 2D Mesh size parameters
|
||||
mesh_dem::MeshStructure2D<DeviceTag> MeshStructure;
|
||||
SortOrderPortalType SortOrderPortal;
|
||||
};
|
||||
|
||||
class MeshBoundary2DExec : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT
|
||||
MeshBoundary2DExec(vtkm::Id nrows, vtkm::Id ncols, const IdArrayType& inSortOrder)
|
||||
: NumRows(nrows)
|
||||
, NumColumns(ncols)
|
||||
, SortOrder(inSortOrder)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
template <typename DeviceTag>
|
||||
MeshBoundary2D<DeviceTag> PrepareForExecution(DeviceTag, vtkm::cont::Token& token) const
|
||||
{
|
||||
return MeshBoundary2D<DeviceTag>(this->NumRows, this->NumColumns, this->SortOrder, token);
|
||||
}
|
||||
|
||||
private:
|
||||
// 2D Mesh size parameters
|
||||
vtkm::Id NumRows;
|
||||
vtkm::Id NumColumns;
|
||||
const IdArrayType& SortOrder;
|
||||
};
|
||||
|
||||
|
||||
template <typename DeviceTag>
|
||||
class MeshBoundary3D : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
// Sort indicies types
|
||||
using SortOrderPortalType = typename IdArrayType::template ExecutionTypes<DeviceTag>::PortalConst;
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
MeshBoundary3D()
|
||||
: MeshStructure(mesh_dem::MeshStructure3D<DeviceTag>(0, 0, 0))
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
MeshBoundary3D(vtkm::Id nrows,
|
||||
vtkm::Id ncols,
|
||||
vtkm::Id nslices,
|
||||
const IdArrayType& sortOrder,
|
||||
vtkm::cont::Token& token)
|
||||
: MeshStructure(mesh_dem::MeshStructure3D<DeviceTag>(nrows, ncols, nslices))
|
||||
{
|
||||
this->SortOrderPortal = sortOrder.PrepareForInput(DeviceTag(), token);
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
bool liesOnBoundary(const vtkm::Id index) const
|
||||
{
|
||||
vtkm::Id meshSortOrderValue = this->SortOrderPortal.Get(index);
|
||||
const vtkm::Id row = this->MeshStructure.VertexRow(meshSortOrderValue);
|
||||
const vtkm::Id col = this->MeshStructure.VertexColumn(meshSortOrderValue);
|
||||
const vtkm::Id sli = this->MeshStructure.VertexSlice(meshSortOrderValue);
|
||||
return (row == 0) || (col == 0) || (sli == 0) || (row == this->MeshStructure.NumRows - 1) ||
|
||||
(col == this->MeshStructure.NumColumns - 1) || (sli == this->MeshStructure.NumSlices - 1);
|
||||
}
|
||||
|
||||
protected:
|
||||
// 3D Mesh size parameters
|
||||
mesh_dem::MeshStructure3D<DeviceTag> MeshStructure;
|
||||
SortOrderPortalType SortOrderPortal;
|
||||
};
|
||||
|
||||
|
||||
class MeshBoundary3DExec : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT
|
||||
MeshBoundary3DExec(vtkm::Id nrows,
|
||||
vtkm::Id ncols,
|
||||
vtkm::Id nslices,
|
||||
const IdArrayType& inSortOrder)
|
||||
: NumRows(nrows)
|
||||
, NumColumns(ncols)
|
||||
, NumSlices(nslices)
|
||||
, SortOrder(inSortOrder)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
template <typename DeviceTag>
|
||||
MeshBoundary3D<DeviceTag> PrepareForExecution(DeviceTag, vtkm::cont::Token& token) const
|
||||
{
|
||||
return MeshBoundary3D<DeviceTag>(
|
||||
this->NumRows, this->NumColumns, this->NumSlices, this->SortOrder, token);
|
||||
}
|
||||
|
||||
protected:
|
||||
// 3D Mesh size parameters
|
||||
vtkm::Id NumRows;
|
||||
vtkm::Id NumColumns;
|
||||
vtkm::Id NumSlices;
|
||||
const IdArrayType& SortOrder;
|
||||
};
|
||||
|
||||
|
||||
template <typename DeviceTag>
|
||||
class MeshBoundaryContourTreeMesh
|
@ -0,0 +1,288 @@
|
||||
//============================================================================
|
||||
// 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_boundary_restricted_augmented_contour_tree_h
|
||||
#define vtk_m_worklet_contourtree_distributed_boundary_restricted_augmented_contour_tree_h
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/PrintVectors.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem/IdRelabeler.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/ContourTreeMesh.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
|
||||
/// \brief Boundary Restricted Augmented Contour Tree (BRACT)
|
||||
///
|
||||
/// A contour tree for boundary vertices with the interior abstracted.
|
||||
/// This is primarily a data storage class. The actual constuction of
|
||||
/// the BRACT is performed by the BoundaryRestrictedAugmentedContourTreeMaker
|
||||
/// (BRACTMaker). As a data store, this class primarily stores a set of
|
||||
/// arrays and provides convenience functions for interacting with the
|
||||
/// the data, e.g., to export the data to dot.
|
||||
class BoundaryRestrictedAugmentedContourTree
|
||||
{ // class BRACT
|
||||
public:
|
||||
// for each vertex, we store the index
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType VertexIndex;
|
||||
|
||||
// and the ID of the vertex it connects to (or NO_SUCH_ELEMENT)
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType Superarcs;
|
||||
|
||||
// prints the contents of the BRACT for comparison with sweep and merge
|
||||
std::string Print();
|
||||
|
||||
// secondary version which takes the mesh as a parameter
|
||||
template <typename Mesh, typename FieldArrayType>
|
||||
std::string PrintGlobalDot(const char* label,
|
||||
const Mesh& mesh,
|
||||
const FieldArrayType& fieldArray,
|
||||
const vtkm::Id3 blockOrigin,
|
||||
const vtkm::Id3 globalSize) const;
|
||||
|
||||
// prints the contents of the BRACT as a dot file using global IDs (version for CT mesh)
|
||||
template <typename FieldType>
|
||||
std::string PrintGlobalDot(
|
||||
const char* label,
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>& mesh);
|
||||
|
||||
// prints the contents of the BRACT in debug format
|
||||
std::string DebugPrint(const char* message, const char* fileName, long lineNum);
|
||||
};
|
||||
|
||||
|
||||
// prints the contents of the BRACT for comparison with sweep and merge
|
||||
std::string BoundaryRestrictedAugmentedContourTree::Print()
|
||||
{ // Print
|
||||
// Use string steam to record text so the user can print it however they like
|
||||
std::stringstream resultStream;
|
||||
resultStream << "Boundary-Restricted Augmented Contour Tree" << std::endl;
|
||||
resultStream << "==========================================" << std::endl;
|
||||
// fill it up
|
||||
auto superarcsPortal = this->Superarcs.ReadPortal();
|
||||
auto vertexIndexPortal = this->VertexIndex.ReadPortal();
|
||||
for (vtkm::Id node = 0; node < superarcsPortal.GetNumberOfValues(); node++)
|
||||
{
|
||||
// retrieve ID of target supernode
|
||||
vtkm::Id from = vertexIndexPortal.Get(node);
|
||||
vtkm::Id to = superarcsPortal.Get(node);
|
||||
// if this is true, it is the last pruned vertex & is omitted
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(to))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// print out the from & to
|
||||
resultStream << std::setw(vtkm::worklet::contourtree_augmented::PRINT_WIDTH) << from << " ";
|
||||
resultStream << std::setw(vtkm::worklet::contourtree_augmented::PRINT_WIDTH) << to << std::endl;
|
||||
}
|
||||
return resultStream.str();
|
||||
} // Print
|
||||
|
||||
// secondary version which takes the mesh as a parameter
|
||||
template <typename Mesh, typename FieldArrayType>
|
||||
std::string BoundaryRestrictedAugmentedContourTree::PrintGlobalDot(const char* label,
|
||||
const Mesh& mesh,
|
||||
const FieldArrayType& fieldArray,
|
||||
const vtkm::Id3 blockOrigin,
|
||||
const vtkm::Id3 globalSize) const
|
||||
{ // PrintGlobalDot
|
||||
std::stringstream resultStream;
|
||||
// print the header information
|
||||
resultStream << "digraph BRACT" << std::endl;
|
||||
resultStream << "\t{" << std::endl;
|
||||
resultStream << "\tlabel=\"" << label << "\"\n\tlabelloc=t\n\tfontsize=30" << std::endl;
|
||||
// create a relabeler
|
||||
vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler relabeler(blockOrigin[0],
|
||||
blockOrigin[1],
|
||||
blockOrigin[2],
|
||||
mesh.NumRows,
|
||||
mesh.NumCols,
|
||||
globalSize[0],
|
||||
globalSize[1]);
|
||||
|
||||
// loop through all nodes
|
||||
auto vertexIndexPortal = this->VertexIndex.ReadPortal();
|
||||
auto superarcsPortal = this->Superarcs.ReadPortal();
|
||||
auto sortOrderPortal = mesh.SortOrder.ReadPortal();
|
||||
auto fieldArrayPortal = fieldArray.ReadPortal();
|
||||
for (vtkm::Id node = 0; node < this->Superarcs.GetNumberOfValues(); node++)
|
||||
{
|
||||
// now convert to mesh IDs from node IDs
|
||||
vtkm::Id from = vertexIndexPortal.Get(node);
|
||||
// find the local & global IDs & data value
|
||||
vtkm::Id fromLocal = sortOrderPortal.Get(from);
|
||||
vtkm::Id fromGlobal = relabeler(fromLocal);
|
||||
auto fromValue = fieldArrayPortal.Get(fromLocal);
|
||||
|
||||
// print the vertex
|
||||
resultStream << node << " [style=filled,fillcolor="
|
||||
<< "grey"
|
||||
<< ",label=\"" << fromGlobal << "\\nv" << fromValue << "\"];" << std::endl;
|
||||
}
|
||||
|
||||
for (vtkm::Id node = 0; node < this->Superarcs.GetNumberOfValues(); node++)
|
||||
{
|
||||
// retrieve ID of target supernode
|
||||
vtkm::Id to = superarcsPortal.Get(node);
|
||||
// if this is true, it is the last pruned vertex & is omitted
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(to))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (node < to)
|
||||
{
|
||||
resultStream << to << " -> " << node << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultStream << node << " -> " << to << std::endl;
|
||||
}
|
||||
}
|
||||
resultStream << "\t}" << std::endl;
|
||||
// return the result
|
||||
return resultStream.str();
|
||||
} // PrintGlobalDot
|
||||
|
||||
// prints the contents of the BRACT as a dot file using global IDs (version for CT mesh)
|
||||
template <typename FieldType>
|
||||
std::string BoundaryRestrictedAugmentedContourTree::PrintGlobalDot(
|
||||
const char* label,
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>& mesh)
|
||||
{ //PrintGlobalDot
|
||||
std::stringstream resultStream;
|
||||
// print the header information
|
||||
resultStream << "digraph BRACT\n\t{\n";
|
||||
resultStream << "\tsize=\"6.5, 9\"\n\tratio=\"fill\"\n";
|
||||
resultStream << "\tlabel=\"" << label << "\"\n\tlabelloc=t\n\tfontsize=30\n" << std::endl;
|
||||
|
||||
// loop through all nodes
|
||||
auto vertexIndexPortal = this->VertexIndex.ReadPortal();
|
||||
auto globalMeshIndexPortal = mesh.GlobalMeshIndex.ReadPortal();
|
||||
auto sortedValuesPortal = mesh.SortedValued.ReadPortal();
|
||||
auto superarcsPortal = this->Superarcs.ReadPortal();
|
||||
for (vtkm::Id node = 0; node < this->VertexIndex.GetNumberOfValues(); node++)
|
||||
{ // per node
|
||||
// work out the node and it's value
|
||||
vtkm::Id meshIndex = vertexIndexPortal.Get(node);
|
||||
vtkm::Id from = globalMeshIndexPortal.Get(meshIndex);
|
||||
auto fromValue = sortedValuesPortal.Get(meshIndex);
|
||||
// print the vertex
|
||||
resultStream << node << " [style=filled,fillcolor="
|
||||
<< "grey"
|
||||
<< ",label=\"" << from << "\\nv" << fromValue << "\"];" << std::endl;
|
||||
} // per node
|
||||
|
||||
|
||||
for (vtkm::Id node = 0; node < this->Superarcs.GetNumberOfValues(); node++)
|
||||
{ // per node
|
||||
// retrieve ID of target supernode
|
||||
vtkm::Id to = superarcsPortal.Get(node);
|
||||
// if this is true, it is the last pruned vertex & is omitted
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(to))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (node < to)
|
||||
{
|
||||
resultStream << to << " -> " << node << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultStream << node << " -> " << to << std::endl;
|
||||
}
|
||||
} // per node
|
||||
resultStream << "\t}" << std::endl;
|
||||
// Return the resulting strin
|
||||
return resultStream.str();
|
||||
} //PrintGlobalDot
|
||||
|
||||
// debug routine
|
||||
inline std::string BoundaryRestrictedAugmentedContourTree::DebugPrint(const char* message,
|
||||
const char* fileName,
|
||||
long lineNum)
|
||||
{ // DebugPrint
|
||||
std::stringstream resultStream;
|
||||
resultStream << "[CUTHERE]-------------------------------------------------------" << std::endl;
|
||||
resultStream << std::setw(30) << std::left << fileName << ":" << std::right << std::setw(4)
|
||||
<< lineNum << std::endl;
|
||||
resultStream << std::left << std::string(message) << std::endl;
|
||||
resultStream << "Boundary Restricted Augmented Contour Tree Contains: " << std::endl;
|
||||
resultStream << "----------------------------------------------------------------" << std::endl;
|
||||
|
||||
vtkm::worklet::contourtree_augmented::PrintHeader(this->VertexIndex.GetNumberOfValues(),
|
||||
resultStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Vertex Index", this->VertexIndex, -1, resultStream);
|
||||
vtkm::worklet::contourtree_augmented::PrintIndices(
|
||||
"Superarcs", this->Superarcs, -1, resultStream);
|
||||
|
||||
resultStream << "---------------------------" << std::endl;
|
||||
resultStream << std::endl;
|
||||
resultStream << std::flush;
|
||||
return resultStream.str();
|
||||
} // DebugPrint
|
||||
|
||||
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
23
vtkm/worklet/contourtree_distributed/CMakeLists.txt
Normal file
23
vtkm/worklet/contourtree_distributed/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
||||
##============================================================================
|
||||
## 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
|
||||
ContourTreeBlockData.h
|
||||
SpatialDecomposition.h
|
||||
MultiBlockContourTreeHelper.h
|
||||
MergeBlockFunctor.h
|
||||
BoundaryRestrictedAugmentedContourTree.h
|
||||
BoundaryRestrictedAugmentedContourTreeMaker.h
|
||||
HierarchicalContourTree.h
|
||||
)
|
||||
|
||||
vtkm_declare_headers(${headers})
|
||||
|
||||
add_subdirectory(bract_maker)
|
143
vtkm/worklet/contourtree_distributed/ContourTreeBlockData.h
Normal file
143
vtkm/worklet/contourtree_distributed/ContourTreeBlockData.h
Normal file
@ -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_contourtreeblockdata_h
|
||||
#define vtk_m_worklet_contourtree_distributed_contourtreeblockdata_h
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
// clang-format off
|
||||
VTKM_THIRDPARTY_PRE_INCLUDE
|
||||
#include <vtkm/thirdparty/diy/diy.h>
|
||||
VTKM_THIRDPARTY_POST_INCLUDE
|
||||
// clang-format on
|
||||
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
template <typename FieldType>
|
||||
struct ContourTreeBlockData
|
||||
{
|
||||
static void* create() { return new ContourTreeBlockData<FieldType>; }
|
||||
static void destroy(void* b) { delete static_cast<ContourTreeBlockData<FieldType>*>(b); }
|
||||
|
||||
// ContourTreeMesh data
|
||||
vtkm::Id NumVertices;
|
||||
// TODO Should be able to remove sortOrder here, but we need to figure out what to return in the worklet instead
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType SortOrder;
|
||||
vtkm::cont::ArrayHandle<FieldType> SortedValue;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType GlobalMeshIndex;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType Neighbours;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType FirstNeighbour;
|
||||
vtkm::Id MaxNeighbours;
|
||||
|
||||
// Block metadata
|
||||
vtkm::Id3 BlockOrigin; // Origin of the data block
|
||||
vtkm::Id3 BlockSize; // Extends of the data block
|
||||
vtkm::Id3 GlobalSize; // Extends of the global mesh
|
||||
unsigned int ComputeRegularStructure; // pass through augmentation setting
|
||||
};
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
|
||||
namespace vtkmdiy
|
||||
{
|
||||
|
||||
// Struct to serialize ContourBlockData objects (i.e., load/save) needed in parralle for DIY
|
||||
template <typename FieldType>
|
||||
struct Serialization<vtkm::worklet::contourtree_distributed::ContourTreeBlockData<FieldType>>
|
||||
{
|
||||
static void save(
|
||||
vtkmdiy::BinaryBuffer& bb,
|
||||
const vtkm::worklet::contourtree_distributed::ContourTreeBlockData<FieldType>& block)
|
||||
{
|
||||
vtkmdiy::save(bb, block.NumVertices);
|
||||
vtkmdiy::save(bb, block.SortOrder);
|
||||
vtkmdiy::save(bb, block.SortedValue);
|
||||
vtkmdiy::save(bb, block.GlobalMeshIndex);
|
||||
vtkmdiy::save(bb, block.Neighbours);
|
||||
vtkmdiy::save(bb, block.FirstNeighbour);
|
||||
vtkmdiy::save(bb, block.MaxNeighbours);
|
||||
vtkmdiy::save(bb, block.BlockOrigin);
|
||||
vtkmdiy::save(bb, block.BlockSize);
|
||||
vtkmdiy::save(bb, block.GlobalSize);
|
||||
vtkmdiy::save(bb, block.ComputeRegularStructure);
|
||||
}
|
||||
|
||||
static void load(vtkmdiy::BinaryBuffer& bb,
|
||||
vtkm::worklet::contourtree_distributed::ContourTreeBlockData<FieldType>& block)
|
||||
{
|
||||
vtkmdiy::load(bb, block.NumVertices);
|
||||
vtkmdiy::load(bb, block.SortOrder);
|
||||
vtkmdiy::load(bb, block.SortedValue);
|
||||
vtkmdiy::load(bb, block.GlobalMeshIndex);
|
||||
vtkmdiy::load(bb, block.Neighbours);
|
||||
vtkmdiy::load(bb, block.FirstNeighbour);
|
||||
vtkmdiy::load(bb, block.MaxNeighbours);
|
||||
vtkmdiy::load(bb, block.BlockOrigin);
|
||||
vtkmdiy::load(bb, block.BlockSize);
|
||||
vtkmdiy::load(bb, block.GlobalSize);
|
||||
vtkmdiy::load(bb, block.ComputeRegularStructure);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mangled_vtkmdiy_namespace
|
||||
|
||||
|
||||
#endif
|
@ -0,0 +1,83 @@
|
||||
//============================================================================
|
||||
// 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_contour_tree_h
|
||||
#define vtk_m_worklet_contourtree_distributed_hierarchical_contour_tree_h
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
|
||||
|
||||
/// \brief Hierarchical Contour Tree data structure
|
||||
///
|
||||
/// TODO this class still needs to be implemented
|
||||
class HierarchicalContourTree
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
HierarchicalContourTree() {}
|
||||
};
|
||||
|
||||
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
250
vtkm/worklet/contourtree_distributed/MergeBlockFunctor.h
Normal file
250
vtkm/worklet/contourtree_distributed/MergeBlockFunctor.h
Normal file
@ -0,0 +1,250 @@
|
||||
//============================================================================
|
||||
// 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_mergeblockfunctor_h
|
||||
#define vtk_m_worklet_contourtree_distributed_mergeblockfunctor_h
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
// clang-format off
|
||||
VTKM_THIRDPARTY_PRE_INCLUDE
|
||||
#include <vtkm/thirdparty/diy/diy.h>
|
||||
VTKM_THIRDPARTY_POST_INCLUDE
|
||||
// clang-format on
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
|
||||
// Functor needed so we can discover the FieldType and DeviceAdapter template parameters to call MergeWith
|
||||
struct MergeFunctor
|
||||
{
|
||||
template <typename DeviceAdapterTag, typename FieldType>
|
||||
bool operator()(DeviceAdapterTag,
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>& in,
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>& out) const
|
||||
{
|
||||
out.template MergeWith<DeviceAdapterTag>(in);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Functor used by DIY reduce the merge data blocks in parallel
|
||||
template <typename FieldType>
|
||||
void MergeBlockFunctor(
|
||||
vtkm::worklet::contourtree_distributed::ContourTreeBlockData<FieldType>* block, // local Block.
|
||||
const vtkmdiy::ReduceProxy& rp, // communication proxy
|
||||
const vtkmdiy::RegularMergePartners& partners // partners of the current block
|
||||
)
|
||||
{ //MergeBlockFunctor
|
||||
(void)partners; // Avoid unused parameter warning
|
||||
|
||||
const auto selfid = rp.gid();
|
||||
|
||||
// TODO This should be changed so that we have the ContourTree itself as the block and then the
|
||||
// ContourTreeMesh would still be used for exchange. In this case we would need to compute
|
||||
// the ContourTreeMesh at the beginning of the function for the current block every time
|
||||
// but then we would not need to compute those meshes when we initialize vtkmdiy
|
||||
// and we don't need to have the special case for rank 0.
|
||||
|
||||
// Here we do the deque first before the send due to the way the iteration is handled in DIY, i.e., in each iteration
|
||||
// A block needs to first collect the data from its neighours and then send the combined block to its neighbours
|
||||
// for the next iteration.
|
||||
// 1. dequeue the block and compute the new contour tree and contour tree mesh for the block if we have the hight GID
|
||||
std::vector<int> incoming;
|
||||
rp.incoming(incoming);
|
||||
for (const int ingid : incoming)
|
||||
{
|
||||
if (ingid != selfid)
|
||||
{
|
||||
vtkm::worklet::contourtree_distributed::ContourTreeBlockData<FieldType> recvblock;
|
||||
rp.dequeue(ingid, recvblock);
|
||||
|
||||
// Construct the two contour tree mesh by assignign the block data
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType> contourTreeMeshIn;
|
||||
contourTreeMeshIn.NumVertices = recvblock.NumVertices;
|
||||
contourTreeMeshIn.SortOrder = recvblock.SortOrder;
|
||||
contourTreeMeshIn.SortedValues = recvblock.SortedValue;
|
||||
contourTreeMeshIn.GlobalMeshIndex = recvblock.GlobalMeshIndex;
|
||||
contourTreeMeshIn.Neighbours = recvblock.Neighbours;
|
||||
contourTreeMeshIn.FirstNeighbour = recvblock.FirstNeighbour;
|
||||
contourTreeMeshIn.MaxNeighbours = recvblock.MaxNeighbours;
|
||||
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType> contourTreeMeshOut;
|
||||
contourTreeMeshOut.NumVertices = block->NumVertices;
|
||||
contourTreeMeshOut.SortOrder = block->SortOrder;
|
||||
contourTreeMeshOut.SortedValues = block->SortedValue;
|
||||
contourTreeMeshOut.GlobalMeshIndex = block->GlobalMeshIndex;
|
||||
contourTreeMeshOut.Neighbours = block->Neighbours;
|
||||
contourTreeMeshOut.FirstNeighbour = block->FirstNeighbour;
|
||||
contourTreeMeshOut.MaxNeighbours = block->MaxNeighbours;
|
||||
// Merge the two contour tree meshes
|
||||
vtkm::cont::TryExecute(MergeFunctor{}, contourTreeMeshIn, contourTreeMeshOut);
|
||||
|
||||
// Compute the origin and size of the new block
|
||||
vtkm::Id3 globalSize = block->GlobalSize;
|
||||
vtkm::Id3 currBlockOrigin;
|
||||
currBlockOrigin[0] = std::min(recvblock.BlockOrigin[0], block->BlockOrigin[0]);
|
||||
currBlockOrigin[1] = std::min(recvblock.BlockOrigin[1], block->BlockOrigin[1]);
|
||||
currBlockOrigin[2] = std::min(recvblock.BlockOrigin[2], block->BlockOrigin[2]);
|
||||
vtkm::Id3 currBlockMaxIndex; // Needed only to compute the block size
|
||||
currBlockMaxIndex[0] = std::max(recvblock.BlockOrigin[0] + recvblock.BlockSize[0],
|
||||
block->BlockOrigin[0] + block->BlockSize[0]);
|
||||
currBlockMaxIndex[1] = std::max(recvblock.BlockOrigin[1] + recvblock.BlockSize[1],
|
||||
block->BlockOrigin[1] + block->BlockSize[1]);
|
||||
currBlockMaxIndex[2] = std::max(recvblock.BlockOrigin[2] + recvblock.BlockSize[2],
|
||||
block->BlockOrigin[2] + block->BlockSize[2]);
|
||||
vtkm::Id3 currBlockSize;
|
||||
currBlockSize[0] = currBlockMaxIndex[0] - currBlockOrigin[0];
|
||||
currBlockSize[1] = currBlockMaxIndex[1] - currBlockOrigin[1];
|
||||
currBlockSize[2] = currBlockMaxIndex[2] - currBlockOrigin[2];
|
||||
|
||||
// On rank 0 we compute the contour tree at the end when the merge is done, so we don't need to do it here
|
||||
if (selfid == 0)
|
||||
{
|
||||
// Save the data from our block for the next iteration
|
||||
block->NumVertices = contourTreeMeshOut.NumVertices;
|
||||
block->SortOrder = contourTreeMeshOut.SortOrder;
|
||||
block->SortedValue = contourTreeMeshOut.SortedValues;
|
||||
block->GlobalMeshIndex = contourTreeMeshOut.GlobalMeshIndex;
|
||||
block->Neighbours = contourTreeMeshOut.Neighbours;
|
||||
block->FirstNeighbour = contourTreeMeshOut.FirstNeighbour;
|
||||
block->MaxNeighbours = contourTreeMeshOut.MaxNeighbours;
|
||||
block->BlockOrigin = currBlockOrigin;
|
||||
block->BlockSize = currBlockSize;
|
||||
block->GlobalSize = globalSize;
|
||||
}
|
||||
else // If we are a block that will continue to be merged then we need compute the contour tree here
|
||||
{
|
||||
// Compute the contour tree from our merged mesh
|
||||
vtkm::Id currNumIterations;
|
||||
vtkm::worklet::contourtree_augmented::ContourTree currContourTree;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType currSortOrder;
|
||||
vtkm::worklet::ContourTreeAugmented worklet;
|
||||
vtkm::cont::ArrayHandle<FieldType> currField;
|
||||
vtkm::Id3 maxIdx(currBlockOrigin[0] + currBlockSize[0] - 1,
|
||||
currBlockOrigin[1] + currBlockSize[1] - 1,
|
||||
currBlockOrigin[2] + currBlockSize[2] - 1);
|
||||
auto meshBoundaryExecObj =
|
||||
contourTreeMeshOut.GetMeshBoundaryExecutionObject(globalSize[0], // totalNRows
|
||||
globalSize[1], // totalNCols
|
||||
currBlockOrigin, // minIdx
|
||||
maxIdx // maxIdx
|
||||
);
|
||||
worklet.Run(
|
||||
contourTreeMeshOut.SortedValues, // Unused param. Provide something to keep the API happy
|
||||
contourTreeMeshOut,
|
||||
currContourTree,
|
||||
currSortOrder,
|
||||
currNumIterations,
|
||||
block->ComputeRegularStructure,
|
||||
meshBoundaryExecObj);
|
||||
vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>* newContourTreeMesh = 0;
|
||||
if (block->ComputeRegularStructure == 1)
|
||||
{
|
||||
// If we have the fully augmented contour tree
|
||||
newContourTreeMesh = new vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>(
|
||||
currContourTree.Arcs, contourTreeMeshOut);
|
||||
}
|
||||
else if (block->ComputeRegularStructure == 2)
|
||||
{
|
||||
// If we have the partially augmented (e.g., boundary augmented) contour tree
|
||||
newContourTreeMesh = new vtkm::worklet::contourtree_augmented::ContourTreeMesh<FieldType>(
|
||||
currContourTree.Augmentnodes, currContourTree.Augmentarcs, contourTreeMeshOut);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We should not be able to get here
|
||||
throw vtkm::cont::ErrorFilterExecution(
|
||||
"Parallel contour tree requires at least parial boundary augmentation");
|
||||
}
|
||||
|
||||
// Copy the data from newContourTreeMesh into block
|
||||
block->NumVertices = newContourTreeMesh->NumVertices;
|
||||
block->SortOrder = newContourTreeMesh->SortOrder;
|
||||
block->SortedValue = newContourTreeMesh->SortedValues;
|
||||
block->GlobalMeshIndex = newContourTreeMesh->GlobalMeshIndex;
|
||||
block->Neighbours = newContourTreeMesh->Neighbours;
|
||||
block->FirstNeighbour = newContourTreeMesh->FirstNeighbour;
|
||||
block->MaxNeighbours = newContourTreeMesh->MaxNeighbours;
|
||||
block->BlockOrigin = currBlockOrigin;
|
||||
block->BlockSize = currBlockSize;
|
||||
block->GlobalSize = globalSize;
|
||||
|
||||
// VTKm keeps track of the arrays for us, so we can savely delete the ContourTreeMesh
|
||||
// as all data has been transferred into our data block
|
||||
delete newContourTreeMesh;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Send our current block (which is either our original block or the one we just combined from the ones we received) to our next neighbour.
|
||||
// Once a rank has send his block (either in its orignal or merged form) it is done with the reduce
|
||||
for (int cc = 0; cc < rp.out_link().size(); ++cc)
|
||||
{
|
||||
auto target = rp.out_link().target(cc);
|
||||
if (target.gid != selfid)
|
||||
{
|
||||
rp.enqueue(target, *block);
|
||||
}
|
||||
}
|
||||
} //end MergeBlockFunctor
|
||||
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
@ -0,0 +1,218 @@
|
||||
//============================================================================
|
||||
// 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_multiblockcontourtreehelper_h
|
||||
#define vtk_m_worklet_contourtree_distributed_multiblockcontourtreehelper_h
|
||||
|
||||
#include <vtkm/worklet/contourtree_distributed/SpatialDecomposition.h>
|
||||
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem_meshtypes/ContourTreeMesh.h>
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/cont/BoundsCompute.h>
|
||||
#include <vtkm/cont/BoundsGlobalCompute.h>
|
||||
//#include <vtkm/cont/AssignerPartitionedDataSet.h>
|
||||
#include <vtkm/cont/ErrorFilterExecution.h>
|
||||
#include <vtkm/cont/PartitionedDataSet.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/mesh_dem/IdRelabeler.h>
|
||||
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
|
||||
//--- Helper class to help with the contstuction of the GlobalContourTree
|
||||
class MultiBlockContourTreeHelper
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
MultiBlockContourTreeHelper(vtkm::Id3 blocksPerDim,
|
||||
vtkm::Id3 globalSize,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockOrigins,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockSizes)
|
||||
: MultiBlockSpatialDecomposition(blocksPerDim,
|
||||
globalSize,
|
||||
localBlockIndices,
|
||||
localBlockOrigins,
|
||||
localBlockSizes)
|
||||
{
|
||||
vtkm::Id localNumBlocks = this->GetLocalNumberOfBlocks();
|
||||
LocalContourTrees.resize(static_cast<std::size_t>(localNumBlocks));
|
||||
LocalSortOrders.resize(static_cast<std::size_t>(localNumBlocks));
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
~MultiBlockContourTreeHelper(void)
|
||||
{
|
||||
LocalContourTrees.clear();
|
||||
LocalSortOrders.clear();
|
||||
}
|
||||
|
||||
inline static vtkm::Bounds GetGlobalBounds(const vtkm::cont::PartitionedDataSet& input)
|
||||
{
|
||||
// Get the spatial bounds of a multi -block data set
|
||||
vtkm::Bounds bounds = vtkm::cont::BoundsGlobalCompute(input);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
inline static vtkm::Bounds GetLocalBounds(const vtkm::cont::PartitionedDataSet& input)
|
||||
{
|
||||
// Get the spatial bounds of a multi -block data set
|
||||
vtkm::Bounds bounds = vtkm::cont::BoundsCompute(input);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
inline vtkm::Id GetLocalNumberOfBlocks() const
|
||||
{
|
||||
return this->MultiBlockSpatialDecomposition.GetLocalNumberOfBlocks();
|
||||
}
|
||||
|
||||
inline vtkm::Id GetGlobalNumberOfBlocks() const
|
||||
{
|
||||
return this->MultiBlockSpatialDecomposition.GetGlobalNumberOfBlocks();
|
||||
}
|
||||
|
||||
inline static vtkm::Id GetGlobalNumberOfBlocks(const vtkm::cont::PartitionedDataSet& input)
|
||||
{
|
||||
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
|
||||
vtkm::Id localSize = input.GetNumberOfPartitions();
|
||||
vtkm::Id globalSize = 0;
|
||||
#ifdef VTKM_ENABLE_MPI
|
||||
vtkmdiy::mpi::all_reduce(comm, localSize, globalSize, std::plus<vtkm::Id>{});
|
||||
#else
|
||||
globalSize = localSize;
|
||||
#endif
|
||||
return globalSize;
|
||||
}
|
||||
|
||||
// Used to compute the local contour tree mesh in after DoExecute. I.e., the function is
|
||||
// used in PostExecute to construct the initial set of local ContourTreeMesh blocks for
|
||||
// DIY. Subsequent construction of updated ContourTreeMeshes is handled separately.
|
||||
template <typename T>
|
||||
inline static vtkm::worklet::contourtree_augmented::ContourTreeMesh<T>*
|
||||
ComputeLocalContourTreeMesh(const vtkm::Id3 localBlockOrigin,
|
||||
const vtkm::Id3 localBlockSize,
|
||||
const vtkm::Id3 globalSize,
|
||||
const vtkm::cont::ArrayHandle<T>& field,
|
||||
const vtkm::worklet::contourtree_augmented::ContourTree& contourTree,
|
||||
const vtkm::worklet::contourtree_augmented::IdArrayType& sortOrder,
|
||||
unsigned int computeRegularStructure)
|
||||
|
||||
{
|
||||
vtkm::Id startRow = localBlockOrigin[0];
|
||||
vtkm::Id startCol = localBlockOrigin[1];
|
||||
vtkm::Id startSlice = localBlockOrigin[2];
|
||||
vtkm::Id numRows = localBlockSize[0];
|
||||
vtkm::Id numCols = localBlockSize[1];
|
||||
vtkm::Id totalNumRows = globalSize[0];
|
||||
vtkm::Id totalNumCols = globalSize[1];
|
||||
// compute the global mesh index and initalize the local contour tree mesh
|
||||
if (computeRegularStructure == 1)
|
||||
{
|
||||
// Compute the global mesh index
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType localGlobalMeshIndex;
|
||||
auto transformedIndex = vtkm::cont::ArrayHandleTransform<
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType,
|
||||
vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler>(
|
||||
sortOrder,
|
||||
vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler(
|
||||
startRow, startCol, startSlice, numRows, numCols, totalNumRows, totalNumCols));
|
||||
vtkm::cont::Algorithm::Copy(transformedIndex, localGlobalMeshIndex);
|
||||
// Compute the local contour tree mesh
|
||||
auto localContourTreeMesh = new vtkm::worklet::contourtree_augmented::ContourTreeMesh<T>(
|
||||
contourTree.Arcs, sortOrder, field, localGlobalMeshIndex);
|
||||
return localContourTreeMesh;
|
||||
}
|
||||
else if (computeRegularStructure == 2)
|
||||
{
|
||||
// Compute the global mesh index for the partially augmented contour tree. I.e., here we
|
||||
// don't need the global mesh index for all nodes, but only for the augmented nodes from the
|
||||
// tree. We, hence, permute the sortOrder by contourTree.augmentednodes and then compute the
|
||||
// GlobalMeshIndex by tranforming those indices with our IdRelabler
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType localGlobalMeshIndex;
|
||||
vtkm::cont::ArrayHandlePermutation<vtkm::worklet::contourtree_augmented::IdArrayType,
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType>
|
||||
permutedSortOrder(contourTree.Augmentnodes, sortOrder);
|
||||
auto transformedIndex = vtkm::cont::make_ArrayHandleTransform(
|
||||
permutedSortOrder,
|
||||
vtkm::worklet::contourtree_augmented::mesh_dem::IdRelabeler(
|
||||
startRow, startCol, startSlice, numRows, numCols, totalNumRows, totalNumCols));
|
||||
vtkm::cont::Algorithm::Copy(transformedIndex, localGlobalMeshIndex);
|
||||
// Compute the local contour tree mesh
|
||||
auto localContourTreeMesh = new vtkm::worklet::contourtree_augmented::ContourTreeMesh<T>(
|
||||
contourTree.Augmentnodes, contourTree.Augmentarcs, sortOrder, field, localGlobalMeshIndex);
|
||||
return localContourTreeMesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We should not be able to get here
|
||||
throw vtkm::cont::ErrorFilterExecution(
|
||||
"Parallel contour tree requires at least parial boundary augmentation");
|
||||
}
|
||||
}
|
||||
|
||||
SpatialDecomposition MultiBlockSpatialDecomposition;
|
||||
std::vector<vtkm::worklet::contourtree_augmented::ContourTree> LocalContourTrees;
|
||||
std::vector<vtkm::worklet::contourtree_augmented::IdArrayType> LocalSortOrders;
|
||||
|
||||
}; // end MultiBlockContourTreeHelper
|
||||
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
139
vtkm/worklet/contourtree_distributed/SpatialDecomposition.h
Normal file
139
vtkm/worklet/contourtree_distributed/SpatialDecomposition.h
Normal file
@ -0,0 +1,139 @@
|
||||
//============================================================================
|
||||
// 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_spatialdecomposition_h
|
||||
#define vtk_m_worklet_contourtree_distributed_spatialdecomposition_h
|
||||
|
||||
#include <vtkm/Types.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
// clang-format off
|
||||
VTKM_THIRDPARTY_PRE_INCLUDE
|
||||
#include <vtkm/thirdparty/diy/diy.h>
|
||||
VTKM_THIRDPARTY_POST_INCLUDE
|
||||
// clang-format on
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
|
||||
// --- Helper class to store the spatial decomposition defined by the PartitionedDataSet input data
|
||||
class SpatialDecomposition
|
||||
{
|
||||
public:
|
||||
VTKM_CONT
|
||||
SpatialDecomposition(vtkm::Id3 blocksPerDim,
|
||||
vtkm::Id3 globalSize,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockIndices,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockOrigins,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Id3>& localBlockSizes)
|
||||
: BlocksPerDimension(blocksPerDim)
|
||||
, GlobalSize(globalSize)
|
||||
, LocalBlockIndices(localBlockIndices)
|
||||
, LocalBlockOrigins(localBlockOrigins)
|
||||
, LocalBlockSizes(localBlockSizes)
|
||||
{
|
||||
}
|
||||
|
||||
inline vtkmdiy::DiscreteBounds GetVTKmDIYBounds() const
|
||||
{
|
||||
if (this->NumberOfDimensions() == 2)
|
||||
{
|
||||
// may need to change back when porting ot later verison of VTKM/vtkmdiy
|
||||
vtkmdiy::DiscreteBounds domain(0); //(2);
|
||||
domain.min[0] = domain.min[1] = 0;
|
||||
domain.max[0] = static_cast<int>(this->GlobalSize[0]);
|
||||
domain.max[1] = static_cast<int>(this->GlobalSize[1]);
|
||||
return domain;
|
||||
}
|
||||
else
|
||||
{
|
||||
// may need to change back when porting to later version of VTMK/vtkmdiy
|
||||
vtkmdiy::DiscreteBounds domain(0); //(3);
|
||||
domain.min[0] = domain.min[1] = domain.min[2] = 0;
|
||||
domain.max[0] = static_cast<int>(this->GlobalSize[0]);
|
||||
domain.max[1] = static_cast<int>(this->GlobalSize[1]);
|
||||
domain.max[2] = static_cast<int>(this->GlobalSize[2]);
|
||||
return domain;
|
||||
}
|
||||
}
|
||||
|
||||
inline vtkm::Id NumberOfDimensions() const { return GlobalSize[2] > 1 ? 3 : 2; }
|
||||
|
||||
inline vtkm::Id GetGlobalNumberOfBlocks() const
|
||||
{
|
||||
return BlocksPerDimension[0] * BlocksPerDimension[1] * BlocksPerDimension[2];
|
||||
}
|
||||
|
||||
inline vtkm::Id GetLocalNumberOfBlocks() const { return LocalBlockSizes.GetNumberOfValues(); }
|
||||
|
||||
// Number of blocks along each dimension
|
||||
vtkm::Id3 BlocksPerDimension;
|
||||
// Size of the global mesh
|
||||
vtkm::Id3 GlobalSize;
|
||||
// Index of the local blocks in x,y,z, i.e., in i,j,k mesh coordinates
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> LocalBlockIndices;
|
||||
// Origin of the local blocks in mesh index space
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> LocalBlockOrigins;
|
||||
// Size of each local block in x, y,z
|
||||
vtkm::cont::ArrayHandle<vtkm::Id3> LocalBlockSizes;
|
||||
};
|
||||
|
||||
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
121
vtkm/worklet/contourtree_distributed/bract_maker/AddTerminalFlagsToUpDownNeighboursWorklet.h
Normal file
121
vtkm/worklet/contourtree_distributed/bract_maker/AddTerminalFlagsToUpDownNeighboursWorklet.h
Normal file
@ -0,0 +1,121 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_add_terminal_flags_to_up_down_neighbours_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_add_terminal_flags_to_up_down_neighbours_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Step 1 of IdentifyRegularisedSupernodes
|
||||
class AddTerminalFlagsToUpDownNeighboursWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn newVertexId, // input
|
||||
WholeArrayOut upNeighbour, // output
|
||||
WholeArrayOut downNeighbour // output
|
||||
);
|
||||
using ExecutionSignature = void(InputIndex, _1, _2, _3);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
AddTerminalFlagsToUpDownNeighboursWorklet() {}
|
||||
|
||||
template <typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& returnIndex,
|
||||
const vtkm::Id& newVertexIdValue,
|
||||
const OutFieldPortalType& upNeighbourPortal,
|
||||
const OutFieldPortalType& downNeighbourPortal)
|
||||
{
|
||||
// per vertex
|
||||
// necessary vertices
|
||||
if (!vtkm::worklet::contourtree_augmented::NoSuchElement(newVertexIdValue))
|
||||
{ // necessary vertex
|
||||
// set both up & down neighbours to self with terminal element set
|
||||
upNeighbourPortal.Set(returnIndex,
|
||||
returnIndex | vtkm::worklet::contourtree_augmented::TERMINAL_ELEMENT);
|
||||
downNeighbourPortal.Set(returnIndex,
|
||||
returnIndex | vtkm::worklet::contourtree_augmented::TERMINAL_ELEMENT);
|
||||
} // necessary vertex
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType returnIndex = 0; returnIndex < bractVertexSuperset.size(); returnIndex++)
|
||||
{ // per vertex
|
||||
// necessary vertices
|
||||
if (!noSuchElement(newVertexID[returnIndex]))
|
||||
{ // necessary vertex
|
||||
// set both up & down neighbours to self with terminal element set
|
||||
upNeighbour[returnIndex] = downNeighbour[returnIndex] = returnIndex | TERMINAL_ELEMENT;
|
||||
} // necessary vertex
|
||||
} // per vertex
|
||||
*/
|
||||
}
|
||||
}; // AddTerminalFlagsToUpDownNeighboursWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
@ -0,0 +1,99 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_array_sum_functor_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_array_sum_functor_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
//Simple functor to implement a fancy array handle that returns the sum of two arrays
|
||||
class ArraySumFunctor
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT
|
||||
ArraySumFunctor() {}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
ArraySumFunctor(const vtkm::worklet::contourtree_augmented::IdArrayType& first,
|
||||
const vtkm::worklet::contourtree_augmented::IdArrayType& second)
|
||||
: First(first)
|
||||
, Second(second)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id operator()(const vtkm::Id index) const
|
||||
{
|
||||
return First.ReadPortal().Get(index) + Second.ReadPortal().Get(index);
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType First;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType Second;
|
||||
};
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
137
vtkm/worklet/contourtree_distributed/bract_maker/AugmentBoundaryWithNecessaryInteriorSupernodesAppendNecessarySupernodesWorklet.h
Normal file
137
vtkm/worklet/contourtree_distributed/bract_maker/AugmentBoundaryWithNecessaryInteriorSupernodesAppendNecessarySupernodesWorklet.h
Normal file
@ -0,0 +1,137 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_augment_boundary_with_necessary_interior_supernodes_append_necessary_supernodes_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_augment_boundary_with_necessary_interior_supernodes_append_necessary_supernodes_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Worklet to transfer the dependent counts for hyperarcs
|
||||
/// Part of the BoundaryRestrictedAugmentedContourTree.PropagateBoundaryCounts function
|
||||
class AugmentBoundaryWithNecessaryInteriorSupernodesAppendNecessarySupernodesWorklet
|
||||
: public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn supernodes, // input
|
||||
FieldIn isNecessaryAndInterior, // input
|
||||
FieldIn boundaryNecessaryId, // input
|
||||
WholeArrayIn meshSortOrder, // input
|
||||
WholeArrayOut boundaryIndices, //output
|
||||
WholeArrayOut bractVertexSuperset // output
|
||||
);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
AugmentBoundaryWithNecessaryInteriorSupernodesAppendNecessarySupernodesWorklet(
|
||||
vtkm::Id numBoundary)
|
||||
: NumBoundary(numBoundary)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename InFieldPortalType, typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& supernode,
|
||||
const bool& isNecessaryAndInterior,
|
||||
const vtkm::Id boundaryNecessaryId,
|
||||
const InFieldPortalType meshSortOrderPortal,
|
||||
const OutFieldPortalType& boundaryIndicesPortal,
|
||||
const OutFieldPortalType& bractVertexSupersetPortal)
|
||||
{
|
||||
// per supernode
|
||||
if (isNecessaryAndInterior)
|
||||
{ // if necessary
|
||||
vtkm::Id sortIndex = vtkm::worklet::contourtree_augmented::MaskedIndex(supernode);
|
||||
// add to last index in old boundary to find where to put it
|
||||
vtkm::Id wherePut = this->NumBoundary - 1 + boundaryNecessaryId;
|
||||
boundaryIndicesPortal.Set(wherePut, sortIndex);
|
||||
bractVertexSupersetPortal.Set(wherePut, meshSortOrderPortal.Get(sortIndex));
|
||||
} // if necessary
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType supernode = 0; supernode < contourTree->supernodes.size(); supernode++)
|
||||
{ // per supernode
|
||||
if (isNecessaryAndInterior[supernode])
|
||||
{ // if necessary
|
||||
indexType sortIndex = maskedIndex(contourTree->supernodes[supernode]);
|
||||
// add to last index in old boundary to find where to put it
|
||||
indexType wherePut = nBoundary - 1 + boundaryNecessaryID[supernode];
|
||||
boundaryIndices[wherePut] = sortIndex;
|
||||
bractVertexSuperset[wherePut] = mesh->SortOrder(sortIndex);
|
||||
} // if necessary
|
||||
} // per supernode
|
||||
*/
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::Id NumBoundary;
|
||||
|
||||
}; // AugmentBoundaryWithNecessaryInteriorSupernodesAppendNecessarySupernodesWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
122
vtkm/worklet/contourtree_distributed/bract_maker/AugmentBoundaryWithNecessaryInteriorSupernodesUnsetBoundarySupernodesWorklet.h
Normal file
122
vtkm/worklet/contourtree_distributed/bract_maker/AugmentBoundaryWithNecessaryInteriorSupernodesUnsetBoundarySupernodesWorklet.h
Normal file
@ -0,0 +1,122 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_augment_boundary_with_necessary_interior_supernodes_unset_boundary_supernodes_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_augment_boundary_with_necessary_interior_supernodes_unset_boundary_supernodes_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Worklet to transfer the dependent counts for hyperarcs
|
||||
/// Part of the BoundaryRestrictedAugmentedContourTree.PropagateBoundaryCounts function
|
||||
class AugmentBoundaryWithNecessaryInteriorSupernodesUnsetBoundarySupernodesWorklet
|
||||
: public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn boundaryIndices, // input
|
||||
WholeArrayIn superparents, // input
|
||||
WholeArrayIn supernodes, // input
|
||||
WholeArrayOut isNecessaryAndInterior // output
|
||||
|
||||
|
||||
);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
AugmentBoundaryWithNecessaryInteriorSupernodesUnsetBoundarySupernodesWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType, typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& boundaryVertexSortID,
|
||||
const InFieldPortalType& superparentsPortal,
|
||||
const InFieldPortalType& supernodesPortal,
|
||||
const OutFieldPortalType& isNecessaryAndInteriorPortal)
|
||||
{
|
||||
vtkm::Id superparent = superparentsPortal.Get(boundaryVertexSortID);
|
||||
// if the superparent's supernode is the vertex, they match
|
||||
if (supernodesPortal.Get(superparent) == boundaryVertexSortID)
|
||||
{
|
||||
isNecessaryAndInteriorPortal.Set(superparent, false);
|
||||
}
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType boundaryVertex = 0; boundaryVertex < nBoundary; boundaryVertex++)
|
||||
{ // per boundary vertex
|
||||
indexType boundaryVertexMeshID = bractVertexSuperset[boundaryVertex];
|
||||
indexType boundaryVertexSortID = boundaryIndices[boundaryVertex];
|
||||
indexType superparent = contourTree->superparents[boundaryVertexSortID];
|
||||
// if the superparent's supernode is the vertex, they match
|
||||
if (contourTree->supernodes[superparent] == boundaryVertexSortID)
|
||||
isNecessaryAndInterior[superparent] = false;
|
||||
} // per boundary vertex
|
||||
*/
|
||||
}
|
||||
|
||||
}; // AugmentBoundaryWithNecessaryInteriorSupernodesUnsetBoundarySupernodesWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
@ -0,0 +1,148 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_bract_node_comparator_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_bract_node_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 bract_maker
|
||||
{
|
||||
|
||||
|
||||
// device implementation of the comparator used for sorting hyperarcs
|
||||
template <typename DeviceAdapter>
|
||||
class BRACTNodeComparatorImpl
|
||||
{
|
||||
public:
|
||||
using IdArrayPortalType =
|
||||
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<DeviceAdapter>::PortalConst;
|
||||
|
||||
// constructor - takes vectors as parameters
|
||||
VTKM_CONT
|
||||
BRACTNodeComparatorImpl(const IdArrayPortalType& regularIdPortal,
|
||||
const IdArrayPortalType& meshSortIndexPortal)
|
||||
: RegularIdPortal(regularIdPortal)
|
||||
, MeshSortIndexPortal(meshSortIndexPortal)
|
||||
{ // constructor
|
||||
} // constructor
|
||||
|
||||
// () operator - gets called to do comparison
|
||||
VTKM_EXEC
|
||||
bool operator()(const vtkm::Id& i, const vtkm::Id& j) const
|
||||
{ // operator()
|
||||
// retrieve the sort order
|
||||
vtkm::Id sortIndexI = MeshSortIndexPortal.Get(RegularIdPortal.Get(i));
|
||||
vtkm::Id sortIndexJ = MeshSortIndexPortal.Get(RegularIdPortal.Get(j));
|
||||
|
||||
// now test on that
|
||||
if (sortIndexI < sortIndexJ)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (sortIndexJ < sortIndexI)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// fallback out of paranoia
|
||||
return false;
|
||||
|
||||
} // operator()
|
||||
|
||||
private:
|
||||
IdArrayPortalType RegularIdPortal;
|
||||
IdArrayPortalType MeshSortIndexPortal;
|
||||
}; // BRACTNodeComparatorImpl
|
||||
|
||||
/// comparator used to compare hyperarcs for sort
|
||||
class BRACTNodeComparator : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
// constructor - takes vectors as parameters
|
||||
VTKM_CONT
|
||||
BRACTNodeComparator(const vtkm::worklet::contourtree_augmented::IdArrayType& regularId,
|
||||
const vtkm::worklet::contourtree_augmented::IdArrayType& meshSortIndex)
|
||||
: RegularId(regularId)
|
||||
, MeshSortIndex(meshSortIndex)
|
||||
{ // constructor
|
||||
} // constructor
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
VTKM_CONT BRACTNodeComparatorImpl<DeviceAdapter> PrepareForExecution(
|
||||
DeviceAdapter device,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
return BRACTNodeComparatorImpl<DeviceAdapter>(
|
||||
this->RegularId.PrepareForInput(device, token),
|
||||
this->MeshSortIndex.PrepareForInput(device, token));
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType RegularId;
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType MeshSortIndex;
|
||||
}; // BRACTNodeComparator
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
184
vtkm/worklet/contourtree_distributed/bract_maker/BoundaryVerticesPerSuperArcWorklets.h
Normal file
184
vtkm/worklet/contourtree_distributed/bract_maker/BoundaryVerticesPerSuperArcWorklets.h
Normal file
@ -0,0 +1,184 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_boundary_vertices_per_superarc_worklets_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_boundary_vertices_per_superarc_worklets_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
// Step 1of2 for BoundaryRestrictedAugmentedContourTreeMaker<MeshType>::ComputeDependentBoundaryCounts
|
||||
class BoundaryVerticiesPerSuperArcStepOneWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(WholeArrayIn boundarySuperparents, // (input)
|
||||
WholeArrayOut superarcIntrinsicBoundaryCount); // (output) hyperarcs
|
||||
using ExecutionSignature = void(_1, InputIndex, _2);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
BoundaryVerticiesPerSuperArcStepOneWorklet(vtkm::Id numBoundary)
|
||||
: NumBoundary(numBoundary)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename InFieldPortalType, typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const InFieldPortalType& boundarySuperparentsPortal,
|
||||
const vtkm::Id& boundaryVertex,
|
||||
const OutFieldPortalType& superarcIntrinsicBoundaryCountPortal)
|
||||
{
|
||||
if (boundaryVertex == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vtkm::Id superarcId = boundarySuperparentsPortal.Get(boundaryVertex);
|
||||
vtkm::Id prevSuperarcId = boundarySuperparentsPortal.Get(boundaryVertex - 1);
|
||||
|
||||
// i. Start by detecting the high end of the range
|
||||
// if they don't match, we're at the beginning of a segment - set the *LOWER* segment's value
|
||||
if (superarcId != prevSuperarcId)
|
||||
{
|
||||
superarcIntrinsicBoundaryCountPortal.Set(prevSuperarcId, boundaryVertex);
|
||||
}
|
||||
// ii. Now set the last one explicitly
|
||||
if (boundaryVertex == (this->NumBoundary - 1))
|
||||
{
|
||||
superarcIntrinsicBoundaryCountPortal.Set(superarcId) = this->NumBoundary;
|
||||
}
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType boundaryVertex = 1; boundaryVertex < nBoundary; boundaryVertex++)
|
||||
{ // per boundary vertex
|
||||
indexType superarcID = boundarySuperparents[boundaryVertex];
|
||||
indexType prevSuperarcID = boundarySuperparents[boundaryVertex-1];
|
||||
// if they don't match, we're at the beginning of a segment - set the *LOWER* segment's value
|
||||
if (superarcID != prevSuperarcID)
|
||||
superarcIntrinsicBoundaryCount[prevSuperarcID] = boundaryVertex;
|
||||
} // per boundary vertex
|
||||
superarcIntrinsicBoundaryCount[boundarySuperparents[nBoundary-1]] = nBoundary;
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::Id NumBoundary;
|
||||
|
||||
}; // BoundaryVerticiesPerSuperArcStepOneWorklet
|
||||
|
||||
|
||||
|
||||
// Step 1of2 for BoundaryRestrictedAugmentedContourTreeMaker<MeshType>::ComputeDependentBoundaryCounts
|
||||
class BoundaryVerticiesPerSuperArcStepTwoWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(WholeArrayIn boundarySuperparents, // (input)
|
||||
WholeArrayOut superarcIntrinsicBoundaryCount); // (output) hyperarcs
|
||||
using ExecutionSignature = void(_1, InputIndex, _2);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
BoundaryVerticiesPerSuperArcStepTwoWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType, typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const InFieldPortalType& boundarySuperparentsPortal,
|
||||
const vtkm::Id& boundaryVertex,
|
||||
const OutFieldPortalType& superarcIntrinsicBoundaryCountPortal)
|
||||
{
|
||||
if (boundaryVertex == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
vtkm::Id superarcId = boundarySuperparentsPortal.Get(boundaryVertex);
|
||||
vtkm::Id prevSuperarcId = boundarySuperparentsPortal.Get(boundaryVertex - 1);
|
||||
|
||||
// i. Start by detecting the high end of the range
|
||||
// if they don't match, we're at the beginning of a segment - set the *LOWER* segment's value
|
||||
if (superarcId != prevSuperarcId)
|
||||
{
|
||||
superarcIntrinsicBoundaryCountPortal.Set(
|
||||
superarcId, superarcIntrinsicBoundaryCountPortal.Get(superarcId) - boundaryVertex);
|
||||
}
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType boundaryVertex = 1; boundaryVertex < nBoundary; boundaryVertex++)
|
||||
{ // per boundary vertex
|
||||
indexType superarcID = boundarySuperparents[boundaryVertex];
|
||||
indexType prevSuperarcID = boundarySuperparents[boundaryVertex-1];
|
||||
// if they don't match, we're at the beginning of a segment - set the *LOWER* segment's value
|
||||
if (superarcID != prevSuperarcID)
|
||||
superarcIntrinsicBoundaryCount[superarcID] -= boundaryVertex;
|
||||
} // per boundary vertex
|
||||
|
||||
*/
|
||||
}
|
||||
}; // BoundaryVerticiesPerSuperArcStepTwoWorklet
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
@ -0,0 +1,40 @@
|
||||
##============================================================================
|
||||
## 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
|
||||
BoundaryVerticesPerSuperArcWorklets.h
|
||||
PropagateBoundaryCountsSubtractDependentCountsWorklet.h
|
||||
PropagateBoundaryCountsTransferDependentCountsWorklet.h
|
||||
PropagateBoundaryCountsTransferCumulativeCountsWorklet.h
|
||||
PropagateBoundaryCountsComputeGroupTotalsWorklet.h
|
||||
FindNecessaryInteriorSupernodesFindNodesWorklet.h
|
||||
FindNecessaryInteriorSetSuperparentNecessaryWorklet.h
|
||||
AugmentBoundaryWithNecessaryInteriorSupernodesUnsetBoundarySupernodesWorklet.h
|
||||
AugmentBoundaryWithNecessaryInteriorSupernodesAppendNecessarySupernodesWorklet.h
|
||||
FindBractSuperarcsSuperarcToWorklet.h
|
||||
SetUpAndDownNeighboursWorklet.h
|
||||
IdentifyRegularisedSupernodesStepOneWorklet.h
|
||||
IdentifyRegularisedSupernodesStepTwoWorklet.h
|
||||
AddTerminalFlagsToUpDownNeighboursWorklet.h
|
||||
PointerDoubleUpDownNeighboursWorklet.h
|
||||
CompressRegularisedNodesCopyNecessaryRegularNodesWorklet.h
|
||||
CompressRegularisedNodesFindNewSuperarcsWorklet.h
|
||||
CompressRegularisedNodesResolveRootWorklet.h
|
||||
CompressRegularisedNodesTransferVerticesWorklet.h
|
||||
CompressRegularisedNodesFillBractSuperarcsWorklet.h
|
||||
ArraySumFunctor.h
|
||||
NoSuchElementFunctor.h
|
||||
SelectRangeFunctor.h
|
||||
HyperarcComparator.h
|
||||
ContourTreeNodeHyperArcComparator.h
|
||||
BRACTNodeComparator.h
|
||||
)
|
||||
|
||||
vtkm_declare_headers(${headers})
|
102
vtkm/worklet/contourtree_distributed/bract_maker/CompressRegularisedNodesCopyNecessaryRegularNodesWorklet.h
Normal file
102
vtkm/worklet/contourtree_distributed/bract_maker/CompressRegularisedNodesCopyNecessaryRegularNodesWorklet.h
Normal file
@ -0,0 +1,102 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_compress_regularised_nodes_copy_necessary_regular_nodes_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_compress_regularised_nodes_copy_necessary_regular_nodes_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Step 1 of IdentifyRegularisedSupernodes
|
||||
class CompressRegularisedNodesCopyNecessaryRegularNodesWorklet
|
||||
: public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldInOut newVertexId, // Input/Output
|
||||
FieldIn keptInBract // input
|
||||
);
|
||||
using ExecutionSignature = void(_1, _2);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
CompressRegularisedNodesCopyNecessaryRegularNodesWorklet() {}
|
||||
|
||||
VTKM_EXEC vtkm::Id operator()(const vtkm::Id& newVertexIdIn, const vtkm::Id& keptInBract)
|
||||
{
|
||||
return (!vtkm::worklet::contourtree_augmented::NoSuchElement(newVertexIdIn)) ? (keptInBract - 1)
|
||||
: newVertexIdIn;
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType returnIndex = 0; returnIndex < bractVertexSuperset.size(); returnIndex++)
|
||||
if (!noSuchElement(newVertexID[returnIndex]))
|
||||
newVertexID[returnIndex] = keptInBract[returnIndex]-1;
|
||||
*/
|
||||
}
|
||||
}; // CompressRegularisedNodesCopyNecessaryRegularNodesWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
119
vtkm/worklet/contourtree_distributed/bract_maker/CompressRegularisedNodesFillBractSuperarcsWorklet.h
Normal file
119
vtkm/worklet/contourtree_distributed/bract_maker/CompressRegularisedNodesFillBractSuperarcsWorklet.h
Normal file
@ -0,0 +1,119 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_compress_regularised_nodes_fill_bract_superarcs_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_compress_regularised_nodes_fill_bract_superarcs_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Step 1 of IdentifyRegularisedSupernodes
|
||||
class CompressRegularisedNodesFillBractSuperarcsWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(WholeArrayIn newSuperarc,
|
||||
WholeArrayIn reverseSorter,
|
||||
FieldIn vertexSorter,
|
||||
FieldOut bractSuperarcs);
|
||||
using ExecutionSignature = void(_1, _2, _3);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
CompressRegularisedNodesFillBractSuperarcsWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType>
|
||||
VTKM_EXEC vtkm::Id operator()(const InFieldPortalType newSuperarcPortal,
|
||||
const InFieldPortalType reverseSorterPortal,
|
||||
const vtkm::Id& vertexSorterIndex)
|
||||
{
|
||||
vtkm::Id newSuperarcIndex = newSuperarcPortal.Get(vertexSorterIndex);
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(newSuperarcIndex))
|
||||
{
|
||||
return vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return reverseSorterPortal.Get(newSuperarcIndex);
|
||||
}
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType bractID = 0; bractID < newSuperarc.size(); bractID++)
|
||||
{ // per bract node
|
||||
// do the same for the superarc, testing for NO_SUCH_ELEMENT
|
||||
if (noSuchElement(newSuperarc[vertexSorter[bractID]]))
|
||||
bract->superarcs[bractID] = NO_SUCH_ELEMENT;
|
||||
else
|
||||
bract->superarcs[bractID] = reverseSorter[newSuperarc[vertexSorter[bractID]]];
|
||||
} // per bract node
|
||||
|
||||
*/
|
||||
}
|
||||
}; // CompressRegularisedNodesFillBractSuperarcsWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
186
vtkm/worklet/contourtree_distributed/bract_maker/CompressRegularisedNodesFindNewSuperarcsWorklet.h
Normal file
186
vtkm/worklet/contourtree_distributed/bract_maker/CompressRegularisedNodesFindNewSuperarcsWorklet.h
Normal file
@ -0,0 +1,186 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_compress_regularised_nodes_find_new_superarcs_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_compress_regularised_nodes_find_new_superarcs_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Step 1 of IdentifyRegularisedSupernodes
|
||||
class CompressRegularisedNodesFindNewSuperarcsWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(WholeArrayIn newVertexId, // Input
|
||||
FieldIn bractSuperarcs, // input
|
||||
WholeArrayIn upNeighbour, //input
|
||||
WholeArrayIn downNeighbour,
|
||||
WholeArrayOut newSuperarc // output
|
||||
);
|
||||
using ExecutionSignature = void(InputIndex, _1, _2, _3, _4, _5);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
CompressRegularisedNodesFindNewSuperarcsWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType, typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& returnIndex,
|
||||
const InFieldPortalType& newVertexIdPortal,
|
||||
const vtkm::Id& bractSuperarcIdIn,
|
||||
const InFieldPortalType& downNeighbourPortal,
|
||||
const InFieldPortalType& upNeighbourPortal,
|
||||
const OutFieldPortalType& newSuperarcPortal)
|
||||
{
|
||||
// per vertex
|
||||
// skip all unnecessary vertices
|
||||
vtkm::Id newVertexIdIn = newVertexIdPortal.Get(returnIndex);
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(newVertexIdIn))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// retrieve the new ID
|
||||
vtkm::Id newId = newVertexIdIn;
|
||||
|
||||
// for necessary vertices, look at the superarc
|
||||
vtkm::Id oldInbound = bractSuperarcIdIn;
|
||||
|
||||
// i. points to nothing - copy it
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement((oldInbound)))
|
||||
{
|
||||
newSuperarcPortal.Set(newId, (vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT));
|
||||
}
|
||||
// ii. points to a necessary vertex - copy it
|
||||
else if (!vtkm::worklet::contourtree_augmented::NoSuchElement(
|
||||
newVertexIdPortal.Get(oldInbound)))
|
||||
{
|
||||
newSuperarcPortal.Set(newId, newVertexIdPortal.Get(oldInbound));
|
||||
}
|
||||
// iii. points to an unnecessary vertex
|
||||
else
|
||||
{ // points to an unnecessary vertex
|
||||
// check the old up neighbour
|
||||
vtkm::Id upNbr =
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(upNeighbourPortal.Get(oldInbound));
|
||||
vtkm::Id downNbr =
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(downNeighbourPortal.Get(oldInbound));
|
||||
|
||||
// if it's us, we've got a downwards inbound arc
|
||||
// and the down neighbour holds the right new superarc
|
||||
if (upNbr == returnIndex)
|
||||
{
|
||||
newSuperarcPortal.Set(newId, newVertexIdPortal.Get(downNbr));
|
||||
}
|
||||
// otherwise the up neighbour does
|
||||
else
|
||||
{
|
||||
newSuperarcPortal.Set(newId, newVertexIdPortal.Get(upNbr));
|
||||
}
|
||||
} // points to an unnecessary vertex
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType returnIndex = 0; returnIndex < bractVertexSuperset.size(); returnIndex++)
|
||||
{ // per vertex
|
||||
// skip all unnecessary vertices
|
||||
if (noSuchElement(newVertexID[returnIndex]))
|
||||
continue;
|
||||
|
||||
// retrieve the new ID
|
||||
indexType newID = newVertexID[returnIndex];
|
||||
|
||||
// for necessary vertices, look at the superarc
|
||||
indexType oldInbound = bract->superarcs[returnIndex];
|
||||
|
||||
// i. points to nothing - copy it
|
||||
if (noSuchElement(oldInbound))
|
||||
newSuperarc[newID] = NO_SUCH_ELEMENT;
|
||||
// ii. points to a necessary vertex - copy it
|
||||
else if (!noSuchElement(newVertexID[oldInbound]))
|
||||
newSuperarc[newID] = newVertexID[oldInbound];
|
||||
// iii. points to an unnecessary vertex
|
||||
else
|
||||
{ // points to an unnecessary vertex
|
||||
// check the old up neighbour
|
||||
indexType upNbr = maskedIndex(upNeighbour[oldInbound]);
|
||||
indexType downNbr = maskedIndex(downNeighbour[oldInbound]);
|
||||
|
||||
// if it's us, we've got a downwards inbound arc
|
||||
// and the down neighbour holds the right new superarc
|
||||
if (upNbr == returnIndex)
|
||||
newSuperarc[newID] = newVertexID[downNbr];
|
||||
// otherwise the up neighbour does
|
||||
else
|
||||
newSuperarc[newID] = newVertexID[upNbr];
|
||||
} // points to an unnecessary vertex
|
||||
} // per vertex
|
||||
*/
|
||||
}
|
||||
}; // CompressRegularisedNodesFindNewSuperarcsWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
136
vtkm/worklet/contourtree_distributed/bract_maker/CompressRegularisedNodesResolveRootWorklet.h
Normal file
136
vtkm/worklet/contourtree_distributed/bract_maker/CompressRegularisedNodesResolveRootWorklet.h
Normal file
@ -0,0 +1,136 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_compress_regularised_nodes_resolve_root_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_compress_regularised_nodes_resolve_root_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Step 1 of IdentifyRegularisedSupernodes
|
||||
class CompressRegularisedNodesResolveRootWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn newIndex, // input
|
||||
WholeArrayInOut newSuperarc // input/output
|
||||
);
|
||||
using ExecutionSignature = void(_1, _2);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
CompressRegularisedNodesResolveRootWorklet() {}
|
||||
|
||||
template <typename InOutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& newIndex, const InOutFieldPortalType& newSuperarcPortal)
|
||||
{
|
||||
// per kept vertex
|
||||
// retrieve it to register
|
||||
vtkm::Id newInbound = newSuperarcPortal.Get(newIndex);
|
||||
|
||||
// if it doesn't exist, do nothing
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(newInbound))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if there is no loopback, do nothing
|
||||
if (newSuperarcPortal.Get(newInbound) != newIndex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// if there is loopback and we're the lower one, substitute NULL
|
||||
if (newIndex < newInbound)
|
||||
{
|
||||
newSuperarcPortal.Set(newIndex, vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT);
|
||||
}
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType newIndex = 0; newIndex < nKept; newIndex++)
|
||||
{ // per kept vertex
|
||||
// retrieve it to register
|
||||
indexType newInbound = newSuperarc[newIndex];
|
||||
|
||||
// if it doesn't exist, do nothing
|
||||
if (noSuchElement(newInbound))
|
||||
continue;
|
||||
|
||||
// if there is no loopback, do nothing
|
||||
if (newSuperarc[newInbound] != newIndex)
|
||||
continue;
|
||||
|
||||
// if there is loopback and we're the lower one, substitute NULL
|
||||
if (newIndex < newInbound)
|
||||
newSuperarc[newIndex] = NO_SUCH_ELEMENT;
|
||||
} // per kept vertex
|
||||
*/
|
||||
}
|
||||
}; // CompressRegularisedNodesResolveRootWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
103
vtkm/worklet/contourtree_distributed/bract_maker/CompressRegularisedNodesTransferVerticesWorklet.h
Normal file
103
vtkm/worklet/contourtree_distributed/bract_maker/CompressRegularisedNodesTransferVerticesWorklet.h
Normal file
@ -0,0 +1,103 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_compress_regularised_nodes_transfer_vertices_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_compress_regularised_nodes_transfer_vertices_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Step 1 of IdentifyRegularisedSupernodes
|
||||
class CompressRegularisedNodesTransferVerticesWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn bractVertexSuperset, // input
|
||||
FieldIn newVertexId, // input
|
||||
FieldOut newVertexIndex);
|
||||
using ExecutionSignature = void(_1, _2);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
CompressRegularisedNodesTransferVerticesWorklet() {}
|
||||
|
||||
VTKM_EXEC vtkm::Id operator()(const vtkm::Id& bractVertexSupersetIndex,
|
||||
const vtkm::Id& newVertexIdIn)
|
||||
{
|
||||
return (!vtkm::worklet::contourtree_augmented::NoSuchElement(newVertexIdIn))
|
||||
? bractVertexSupersetIndex
|
||||
: 0;
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType returnIndex = 0; returnIndex < bractVertexSuperset.size(); returnIndex++)
|
||||
if (!noSuchElement(newVertexID[returnIndex]))
|
||||
newVertexIndex[newVertexID[returnIndex]] = bractVertexSuperset[returnIndex];
|
||||
*/
|
||||
}
|
||||
}; // CompressRegularisedNodesTransferVerticesWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
166
vtkm/worklet/contourtree_distributed/bract_maker/ContourTreeNodeHyperArcComparator.h
Normal file
166
vtkm/worklet/contourtree_distributed/bract_maker/ContourTreeNodeHyperArcComparator.h
Normal file
@ -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.
|
||||
//
|
||||
//=============================================================================
|
||||
//
|
||||
// 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_bract_maker_contourtree_node_hyperarc_comperator_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_contourtree_node_hyperarc_comperator_h
|
||||
|
||||
#include <vtkm/cont/ArrayHandle.h>
|
||||
#include <vtkm/cont/ExecutionObjectBase.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace ctaug = vtkm::worklet::contourtree_augmented;
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
|
||||
// device implementation of the ContourTreeNodeHyperArcComparator
|
||||
template <typename DeviceAdapter>
|
||||
class ContourTreeNodeHyperArcComparatorImpl
|
||||
{
|
||||
public:
|
||||
using IdArrayPortalType =
|
||||
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<DeviceAdapter>::PortalConst;
|
||||
|
||||
// constructor - takes vectors as parameters
|
||||
VTKM_CONT
|
||||
ContourTreeNodeHyperArcComparatorImpl(const IdArrayPortalType& superarcsPortal,
|
||||
const IdArrayPortalType& superparentsPortal)
|
||||
: SuperarcsPortal(superarcsPortal)
|
||||
, SuperparentsPortal(superparentsPortal)
|
||||
{ // constructor
|
||||
} // constructor
|
||||
|
||||
// () operator - gets called to do comparison
|
||||
VTKM_EXEC
|
||||
bool operator()(const vtkm::Id& i, const vtkm::Id& j) const
|
||||
{ // operator()
|
||||
// retrieve the left & right superparents
|
||||
vtkm::Id leftSuperparent = this->SuperparentsPortal.Get(ctaug::MaskedIndex(i));
|
||||
vtkm::Id rightSuperparent = this->SuperparentsPortal.Get(ctaug::MaskedIndex(j));
|
||||
// compare the superparents
|
||||
if (ctaug::MaskedIndex(leftSuperparent) < ctaug::MaskedIndex(rightSuperparent))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (ctaug::MaskedIndex(leftSuperparent) > ctaug::MaskedIndex(rightSuperparent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// parents are equal, so retrieve superarc for ascending flag & compare indices
|
||||
// TODO We masked the leftSuperparent here. Check if we need to do this or not
|
||||
bool ascentFlag =
|
||||
ctaug::IsAscending(this->SuperarcsPortal.Get(ctaug::MaskedIndex(leftSuperparent)));
|
||||
|
||||
// compare the sort indices, flipping based on ascending index from superparent
|
||||
if (i < j)
|
||||
{
|
||||
return ascentFlag;
|
||||
}
|
||||
else if (i > j)
|
||||
{
|
||||
return !ascentFlag;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} // operator()
|
||||
|
||||
private:
|
||||
IdArrayPortalType SuperarcsPortal;
|
||||
IdArrayPortalType SuperparentsPortal;
|
||||
}; // ContourTreeNodeHyperArcComparatorImpl
|
||||
|
||||
/// comparator to use for sorting nodes by hyperparent (i.e. amalgamates augmentation & sorting)
|
||||
/// for this one, we don't care (yet) about *WHEN* they were transferred
|
||||
/// The original version of this took the sortIndex array, but it turns out that it only gets used
|
||||
/// on an array that already contains sortIndex, and this simplifies code elsewhere, so I have removed it
|
||||
class ContourTreeNodeHyperArcComparator : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
// constructor - takes vectors as parameters
|
||||
VTKM_CONT
|
||||
ContourTreeNodeHyperArcComparator(const ctaug::IdArrayType superarcs,
|
||||
const ctaug::IdArrayType superparents)
|
||||
: Superarcs(superarcs)
|
||||
, Superparents(superparents)
|
||||
{ // constructor
|
||||
} // constructor
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
VTKM_CONT ContourTreeNodeHyperArcComparatorImpl<DeviceAdapter> PrepareForExecution(
|
||||
DeviceAdapter device,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
return ContourTreeNodeHyperArcComparatorImpl<DeviceAdapter>(
|
||||
this->Superarcs.PrepareForInput(device, token),
|
||||
this->Superparents.PrepareForInput(device, token));
|
||||
}
|
||||
|
||||
private:
|
||||
ctaug::IdArrayType Superarcs;
|
||||
ctaug::IdArrayType Superparents;
|
||||
}; // ContourTreeNodeHyperArcComparator
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributes
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
253
vtkm/worklet/contourtree_distributed/bract_maker/FindBractSuperarcsSuperarcToWorklet.h
Normal file
253
vtkm/worklet/contourtree_distributed/bract_maker/FindBractSuperarcsSuperarcToWorklet.h
Normal file
@ -0,0 +1,253 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_find_bract_superacrs_superarc_to_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_find_bract_superacrs_superarc_to_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Compute the superarc "to" for every bract node
|
||||
/// Part of the BoundaryRestrictedAugmentedContourTree.FindBractSuperarcs function
|
||||
class FindBractSuperarcsSuperarcToWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(WholeArrayIn bractVertexSuperset, // input
|
||||
WholeArrayIn boundaryIndices, // input
|
||||
WholeArrayIn boundaryTreeId, // input
|
||||
WholeArrayIn contourtreeSuperparents, // input
|
||||
WholeArrayIn contourtreeHyperparents, // input
|
||||
WholeArrayIn contourtreeHyperarcs, // input
|
||||
WholeArrayIn contourtreeSupernodes, // input
|
||||
WholeArrayIn meshSortOrder, // input
|
||||
WholeArrayOut treeToSuperset, // output
|
||||
FieldOut bractSuperarcs // output
|
||||
);
|
||||
using ExecutionSignature = _10(InputIndex, _1, _2, _3, _4, _5, _6, _7, _8, _9);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
FindBractSuperarcsSuperarcToWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType, typename OutFieldPortalType>
|
||||
VTKM_EXEC vtkm::Id operator()(const vtkm::Id& from,
|
||||
const InFieldPortalType& bractVertexSupersetPortal,
|
||||
const InFieldPortalType& boundaryIndicesPortal,
|
||||
const InFieldPortalType& boundaryTreeIdPortal,
|
||||
const InFieldPortalType& contourtreeSuperparentsPortal,
|
||||
const InFieldPortalType& contourtreeHyperparentsPortal,
|
||||
const InFieldPortalType& contourtreeHyperarcsPortal,
|
||||
const InFieldPortalType& contourtreeSupernodesPortal,
|
||||
const InFieldPortalType& meshSortOrderPortal,
|
||||
const OutFieldPortalType& treeToSupersetPortal)
|
||||
{
|
||||
// find the sort order, super- and hyper- parent
|
||||
// vtkm::Id fromIndex = bractVertexSupersetPortal.Get(from);
|
||||
vtkm::Id fromSort = boundaryIndicesPortal.Get(from);
|
||||
vtkm::Id fromSuper = contourtreeSuperparentsPortal.Get(fromSort);
|
||||
vtkm::Id fromHyper = contourtreeHyperparentsPortal.Get(fromSuper);
|
||||
|
||||
// also allocate space for the from, with index, &c.
|
||||
vtkm::Id to = vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
|
||||
vtkm::Id toIndex = vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
|
||||
vtkm::Id toSort = vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
|
||||
vtkm::Id toSuper = vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
|
||||
vtkm::Id toHyper = vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
|
||||
|
||||
// for any vertex OTHER than the one at the RHE, set these variables
|
||||
if (from != bractVertexSupersetPortal.GetNumberOfValues() - 1)
|
||||
{ // not RHE
|
||||
to = from + 1;
|
||||
toIndex = bractVertexSupersetPortal.Get(to);
|
||||
toSort = boundaryIndicesPortal.Get(to);
|
||||
toSuper = contourtreeSuperparentsPortal.Get(toSort);
|
||||
toHyper = contourtreeHyperparentsPortal.Get(toSuper);
|
||||
} // not RHE
|
||||
|
||||
// while we are here, we want to establish the mapping from the contour tree ID to the superset ID
|
||||
// so we test whether the node is a supernode, by seeing if it's sort ID matches its superparent
|
||||
// In the original code this was done last. We do this here first, because the values for
|
||||
// bractSuperarcs are set by return statements, so we don't reach the end of the function
|
||||
// and reordering the operation should be no problem.
|
||||
if (contourtreeSupernodesPortal.Get(fromSuper) == fromSort)
|
||||
{ // supernode
|
||||
treeToSupersetPortal.Set(fromSuper, from);
|
||||
} // supernode
|
||||
|
||||
// the easy case - there is a "hyper-neighbour" to link to
|
||||
if (fromHyper == toHyper)
|
||||
{ // hyperparents match
|
||||
return to; // same as bractSuperarcs.WritePortal().Set(from, to);
|
||||
} // hyperparents match
|
||||
// the rest: we're at the RHE of a hyperarc and need to connect onwards
|
||||
else
|
||||
{ // hyperparents do not match
|
||||
// retrieve the hypertarget
|
||||
vtkm::Id hyperTarget = contourtreeHyperarcsPortal.Get(fromHyper);
|
||||
|
||||
// if it's non-existent, we're at the root, in which case our from vertex becomes the root
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(hyperTarget))
|
||||
{ // root vertex
|
||||
// same as bractSuperarcs.WritePortal().Set(from, NO_SUCH_ELEMENT)
|
||||
return vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
|
||||
} // root vertex
|
||||
// otherwise it points to a supernode
|
||||
else
|
||||
{ // not root vertex
|
||||
// check whether the target will be in the BRACT
|
||||
vtkm::Id regularTargetId = meshSortOrderPortal.Get(contourtreeSupernodesPortal.Get(
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(hyperTarget)));
|
||||
// now look up the ID in the BRACT
|
||||
vtkm::Id bract_id = boundaryTreeIdPortal.Get(regularTargetId);
|
||||
|
||||
// if it is not in the tree, then this node becomes the root
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(bract_id))
|
||||
{
|
||||
// same as bractSuperarcs.WritePortal().Set(from, NO_SUCH_ELEMENT)
|
||||
return vtkm::worklet::contourtree_augmented::NO_SUCH_ELEMENT;
|
||||
}
|
||||
// otherwise, we use the ID just retrieved
|
||||
else
|
||||
{
|
||||
// same as // same as bractSuperarcs.WritePortal().Set(from, bract_it)
|
||||
return bract_id;
|
||||
}
|
||||
} // not root vertex
|
||||
} // hyperparents do not match
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType from = 0; from < bractVertexSuperset.size(); from++)
|
||||
{ // per vertex in boundary tree
|
||||
// find the sort order, super- and hyper- parent
|
||||
indexType fromIndex = bractVertexSuperset[from], fromSort = boundaryIndices[from];
|
||||
indexType fromSuper = contourTree->superparents[fromSort], fromHyper = contourTree->hyperparents[fromSuper];
|
||||
|
||||
// also allocate space for the from, with index, &c.
|
||||
indexType to = NO_SUCH_ELEMENT, toIndex = NO_SUCH_ELEMENT, toSort = NO_SUCH_ELEMENT;
|
||||
indexType toSuper = NO_SUCH_ELEMENT, toHyper = NO_SUCH_ELEMENT;
|
||||
|
||||
// for any vertex OTHER than the one at the RHE, set these variables
|
||||
if (from != bractVertexSuperset.size() - 1)
|
||||
{ // not RHE
|
||||
to = from + 1;
|
||||
toIndex = bractVertexSuperset[to];
|
||||
toSort = boundaryIndices[to];
|
||||
toSuper = contourTree->superparents[toSort];
|
||||
toHyper = contourTree->hyperparents[toSuper];
|
||||
} // not RHE
|
||||
|
||||
// the easy case - there is a "hyper-neighbour" to link to
|
||||
if (fromHyper == toHyper)
|
||||
{ // hyperparents match
|
||||
bract->superarcs[from] = to;
|
||||
} // hyperparents match
|
||||
else
|
||||
// the rest: we're at the RHE of a hyperarc and need to connect onwards
|
||||
{ // hyperparents do not match
|
||||
// retrieve the hypertarget
|
||||
indexType hyperTarget = contourTree->hyperarcs[fromHyper];
|
||||
|
||||
// if it's non-existent, we're at the root, in which case our from vertex becomes the root
|
||||
if (noSuchElement(hyperTarget))
|
||||
{ // root vertex
|
||||
bract->superarcs[from] = NO_SUCH_ELEMENT;
|
||||
} // root vertex
|
||||
// otherwise it points to a supernode
|
||||
else
|
||||
{ // not root vertex
|
||||
// check whether the target will be in the BRACT
|
||||
indexType regularTargetID = mesh->SortOrder(contourTree->supernodes[maskedIndex(hyperTarget)]);
|
||||
|
||||
// now look up the ID in the BRACT
|
||||
indexType BRACTID = boundaryTreeID[regularTargetID];
|
||||
|
||||
// if it is not in the tree, then this node becomes the root
|
||||
if (noSuchElement(BRACTID))
|
||||
bract->superarcs[from] = NO_SUCH_ELEMENT;
|
||||
// otherwise, we use the ID just retrieved
|
||||
else
|
||||
bract->superarcs[from] = BRACTID;
|
||||
|
||||
} // not root vertex
|
||||
|
||||
} // hyperparents do not match
|
||||
|
||||
// while we are here, we want to establish the mapping from the contour tree ID to the superset ID
|
||||
// so we test whether the node is a supernode, by seeing if it's sort ID matches its superparent
|
||||
if (contourTree->supernodes[fromSuper] == fromSort)
|
||||
{ // supernode
|
||||
tree2Superset[fromSuper] = from;
|
||||
} // supernode
|
||||
} // per vertex in boundary tree
|
||||
*/
|
||||
} // operator()()
|
||||
|
||||
}; // FindBractSuperarcsSuperarcToWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
133
vtkm/worklet/contourtree_distributed/bract_maker/FindNecessaryInteriorSetSuperparentNecessaryWorklet.h
Normal file
133
vtkm/worklet/contourtree_distributed/bract_maker/FindNecessaryInteriorSetSuperparentNecessaryWorklet.h
Normal file
@ -0,0 +1,133 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_find_necessary_interior_supernodes_set_superparent_necessary_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_find_necessary_interior_supernodes_set_superparent_necessary_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Worklet to transfer the dependent counts for hyperarcs
|
||||
/// Part of the BoundaryRestrictedAugmentedContourTree.PropagateBoundaryCounts function
|
||||
class FindNecessaryInteriorSetSuperparentNecessaryWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn boundaryIndices, // (input)
|
||||
WholeArrayIn superparents, // (input)
|
||||
WholeArrayIn superarcs, // (input)
|
||||
WholeArrayOut isNecessary // (output)
|
||||
);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
FindNecessaryInteriorSetSuperparentNecessaryWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType, typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& boundaryIndex,
|
||||
const InFieldPortalType superparentsPortal,
|
||||
const InFieldPortalType superarcsPortal,
|
||||
const OutFieldPortalType& isNecessaryPortal)
|
||||
{
|
||||
// per boundary node
|
||||
// find the superparent
|
||||
vtkm::Id superparent =
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(superparentsPortal.Get(boundaryIndex));
|
||||
// make it necessary
|
||||
isNecessaryPortal.Set(superparent, true);
|
||||
// retrieve the supertarget
|
||||
vtkm::Id supertarget = superarcsPortal.Get(superparent);
|
||||
// check for NULL ness & set the target as well if it exists
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(supertarget))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// set the target as well
|
||||
isNecessaryPortal.Set(vtkm::worklet::contourtree_augmented::MaskedIndex(supertarget), true);
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType boundaryNode = 0; boundaryNode < boundaryIndices.size(); boundaryNode++)
|
||||
{ // per boundary node
|
||||
|
||||
// find the superparent
|
||||
indexType superparent = maskedIndex(contourTree->superparents[boundaryIndices[boundaryNode]]);
|
||||
// make it necessary
|
||||
isNecessary[superparent] = true;
|
||||
// retrieve the supertarget
|
||||
indexType supertarget = contourTree->superarcs[superparent];
|
||||
// check for NULL ness & set the target as well if it exists
|
||||
if (noSuchElement(supertarget))
|
||||
continue;
|
||||
// set the target as well
|
||||
isNecessary[maskedIndex(supertarget)] = true;
|
||||
} // per boundary node
|
||||
*/
|
||||
}
|
||||
}; // FindNecessaryInteriorSetSuperparentNecessaryWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
134
vtkm/worklet/contourtree_distributed/bract_maker/FindNecessaryInteriorSupernodesFindNodesWorklet.h
Normal file
134
vtkm/worklet/contourtree_distributed/bract_maker/FindNecessaryInteriorSupernodesFindNodesWorklet.h
Normal file
@ -0,0 +1,134 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_find_necessary_interior_supernodes_find_nodes_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_find_necessary_interior_supernodes_find_nodes_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// 1.B. Our condition is that if the superarc dependent count is neither 0 nor the # of boundary
|
||||
/// points, the superarc target is necessary. Note that there may be write conflicts, but it's
|
||||
/// an OR operation, so it doesn't matter
|
||||
/// Part of the BoundaryRestrictedAugmentedContourTree.FindNecessaryInteriorSupernodes function
|
||||
class FindNecessaryInteriorSupernodesFindNodesWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn superarc, // (input) superarcs
|
||||
FieldIn superarcDependentBoundaryCount, // (input)
|
||||
WholeArrayOut isNecessary // (output)
|
||||
);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
FindNecessaryInteriorSupernodesFindNodesWorklet(vtkm::Id numBoundary)
|
||||
: NumBoundary(numBoundary)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& superarc,
|
||||
const vtkm::Id& dependentWeight,
|
||||
const OutFieldPortalType& isNecessaryPortal)
|
||||
{
|
||||
// skip the stub superarc at the root
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(superarc))
|
||||
{
|
||||
return;
|
||||
}
|
||||
// skip vertices with 0 / ALL
|
||||
if ((dependentWeight != 0) && (dependentWeight != this->NumBoundary))
|
||||
{ // mark target
|
||||
isNecessaryPortal.Set(vtkm::worklet::contourtree_augmented::MaskedIndex(superarc), true);
|
||||
} // mark target
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType supernode = 0; supernode < contourTree->supernodes.size(); supernode++)
|
||||
{ // per supernode
|
||||
// skip the stub superarc at the root
|
||||
if (noSuchElement(contourTree->superarcs[supernode]))
|
||||
continue;
|
||||
indexType dependentWeight = superarcDependentBoundaryCount[supernode];
|
||||
|
||||
// skip vertices with 0 / ALL
|
||||
if ((dependentWeight != 0) && (dependentWeight != nBoundary))
|
||||
// mark the target
|
||||
{ // mark target
|
||||
isNecessary[maskedIndex(contourTree->superarcs[supernode])] = true;
|
||||
} // mark target
|
||||
} // per supernode
|
||||
*/
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::Id NumBoundary;
|
||||
|
||||
}; // FindNecessaryInteriorSupernodesFindNodesWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
@ -0,0 +1,125 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_hyperarc_comparator_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_hyperarc_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 bract_maker
|
||||
{
|
||||
|
||||
|
||||
// device implementation of the comparator used for sorting hyperarcs
|
||||
template <typename DeviceAdapter>
|
||||
class HyperarcComparatorImpl
|
||||
{
|
||||
public:
|
||||
using IdArrayPortalType =
|
||||
typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<DeviceAdapter>::PortalConst;
|
||||
|
||||
// constructor - takes vectors as parameters
|
||||
VTKM_CONT
|
||||
HyperarcComparatorImpl(const IdArrayPortalType& hyperarcsPortal)
|
||||
: HyperarcsPortal(hyperarcsPortal)
|
||||
{ // constructor
|
||||
} // constructor
|
||||
|
||||
// () operator - gets called to do comparison
|
||||
VTKM_EXEC
|
||||
bool operator()(const vtkm::Id& i, const vtkm::Id& j) const
|
||||
{ // operator()
|
||||
return vtkm::worklet::contourtree_augmented::MaskedIndex(HyperarcsPortal.Get(i)) <
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(HyperarcsPortal.Get(j));
|
||||
} // operator()
|
||||
|
||||
private:
|
||||
IdArrayPortalType HyperarcsPortal;
|
||||
}; // HyperarcComparatorImpl
|
||||
|
||||
/// comparator used to compare hyperarcs for sort
|
||||
class HyperarcComparator : public vtkm::cont::ExecutionObjectBase
|
||||
{
|
||||
public:
|
||||
// constructor - takes vectors as parameters
|
||||
VTKM_CONT
|
||||
HyperarcComparator(const vtkm::worklet::contourtree_augmented::IdArrayType hyperarcs)
|
||||
: Hyperarcs(hyperarcs)
|
||||
{ // constructor
|
||||
} // constructor
|
||||
|
||||
template <typename DeviceAdapter>
|
||||
VTKM_CONT HyperarcComparatorImpl<DeviceAdapter> PrepareForExecution(
|
||||
DeviceAdapter device,
|
||||
vtkm::cont::Token& token) const
|
||||
{
|
||||
return HyperarcComparatorImpl<DeviceAdapter>(this->Hyperarcs.PrepareForInput(device, token));
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::cont::ArrayHandle<vtkm::Id> Hyperarcs;
|
||||
}; // HyperarcComparator
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
168
vtkm/worklet/contourtree_distributed/bract_maker/IdentifyRegularisedSupernodesStepOneWorklet.h
Normal file
168
vtkm/worklet/contourtree_distributed/bract_maker/IdentifyRegularisedSupernodesStepOneWorklet.h
Normal file
@ -0,0 +1,168 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_identify_regularise_supernodes_step_one_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_identify_regularise_supernodes_step_one_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Step 1 of IdentifyRegularisedSupernodes
|
||||
class IdentifyRegularisedSupernodesStepOneWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(WholeArrayIn bractVertexSuperset, // input
|
||||
FieldIn bractSuperarcs, // input
|
||||
WholeArrayIn meshSortIndex, // input
|
||||
WholeArrayIn upNeighbour, // input
|
||||
WholeArrayIn downNeighbour, // input
|
||||
WholeArrayOut newVertexId // output
|
||||
|
||||
);
|
||||
using ExecutionSignature = void(InputIndex, _2, _1, _3, _4, _5, _6);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
IdentifyRegularisedSupernodesStepOneWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType, typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& from,
|
||||
const vtkm::Id& to,
|
||||
const InFieldPortalType& bractVertexSupersetPortal,
|
||||
const InFieldPortalType& meshSortIndexPortal,
|
||||
const InFieldPortalType& upNeighbourPortal,
|
||||
const InFieldPortalType& downNeighbourPortal,
|
||||
const OutFieldPortalType& newVertexIdPortal)
|
||||
{
|
||||
// per vertex
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(to))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// now find the sort index of the from and to
|
||||
vtkm::Id fromSort = meshSortIndexPortal.Get(bractVertexSupersetPortal.Get(from));
|
||||
vtkm::Id toSort = meshSortIndexPortal.Get(bractVertexSupersetPortal.Get(to));
|
||||
|
||||
// use this to identify direction of edge
|
||||
if (fromSort < toSort)
|
||||
{ // from is lower
|
||||
if (upNeighbourPortal.Get(from) != to)
|
||||
{
|
||||
newVertexIdPortal.Set(from, vtkm::worklet::contourtree_augmented::ELEMENT_EXISTS);
|
||||
}
|
||||
if (downNeighbourPortal.Get(to) != from)
|
||||
{
|
||||
newVertexIdPortal.Set(to, vtkm::worklet::contourtree_augmented::ELEMENT_EXISTS);
|
||||
}
|
||||
} // from is lower
|
||||
else
|
||||
{ // to is lower
|
||||
if (upNeighbourPortal.Get(to) != from)
|
||||
{
|
||||
newVertexIdPortal.Set(to, vtkm::worklet::contourtree_augmented::ELEMENT_EXISTS);
|
||||
}
|
||||
if (downNeighbourPortal.Get(from) != to)
|
||||
{
|
||||
newVertexIdPortal.Set(from, vtkm::worklet::contourtree_augmented::ELEMENT_EXISTS);
|
||||
}
|
||||
} // to is lower
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType from = 0; from < bractVertexSuperset.size(); from++)
|
||||
{ // per vertex
|
||||
indexType to = bract->superarcs[from];
|
||||
// ignore the last terminating edge
|
||||
if (noSuchElement(to))
|
||||
continue;
|
||||
// now find the sort index of the from and to
|
||||
indexType fromSort = mesh->SortIndex(bractVertexSuperset[from]);
|
||||
indexType toSort = mesh->SortIndex(bractVertexSuperset[to]);
|
||||
|
||||
// use this to identify direction of edge
|
||||
if (fromSort < toSort)
|
||||
{ // from is lower
|
||||
if (upNeighbour[from] != to)
|
||||
newVertexID[from] = ELEMENT_EXISTS;
|
||||
if (downNeighbour[to] != from)
|
||||
newVertexID[to] = ELEMENT_EXISTS;
|
||||
} // from is lower
|
||||
else
|
||||
{ // to is lower
|
||||
if (upNeighbour[to] != from)
|
||||
newVertexID[to] = ELEMENT_EXISTS;
|
||||
if (downNeighbour[from] != to)
|
||||
newVertexID[from] = ELEMENT_EXISTS;
|
||||
} // to is lower
|
||||
} // per vertex
|
||||
*/
|
||||
}
|
||||
}; // IdentifyRegularisedSupernodesStepOneWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
130
vtkm/worklet/contourtree_distributed/bract_maker/IdentifyRegularisedSupernodesStepTwoWorklet.h
Normal file
130
vtkm/worklet/contourtree_distributed/bract_maker/IdentifyRegularisedSupernodesStepTwoWorklet.h
Normal file
@ -0,0 +1,130 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_identify_regularise_supernodes_step_two_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_identify_regularise_supernodes_step_two_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Step 2 of IdentifyRegularisedSupernodes
|
||||
/// We also want to flag the leaves and boundary nodes as necessary
|
||||
class IdentifyRegularisedSupernodesStepTwoWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn bractVertexSuperset, // input
|
||||
FieldIn upNeighbour, // input
|
||||
FieldIn downNeighbour, // input
|
||||
ExecObject meshBoundary, // input
|
||||
WholeArrayOut newVertexId // output
|
||||
|
||||
);
|
||||
using ExecutionSignature = void(InputIndex, _1, _2, _3, _4, _5);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
IdentifyRegularisedSupernodesStepTwoWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType, typename MeshBoundaryType, typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& boundaryNode,
|
||||
const vtkm::Id& bractVertexSupersetValue,
|
||||
const vtkm::Id& upNeighbourValue,
|
||||
const vtkm::Id& downNeighbourValue,
|
||||
const MeshBoundaryType& meshBoundary,
|
||||
const OutFieldPortalType& newVertexIdPortal)
|
||||
{
|
||||
// per vertex
|
||||
// check for leaf criticality
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(upNeighbourValue) ||
|
||||
vtkm::worklet::contourtree_augmented::NoSuchElement(downNeighbourValue))
|
||||
{
|
||||
newVertexIdPortal.Set(boundaryNode, vtkm::worklet::contourtree_augmented::ELEMENT_EXISTS);
|
||||
}
|
||||
// retrieve mesh index (i.e., bractVertexSupersetValue) & check whether on the boundary
|
||||
if (meshBoundary.liesOnBoundary(bractVertexSupersetValue))
|
||||
{
|
||||
newVertexIdPortal.Set(boundaryNode, vtkm::worklet::contourtree_augmented::ELEMENT_EXISTS);
|
||||
}
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType boundaryNode = 0; boundaryNode < bractVertexSuperset.size(); boundaryNode++)
|
||||
{ // per vertex
|
||||
// check for leaf criticality
|
||||
if (noSuchElement(upNeighbour[boundaryNode]) || noSuchElement(downNeighbour[boundaryNode]))
|
||||
newVertexID[boundaryNode] = ELEMENT_EXISTS;
|
||||
// retrieve mesh index & check whether on the boundary
|
||||
indexType meshIndex = bractVertexSuperset[boundaryNode];
|
||||
if (mesh->liesOnBoundary(meshIndex))
|
||||
newVertexID[boundaryNode] = ELEMENT_EXISTS;
|
||||
} // per vertex
|
||||
*/
|
||||
}
|
||||
}; // IdentifyRegularisedSupernodesStepTwoWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
@ -0,0 +1,90 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_no_such_element_functor_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_no_such_element_functor_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
//Simple functor to subset a VTKm ArrayHandle
|
||||
class NoSuchElementFunctor
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT
|
||||
NoSuchElementFunctor(){};
|
||||
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id operator()(const vtkm::Id value) const
|
||||
{
|
||||
return static_cast<vtkm::Id>(!vtkm::worklet::contourtree_augmented::NoSuchElement(value));
|
||||
}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
129
vtkm/worklet/contourtree_distributed/bract_maker/PointerDoubleUpDownNeighboursWorklet.h
Normal file
129
vtkm/worklet/contourtree_distributed/bract_maker/PointerDoubleUpDownNeighboursWorklet.h
Normal file
@ -0,0 +1,129 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_pointer_double_up_down_neighbours_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_pointer_double_up_down_neighbours_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Step 1 of IdentifyRegularisedSupernodes
|
||||
class PointerDoubleUpDownNeighboursWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(WholeArrayInOut upNeighbour, // input/output
|
||||
WholeArrayInOut downNeighbour // input/output
|
||||
);
|
||||
using ExecutionSignature = void(InputIndex, _1, _2);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
PointerDoubleUpDownNeighboursWorklet() {}
|
||||
|
||||
template <typename InOutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id* returnIndex,
|
||||
const InOutFieldPortalType& upNeighbourPortal,
|
||||
const InOutFieldPortalType& downNeighbourPortal)
|
||||
{
|
||||
// per vertex
|
||||
// retrieve nbr & see if it's terminal
|
||||
vtkm::Id upNbr = upNeighbourPortal.Get(returnIndex);
|
||||
// otherwise jump
|
||||
if (!vtkm::worklet::contourtree_augmented::IsTerminalElement(upNbr))
|
||||
{
|
||||
upNeighbourPortal.Set(returnIndex, upNeighbourPortal.Get(upNbr));
|
||||
}
|
||||
// retrieve nbr & see if it's terminal
|
||||
vtkm::Id dnNbr = downNeighbourPortal.Get(returnIndex);
|
||||
// otherwise jump
|
||||
if (!vtkm::worklet::contourtree_augmented::IsTerminalElement(dnNbr))
|
||||
{
|
||||
downNeighbourPortal.Set(returnIndex, downNeighbourPortal.Get(dnNbr));
|
||||
}
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (indexType returnIndex = 0; returnIndex < bractVertexSuperset.size(); returnIndex++)
|
||||
{ // per vertex
|
||||
// retrieve nbr & see if it's terminal
|
||||
indexType upNbr = upNeighbour[returnIndex];
|
||||
// otherwise jump
|
||||
if (!isTerminalElement(upNeighbour[returnIndex]))
|
||||
upNeighbour[returnIndex] = upNeighbour[upNbr];
|
||||
|
||||
// retrieve nbr & see if it's terminal
|
||||
indexType dnNbr = downNeighbour[returnIndex];
|
||||
// otherwise jump
|
||||
if (!isTerminalElement(downNeighbour[returnIndex]))
|
||||
downNeighbour[returnIndex] = downNeighbour[dnNbr];
|
||||
} // per vertex
|
||||
*/
|
||||
}
|
||||
}; // PointerDoubleUpDownNeighboursWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
149
vtkm/worklet/contourtree_distributed/bract_maker/PropagateBoundaryCountsComputeGroupTotalsWorklet.h
Normal file
149
vtkm/worklet/contourtree_distributed/bract_maker/PropagateBoundaryCountsComputeGroupTotalsWorklet.h
Normal file
@ -0,0 +1,149 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_propagate_boundary_counts_compute_group_totals_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_propagate_boundary_counts_compute_group_totals_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Worklet to subtract the beginning of the group to get the total for each group
|
||||
/// Part of the BoundaryRestrictedAugmentedContourTree.PropagateBoundaryCounts function
|
||||
///
|
||||
/// 5. Finally, we subtract the beginning of the group to get the total for each group
|
||||
class PropagateBoundaryCountsComputeGroupTotalsWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(
|
||||
WholeArrayIn hyperarcTargetSortPermutation, // (input)
|
||||
WholeArrayIn hyperarcs, // (input) contour tree hyperarcs
|
||||
WholeArrayIn accumulatedBoundaryCountPortal, // (input)
|
||||
WholeArrayInOut supernodeTransferBoundaryCountPortal // (input/output)
|
||||
);
|
||||
using ExecutionSignature = void(InputIndex, _1, _2, _3, _4, _5);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
PropagateBoundaryCountsComputeGroupTotalsWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType, typename InOutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& hyperarc,
|
||||
const InFieldPortalType& hyperarcTargetSortPermutationPortal,
|
||||
const InFieldPortalType& hyperarcsPortal,
|
||||
const InFieldPortalType& accumulatedBoundaryCountPortal,
|
||||
const InOutFieldPortalType& supernodeTransferBoundaryCountPortal)
|
||||
{
|
||||
// the prefix sum of the first element is the correct value anyway so we can ignore it
|
||||
if (hyperarc == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// retrieve the hypertarget & the previous one as well
|
||||
vtkm::Id hyperarcTarget = vtkm::worklet::contourtree_augmented::MaskedIndex(
|
||||
hyperarcsPortal.Get(hyperarcTargetSortPermutationPortal.Get(hyperarc)));
|
||||
vtkm::Id prevHyperarcTarget = vtkm::worklet::contourtree_augmented::MaskedIndex(
|
||||
hyperarcsPortal.Get(hyperarcTargetSortPermutationPortal.Get(hyperarc - 1)));
|
||||
|
||||
// if they differ, write
|
||||
if (hyperarcTarget != prevHyperarcTarget)
|
||||
{ // they're different
|
||||
// if it's not the last one, transfer it to the supernode at the far end
|
||||
if (!vtkm::worklet::contourtree_augmented::NoSuchElement(hyperarcTarget))
|
||||
{ // valid target
|
||||
supernodeTransferBoundaryCountPortal.Set(
|
||||
hyperarcTarget,
|
||||
supernodeTransferBoundaryCountPortal.Get(hyperarcTarget) -
|
||||
accumulatedBoundaryCountPortal.Get(hyperarc - 1));
|
||||
} // valid target
|
||||
} // they're different
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
// NOTE: in contrast to the original imlementation this worklet starts the iteration at
|
||||
// 0 for simplicity, hence, we need to check this case separately here
|
||||
for (vtkm::Id hyperarc = 1; hyperarc < hyperarcTargetSortPermutation.size(); hyperarc++)
|
||||
{ // per hyperarc
|
||||
// retrieve the hypertarget & the previous one as well
|
||||
vtkm::Id hyperarcTarget = maskedIndex(contourTree->hyperarcs[hyperarcTargetSortPermutation[hyperarc]]);
|
||||
vtkm::Id prevHyperarcTarget = maskedIndex(contourTree->hyperarcs[hyperarcTargetSortPermutation[hyperarc-1]]);
|
||||
|
||||
// if they differ, write
|
||||
if (hyperarcTarget != prevHyperarcTarget)
|
||||
{ // they're different
|
||||
// if it's not the last one, transfer it to the supernode at the far end
|
||||
if (! noSuchElement(hyperarcTarget))
|
||||
{ // valid target
|
||||
supernodeTransferBoundaryCount[hyperarcTarget] -= accumulatedBoundaryCount[hyperarc-1];
|
||||
} // valid target
|
||||
} // they're different
|
||||
} // per hyperarc
|
||||
*/
|
||||
}
|
||||
}; // PropagateBoundaryCountsComputeGroupTotalsWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
146
vtkm/worklet/contourtree_distributed/bract_maker/PropagateBoundaryCountsSubtractDependentCountsWorklet.h
Normal file
146
vtkm/worklet/contourtree_distributed/bract_maker/PropagateBoundaryCountsSubtractDependentCountsWorklet.h
Normal file
@ -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.
|
||||
//
|
||||
//=============================================================================
|
||||
//
|
||||
// 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_bract_maker_propagate_boundary_counts_subtract_dependent_counts_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_propagate_boundary_counts_subtract_dependent_counts_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Worklet to Subtract out the dependent count of the prefix to the entire hyperarc
|
||||
/// Part of the BoundaryRestrictedAugmentedContourTree.PropagateBoundaryCounts function
|
||||
class PropagateBoundaryCountsSubtractDependentCountsWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn supernodeIndex, // (input) index of supernodes for iteration
|
||||
WholeArrayIn hyperparents, // (input) contour tree hyperparents
|
||||
WholeArrayIn hypernodes, // (input) contour tree hypernodes
|
||||
WholeArrayIn superarcDependentBoundaryCount, // (input)
|
||||
WholeArrayInOut newSuperArcDependentBoundaryCount // (input/output)
|
||||
);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4, _5);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
PropagateBoundaryCountsSubtractDependentCountsWorklet(vtkm::Id firstSupernode,
|
||||
vtkm::Id firstHypernode)
|
||||
: FirstSupernode(firstSupernode)
|
||||
, FirstHypernode(firstHypernode)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename InFieldPortalType, typename InOutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& supernode,
|
||||
const InFieldPortalType& hyperparentsPortal,
|
||||
const InFieldPortalType& hypernodesPortal,
|
||||
const InFieldPortalType& superarcDependentBoundaryCountPortal,
|
||||
const InOutFieldPortalType& newSuperArcDependentBoundaryCountPortal)
|
||||
{
|
||||
// A. Retrieve hyperparent & convert to supernode ID
|
||||
vtkm::Id hyperparent = hyperparentsPortal.Get(supernode);
|
||||
vtkm::Id hyperparentSuperId = hypernodesPortal.Get(hyperparent);
|
||||
|
||||
// B. If hyperparent is first in sequence, count is already correct
|
||||
if (hyperparent == this->FirstHypernode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// C. Otherwise, subtract out the immediately previous count to get correct value
|
||||
vtkm::Id supernodeOffset = supernode - this->FirstSupernode;
|
||||
newSuperArcDependentBoundaryCountPortal.Set(
|
||||
supernodeOffset,
|
||||
newSuperArcDependentBoundaryCountPortal.Get(supernodeOffset) -
|
||||
superarcDependentBoundaryCountPortal.Get(hyperparentSuperId - 1));
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (vtkm::Id supernode = lastSupernode-1; supernode > firstSupernode; supernode--)
|
||||
// NB: Loops backward to use the correct values, also tests > firstSupernode (the first one is guaranteed to be correct already - see ComputeWeights())
|
||||
{ // iv. per supernode
|
||||
// A. Retrieve hyperparent & convert to supernode ID
|
||||
vtkm::Id hyperparent = contourTree->hyperparents[supernode];
|
||||
vtkm::Id hyperparentSuperID = contourTree->hypernodes[hyperparent];
|
||||
|
||||
// B. If hyperparent is first in sequence, count is already correct
|
||||
if (hyperparent == firstHypernode)
|
||||
continue;
|
||||
|
||||
// C. Otherwise, subtract out the immediately previous count to get correct value
|
||||
vtkm::Id supernodeOffset = supernode - firstSupernode;
|
||||
newSuperArcDependentBoundaryCount[supernodeOffset] -= superarcDependentBoundaryCount[hyperparentSuperID-1];
|
||||
} // iv. per supernode
|
||||
*/
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::Id FirstSupernode;
|
||||
vtkm::Id FirstHypernode;
|
||||
|
||||
}; // PropagateBoundaryCountsSubtractDependentCountsWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
175
vtkm/worklet/contourtree_distributed/bract_maker/PropagateBoundaryCountsTransferCumulativeCountsWorklet.h
Normal file
175
vtkm/worklet/contourtree_distributed/bract_maker/PropagateBoundaryCountsTransferCumulativeCountsWorklet.h
Normal file
@ -0,0 +1,175 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_propagate_boundary_counts_transfer_cumulative_counts_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_propagate_boundary_counts_transfer_cumulative_counts_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Worklet to transfer the cumulative counts for hyperarcs
|
||||
/// Part of the BoundaryRestrictedAugmentedContourTree.PropagateBoundaryCounts function
|
||||
///
|
||||
/// 4. The partial sum is now over ALL hypertargets, so within each group we need to subtract the first from the last
|
||||
/// To do so, the last hyperarc in each cluster copies its cumulative count to the output array
|
||||
class PropagateBoundaryCountsTransferCumulativeCountsWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(
|
||||
WholeArrayIn hyperarcTargetSortPermutation, // (input)
|
||||
WholeArrayIn hyperarcs, // (input) contour tree hyperarcs
|
||||
WholeArrayIn accumulatedBoundaryCountPortal, // (input)
|
||||
WholeArrayInOut supernodeTransferBoundaryCountPortal // (input/output)
|
||||
);
|
||||
using ExecutionSignature = void(InputIndex, _1, _2, _3, _4, _5);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
PropagateBoundaryCountsTransferCumulativeCountsWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType, typename InOutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& hyperarc,
|
||||
const InFieldPortalType& hyperarcTargetSortPermutationPortal,
|
||||
const InFieldPortalType& hyperarcsPortal,
|
||||
const InFieldPortalType& accumulatedBoundaryCountPortal,
|
||||
const InOutFieldPortalType& supernodeTransferBoundaryCountPortal)
|
||||
{
|
||||
// per hyperarc
|
||||
// retrieve the hypertarget
|
||||
vtkm::Id hyperarcTarget =
|
||||
hyperarcsPortal.Get(hyperarcTargetSortPermutationPortal.Get(hyperarc));
|
||||
|
||||
// in the last loop, no transfer is needed
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(hyperarcTarget))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// now mask out the flag
|
||||
hyperarcTarget = vtkm::worklet::contourtree_augmented::MaskedIndex(hyperarcTarget);
|
||||
|
||||
// the last one of all has a different rule
|
||||
if (hyperarc == hyperarcTargetSortPermutationPortal.GetNumberOfValues() - 1)
|
||||
{ // last hyperarc
|
||||
supernodeTransferBoundaryCountPortal.Set(
|
||||
hyperarcTarget,
|
||||
supernodeTransferBoundaryCountPortal.Get(hyperarcTarget) +
|
||||
accumulatedBoundaryCountPortal.Get(hyperarc));
|
||||
} // last hyperarc
|
||||
// the others compute a delta
|
||||
else
|
||||
{ // not last hyperarc
|
||||
vtkm::Id nextHyperarcTarget = vtkm::worklet::contourtree_augmented::MaskedIndex(
|
||||
hyperarcsPortal.Get(hyperarcTargetSortPermutationPortal.Get(hyperarc + 1)));
|
||||
// only write for the last one in the cluster
|
||||
// note that this is an addition because a target may accumulate in multiple passes
|
||||
if (hyperarcTarget != nextHyperarcTarget)
|
||||
{ // no match
|
||||
supernodeTransferBoundaryCountPortal.Set(
|
||||
hyperarcTarget,
|
||||
supernodeTransferBoundaryCountPortal.Get(hyperarcTarget) +
|
||||
accumulatedBoundaryCountPortal.Get(hyperarc));
|
||||
} // no match
|
||||
} // not last hyperarc
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (vtkm::Id hyperarc = 0; hyperarc < hyperarcTargetSortPermutation.size(); hyperarc++)
|
||||
{ // per hyperarc
|
||||
// retrieve the hypertarget
|
||||
vtkm::Id hyperarcTarget = contourTree->hyperarcs[hyperarcTargetSortPermutation[hyperarc]];
|
||||
|
||||
// in the last loop, no transfer is needed
|
||||
if (noSuchElement(hyperarcTarget))
|
||||
continue;
|
||||
|
||||
// now mask out the flag
|
||||
hyperarcTarget = maskedIndex(hyperarcTarget);
|
||||
|
||||
// the last one of all has a different rule
|
||||
if (hyperarc == hyperarcTargetSortPermutation.size() - 1)
|
||||
{ // last hyperarc
|
||||
supernodeTransferBoundaryCount[hyperarcTarget] += accumulatedBoundaryCount[hyperarc];
|
||||
} // last hyperarc
|
||||
// the others compute a delta
|
||||
else
|
||||
{ // not last hyperarc
|
||||
vtkm::Id nextHyperarcTarget = maskedIndex(contourTree->hyperarcs[hyperarcTargetSortPermutation[hyperarc+1]]);
|
||||
// only write for the last one in the cluster
|
||||
// note that this is an addition because a target may accumulate in multiple passes
|
||||
if (hyperarcTarget != nextHyperarcTarget)
|
||||
{ // no match
|
||||
supernodeTransferBoundaryCount[hyperarcTarget] += accumulatedBoundaryCount[hyperarc];
|
||||
} // no match
|
||||
} // not last hyperarc
|
||||
} // per hyperarc
|
||||
*/
|
||||
}
|
||||
}; // PropagateBoundaryCountsTransferCumulativeCountsWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
144
vtkm/worklet/contourtree_distributed/bract_maker/PropagateBoundaryCountsTransferDependentCountsWorklet.h
Normal file
144
vtkm/worklet/contourtree_distributed/bract_maker/PropagateBoundaryCountsTransferDependentCountsWorklet.h
Normal file
@ -0,0 +1,144 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_propagate_boundary_counts_transfer_dependent_counts_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_propagate_boundary_counts_transfer_dependent_counts_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Worklet to transfer the dependent counts for hyperarcs
|
||||
/// Part of the BoundaryRestrictedAugmentedContourTree.PropagateBoundaryCounts function
|
||||
class PropagateBoundaryCountsTransferDependentCountsWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(FieldIn supernodeIndex, // (input) index of supernodes for iteration
|
||||
WholeArrayIn hypernodes, // (input) contour tree hypernodes
|
||||
WholeArrayIn superarcDependentBoundaryCount, // (input)
|
||||
WholeArrayOut hyperarcDependentBoundaryCount // (output)
|
||||
);
|
||||
using ExecutionSignature = void(_1, _2, _3, _4);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
PropagateBoundaryCountsTransferDependentCountsWorklet(vtkm::Id numSupernodes,
|
||||
vtkm::Id numHypernodes)
|
||||
: NumSupernodes(numSupernodes)
|
||||
, NumHypernodes(numHypernodes)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename InFieldPortalType, typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& hypernode,
|
||||
const InFieldPortalType& hypernodesPortal,
|
||||
const InFieldPortalType& superarcDependentBoundaryCountPortal,
|
||||
const OutFieldPortalType& hyperarcDependentBoundaryCountPortal)
|
||||
{
|
||||
// v. per hypernode
|
||||
// A.Transfer dependent count from last superarc to hyperarc
|
||||
// Last superarc for the hyperarc
|
||||
vtkm::Id lastSuperarc;
|
||||
// special case for the last hyperarc
|
||||
if (hypernode == this->NumHypernodes - 1)
|
||||
{
|
||||
lastSuperarc = this->NumSupernodes - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastSuperarc =
|
||||
vtkm::worklet::contourtree_augmented::MaskedIndex(hypernodesPortal.Get(hypernode + 1)) - 1;
|
||||
}
|
||||
// Transfer the dependent count
|
||||
hyperarcDependentBoundaryCountPortal.Set(
|
||||
hypernode, superarcDependentBoundaryCountPortal.Get(lastSuperarc));
|
||||
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
for (vtkm::Id hypernode = firstHypernode; hypernode < lastHypernode; hypernode++)
|
||||
{ // v. per hypernode
|
||||
// A. Transfer dependent count from last superarc to hyperarc
|
||||
// Last superarc for the hyperarc
|
||||
vtkm::Id lastSuperarc;
|
||||
// special case for the last hyperarc
|
||||
if (hypernode == contourTree->hypernodes.size() - 1)
|
||||
lastSuperarc = contourTree->supernodes.size() - 1;
|
||||
else
|
||||
lastSuperarc = maskedIndex(contourTree->hypernodes[hypernode + 1]) - 1;
|
||||
|
||||
// Transfer the dependent count
|
||||
hyperarcDependentBoundaryCount[hypernode] = superarcDependentBoundaryCount[lastSuperarc];
|
||||
*/
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::Id NumSupernodes;
|
||||
vtkm::Id NumHypernodes;
|
||||
|
||||
}; // PropagateBoundaryCountsTransferDependentCountsWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
@ -0,0 +1,99 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_select_range_functor_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_select_range_functor_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
//Simple functor to subset a VTKm ArrayHandle
|
||||
class SelectRangeFunctor
|
||||
{
|
||||
public:
|
||||
VTKM_EXEC_CONT
|
||||
SelectRangeFunctor();
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
SelectRangeFunctor(const vtkm::worklet::contourtree_augmented::IdArrayType& dataArray,
|
||||
vtkm::Id startIndex)
|
||||
: DataArray(dataArray)
|
||||
, StartIndex(startIndex)
|
||||
{
|
||||
}
|
||||
|
||||
VTKM_EXEC_CONT
|
||||
vtkm::Id operator()(const vtkm::Id index) const
|
||||
{
|
||||
return this->DataArray.ReadPortal().Get(this->StartIndex + index);
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::worklet::contourtree_augmented::IdArrayType DataArray;
|
||||
vtkm::Id StartIndex;
|
||||
};
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
@ -0,0 +1,152 @@
|
||||
//============================================================================
|
||||
// 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_bract_maker_set_up_and_down_neighbours_worklet_h
|
||||
#define vtk_m_worklet_contourtree_distributed_bract_maker_set_up_and_down_neighbours_worklet_h
|
||||
|
||||
#include <vtkm/worklet/WorkletMapField.h>
|
||||
#include <vtkm/worklet/contourtree_augmented/Types.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace worklet
|
||||
{
|
||||
namespace contourtree_distributed
|
||||
{
|
||||
namespace bract_maker
|
||||
{
|
||||
|
||||
/// Worklet to transfer the dependent counts for hyperarcs
|
||||
/// Part of the BoundaryRestrictedAugmentedContourTree.PropagateBoundaryCounts function
|
||||
class SetUpAndDownNeighboursWorklet : public vtkm::worklet::WorkletMapField
|
||||
{
|
||||
public:
|
||||
using ControlSignature = void(WholeArrayIn bractVertexSuperset, // input
|
||||
FieldIn bractSuperarcs, // input
|
||||
WholeArrayIn meshSortIndex, // input
|
||||
WholeArrayOut upNeighbour, // output
|
||||
WholeArrayOut downNeighbour // output
|
||||
);
|
||||
using ExecutionSignature = void(InputIndex, _2, _1, _3, _4, _5);
|
||||
using InputDomain = _1;
|
||||
|
||||
// Default Constructor
|
||||
VTKM_EXEC_CONT
|
||||
SetUpAndDownNeighboursWorklet() {}
|
||||
|
||||
template <typename InFieldPortalType, typename OutFieldPortalType>
|
||||
VTKM_EXEC void operator()(const vtkm::Id& from,
|
||||
vtkm::Id& to,
|
||||
InFieldPortalType bractVertexSupersetPortal,
|
||||
InFieldPortalType meshSortIndexPortal,
|
||||
OutFieldPortalType upNeighbourPortal,
|
||||
OutFieldPortalType downNeighbourPortal)
|
||||
{
|
||||
// per vertex
|
||||
// ignore the last terminating edge
|
||||
if (vtkm::worklet::contourtree_augmented::NoSuchElement(to))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// now find the sort index of the from and to
|
||||
vtkm::Id fromSort = meshSortIndexPortal.Get(bractVertexSupersetPortal.Get(from));
|
||||
vtkm::Id toSort = meshSortIndexPortal.Get(bractVertexSupersetPortal.Get(to));
|
||||
|
||||
// use this to identify direction of edge
|
||||
if (fromSort < toSort)
|
||||
{ // from is lower
|
||||
upNeighbourPortal.Set(from, to);
|
||||
downNeighbourPortal.Set(to, from);
|
||||
} // from is lower
|
||||
else
|
||||
{ // to is lower
|
||||
upNeighbourPortal.Set(to, from);
|
||||
downNeighbourPortal.Set(from, to);
|
||||
} // to is lower
|
||||
// In serial this worklet implements the following operation
|
||||
/*
|
||||
// a. Loop through all of the superarcs in the return tree, retrieving the two ends
|
||||
for (indexType from = 0; from < bractVertexSuperset.size(); from++)
|
||||
{ // per vertex
|
||||
indexType to = bract->superarcs[from];
|
||||
// ignore the last terminating edge
|
||||
if (noSuchElement(to))
|
||||
continue;
|
||||
// now find the sort index of the from and to
|
||||
indexType fromSort = mesh->SortIndex(bractVertexSuperset[from]);
|
||||
indexType toSort = mesh->SortIndex(bractVertexSuperset[to]);
|
||||
|
||||
// use this to identify direction of edge
|
||||
if (fromSort < toSort)
|
||||
{ // from is lower
|
||||
upNeighbour[from] = to;
|
||||
downNeighbour[to] = from;
|
||||
} // from is lower
|
||||
else
|
||||
{ // to is lower
|
||||
upNeighbour[to] = from;
|
||||
downNeighbour[from] = to;
|
||||
} // to is lower
|
||||
} // per vertex
|
||||
*/
|
||||
}
|
||||
|
||||
}; // SetUpAndDownNeighboursWorklet
|
||||
|
||||
|
||||
} // namespace bract_maker
|
||||
} // namespace contourtree_distributed
|
||||
} // namespace worklet
|
||||
} // namespace vtkm
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user