Merge branch 'master' into NewFilter

This commit is contained in:
Li-Ta Lo 2022-01-04 07:54:04 -07:00
commit 6461857e4e
74 changed files with 1593 additions and 528 deletions

@ -132,6 +132,12 @@
when: on_success
- when: never
.run_ecp_ci: &run_ecp_ci
rules:
- if: '$CI_PROJECT_PATH == "ecpcitest/vtk-m"'
when: on_success
- when: never
# General Longer Term Tasks:
# - Setup clang tidy as sub-pipeline
# - Setup a machine to replicate the issue in https://gitlab.kitware.com/vtk/vtk-m/-/issues/447
@ -170,6 +176,41 @@ stages:
script:
- "ctest -VV -S .gitlab/ci/ctest_build.cmake"
- sccache --show-stats
extends:
- .cmake_build_artifacts
.cmake_test_linux: &cmake_test_linux
stage: test
timeout: 50 minutes
interruptible: true
before_script:
- *install_cmake
script:
- "ctest $CTEST_TIMEOUT -VV -S .gitlab/ci/ctest_test.cmake"
extends:
- .cmake_test_artifacts
.cmake_memcheck_linux: &cmake_memcheck_linux
stage: test
timeout: 2 hours
interruptible: true
before_script:
- *install_cmake
script:
- "ctest -VV -S .gitlab/ci/ctest_memcheck.cmake"
artifacts:
expire_in: 24 hours
when: always
paths:
# The generated regression testing images
- build/*.png
- build/*.pnm
- build/*.pmm
reports:
junit:
- build/junit.xml
.cmake_build_artifacts: &cmake_build_artifacts
artifacts:
expire_in: 24 hours
when: always
@ -198,14 +239,7 @@ stages:
# CDash files.
- build/DartConfiguration.tcl
.cmake_test_linux: &cmake_test_linux
stage: test
timeout: 50 minutes
interruptible: true
before_script:
- *install_cmake
script:
- "ctest $CTEST_TIMEOUT -VV -S .gitlab/ci/ctest_test.cmake"
.cmake_test_artifacts: &cmake_test_artifacts
artifacts:
expire_in: 24 hours
when: always
@ -227,25 +261,6 @@ stages:
junit:
- build/junit.xml
.cmake_memcheck_linux: &cmake_memcheck_linux
stage: test
timeout: 2 hours
interruptible: true
before_script:
- *install_cmake
script:
- "ctest -VV -S .gitlab/ci/ctest_memcheck.cmake"
artifacts:
expire_in: 24 hours
when: always
paths:
# The generated regression testing images
- build/*.png
- build/*.pnm
- build/*.pmm
reports:
junit:
- build/junit.xml
include:
- local: '/.gitlab/ci/centos7.yml'
@ -256,3 +271,4 @@ include:
- local: '/.gitlab/ci/ubuntu1804.yml'
- local: '/.gitlab/ci/ubuntu2004.yml'
- local: '/.gitlab/ci/windows10.yml'
- local: '/.gitlab/ci/ascent.yml'

92
.gitlab/ci/ascent.yml Normal file

@ -0,0 +1,92 @@
# Ad-hoc build that runs in the ECP Hardware, concretely in OLCF Ascent.
build:ascent_gcc_cuda:
tags: [olcf, ascent, nobatch]
extends:
- .ascent_gcc_cuda
- .ascent_build
- .run_ecp_ci
- .cmake_build_artifacts
test:ascent_gcc_cuda:
tags: [olcf, ascent, batch]
extends:
- .ascent_gcc_cuda
- .ascent_test
- .run_ecp_ci
- .cmake_test_artifacts
.ascent_gcc_cuda:
variables:
CCACHE_BASEDIR: /gpfs/wolf/
CCACHE_DIR: "/gpfs/wolf/proj-shared/csc331/vtk-m/ci/ccache/"
# -isystem= is not affected by CCACHE_BASEDIR, thus we must ignore it
CCACHE_IGNOREOPTIONS: "-isystem=*"
CCACHE_NOHASHDIR: "true"
CMAKE_BUILD_TYPE: RelWithDebInfo
CMAKE_GENERATOR: Unix Makefiles
CUSTOM_CI_BUILDS_DIR: "/gpfs/wolf/proj-shared/csc331/vtk-m/ci/runtime"
FF_ENABLE_JOB_CLEANUP: "true"
CC: gcc
CXX: g++
CUDAHOSTCXX: g++
JOB_MODULES: gcc/8.1.1 spectrum-mpi lsf-tools cuda/11.2.0
VTKM_SETTINGS: cuda+ascent+ccache
.ascent_build:
stage: build
variables:
CTEST_MAX_PARALLELISM: 4
before_script:
# Prep the environment
- module purge
- echo ${JOB_MODULES}
- module load git git-lfs cmake zstd ${JOB_MODULES}
- export PATH="/gpfs/wolf/proj-shared/csc331/vtk-m/ci/utils:$PATH"
- ccache -p
- ccache -z
- git remote add lfs https://gitlab.kitware.com/vtk/vtk-m.git
- git fetch lfs
- git-lfs install
- git-lfs pull lfs
# Start running the builds scripts
- cmake --version
- "cmake -V -P .gitlab/ci/config/gitlab_ci_setup.cmake"
- "ctest -VV -S .gitlab/ci/ctest_configure.cmake"
script:
- "ctest -VV -S .gitlab/ci/ctest_build.cmake"
- ccache -s
.ascent_test:
stage: test
variables:
GITLAB_CI_EMULATION: "true"
SCHEDULER_PARAMETERS: -P CSC331 -W 1:00 -nnodes 1 -alloc_flags gpudefault
CTEST_MAX_PARALLELISM: 8
# Tests errors to address due to different env/arch in Ascent
# Refer to issue: https://gitlab.kitware.com/vtk/vtk-m/-/issues/652
CTEST_EXCLUSIONS: >-
UnitTestMathSERIAL
UnitTestMathCUDA
UnitTestSerialDeviceAdapter
UnitTestAverageByKeySERIAL
UnitTestKeysSERIAL
UnitTestWorkletReduceByKeySERIAL
RegressionTestAmrArraysSERIAL
RegressionTestAmrArraysCUDA
before_script:
# Prep the environment
- module purge
- module load git cmake ${JOB_MODULES}
script:
- "jsrun -n1 -r1 -a1 -g1 -c7 ctest -VV -S .gitlab/ci/ctest_test.cmake || test_output=$?"
- ctest -VV -S .gitlab/ci/ctest_test_submit.cmake
- $(exit $test_output)

@ -57,7 +57,7 @@ foreach(option IN LISTS options)
set(VTKm_NO_DEPRECATED_VIRTUAL "OFF" CACHE STRING "")
elseif(no_testing STREQUAL option)
set(VTKm_ENABLE_TESTING OFF CACHE BOOL "")
set(VTKm_ENABLE_TESTING "OFF" CACHE STRING "")
elseif(examples STREQUAL option)
set(VTKm_ENABLE_EXAMPLES "ON" CACHE STRING "")
@ -108,6 +108,37 @@ foreach(option IN LISTS options)
set(CMAKE_CXX_COMPILER "/opt/rocm/llvm/bin/clang++" CACHE FILEPATH "")
set(VTKm_ENABLE_KOKKOS_HIP ON CACHE STRING "")
set(CMAKE_HIP_ARCHITECTURES "gfx900" CACHE STRING "")
elseif(ascent STREQUAL option)
set(CMAKE_C_FLAGS "-mcpu=power9" CACHE STRING "")
set(CMAKE_CXX_FLAGS "-mcpu=power9" CACHE STRING "")
elseif(ccache STREQUAL option)
find_program(CCACHE_COMMAND NAMES ccache REQUIRED)
set(CCACHE_VERSION "NotFound")
execute_process(
COMMAND ${CCACHE_COMMAND} "--version"
OUTPUT_VARIABLE CCACHE_VERSION
ECHO_ERROR_VARIABLE
)
string(REGEX REPLACE "\n" " " CCACHE_VERSION ${CCACHE_VERSION})
string(REGEX REPLACE "^.*ccache version ([.0-9]*).*$" "\\1"
CCACHE_VERSION ${CCACHE_VERSION})
# We need a recent version of ccache in order to ignore -isystem while
# hashing keys for the building cache.
if(${CCACHE_VERSION} VERSION_GREATER_EQUAL 4)
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_COMMAND}" CACHE STRING "")
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_COMMAND}" CACHE STRING "")
if(VTKm_ENABLE_CUDA)
set(CMAKE_CUDA_COMPILER_LAUNCHER "${CCACHE_COMMAND}" CACHE STRING "")
endif()
else()
message(FATAL_ERROR "CCACHE version [${CCACHE_VERSION}] is <= 4")
endif()
endif()
endforeach()

@ -11,7 +11,7 @@
##=============================================================================
# We need this CMake versions for tests
cmake_minimum_required(VERSION 3.21)
cmake_minimum_required(VERSION 3.18)
# Read the files from the build directory that contain
# host information ( name, parallel level, etc )
@ -26,17 +26,27 @@ set(test_exclusions
$ENV{CTEST_EXCLUSIONS}
)
string(REPLACE " " ";" test_exclusions "${test_exclusions}")
string(REPLACE ";" "|" test_exclusions "${test_exclusions}")
if (test_exclusions)
set(test_exclusions "(${test_exclusions})")
endif ()
if (CMAKE_VERSION VERSION_GREATER 3.21.0)
set(junit_args OUTPUT_JUNIT "${CTEST_BINARY_DIRECTORY}/junit.xml")
endif()
set(PARALLEL_LEVEL "10")
if (DEFINED ENV{CTEST_MAX_PARALLELISM})
set(PARALLEL_LEVEL $ENV{CTEST_MAX_PARALLELISM})
endif()
ctest_test(APPEND
PARALLEL_LEVEL "10"
PARALLEL_LEVEL ${PARALLEL_LEVEL}
RETURN_VALUE test_result
EXCLUDE "${test_exclusions}"
REPEAT "UNTIL_PASS:3"
OUTPUT_JUNIT "${CTEST_BINARY_DIRECTORY}/junit.xml"
${junit_args}
)
message(STATUS "ctest_test RETURN_VALUE: ${test_result}")

@ -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.
##
##=============================================================================
# We need this CMake versions for tests
cmake_minimum_required(VERSION 3.18)
# Read the files from the build directory that contain
# host information ( name, parallel level, etc )
include("$ENV{CI_PROJECT_DIR}/build/CIState.cmake")
ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}")
ctest_start(APPEND)
ctest_submit(PARTS Test BUILD_ID build_id)
message(STATUS "Test submission build_id: ${build_id}")

@ -41,6 +41,12 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
# I am seeing these for the Kokkos builds, and I don't want to fight the
# compiler flags there, so I'm just going to suppress those.
".*nvlink warning.*SM Arch.*not found in.*"
# Disable warnings about third party libraries.
# Normally compilers do not generate warnings for includes using -isystem,
# however, that is not always the case, specially in exotic systems such as
# OLCF Ascent/Summit
".*vtkm/thirdparty.*"
)
list(APPEND CTEST_CUSTOM_WARNING_MATCH

@ -1,4 +1,3 @@
Gitlab CI
===============
@ -17,8 +16,8 @@ Gitlab CI
- How to add a new tester
- How to update an existing docker image
4. ECP OSTI CI
- Issues
4. ECP Continuous Integration
- OLCF Ascent testing machine
# Kitware Gitlab CI
@ -258,3 +257,55 @@ sudo docker login --username=<docker_hub_name>
cd .gitlab/ci/docker
sudo ./update_all.sh 20201230
```
# ECP Continuous Integration
## OLCF Ascent testing machine
VTK-m provides CI builds that run at the OLCF Ascent testing cluster. OLCF
Ascent is a scaled down version of OLCF Summit which replicates the same
provisions of software and architecture found at OLCF Summit, this is very
useful for us since we are allowed to periodically and automatically branches of
VTK-m. This is a significant leap compared to our previous workflow in which we
would have someone to manually test at OLCF Summit every few months.
The ECP Gitlab continuous integration infrastructure differs from the Kitware
Gitlab CI infrastructure at the following points:
- Kitare Gitlab CI uses the `docker` executer as the _backend_ for its
`Gitlab-Runner` daemon whereas ECP Gitlab CI uses the Jacamar CI executer as
the _backend_ for the `Gitlab-Runner` daemon.
- ECP Gitlab VTK-m project is a mirror Gitlab project of the main Kitware Gitlab
VTK-m repository.
- The runners provided by the ECP Gitlab CI reside inside the OLCF Ascent
cluster.
Jacamar CI allows us to implicitly launch jobs using the HPC job scheduler LSF.
Jacamar-CI also connects the LSF job with the GitLab project which allows us to
control its state, monitor its output, and access its artifacts. Below is a brief
diagram describing the relations between the GitLab CI instance and the job.
![Jacamar CI with LSF](./batch_lsf.png)
Our Ascent Pipeline is composed of two stages:
1. The build stage, which builds VTK-m and runs in the batch nodes
2. The test stage, which runs VTK-m unit tests and runs at the compute nodes.
Due to the isolated environment in which LFS jobs run at Ascent, we are not able
to access to our `sccache` file server as we do in our other CI builds, thus,
for this very site we provide a local installation of `ccache`. This it turns
out to provided similar hit ratios as `sscache`, since we do not have any other
CI site that runs a _Power9_ architecture.
Lastly, builds and tests status are reported to our VTK-m CDashboard and are
displayed in the same groups as Kitware Gitlab's builds.
As for the flavor being currently tested at ECP Ascent is VTK-m with CUDA and
GCC8.
For a view of only ascent jobs refer to the following [link][cdash-ascent].
[cdash-ascent]: https://open.cdash.org/index.php?project=VTKM&filtercount=1&showfilters=1&field1=site&compare1=63&value1=ascent

BIN
docs/batch_lsf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -0,0 +1,13 @@
# Perlin Noise source
A new source, `vtkm::source::PerlinNoise`, has been added. As the name
would imply, this source generates a pseudo-random [Perlin
noise](https://en.wikipedia.org/wiki/Perlin_noise) field.
The field is defined on a 3D grid of specified dimensions. A seed value can
also be specified to enforce consistent results in, for example, test code.
If a seed is not specified, one will be created based on the current system
time.
Perlin noise is useful for testing purposes as it can create non-trivial
geometry at pretty much any scale.

@ -0,0 +1,21 @@
# UnknownCellSet
The `DynamicCellSet` class has been replaced with `UnknownCellSet`.
Likewise, the `DynamicCellSetBase` class (a templated version of
`DynamicCellSet`) has been replaced with `UncertainCellSet`.
These changes principally follow the changes to the `UnknownArrayHandle`
management class. The `ArrayHandle` version of a polymorphic manager has
gone through several refinements from `DynamicArrayHandle` to
`VariantArrayHandle` to its current form as `UnknownArrayHandle`.
Throughout these improvements for `ArrayHandle`, the equivalent classes for
`CellSet` have lagged behind. The `CellSet` version is decidedly simpler
because `CellSet` itself is polymorphic, but there were definitely
improvements to be had.
The biggest improvement was to remove the templating from the basic unknown
cell set. The old `DynamicArrayHandle` was actually a type alias for
`DynamicArrayHandleBase<VTKM_DEFAULT_CELL_SET_LIST>`. As
`VTKM_DEFAULT_CELL_SET_LIST` tends to be pretty long, `DynamicArrayHandle`
was actually a really long type. In contrast, `UnknownArrayHandle` is its
own untemplated class and will show up in linker symbols as such.

@ -122,7 +122,9 @@ set(headers
TryExecute.h
SerializableTypeString.h
UncertainArrayHandle.h
UncertainCellSet.h
UnknownArrayHandle.h
UnknownCellSet.h
VariantArrayHandle.h
)
@ -139,12 +141,28 @@ set(sources
ArrayHandleSOA.cxx
ArrayHandleStride.cxx
ArrayHandleUniformPointCoordinates.cxx
AssignerPartitionedDataSet.cxx
BitField.cxx
BoundsCompute.cxx
BoundsGlobalCompute.cxx
CellLocatorGeneral.cxx
CellLocatorRectilinearGrid.cxx
CellLocatorUniformGrid.cxx
CellSet.cxx
CellSetStructured.cxx
ColorTablePresets.cxx
CoordinateSystem.cxx
DataSet.cxx
DataSetBuilderCurvilinear.cxx
DataSetBuilderExplicit.cxx
DataSetBuilderRectilinear.cxx
DataSetBuilderUniform.cxx
DeviceAdapterTag.cxx
EnvironmentTracker.cxx
ErrorBadDevice.cxx
ErrorBadType.cxx
FieldRangeCompute.cxx
FieldRangeGlobalCompute.cxx
internal/Buffer.cxx
internal/DeviceAdapterMemoryManager.cxx
internal/DeviceAdapterMemoryManagerShared.cxx
@ -154,9 +172,12 @@ set(sources
Initialize.cxx
Logging.cxx
RuntimeDeviceTracker.cxx
PartitionedDataSet.cxx
Storage.cxx
Token.cxx
TryExecute.cxx
UnknownArrayHandle.cxx
UnknownCellSet.cxx
)
# This list of sources has code that uses devices and so might need to be
@ -165,35 +186,17 @@ set(device_sources
ArrayCopy.cxx
ArrayGetValues.cxx
ArrayRangeCompute.cxx
AssignerPartitionedDataSet.cxx
BoundsCompute.cxx
BoundsGlobalCompute.cxx
CellLocatorBoundingIntervalHierarchy.cxx
CellLocatorGeneral.cxx
CellLocatorRectilinearGrid.cxx
CellLocatorTwoLevel.cxx
CellLocatorUniformGrid.cxx
CellSet.cxx
CellSetExplicit.cxx
CellSetExtrude.cxx
CellSetStructured.cxx
ColorTable.cxx
ConvertNumComponentsToOffsets.cxx
CoordinateSystem.cxx
DataSet.cxx
DataSetBuilderCurvilinear.cxx
DataSetBuilderExplicit.cxx
DataSetBuilderRectilinear.cxx
DataSetBuilderUniform.cxx
Field.cxx
FieldRangeCompute.cxx
FieldRangeGlobalCompute.cxx
MergePartitionedDataSet.cxx
PartitionedDataSet.cxx
PointLocatorSparseGrid.cxx
RuntimeDeviceInformation.cxx
Timer.cxx
UnknownArrayHandle.cxx
)
if (NOT VTKm_NO_DEPRECATED_VIRTUAL)

@ -27,6 +27,8 @@
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/WorkletMapTopology.h>
#include <vtkm/worklet/spatialstructure/BoundingIntervalHierarchy.h>
namespace vtkm
{
namespace cont

@ -22,8 +22,6 @@
#include <vtkm/exec/CellLocatorBoundingIntervalHierarchy.h>
#include <vtkm/exec/CellLocatorMultiplexer.h>
#include <vtkm/worklet/spatialstructure/BoundingIntervalHierarchy.h>
namespace vtkm
{
namespace cont

@ -126,12 +126,11 @@ struct CastAndCallCellLocatorChooserFunctor
///
/// Any additional args are passed to the functor.
///
template <typename CellSetList, typename Functor, typename... Args>
VTKM_CONT void CastAndCallCellLocatorChooser(
const vtkm::cont::DynamicCellSetBase<CellSetList>& cellSet,
const vtkm::cont::CoordinateSystem& coordinateSystem,
Functor&& functor,
Args&&... args)
template <typename CellSetType, typename Functor, typename... Args>
VTKM_CONT void CastAndCallCellLocatorChooser(const CellSetType& cellSet,
const vtkm::cont::CoordinateSystem& coordinateSystem,
Functor&& functor,
Args&&... args)
{
vtkm::cont::CastAndCall(cellSet,
detail::CastAndCallCellLocatorChooserFunctor{},

@ -8,7 +8,6 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/CellLocatorUniformGrid.h>
#include <vtkm/cont/CellSetStructured.h>

@ -65,7 +65,7 @@ template <typename T>
struct CellSetCheck
{
using U = typename std::remove_pointer<T>::type;
using type = typename std::is_base_of<vtkm::cont::CellSet, U>;
using type = typename std::is_base_of<vtkm::cont::CellSet, U>::type;
};
#define VTKM_IS_CELL_SET(T) VTKM_STATIC_ASSERT(::vtkm::cont::internal::CellSetCheck<T>::type::value)

@ -14,7 +14,6 @@
#include <vtkm/cont/ColorTable.h>
#include <vtkm/cont/ColorTableMap.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/TryExecute.h>
namespace

@ -14,7 +14,6 @@
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/ColorTable.h>
#include <vtkm/cont/ColorTableSamples.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/colorconversion/LookupTable.h>

@ -14,11 +14,10 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/UnknownArrayHandle.h>
#include <vtkm/cont/UnknownCellSet.h>
namespace vtkm
{
@ -222,21 +221,18 @@ public:
vtkm::cont::CoordinateSystem& GetCoordinateSystem(const std::string& name);
//@}
VTKM_CONT
void SetCellSet(const vtkm::cont::DynamicCellSet& cellSet) { this->CellSet = cellSet; }
template <typename CellSetType>
VTKM_CONT void SetCellSet(const CellSetType& cellSet)
{
VTKM_IS_CELL_SET(CellSetType);
this->CellSet = vtkm::cont::DynamicCellSet(cellSet);
VTKM_IS_KNOWN_OR_UNKNOWN_CELL_SET(CellSetType);
this->CellSet = vtkm::cont::UnknownCellSet(cellSet);
}
VTKM_CONT
const vtkm::cont::DynamicCellSet& GetCellSet() const { return this->CellSet; }
const vtkm::cont::UnknownCellSet& GetCellSet() const { return this->CellSet; }
VTKM_CONT
vtkm::cont::DynamicCellSet& GetCellSet() { return this->CellSet; }
vtkm::cont::UnknownCellSet& GetCellSet() { return this->CellSet; }
VTKM_CONT
vtkm::IdComponent GetNumberOfFields() const
@ -291,7 +287,7 @@ private:
std::vector<vtkm::cont::CoordinateSystem> CoordSystems;
std::map<FieldCompare::Key, vtkm::cont::Field, FieldCompare> Fields;
vtkm::cont::DynamicCellSet CellSet;
vtkm::cont::UnknownCellSet CellSet;
VTKM_CONT
vtkm::Id FindFieldIndex(const std::string& name,
@ -371,9 +367,9 @@ public:
dataset.AddCoordinateSystem(coords);
}
vtkm::cont::DynamicCellSetBase<CellSetTypesList> cells;
vtkm::cont::UncertainCellSet<CellSetTypesList> cells;
vtkmdiy::load(bb, cells);
dataset.SetCellSet(vtkm::cont::DynamicCellSet(cells));
dataset.SetCellSet(cells);
vtkm::IdComponent numberOfFields = 0;
vtkmdiy::load(bb, numberOfFields);

@ -16,6 +16,7 @@
#include <vtkm/cont/DefaultTypes.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/UncertainCellSet.h>
namespace vtkm
{
@ -52,250 +53,63 @@ namespace cont
/// with the default cell set list.
///
template <typename CellSetList>
class VTKM_ALWAYS_EXPORT DynamicCellSetBase
class VTKM_ALWAYS_EXPORT DynamicCellSetBase : public vtkm::cont::UncertainCellSet<CellSetList>
{
VTKM_IS_LIST(CellSetList);
using Superclass = vtkm::cont::UncertainCellSet<CellSetList>;
public:
VTKM_CONT
DynamicCellSetBase() = default;
using Superclass::Superclass;
template <typename CellSetType>
VTKM_CONT DynamicCellSetBase(const CellSetType& cellSet)
: CellSet(std::make_shared<CellSetType>(cellSet))
VTKM_CONT DynamicCellSetBase<CellSetList> NewInstance() const
{
VTKM_IS_CELL_SET(CellSetType);
return DynamicCellSetBase<CellSetList>(this->Superclass::NewInstance());
}
template <typename OtherCellSetList>
VTKM_CONT explicit DynamicCellSetBase(const DynamicCellSetBase<OtherCellSetList>& src)
: CellSet(src.CellSet)
{
}
VTKM_CONT explicit DynamicCellSetBase(const std::shared_ptr<vtkm::cont::CellSet>& cs)
: CellSet(cs)
{
}
/// Returns true if this cell set is of the provided type.
///
template <typename CellSetType>
VTKM_CONT bool IsType() const
{
return (dynamic_cast<CellSetType*>(this->CellSet.get()) != nullptr);
}
/// Returns true if this cell set is the same (or equivalent) type as the
/// object provided.
///
template <typename CellSetType>
VTKM_CONT bool IsSameType(const CellSetType&) const
{
return this->IsType<CellSetType>();
}
/// Returns this cell set cast to the given \c CellSet type. Throws \c
/// ErrorBadType if the cast does not work. Use \c IsType to check if
/// the cast can happen.
///
template <typename CellSetType>
VTKM_CONT CellSetType& Cast() const
{
auto cellSetPointer = dynamic_cast<CellSetType*>(this->CellSet.get());
if (cellSetPointer == nullptr)
{
VTKM_LOG_CAST_FAIL(*this, CellSetType);
throw vtkm::cont::ErrorBadType("Bad cast of dynamic cell set.");
}
VTKM_LOG_CAST_SUCC(*this, *cellSetPointer);
return *cellSetPointer;
}
/// Given a reference to a concrete \c CellSet object, attempt to downcast
/// the contain cell set to the provided type and copy into the given \c
/// CellSet object. Throws \c ErrorBadType if the cast does not work.
/// Use \c IsType to check if the cast can happen.
///
/// Note that this is a shallow copy. Any data in associated arrays are not
/// copied.
///
template <typename CellSetType>
VTKM_CONT void CopyTo(CellSetType& cellSet) const
{
cellSet = this->Cast<CellSetType>();
}
/// Changes the cell set types to try casting to when resolving this dynamic
/// cell set, which is specified with a list tag like those in
/// CellSetList.h. Since C++ does not allow you to actually change the
/// template arguments, this method returns a new dynamic cell setobject.
/// This method is particularly useful to narrow down (or expand) the types
/// when using a cell set of particular constraints.
///
template <typename NewCellSetList>
VTKM_CONT DynamicCellSetBase<NewCellSetList> ResetCellSetList(
NewCellSetList = NewCellSetList()) const
VTKM_CONT vtkm::cont::DynamicCellSetBase<NewCellSetList> ResetCellSetList(NewCellSetList) const
{
VTKM_IS_LIST(NewCellSetList);
return DynamicCellSetBase<NewCellSetList>(*this);
return vtkm::cont::DynamicCellSetBase<NewCellSetList>(*this);
}
/// Attempts to cast the held cell set to a specific concrete type, then call
/// the given functor with the cast cell set. The cell sets tried in the cast
/// are those in the \c CellSetList template argument of the \c
/// DynamicCellSetBase class (or \c VTKM_DEFAULT_CELL_SET_LIST for \c
/// DynamicCellSet). You can use \c ResetCellSetList to get different
/// behavior from \c CastAndCall.
///
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCall(Functor&& f, Args&&...) const;
/// \brief Create a new cell set of the same type as this cell set.
///
/// This method creates a new cell set that is the same type as this one and
/// returns a new dynamic cell set for it. This method is convenient when
/// creating output data sets that should be the same type as some input cell
/// set.
///
VTKM_CONT
DynamicCellSetBase<CellSetList> NewInstance() const
template <typename NewCellSetList>
VTKM_CONT vtkm::cont::DynamicCellSetBase<NewCellSetList> ResetCellSetList() const
{
DynamicCellSetBase<CellSetList> newCellSet;
if (this->CellSet)
{
newCellSet.CellSet = this->CellSet->NewInstance();
}
return newCellSet;
return vtkm::cont::DynamicCellSetBase<NewCellSetList>(*this);
}
VTKM_CONT
vtkm::cont::CellSet* GetCellSetBase() { return this->CellSet.get(); }
VTKM_CONT
const vtkm::cont::CellSet* GetCellSetBase() const { return this->CellSet.get(); }
VTKM_CONT
vtkm::Id GetNumberOfCells() const
{
return this->CellSet ? this->CellSet->GetNumberOfCells() : 0;
}
VTKM_CONT
vtkm::Id GetNumberOfFaces() const
{
return this->CellSet ? this->CellSet->GetNumberOfFaces() : 0;
}
VTKM_CONT
vtkm::Id GetNumberOfEdges() const
{
return this->CellSet ? this->CellSet->GetNumberOfEdges() : 0;
}
VTKM_CONT
vtkm::Id GetNumberOfPoints() const
{
return this->CellSet ? this->CellSet->GetNumberOfPoints() : 0;
}
VTKM_CONT
void ReleaseResourcesExecution()
{
if (this->CellSet)
{
this->CellSet->ReleaseResourcesExecution();
}
}
VTKM_CONT
void PrintSummary(std::ostream& stream) const
{
if (this->CellSet)
{
this->CellSet->PrintSummary(stream);
}
else
{
stream << " DynamicCellSet = nullptr" << std::endl;
}
}
private:
std::shared_ptr<vtkm::cont::CellSet> CellSet;
template <typename>
friend class DynamicCellSetBase;
};
//=============================================================================
// Free function casting helpers
/// Returns true if \c dynamicCellSet matches the type of CellSetType.
///
template <typename CellSetType, typename Ts>
VTKM_CONT inline bool IsType(const vtkm::cont::DynamicCellSetBase<Ts>& dynamicCellSet)
struct VTKM_ALWAYS_EXPORT DynamicCellSet : public vtkm::cont::UnknownCellSet
{
return dynamicCellSet.template IsType<CellSetType>();
}
using UnknownCellSet::UnknownCellSet;
/// Returns \c dynamicCellSet cast to the given \c CellSet type. Throws \c
/// ErrorBadType if the cast does not work. Use \c IsType
/// to check if the cast can happen.
///
template <typename CellSetType, typename Ts>
VTKM_CONT inline CellSetType Cast(const vtkm::cont::DynamicCellSetBase<Ts>& dynamicCellSet)
{
return dynamicCellSet.template Cast<CellSetType>();
}
DynamicCellSet() = default;
namespace detail
{
struct DynamicCellSetTry
{
DynamicCellSetTry(const vtkm::cont::CellSet* const cellSetBase)
: CellSetBase(cellSetBase)
DynamicCellSet(const vtkm::cont::UnknownCellSet& src)
: UnknownCellSet(src)
{
}
template <typename CellSetType, typename Functor, typename... Args>
void operator()(CellSetType, Functor&& f, bool& called, Args&&... args) const
operator vtkm::cont::DynamicCellSetBase<VTKM_DEFAULT_CELL_SET_LIST>() const
{
if (!called)
{
auto* cellset = dynamic_cast<const CellSetType*>(this->CellSetBase);
if (cellset)
{
VTKM_LOG_CAST_SUCC(*this->CellSetBase, *cellset);
f(*cellset, std::forward<Args>(args)...);
called = true;
}
}
return vtkm::cont::DynamicCellSetBase<VTKM_DEFAULT_CELL_SET_LIST>{ *this };
}
const vtkm::cont::CellSet* const CellSetBase;
VTKM_CONT vtkm::cont::DynamicCellSet NewInstance() const
{
return vtkm::cont::DynamicCellSet(this->UnknownCellSet::NewInstance());
}
template <typename NewCellSetList>
VTKM_CONT vtkm::cont::DynamicCellSetBase<NewCellSetList> ResetCellSetList(NewCellSetList) const
{
return vtkm::cont::DynamicCellSetBase<NewCellSetList>(*this);
}
template <typename NewCellSetList>
VTKM_CONT vtkm::cont::DynamicCellSetBase<NewCellSetList> ResetCellSetList() const
{
return vtkm::cont::DynamicCellSetBase<NewCellSetList>(*this);
}
};
} // namespace detail
template <typename CellSetList>
template <typename Functor, typename... Args>
VTKM_CONT void DynamicCellSetBase<CellSetList>::CastAndCall(Functor&& f, Args&&... args) const
{
bool called = false;
detail::DynamicCellSetTry tryCellSet(this->CellSet.get());
vtkm::ListForEach(
tryCellSet, CellSetList{}, std::forward<Functor>(f), called, std::forward<Args>(args)...);
if (!called)
{
VTKM_LOG_CAST_FAIL(*this, CellSetList);
throw vtkm::cont::ErrorBadValue("Could not find appropriate cast for cell set.");
}
}
using DynamicCellSet = DynamicCellSetBase<VTKM_DEFAULT_CELL_SET_LIST>;
namespace internal
{
@ -305,6 +119,12 @@ struct DynamicTransformTraits<vtkm::cont::DynamicCellSetBase<CellSetList>>
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
};
template <>
struct DynamicTransformTraits<vtkm::cont::DynamicCellSet>
{
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
};
} // namespace internal
namespace internal
@ -317,13 +137,7 @@ namespace internal
template <typename T>
struct DynamicCellSetCheck
{
using type = std::false_type;
};
template <typename CellSetList>
struct DynamicCellSetCheck<vtkm::cont::DynamicCellSetBase<CellSetList>>
{
using type = std::true_type;
using type = vtkm::cont::internal::UnknownCellSetCheck<T>;
};
#define VTKM_IS_DYNAMIC_CELL_SET(T) \

@ -9,7 +9,9 @@
//============================================================================
#include <vtkm/cont/FieldRangeCompute.h>
#include <vtkm/cont/Algorithm.h>
#include <algorithm>
#include <numeric>
#include <vector>
namespace vtkm
{

@ -9,10 +9,8 @@
//============================================================================
#include <vtkm/StaticAssert.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/EnvironmentTracker.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/Field.h>

@ -14,7 +14,6 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/Field.h>
namespace vtkm

@ -19,6 +19,12 @@
//============================================================================
#include <vtkm/cont/PointLocatorSparseGrid.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/WorkletMapField.h>
namespace vtkm
{
namespace cont
@ -85,8 +91,8 @@ void PointLocatorSparseGrid::Build()
// bin points into cells and give each of them the cell id.
vtkm::cont::ArrayHandle<vtkm::Id> cellIds;
BinPointsWorklet cellIdWorklet(rmin, rmax, this->Dims);
vtkm::worklet::DispatcherMapField<BinPointsWorklet> dispatchCellId(cellIdWorklet);
dispatchCellId.Invoke(this->GetCoordinates(), cellIds);
vtkm::cont::Invoker invoke;
invoke(cellIdWorklet, this->GetCoordinates(), cellIds);
// Group points of the same cell together by sorting them according to the cell ids
vtkm::cont::Algorithm::SortByKey(cellIds, this->PointIds);

@ -10,12 +10,6 @@
#ifndef vtk_m_cont_PointLocatorSparseGrid_h
#define vtk_m_cont_PointLocatorSparseGrid_h
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/internal/PointLocatorBase.h>
#include <vtkm/exec/PointLocatorSparseGrid.h>

@ -0,0 +1,206 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_cont_UncertainCellSet_h
#define vtk_m_cont_UncertainCellSet_h
#include <vtkm/cont/UnknownCellSet.h>
namespace vtkm
{
namespace cont
{
/// \brief A `CellSet` of an uncertain type.
///
/// `UncertainCellSet` holds a `CellSet` object using runtime polymorphism to
/// manage different types. It behaves like its superclass, `UnknownCellSet`,
/// except that it also contains a template parameter that provides a
/// `vtkm::List` of potential cell set types.
///
/// These potental types come into play when the `CastAndCall` method is called
/// (or the `UncertainCellSet` is used in the `vtkm::cont::CastAndCall` function).
/// In this case, the `CastAndCall` will search for `CellSet`s of types that match
/// this list.
///
/// Both `UncertainCellSet` and `UnknownCellSet` have a method named
/// `ResetCellSetList` that redefines the list of potential cell sets by returning
/// a new `UncertainCellSet` containing the same `CellSet` but with the new cell
/// set type list.
///
template <typename CellSetList>
class VTKM_ALWAYS_EXPORT UncertainCellSet : public vtkm::cont::UnknownCellSet
{
VTKM_IS_LIST(CellSetList);
VTKM_STATIC_ASSERT_MSG((!std::is_same<CellSetList, vtkm::ListUniversal>::value),
"Cannot use vtkm::ListUniversal with UncertainCellSet.");
using Superclass = UnknownCellSet;
using Thisclass = UncertainCellSet<CellSetList>;
public:
VTKM_CONT UncertainCellSet() = default;
template <typename CellSetType>
VTKM_CONT UncertainCellSet(const CellSetType& cellSet)
: Superclass(cellSet)
{
}
explicit VTKM_CONT UncertainCellSet(const vtkm::cont::UnknownCellSet& src)
: Superclass(src)
{
}
UncertainCellSet(const Thisclass&) = default;
template <typename OtherCellSetList>
explicit VTKM_CONT UncertainCellSet(const UncertainCellSet<OtherCellSetList>& src)
: Superclass(src)
{
}
/// \brief Create a new cell set of the same type as this.
///
/// This method creates a new cell set that is the same type as this one and
/// returns a new `UncertainCellSet` for it.
///
VTKM_CONT Thisclass NewInstance() const { return Thisclass(this->Superclass::NewInstance()); }
/// \brief Call a functor using the underlying cell set type.
///
/// `CastAndCall` attempts to cast the held cell set to a specific type,
/// and then calls the given functor with the cast cell set.
///
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCall(Functor&& functor, Args&&... args) const
{
this->CastAndCallForTypes<CellSetList>(std::forward<Functor>(functor),
std::forward<Args>(args)...);
}
};
// Defined here to avoid circular dependencies between UnknownCellSet and UncertainCellSet.
template <typename NewCellSetList>
VTKM_CONT vtkm::cont::UncertainCellSet<NewCellSetList> UnknownCellSet::ResetCellSetList(
NewCellSetList) const
{
return vtkm::cont::UncertainCellSet<NewCellSetList>(*this);
}
template <typename NewCellSetList>
VTKM_CONT vtkm::cont::UncertainCellSet<NewCellSetList> UnknownCellSet::ResetCellSetList() const
{
return vtkm::cont::UncertainCellSet<NewCellSetList>(*this);
}
namespace internal
{
template <typename CellSetList>
struct DynamicTransformTraits<vtkm::cont::UncertainCellSet<CellSetList>>
{
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
};
} // namespace internal
} // namespace vtkm::cont
} // namespace vtkm
//=============================================================================
// Specializations of serialization related classes
/// @cond SERIALIZATION
namespace vtkm
{
namespace cont
{
template <typename CellSetList>
struct SerializableTypeString<vtkm::cont::UncertainCellSet<CellSetList>>
{
static VTKM_CONT std::string Get()
{
return SerializableTypeString<vtkm::cont::UnknownCellSet>::Get();
}
};
}
} // namespace vtkm::cont
namespace mangled_diy_namespace
{
namespace internal
{
struct UncertainCellSetSerializeFunctor
{
template <typename CellSetType>
void operator()(const CellSetType& cs, BinaryBuffer& bb) const
{
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<CellSetType>::Get());
vtkmdiy::save(bb, cs);
}
};
struct UncertainCellSetDeserializeFunctor
{
template <typename CellSetType>
void operator()(CellSetType,
vtkm::cont::UnknownCellSet& unknownCellSet,
const std::string& typeString,
bool& success,
BinaryBuffer& bb) const
{
if (!success && (typeString == vtkm::cont::SerializableTypeString<CellSetType>::Get()))
{
CellSetType knownCellSet;
vtkmdiy::load(bb, knownCellSet);
unknownCellSet = knownCellSet;
success = true;
}
}
};
} // internal
template <typename CellSetList>
struct Serialization<vtkm::cont::UncertainCellSet<CellSetList>>
{
using Type = vtkm::cont::UncertainCellSet<CellSetList>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj)
{
obj.CastAndCall(internal::UncertainCellSetSerializeFunctor{}, bb);
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& obj)
{
std::string typeString;
vtkmdiy::load(bb, typeString);
bool success = false;
vtkm::ListForEach(
internal::UncertainCellSetDeserializeFunctor{}, CellSetList{}, obj, typeString, success, bb);
if (!success)
{
throw vtkm::cont::ErrorBadType(
"Error deserializing Unknown/UncertainCellSet. Message TypeString: " + typeString);
}
}
};
} // namespace mangled_diy_namespace
/// @endcond SERIALIZATION
#endif //vtk_m_cont_UncertainCellSet_h

@ -600,7 +600,7 @@ public:
///@{
/// Returns this array cast appropriately and stored in the given `ArrayHandle` type.
/// Throws an `ErrorBadType` if the stored array cannot be stored in the given array type.
/// Use the `IsType` method to determine if the array can be returned with the given type.
/// Use the `CanConvert` method to determine if the array can be returned with the given type.
///
template <typename T, typename S>
VTKM_CONT void AsArrayHandle(vtkm::cont::ArrayHandle<T, S>& array) const

@ -0,0 +1,114 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/UnknownCellSet.h>
#include <vtkm/cont/UncertainCellSet.h>
#include <sstream>
namespace
{
// Could potentially precompile more cell sets to serialze if that is useful.
using UnknownSerializationCellSets = VTKM_DEFAULT_CELL_SET_LIST;
}
namespace vtkm
{
namespace cont
{
vtkm::cont::UnknownCellSet UnknownCellSet::NewInstance() const
{
UnknownCellSet newCellSet;
if (this->Container)
{
newCellSet.Container = this->Container->NewInstance();
}
return newCellSet;
}
std::string UnknownCellSet::GetCellSetName() const
{
if (this->Container)
{
return vtkm::cont::TypeToString(typeid(this->Container.get()));
}
else
{
return "";
}
}
void UnknownCellSet::PrintSummary(std::ostream& os) const
{
if (this->Container)
{
this->Container->PrintSummary(os);
}
else
{
os << " UnknownCellSet = nullptr\n";
}
}
namespace internal
{
void ThrowCastAndCallException(const vtkm::cont::UnknownCellSet& ref, const std::type_info& type)
{
std::ostringstream out;
out << "Could not find appropriate cast for cell set in CastAndCall.\n"
"CellSet: ";
ref.PrintSummary(out);
out << "TypeList: " << vtkm::cont::TypeToString(type) << "\n";
throw vtkm::cont::ErrorBadType(out.str());
}
} // namespace internal
} // namespace vtkm::cont
} // namespace vtkm
//=============================================================================
// Specializations of serialization related classes
namespace vtkm
{
namespace cont
{
std::string SerializableTypeString<vtkm::cont::UnknownCellSet>::Get()
{
return "UnknownCS";
}
}
} // namespace vtkm::cont
namespace mangled_diy_namespace
{
void Serialization<vtkm::cont::UnknownCellSet>::save(BinaryBuffer& bb,
const vtkm::cont::UnknownCellSet& obj)
{
vtkmdiy::save(bb, obj.ResetCellSetList<UnknownSerializationCellSets>());
}
void Serialization<vtkm::cont::UnknownCellSet>::load(BinaryBuffer& bb,
vtkm::cont::UnknownCellSet& obj)
{
vtkm::cont::UncertainCellSet<UnknownSerializationCellSets> uncertainCellSet;
vtkmdiy::load(bb, uncertainCellSet);
obj = uncertainCellSet;
}
} // namespace mangled_diy_namespace

391
vtkm/cont/UnknownCellSet.h Normal file

@ -0,0 +1,391 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_cont_UnknownCellSet_h
#define vtk_m_cont_UnknownCellSet_h
#include <vtkm/cont/CastAndCall.h>
#include <vtkm/cont/CellSet.h>
#include <vtkm/cont/DefaultTypes.h>
#include <vtkm/cont/vtkm_cont_export.h>
#include <memory>
namespace vtkm
{
namespace cont
{
// Forward declaration. Include UncertainCellSet.h if using this.
template <typename CellSetList>
class UncertainCellSet;
/// \brief A CellSet of an unknown type.
///
/// `UnknownCellSet` holds a `CellSet` object using runtime polymorphism to manage
/// the dynamic type rather than compile-time templates. This adds a programming
/// convenience that helps avoid a proliferation of templates.
///
/// To interface between the runtime polymorphism and the templated algorithms
/// in VTK-m, `UnknownCellSet` contains a method named `CastAndCallForTypes` that
/// determines the correct type from some known list of types. This mechanism is
/// used internally by VTK-m's worklet invocation mechanism to determine the type
/// when running algorithms.
///
/// If the `UnknownCellSet` is used in a context where the possible cell set types
/// can be whittled down to a finite list, you can specify lists of cell set types
/// using the `ResetCellSetList` method. This will convert this object to an
/// `UncertainCellSet` of the given types. In cases where a finite set of types
/// are needed but there is no subset, `VTKM_DEFAULT_CELL_SET_LIST`
///
class VTKM_CONT_EXPORT UnknownCellSet
{
std::shared_ptr<vtkm::cont::CellSet> Container;
void InitializeKnownOrUnknownCellSet(const UnknownCellSet& cellSet,
std::true_type vtkmNotUsed(isUnknownCellSet))
{
*this = cellSet;
}
template <typename CellSetType>
void InitializeKnownOrUnknownCellSet(const CellSetType& cellSet,
std::false_type vtkmNotUsed(isUnknownCellSet))
{
VTKM_IS_CELL_SET(CellSetType);
this->Container = std::shared_ptr<vtkm::cont::CellSet>(new CellSetType(cellSet));
}
public:
VTKM_CONT UnknownCellSet() = default;
UnknownCellSet(const UnknownCellSet&) = default;
template <typename CellSetType>
VTKM_CONT UnknownCellSet(const CellSetType& cellSet)
{
this->InitializeKnownOrUnknownCellSet(
cellSet, typename std::is_base_of<UnknownCellSet, CellSetType>::type{});
}
/// \brief Returns whether a cell set is stored in this `UnknownCellSet`.
///
/// If the `UnknownCellSet` is constructed without a `CellSet`, it will not
/// have an underlying type, and therefore the operations will be invalid.
///
VTKM_CONT bool IsValid() const { return static_cast<bool>(this->Container); }
/// \brief Returns a pointer to the `CellSet` base class.
///
VTKM_CONT vtkm::cont::CellSet* GetCellSetBase() { return this->Container.get(); }
VTKM_CONT const vtkm::cont::CellSet* GetCellSetBase() const { return this->Container.get(); }
/// \brief Create a new cell set of the same type as this cell set.
///
/// This method creates a new cell set that is the same type as this one
/// and returns a new `UnknownCellSet` for it. This method is convenient
/// when creating output cell sets that should be the same type as the
/// input cell set.
///
VTKM_CONT UnknownCellSet NewInstance() const;
/// \brief Returns the name of the cell set type stored in this class.
///
/// Returns an empty string if no cell set is stored.
///
VTKM_CONT std::string GetCellSetName() const;
/// \brief Returns true if this cell set matches the `CellSetType` template argument.
///
template <typename CellSetType>
VTKM_CONT bool IsType() const
{
return (dynamic_cast<const CellSetType*>(this->Container.get()) != nullptr);
}
VTKM_CONT vtkm::Id GetNumberOfCells() const
{
return this->Container ? this->Container->GetNumberOfCells() : 0;
}
VTKM_CONT vtkm::Id GetNumberOfFaces() const
{
return this->Container ? this->Container->GetNumberOfFaces() : 0;
}
VTKM_CONT vtkm::Id GetNumberOfEdges() const
{
return this->Container ? this->Container->GetNumberOfEdges() : 0;
}
VTKM_CONT vtkm::Id GetNumberOfPoints() const
{
return this->Container ? this->Container->GetNumberOfPoints() : 0;
}
VTKM_CONT vtkm::UInt8 GetCellShape(vtkm::Id id) const
{
return this->GetCellSetBase()->GetCellShape(id);
}
VTKM_CONT vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id id) const
{
return this->GetCellSetBase()->GetNumberOfPointsInCell(id);
}
VTKM_CONT void GetCellPointIds(vtkm::Id id, vtkm::Id* ptids) const
{
return this->GetCellSetBase()->GetCellPointIds(id, ptids);
}
VTKM_CONT void DeepCopyFrom(const CellSet* src) { this->GetCellSetBase()->DeepCopy(src); }
VTKM_CONT void PrintSummary(std::ostream& os) const;
VTKM_CONT void ReleaseResourcesExecution()
{
if (this->Container)
{
this->Container->ReleaseResourcesExecution();
}
}
/// \brief Returns true if this cell set can be retrieved as the given type.
///
/// This method will return true if calling `AsCellSet` of the given type will
/// succeed. This result is similar to `IsType`, and if `IsType` returns true,
/// then this will return true. However, this method will also return true for
/// other types where automatic conversions are made.
///
template <typename CellSetType>
VTKM_CONT bool CanConvert() const
{
// TODO: Currently, these are the same. But in the future we expect to support
// special CellSet types that can convert back and forth such as multiplexed
// cell sets or a cell set that can hold structured grids of any dimension.
return this->IsType<CellSetType>();
}
///@{
/// \brief Get the cell set as a known type.
///
/// Returns this cell set cast appropriately and stored in the given `CellSet`
/// type. Throws an `ErrorBadType` if the stored cell set cannot be stored in
/// the given cell set type. Use the `CanConvert` method to determine if the
/// cell set can be returned with the given type.
///
template <typename CellSetType>
VTKM_CONT void AsCellSet(CellSetType& cellSet) const
{
VTKM_IS_CELL_SET(CellSetType);
CellSetType* cellSetPointer = dynamic_cast<CellSetType*>(this->Container.get());
if (cellSetPointer == nullptr)
{
VTKM_LOG_CAST_FAIL(*this, CellSetType);
throwFailedDynamicCast(this->GetCellSetName(), vtkm::cont::TypeToString(cellSet));
}
VTKM_LOG_CAST_SUCC(*this, *cellSetPointer);
cellSet = *cellSetPointer;
}
template <typename CellSetType>
VTKM_CONT CellSetType AsCellSet() const
{
CellSetType cellSet;
this->AsCellSet(cellSet);
return cellSet;
}
///@}
/// \brief Assigns potential cell set types.
///
/// Calling this method will return an `UncertainCellSet` with the provided
/// cell set list. The returned object will hold the same `CellSet`, but
/// `CastAndCall`'s on the returned object will be constrained to the given
/// types.
///
// Defined in UncertainCellSet.h
template <typename CellSetList>
VTKM_CONT vtkm::cont::UncertainCellSet<CellSetList> ResetCellSetList(CellSetList) const;
template <typename CellSetList>
VTKM_CONT vtkm::cont::UncertainCellSet<CellSetList> ResetCellSetList() const;
/// \brief Call a functor using the underlying cell set type.
///
/// `CastAndCallForTypes` attemts to cast the held cell set to a specific type
/// and then calls the given functor with the cast cell set. You must specify
/// the `CellSetList` (in a `vtkm::List`) as a template argument.
///
/// After the functor argument, you may add any number of arguments that will
/// be passed to the functor after the converted cell set.
///
template <typename CellSetList, typename Functor, typename... Args>
VTKM_CONT void CastAndCallForTypes(Functor&& functor, Args&&... args) const;
// Support for (soon to be) deprecated DynamicCellSet
// TODO: Deprecate these methods
template <typename CellSetType>
VTKM_CONT bool IsSameType(const CellSetType&) const
{
return this->IsType<CellSetType>();
}
template <typename CellSetType>
VTKM_CONT CellSetType& Cast() const
{
VTKM_IS_CELL_SET(CellSetType);
CellSetType* cellSetPointer = dynamic_cast<CellSetType*>(this->Container.get());
if (cellSetPointer == nullptr)
{
VTKM_LOG_CAST_FAIL(*this, CellSetType);
throwFailedDynamicCast(this->GetCellSetName(), vtkm::cont::TypeToString<CellSetType>());
}
VTKM_LOG_CAST_SUCC(*this, *cellSetPointer);
return *cellSetPointer;
}
template <typename CellSetType>
VTKM_CONT void CopyTo(CellSetType& cellSet) const
{
return this->AsCellSet(cellSet);
}
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCall(Functor&& f, Args&&... args) const
{
this->CastAndCallForTypes<VTKM_DEFAULT_CELL_SET_LIST>(std::forward<Functor>(f),
std::forward<Args>(args)...);
}
};
//=============================================================================
// Free function casting helpers
// (Not sure if these should be deprecated.)
/// Returns true if `unknownCellSet` matches the type of `CellSetType`.
///
template <typename CellSetType>
VTKM_CONT inline bool IsType(const vtkm::cont::UnknownCellSet& unknownCellSet)
{
return unknownCellSet.IsType<CellSetType>();
}
/// Returns `unknownCellSet` cast to the given `CellSet` type. Throws
/// `ErrorBadType` if the cast does not work. Use `IsType`
/// to check if the cast can happen.
///
template <typename CellSetType>
VTKM_CONT inline CellSetType Cast(const vtkm::cont::UnknownCellSet& unknownCellSet)
{
return unknownCellSet.Cast<CellSetType>();
}
namespace internal
{
VTKM_CONT_EXPORT void ThrowCastAndCallException(const vtkm::cont::UnknownCellSet&,
const std::type_info&);
template <>
struct DynamicTransformTraits<vtkm::cont::UnknownCellSet>
{
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
};
} // namespace internal
template <typename CellSetList, typename Functor, typename... Args>
VTKM_CONT void UnknownCellSet::CastAndCallForTypes(Functor&& functor, Args&&... args) const
{
VTKM_IS_LIST(CellSetList);
bool called = false;
vtkm::ListForEach(
[&](auto cellSet) {
if (!called && this->CanConvert<decltype(cellSet)>())
{
called = true;
this->AsCellSet(cellSet);
VTKM_LOG_CAST_SUCC(*this, cellSet);
// If you get a compile error here, it means that you have called CastAndCall for a
// vtkm::cont::UnknownCellSet and the arguments of the functor do not match those
// being passed. This is often because it is calling the functor with a CellSet
// type that was not expected. Either add overloads to the functor to accept all
// possible cell set types or constrain the types tried for the CastAndCall.
functor(cellSet, args...);
}
},
CellSetList{});
if (!called)
{
VTKM_LOG_CAST_FAIL(*this, CellSetList);
internal::ThrowCastAndCallException(*this, typeid(CellSetList));
}
}
/// A specialization of `CastAndCall` for `UnknownCellSet`.
/// Since we have no hints on the types, use `VTKM_DEFAULT_CELL_SET_LIST`.
template <typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::UnknownCellSet& cellSet, Functor&& f, Args&&... args)
{
cellSet.CastAndCallForTypes<VTKM_DEFAULT_CELL_SET_LIST>(std::forward<Functor>(f),
std::forward<Args>(args)...);
}
namespace internal
{
/// Checks to see if the given object is an unknown (or uncertain) cell set. It
/// resolves to either `std::true_type` or `std::false_type`.
///
template <typename T>
using UnknownCellSetCheck = typename std::is_base_of<vtkm::cont::UnknownCellSet, T>::type;
#define VTKM_IS_UNKNOWN_CELL_SET(T) \
VTKM_STATIC_ASSERT(::vtkm::cont::internal::UnknownCellSetCheck<T>::value)
#define VTKM_IS_KNOWN_OR_UNKNOWN_CELL_SET(T) \
VTKM_STATIC_ASSERT(::vtkm::cont::internal::CellSetCheck<T>::type::value || \
::vtkm::cont::internal::UnknownCellSetCheck<T>::value)
} // namespace internal
} // namespace vtkm::cont
} // namespace vtkm
//=============================================================================
// Specializations of serialization related classes
/// @cond SERIALIZATION
namespace vtkm
{
namespace cont
{
template <>
struct VTKM_CONT_EXPORT SerializableTypeString<vtkm::cont::UnknownCellSet>
{
static VTKM_CONT std::string Get();
};
}
} // namespace vtkm::cont
namespace mangled_diy_namespace
{
template <>
struct VTKM_CONT_EXPORT Serialization<vtkm::cont::UnknownCellSet>
{
public:
static VTKM_CONT void save(BinaryBuffer& bb, const vtkm::cont::UnknownCellSet& obj);
static VTKM_CONT void load(BinaryBuffer& bb, vtkm::cont::UnknownCellSet& obj);
};
} // namespace mangled_diy_namespace
/// @endcond SERIALIZATION
#endif //vtk_m_cont_UnknownCellSet_h

@ -94,6 +94,7 @@ set(unit_tests
UnitTestToken.cxx
UnitTestTryExecute.cxx
UnitTestUnknownArrayHandle.cxx
UnitTestUnknownCellSet.cxx
UnitTestVariantArrayHandle.cxx
)
@ -103,7 +104,6 @@ set(library_sources
)
set(library_sources_device
TestEqualArrayHandles.cxx # Really doesn't need device, but currently includes device headers
)
vtkm_library(

@ -22,6 +22,7 @@
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/UncertainCellSet.h>
#include <vtkm/cont/UnknownArrayHandle.h>
#include <vtkm/cont/testing/vtkm_cont_testing_export.h>
@ -459,10 +460,24 @@ namespace detail
struct TestEqualCellSet
{
template <typename CellSetType1, typename CellSetType2>
void operator()(const CellSetType1& cs1, const CellSetType2& cs2, TestEqualResult& result) const
{
// Avoid ambiguous overloads by specifying whether each cell type is known or unknown.
this->Run(cs1,
typename vtkm::cont::internal::CellSetCheck<CellSetType1>::type{},
cs2,
typename vtkm::cont::internal::CellSetCheck<CellSetType2>::type{},
result);
}
private:
template <typename ShapeST, typename ConnectivityST, typename OffsetST>
void operator()(const vtkm::cont::CellSetExplicit<ShapeST, ConnectivityST, OffsetST>& cs1,
const vtkm::cont::CellSetExplicit<ShapeST, ConnectivityST, OffsetST>& cs2,
TestEqualResult& result) const
void Run(const vtkm::cont::CellSetExplicit<ShapeST, ConnectivityST, OffsetST>& cs1,
std::true_type,
const vtkm::cont::CellSetExplicit<ShapeST, ConnectivityST, OffsetST>& cs2,
std::true_type,
TestEqualResult& result) const
{
vtkm::TopologyElementTagCell visitTopo{};
vtkm::TopologyElementTagPoint incidentTopo{};
@ -505,9 +520,11 @@ struct TestEqualCellSet
}
template <vtkm::IdComponent DIMENSION>
void operator()(const vtkm::cont::CellSetStructured<DIMENSION>& cs1,
const vtkm::cont::CellSetStructured<DIMENSION>& cs2,
TestEqualResult& result) const
void Run(const vtkm::cont::CellSetStructured<DIMENSION>& cs1,
std::true_type,
const vtkm::cont::CellSetStructured<DIMENSION>& cs2,
std::true_type,
TestEqualResult& result) const
{
if (cs1.GetPointDimensions() != cs2.GetPointDimensions())
{
@ -517,26 +534,56 @@ struct TestEqualCellSet
}
template <typename CellSetTypes1, typename CellSetTypes2>
void operator()(const vtkm::cont::DynamicCellSetBase<CellSetTypes1>& cs1,
const vtkm::cont::DynamicCellSetBase<CellSetTypes2>& cs2,
TestEqualResult& result) const
void Run(const vtkm::cont::DynamicCellSetBase<CellSetTypes1>& cs1,
std::false_type,
const vtkm::cont::DynamicCellSetBase<CellSetTypes2>& cs2,
std::false_type,
TestEqualResult& result) const
{
cs1.CastAndCall(*this, cs2, result);
}
template <typename CellSet, typename CellSetTypes>
void operator()(const CellSet& cs,
const vtkm::cont::DynamicCellSetBase<CellSetTypes>& dcs,
TestEqualResult& result) const
template <typename CellSetType>
void Run(const CellSetType& cs1,
std::true_type,
const vtkm::cont::UnknownCellSet& cs2,
std::false_type,
TestEqualResult& result) const
{
if (!dcs.IsSameType(cs))
if (!cs2.CanConvert<CellSetType>())
{
result.PushMessage("types don't match");
return;
}
this->operator()(cs, dcs.template Cast<CellSet>(), result);
this->Run(cs1, std::true_type{}, cs2.AsCellSet<CellSetType>(), std::true_type{}, result);
}
template <typename CellSetType>
void Run(const vtkm::cont::UnknownCellSet& cs1,
std::false_type,
const CellSetType& cs2,
std::true_type,
TestEqualResult& result) const
{
if (!cs1.CanConvert<CellSetType>())
{
result.PushMessage("types don't match");
return;
}
this->Run(cs1.AsCellSet<CellSetType>(), std::true_type{}, cs2, std::true_type{}, result);
}
template <typename UnknownCellSetType>
void Run(const UnknownCellSetType& cs1,
std::false_type,
const vtkm::cont::UnknownCellSet& cs2,
std::false_type,
TestEqualResult& result) const
{
vtkm::cont::CastAndCall(cs1, *this, cs2, result);
}
};
} // detail
template <typename CellSet1, typename CellSet2>

@ -17,6 +17,8 @@
#include <vtkm/cont/PointLocatorSparseGrid.h>
#include <vtkm/worklet/WorkletMapField.h>
////brute force method /////
template <typename CoordiVecT, typename CoordiPortalT, typename CoordiT>
VTKM_EXEC_CONT vtkm::Id NNSVerify3D(CoordiVecT qc, CoordiPortalT coordiPortal, CoordiT& dis2)
@ -91,7 +93,6 @@ template <typename DeviceAdapter>
class TestingPointLocatorSparseGrid
{
public:
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
void TestTest() const
{
vtkm::Int32 nTrainingPoints = 5;

@ -100,7 +100,7 @@ void CheckDynamicCellSet(const CellSetType& cellSet,
}
template <typename CellSetType, typename CellSetList>
void TryNewInstance(CellSetType, vtkm::cont::DynamicCellSetBase<CellSetList>& originalCellSet)
void TryNewInstance(CellSetType, vtkm::cont::DynamicCellSetBase<CellSetList> originalCellSet)
{
vtkm::cont::DynamicCellSetBase<CellSetList> newCellSet = originalCellSet.NewInstance();
@ -111,7 +111,7 @@ void TryNewInstance(CellSetType, vtkm::cont::DynamicCellSetBase<CellSetList>& or
}
template <typename CellSetType, typename CellSetList>
void TryCellSet(CellSetType cellSet, vtkm::cont::DynamicCellSetBase<CellSetList>& dynamicCellSet)
void TryCellSet(CellSetType cellSet, vtkm::cont::DynamicCellSetBase<CellSetList> dynamicCellSet)
{
CheckDynamicCellSet(cellSet, dynamicCellSet);
@ -120,6 +120,12 @@ void TryCellSet(CellSetType cellSet, vtkm::cont::DynamicCellSetBase<CellSetList>
TryNewInstance(cellSet, dynamicCellSet);
}
template <typename CellSetType>
void TryCellSet(CellSetType cellSet, vtkm::cont::DynamicCellSet dynamicCellSet)
{
TryCellSet(cellSet, dynamicCellSet.ResetCellSetList<VTKM_DEFAULT_CELL_SET_LIST>());
}
template <typename CellSetType>
void TryDefaultCellSet(CellSetType cellSet)
{

@ -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.
//============================================================================
#include <vtkm/cont/UncertainCellSet.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
using NonDefaultCellSetList =
vtkm::List<vtkm::cont::CellSetStructured<1>,
vtkm::cont::CellSetExplicit<vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag>>;
template <typename ExpectedCellType>
struct CheckFunctor
{
void operator()(const ExpectedCellType&, bool& called) const { called = true; }
template <typename UnexpectedType>
void operator()(const UnexpectedType&, bool& called) const
{
VTKM_TEST_FAIL("CastAndCall functor called with wrong type.");
called = false;
}
};
class DummyCellSet : public vtkm::cont::CellSet
{
};
void CheckEmptyUnknownCellSet()
{
vtkm::cont::UnknownCellSet empty;
VTKM_TEST_ASSERT(empty.GetNumberOfCells() == 0, "UnknownCellSet should have no cells");
VTKM_TEST_ASSERT(empty.GetNumberOfFaces() == 0, "UnknownCellSet should have no faces");
VTKM_TEST_ASSERT(empty.GetNumberOfEdges() == 0, "UnknownCellSet should have no edges");
VTKM_TEST_ASSERT(empty.GetNumberOfPoints() == 0, "UnknownCellSet should have no points");
empty.PrintSummary(std::cout);
using CellSet2D = vtkm::cont::CellSetStructured<2>;
using CellSet3D = vtkm::cont::CellSetStructured<3>;
VTKM_TEST_ASSERT(!empty.IsType<CellSet2D>(), "UnknownCellSet reports wrong type.");
VTKM_TEST_ASSERT(!empty.IsType<CellSet3D>(), "UnknownCellSet reports wrong type.");
VTKM_TEST_ASSERT(!empty.IsType<DummyCellSet>(), "UnknownCellSet reports wrong type.");
VTKM_TEST_ASSERT(!empty.CanConvert<CellSet2D>(), "UnknownCellSet reports wrong type.");
VTKM_TEST_ASSERT(!empty.CanConvert<CellSet3D>(), "UnknownCellSet reports wrong type.");
VTKM_TEST_ASSERT(!empty.CanConvert<DummyCellSet>(), "UnknownCellSet reports wrong type.");
bool gotException = false;
try
{
CellSet2D instance = empty.AsCellSet<CellSet2D>();
}
catch (vtkm::cont::ErrorBadType&)
{
gotException = true;
}
VTKM_TEST_ASSERT(gotException, "Empty UnknownCellSet should have thrown on casting");
auto empty2 = empty.NewInstance();
VTKM_TEST_ASSERT(empty.GetCellSetBase() == nullptr, "UnknownCellSet should contain a nullptr");
VTKM_TEST_ASSERT(empty2.GetCellSetBase() == nullptr, "UnknownCellSet should contain a nullptr");
}
template <typename CellSetType, typename CellSetList>
void CheckUnknownCellSet(vtkm::cont::UnknownCellSet unknownCellSet)
{
VTKM_TEST_ASSERT(unknownCellSet.CanConvert<CellSetType>());
VTKM_TEST_ASSERT(!unknownCellSet.CanConvert<DummyCellSet>());
unknownCellSet.AsCellSet<CellSetType>();
bool called = false;
unknownCellSet.CastAndCallForTypes<CellSetList>(CheckFunctor<CellSetType>(), called);
VTKM_TEST_ASSERT(
called, "The functor was never called (and apparently a bad value exception not thrown).");
if (vtkm::ListHas<CellSetList, VTKM_DEFAULT_CELL_SET_LIST>::value)
{
called = false;
CastAndCall(unknownCellSet, CheckFunctor<CellSetType>(), called);
VTKM_TEST_ASSERT(
called, "The functor was never called (and apparently a bad value exception not thrown).");
}
vtkm::cont::UncertainCellSet<CellSetList> uncertainCellSet(unknownCellSet);
called = false;
uncertainCellSet.CastAndCall(CheckFunctor<CellSetType>(), called);
VTKM_TEST_ASSERT(
called, "The functor was never called (and apparently a bad value exception not thrown).");
called = false;
CastAndCall(uncertainCellSet, CheckFunctor<CellSetType>(), called);
VTKM_TEST_ASSERT(
called, "The functor was never called (and apparently a bad value exception not thrown).");
}
template <typename CellSetType>
void TryNewInstance(vtkm::cont::UnknownCellSet& originalCellSet)
{
vtkm::cont::UnknownCellSet newCellSet = originalCellSet.NewInstance();
VTKM_TEST_ASSERT(newCellSet.IsType<CellSetType>(), "New cell set wrong type.");
VTKM_TEST_ASSERT(originalCellSet.GetCellSetBase() != newCellSet.GetCellSetBase(),
"NewInstance did not make a copy.");
}
template <typename CellSetType, typename CellSetList>
void TryCellSet(vtkm::cont::UnknownCellSet& unknownCellSet)
{
CheckUnknownCellSet<CellSetType, CellSetList>(unknownCellSet);
CheckUnknownCellSet<CellSetType, vtkm::List<CellSetType>>(unknownCellSet);
TryNewInstance<CellSetType>(unknownCellSet);
}
template <typename CellSetType>
void TryDefaultCellSet(CellSetType cellSet)
{
vtkm::cont::UnknownCellSet unknownCellSet(cellSet);
TryCellSet<CellSetType, VTKM_DEFAULT_CELL_SET_LIST>(unknownCellSet);
}
template <typename CellSetType>
void TryNonDefaultCellSet(CellSetType cellSet)
{
vtkm::cont::UnknownCellSet unknownCellSet(cellSet);
TryCellSet<CellSetType, NonDefaultCellSetList>(unknownCellSet);
}
void TestDynamicCellSet()
{
std::cout << "Try default types with default type lists." << std::endl;
std::cout << "*** 2D Structured Grid ******************" << std::endl;
TryDefaultCellSet(vtkm::cont::CellSetStructured<2>());
std::cout << "*** 3D Structured Grid ******************" << std::endl;
TryDefaultCellSet(vtkm::cont::CellSetStructured<3>());
std::cout << "*** Explicit Grid ***********************" << std::endl;
TryDefaultCellSet(vtkm::cont::CellSetExplicit<>());
std::cout << std::endl << "Try non-default types." << std::endl;
std::cout << "*** 1D Structured Grid ******************" << std::endl;
TryNonDefaultCellSet(vtkm::cont::CellSetStructured<1>());
std::cout << "*** Explicit Grid Constant Shape ********" << std::endl;
TryNonDefaultCellSet(
vtkm::cont::CellSetExplicit<vtkm::cont::ArrayHandleConstant<vtkm::UInt8>::StorageTag>());
std::cout << std::endl << "Try empty DynamicCellSet." << std::endl;
CheckEmptyUnknownCellSet();
}
} // anonymous namespace
int UnitTestUnknownCellSet(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestDynamicCellSet, argc, argv);
}

@ -11,8 +11,6 @@
#define vtk_m_exec_PointLocatorSparseGrid_h
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/Deprecated.h>
#include <vtkm/VectorAnalysis.h>

@ -26,8 +26,7 @@ namespace filter
namespace
{
template <typename CellSetList>
inline bool IsCellSetStructured(const vtkm::cont::DynamicCellSetBase<CellSetList>& cellset)
inline bool IsCellSetStructured(const vtkm::cont::UnknownCellSet& cellset)
{
if (cellset.template IsType<vtkm::cont::CellSetStructured<1>>() ||
cellset.template IsType<vtkm::cont::CellSetStructured<2>>() ||

@ -25,7 +25,7 @@ namespace filter
/// Takes as input a vector field and seed locations and advects the seeds
/// through the flow field.
template <class Derived>
template <class Derived, typename ParticleType>
class FilterParticleAdvection : public vtkm::filter::FilterDataSetWithField<Derived>
{
public:
@ -41,14 +41,14 @@ public:
void SetNumberOfSteps(vtkm::Id n) { this->NumberOfSteps = n; }
VTKM_CONT
void SetSeeds(const std::vector<vtkm::Particle>& seeds,
void SetSeeds(const std::vector<ParticleType>& seeds,
vtkm::CopyFlag copyFlag = vtkm::CopyFlag::On)
{
this->Seeds = vtkm::cont::make_ArrayHandle(seeds, copyFlag);
}
VTKM_CONT
void SetSeeds(vtkm::cont::ArrayHandle<vtkm::Particle>& seeds) { this->Seeds = seeds; }
void SetSeeds(vtkm::cont::ArrayHandle<ParticleType>& seeds) { this->Seeds = seeds; }
VTKM_CONT
bool GetUseThreadedAlgorithm() { return this->UseThreadedAlgorithm; }
@ -71,14 +71,13 @@ public:
protected:
VTKM_CONT virtual void ValidateOptions() const;
using DSIType = vtkm::filter::particleadvection::DataSetIntegrator;
VTKM_CONT std::vector<DSIType> CreateDataSetIntegrators(
const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::particleadvection::BoundsMap& boundsMap) const;
VTKM_CONT std::vector<vtkm::filter::particleadvection::DataSetIntegrator>
CreateDataSetIntegrators(const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::particleadvection::BoundsMap& boundsMap) const;
vtkm::Id NumberOfSteps;
vtkm::FloatDefault StepSize;
vtkm::cont::ArrayHandle<vtkm::Particle> Seeds;
vtkm::cont::ArrayHandle<ParticleType> Seeds;
bool UseThreadedAlgorithm;
private:

@ -18,8 +18,8 @@ namespace filter
{
//-----------------------------------------------------------------------------
template <typename Derived>
inline VTKM_CONT FilterParticleAdvection<Derived>::FilterParticleAdvection()
template <typename Derived, typename ParticleType>
inline VTKM_CONT FilterParticleAdvection<Derived, ParticleType>::FilterParticleAdvection()
: vtkm::filter::FilterDataSetWithField<Derived>()
, NumberOfSteps(0)
, StepSize(0)
@ -27,8 +27,8 @@ inline VTKM_CONT FilterParticleAdvection<Derived>::FilterParticleAdvection()
{
}
template <typename Derived>
void FilterParticleAdvection<Derived>::ValidateOptions() const
template <typename Derived, typename ParticleType>
void FilterParticleAdvection<Derived, ParticleType>::ValidateOptions() const
{
if (this->GetUseCoordinateSystemAsField())
throw vtkm::cont::ErrorFilterExecution("Coordinate system as field not supported");
@ -40,13 +40,15 @@ void FilterParticleAdvection<Derived>::ValidateOptions() const
throw vtkm::cont::ErrorFilterExecution("Step size not specified.");
}
template <typename Derived>
template <typename Derived, typename ParticleType>
std::vector<vtkm::filter::particleadvection::DataSetIntegrator>
FilterParticleAdvection<Derived>::CreateDataSetIntegrators(
FilterParticleAdvection<Derived, ParticleType>::CreateDataSetIntegrators(
const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::particleadvection::BoundsMap& boundsMap) const
{
std::vector<vtkm::filter::particleadvection::DataSetIntegrator> dsi;
using DSIType = vtkm::filter::particleadvection::DataSetIntegrator;
std::vector<DSIType> dsi;
if (boundsMap.GetTotalNumBlocks() == 0)
throw vtkm::cont::ErrorFilterExecution("No input datasets.");
@ -66,9 +68,10 @@ FilterParticleAdvection<Derived>::CreateDataSetIntegrators(
}
//-----------------------------------------------------------------------------
template <typename Derived>
template <typename Derived, typename ParticleType>
template <typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet FilterParticleAdvection<Derived>::PrepareForExecution(
inline VTKM_CONT vtkm::cont::DataSet
FilterParticleAdvection<Derived, ParticleType>::PrepareForExecution(
const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
{

@ -25,8 +25,9 @@ namespace filter
/// Takes as input a vector field and seed locations and advects the seeds
/// through the flow field.
template <class Derived>
class FilterTemporalParticleAdvection : public vtkm::filter::FilterParticleAdvection<Derived>
template <class Derived, typename ParticleType>
class FilterTemporalParticleAdvection
: public vtkm::filter::FilterParticleAdvection<Derived, ParticleType>
{
public:
VTKM_CONT
@ -52,12 +53,11 @@ public:
protected:
VTKM_CONT void ValidateOptions(const vtkm::cont::PartitionedDataSet& input) const;
using vtkm::filter::FilterParticleAdvection<Derived>::ValidateOptions;
using vtkm::filter::FilterParticleAdvection<Derived, ParticleType>::ValidateOptions;
using DSIType = vtkm::filter::particleadvection::TemporalDataSetIntegrator;
VTKM_CONT std::vector<DSIType> CreateDataSetIntegrators(
const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::particleadvection::BoundsMap& boundsMap) const;
VTKM_CONT std::vector<vtkm::filter::particleadvection::TemporalDataSetIntegrator>
CreateDataSetIntegrators(const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::particleadvection::BoundsMap& boundsMap) const;
vtkm::FloatDefault PreviousTime;
vtkm::FloatDefault NextTime;

@ -18,19 +18,20 @@ namespace filter
{
//-----------------------------------------------------------------------------
template <typename Derived>
inline VTKM_CONT FilterTemporalParticleAdvection<Derived>::FilterTemporalParticleAdvection()
: vtkm::filter::FilterParticleAdvection<Derived>()
template <typename Derived, typename ParticleType>
inline VTKM_CONT
FilterTemporalParticleAdvection<Derived, ParticleType>::FilterTemporalParticleAdvection()
: vtkm::filter::FilterParticleAdvection<Derived, ParticleType>()
, PreviousTime(0)
, NextTime(0)
{
}
template <typename Derived>
void FilterTemporalParticleAdvection<Derived>::ValidateOptions(
template <typename Derived, typename ParticleType>
void FilterTemporalParticleAdvection<Derived, ParticleType>::ValidateOptions(
const vtkm::cont::PartitionedDataSet& input) const
{
this->vtkm::filter::FilterParticleAdvection<Derived>::ValidateOptions();
this->vtkm::filter::FilterParticleAdvection<Derived, ParticleType>::ValidateOptions();
if (this->NextDataSet.GetNumberOfPartitions() != input.GetNumberOfPartitions())
throw vtkm::cont::ErrorFilterExecution("Number of partitions do not match");
@ -38,12 +39,13 @@ void FilterTemporalParticleAdvection<Derived>::ValidateOptions(
throw vtkm::cont::ErrorFilterExecution("Previous time must be less than Next time.");
}
template <typename Derived>
template <typename Derived, typename ParticleType>
std::vector<vtkm::filter::particleadvection::TemporalDataSetIntegrator>
FilterTemporalParticleAdvection<Derived>::CreateDataSetIntegrators(
FilterTemporalParticleAdvection<Derived, ParticleType>::CreateDataSetIntegrators(
const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::particleadvection::BoundsMap& boundsMap) const
{
using DSIType = vtkm::filter::particleadvection::TemporalDataSetIntegrator;
std::vector<DSIType> dsi;
std::string activeField = this->GetActiveFieldName();
@ -65,9 +67,10 @@ FilterTemporalParticleAdvection<Derived>::CreateDataSetIntegrators(
}
//-----------------------------------------------------------------------------
template <typename Derived>
template <typename Derived, typename ParticleType>
template <typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet FilterTemporalParticleAdvection<Derived>::PrepareForExecution(
inline VTKM_CONT vtkm::cont::DataSet
FilterTemporalParticleAdvection<Derived, ParticleType>::PrepareForExecution(
const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
{

@ -23,16 +23,20 @@ namespace filter
/// Takes as input a vector field and seed locations and generates the
/// end points for each seed through the vector field.
class ParticleAdvection : public vtkm::filter::FilterParticleAdvection<ParticleAdvection>
template <typename ParticleType = vtkm::Particle>
class ParticleAdvectionBase
: public vtkm::filter::FilterParticleAdvection<ParticleAdvectionBase<ParticleType>, ParticleType>
{
public:
VTKM_CONT ParticleAdvection();
VTKM_CONT ParticleAdvectionBase();
template <typename DerivedPolicy>
vtkm::cont::PartitionedDataSet PrepareForExecution(
const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
};
using ParticleAdvection = ParticleAdvectionBase<vtkm::Particle>;
}
} // namespace vtkm::filter

@ -22,19 +22,23 @@ namespace filter
{
//-----------------------------------------------------------------------------
inline VTKM_CONT ParticleAdvection::ParticleAdvection()
: vtkm::filter::FilterParticleAdvection<ParticleAdvection>()
template <typename ParticleType>
inline VTKM_CONT ParticleAdvectionBase<ParticleType>::ParticleAdvectionBase()
: vtkm::filter::FilterParticleAdvection<ParticleAdvectionBase<ParticleType>, ParticleType>()
{
}
//-----------------------------------------------------------------------------
template <typename ParticleType>
template <typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::PartitionedDataSet ParticleAdvection::PrepareForExecution(
inline VTKM_CONT vtkm::cont::PartitionedDataSet
ParticleAdvectionBase<ParticleType>::PrepareForExecution(
const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
using AlgorithmType = vtkm::filter::particleadvection::ParticleAdvectionAlgorithm;
using ThreadedAlgorithmType = vtkm::filter::particleadvection::ParticleAdvectionThreadedAlgorithm;
using DSIType = vtkm::filter::particleadvection::DataSetIntegrator;
this->ValidateOptions();
vtkm::filter::particleadvection::BoundsMap boundsMap(input);

@ -21,11 +21,14 @@ namespace filter
/// Takes as input a vector field and seed locations and generates the
/// paths taken by the seeds through the vector field.
class PathParticle : public vtkm::filter::FilterTemporalParticleAdvection<PathParticle>
template <typename ParticleType>
class PathParticleBase
: public vtkm::filter::FilterTemporalParticleAdvection<PathParticleBase<ParticleType>,
ParticleType>
{
public:
VTKM_CONT
PathParticle();
PathParticleBase();
template <typename DerivedPolicy>
vtkm::cont::PartitionedDataSet PrepareForExecution(
@ -36,6 +39,8 @@ protected:
private:
};
using PathParticle = PathParticleBase<vtkm::Particle>;
}
} // namespace vtkm::filter

@ -23,19 +23,22 @@ namespace filter
{
//-----------------------------------------------------------------------------
inline VTKM_CONT PathParticle::PathParticle()
: vtkm::filter::FilterTemporalParticleAdvection<PathParticle>()
template <typename ParticleType>
inline VTKM_CONT PathParticleBase<ParticleType>::PathParticleBase()
: vtkm::filter::FilterTemporalParticleAdvection<PathParticleBase<ParticleType>, ParticleType>()
{
}
//-----------------------------------------------------------------------------
template <typename ParticleType>
template <typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::PartitionedDataSet PathParticle::PrepareForExecution(
inline VTKM_CONT vtkm::cont::PartitionedDataSet PathParticleBase<ParticleType>::PrepareForExecution(
const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
using AlgorithmType = vtkm::filter::particleadvection::PathParticleAlgorithm;
using ThreadedAlgorithmType = vtkm::filter::particleadvection::PathParticleThreadedAlgorithm;
using TDSIType = vtkm::filter::particleadvection::TemporalDataSetIntegrator;
this->ValidateOptions(input);
@ -43,10 +46,10 @@ inline VTKM_CONT vtkm::cont::PartitionedDataSet PathParticle::PrepareForExecutio
auto dsi = this->CreateDataSetIntegrators(input, boundsMap);
if (this->GetUseThreadedAlgorithm())
return vtkm::filter::particleadvection::RunAlgo<DSIType, ThreadedAlgorithmType>(
return vtkm::filter::particleadvection::RunAlgo<TDSIType, ThreadedAlgorithmType>(
boundsMap, dsi, this->NumberOfSteps, this->StepSize, this->Seeds);
else
return vtkm::filter::particleadvection::RunAlgo<DSIType, AlgorithmType>(
return vtkm::filter::particleadvection::RunAlgo<TDSIType, AlgorithmType>(
boundsMap, dsi, this->NumberOfSteps, this->StepSize, this->Seeds);
}

@ -21,11 +21,13 @@ namespace filter
/// Takes as input a vector field and seed locations and generates the
/// paths taken by the seeds through the vector field.
class Pathline : public vtkm::filter::FilterTemporalParticleAdvection<Pathline>
template <typename ParticleType>
class PathlineBase
: public vtkm::filter::FilterTemporalParticleAdvection<PathlineBase<ParticleType>, ParticleType>
{
public:
VTKM_CONT
Pathline();
PathlineBase();
template <typename DerivedPolicy>
vtkm::cont::PartitionedDataSet PrepareForExecution(
@ -36,6 +38,8 @@ protected:
private:
};
using Pathline = PathlineBase<vtkm::Particle>;
}
} // namespace vtkm::filter

@ -23,19 +23,22 @@ namespace filter
{
//-----------------------------------------------------------------------------
inline VTKM_CONT Pathline::Pathline()
: vtkm::filter::FilterTemporalParticleAdvection<Pathline>()
template <typename ParticleType>
inline VTKM_CONT PathlineBase<ParticleType>::PathlineBase()
: vtkm::filter::FilterTemporalParticleAdvection<PathlineBase<ParticleType>, ParticleType>()
{
}
//-----------------------------------------------------------------------------
template <typename ParticleType>
template <typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::PartitionedDataSet Pathline::PrepareForExecution(
inline VTKM_CONT vtkm::cont::PartitionedDataSet PathlineBase<ParticleType>::PrepareForExecution(
const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
using AlgorithmType = vtkm::filter::particleadvection::PathlineAlgorithm;
using ThreadedAlgorithmType = vtkm::filter::particleadvection::PathlineThreadedAlgorithm;
using TDSIType = vtkm::filter::particleadvection::TemporalDataSetIntegrator;
this->ValidateOptions(input);
@ -43,10 +46,10 @@ inline VTKM_CONT vtkm::cont::PartitionedDataSet Pathline::PrepareForExecution(
auto dsi = this->CreateDataSetIntegrators(input, boundsMap);
if (this->GetUseThreadedAlgorithm())
return vtkm::filter::particleadvection::RunAlgo<DSIType, ThreadedAlgorithmType>(
return vtkm::filter::particleadvection::RunAlgo<TDSIType, ThreadedAlgorithmType>(
boundsMap, dsi, this->NumberOfSteps, this->StepSize, this->Seeds);
else
return vtkm::filter::particleadvection::RunAlgo<DSIType, AlgorithmType>(
return vtkm::filter::particleadvection::RunAlgo<TDSIType, AlgorithmType>(
boundsMap, dsi, this->NumberOfSteps, this->StepSize, this->Seeds);
}

@ -21,11 +21,13 @@ namespace filter
/// Takes as input a vector field and seed locations and generates the
/// paths taken by the seeds through the vector field.
class Streamline : public vtkm::filter::FilterParticleAdvection<Streamline>
template <typename ParticleType = vtkm::Particle>
class StreamlineBase
: public vtkm::filter::FilterParticleAdvection<StreamlineBase<ParticleType>, ParticleType>
{
public:
VTKM_CONT
Streamline();
StreamlineBase();
template <typename DerivedPolicy>
vtkm::cont::PartitionedDataSet PrepareForExecution(
@ -34,6 +36,8 @@ public:
private:
};
using Streamline = StreamlineBase<vtkm::Particle>;
}
} // namespace vtkm::filter

@ -22,19 +22,22 @@ namespace filter
{
//-----------------------------------------------------------------------------
inline VTKM_CONT Streamline::Streamline()
: vtkm::filter::FilterParticleAdvection<Streamline>()
template <typename ParticleType>
inline VTKM_CONT StreamlineBase<ParticleType>::StreamlineBase()
: vtkm::filter::FilterParticleAdvection<StreamlineBase<ParticleType>, ParticleType>()
{
}
//-----------------------------------------------------------------------------
template <typename ParticleType>
template <typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::PartitionedDataSet Streamline::PrepareForExecution(
inline VTKM_CONT vtkm::cont::PartitionedDataSet StreamlineBase<ParticleType>::PrepareForExecution(
const vtkm::cont::PartitionedDataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
using AlgorithmType = vtkm::filter::particleadvection::StreamlineAlgorithm;
using ThreadedAlgorithmType = vtkm::filter::particleadvection::StreamlineThreadedAlgorithm;
using DSIType = vtkm::filter::particleadvection::DataSetIntegrator;
this->ValidateOptions();
vtkm::filter::particleadvection::BoundsMap boundsMap(input);

@ -63,7 +63,7 @@ void TestExternalFacesExplicitGrid(const vtkm::cont::DataSet& ds,
vtkm::cont::DataSet resultds = externalFaces.Execute(ds);
// verify cellset
vtkm::cont::CellSetExplicit<>& new_cellSet =
vtkm::cont::CellSetExplicit<> new_cellSet =
resultds.GetCellSet().Cast<vtkm::cont::CellSetExplicit<>>();
const vtkm::Id numOutputExtFaces = new_cellSet.GetNumberOfCells();
VTKM_TEST_ASSERT(numOutputExtFaces == numExpectedExtFaces, "Number of External Faces mismatch");

@ -19,6 +19,8 @@
#include <vtkm/io/ImageWriterPNG.h>
#include <vtkm/io/ImageWriterPNM.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <memory>
namespace vtkm
@ -48,7 +50,7 @@ vtkm::cont::DataSet ReadImageFile(const std::string& fullPath, const std::string
std::ifstream check(fullPath.c_str());
if (!check.good())
{
throw vtkm::cont::ErrorExecution("File does not exist: " + fullPath);
throw vtkm::cont::ErrorBadValue("File does not exist: " + fullPath);
}
std::unique_ptr<vtkm::io::ImageReaderBase> reader;

@ -64,7 +64,7 @@ struct StreamIOType<vtkm::UInt8>
using Type = vtkm::UInt16;
};
inline vtkm::cont::DynamicCellSet CreateCellSetStructured(const vtkm::Id3& dim)
inline vtkm::cont::UnknownCellSet CreateCellSetStructured(const vtkm::Id3& dim)
{
if (dim[0] > 1 && dim[1] > 1 && dim[2] > 1)
{

@ -516,7 +516,7 @@ void Write(std::ostream& out, const vtkm::cont::DataSet& dataSet, vtkm::io::File
break;
}
vtkm::cont::DynamicCellSet cellSet = dataSet.GetCellSet();
vtkm::cont::UnknownCellSet cellSet = dataSet.GetCellSet();
if (cellSet.IsType<vtkm::cont::CellSetExplicit<>>())
{
WriteDataSetAsUnstructured(

@ -31,4 +31,4 @@ if(VTKm_ENABLE_RENDERING)
list(APPEND unit_test_libraries vtkm_rendering)
endif()
vtkm_unit_tests(SOURCES ${unit_tests} ALL_BACKENDS LIBRARIES ${unit_test_libraries})
vtkm_unit_tests(SOURCES ${unit_tests} LIBRARIES ${unit_test_libraries})

@ -65,31 +65,43 @@ set(headers
)
set(sources
Actor.cxx
AxisAnnotation.cxx
AxisAnnotation2D.cxx
AxisAnnotation3D.cxx
BitmapFont.cxx
BitmapFontFactory.cxx
BoundingBoxAnnotation.cxx
Camera.cxx
Color.cxx
ColorBarAnnotation.cxx
ColorLegendAnnotation.cxx
LineRenderer.cxx
Mapper.cxx
MapperConnectivity.cxx
Scene.cxx
TextAnnotation.cxx
TextAnnotationBillboard.cxx
TextAnnotationScreen.cxx
TextRenderer.cxx
View.cxx
View1D.cxx
View2D.cxx
View3D.cxx
WorldAnnotator.cxx
raytracing/Logger.cxx
raytracing/MeshConnectivityContainers.cxx
raytracing/TriangleExtractor.cxx
)
# This list of sources has code that uses devices and so might need to be
# compiled with a device-specific compiler (like CUDA).
set(device_sources
Actor.cxx
AxisAnnotation.cxx
AxisAnnotation2D.cxx
AxisAnnotation3D.cxx
BoundingBoxAnnotation.cxx
Canvas.cxx
CanvasRayTracer.cxx
ColorBarAnnotation.cxx
ColorLegendAnnotation.cxx
ConnectivityProxy.cxx
LineRenderer.cxx
LineRendererBatcher.cxx
Mapper.cxx
MapperConnectivity.cxx
MapperCylinder.cxx
MapperPoint.cxx
MapperQuad.cxx
@ -97,19 +109,10 @@ set(device_sources
MapperVolume.cxx
MapperWireframer.cxx
ScalarRenderer.cxx
Scene.cxx
TextAnnotation.cxx
TextAnnotationBillboard.cxx
TextAnnotationScreen.cxx
TextRenderer.cxx
TextRendererBatcher.cxx
View.cxx
View1D.cxx
View2D.cxx
View3D.cxx
WorldAnnotator.cxx
internal/RunTriangulator.cxx
raytracing/BoundingVolumeHierarchy.cxx
raytracing/Camera.cxx
raytracing/ChannelBuffer.cxx
@ -117,16 +120,14 @@ set(device_sources
raytracing/CylinderExtractor.cxx
raytracing/CylinderIntersector.cxx
raytracing/MeshConnectivityBuilder.cxx
raytracing/MeshConnectivityContainers.cxx
raytracing/QuadExtractor.cxx
raytracing/QuadIntersector.cxx
raytracing/RayTracer.cxx
raytracing/RayOperations.cxx
raytracing/RayTracer.cxx
raytracing/ScalarRenderer.cxx
raytracing/ShapeIntersector.cxx
raytracing/SphereExtractor.cxx
raytracing/SphereIntersector.cxx
raytracing/TriangleExtractor.cxx
raytracing/TriangleIntersector.cxx
raytracing/VolumeRendererStructured.cxx
)

@ -13,8 +13,6 @@
#include <vtkm/Transform3D.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/rendering/LineRendererBatcher.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
namespace vtkm
{

@ -13,8 +13,6 @@
#include <vtkm/Transform3D.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/rendering/TextRendererBatcher.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
namespace vtkm
{

@ -11,7 +11,6 @@
#ifndef vtk_m_rendering_Texture2D_h
#define vtk_m_rendering_Texture2D_h
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ExecutionObjectBase.h>
@ -65,7 +64,7 @@ public:
// We do not know the lifetime of the underlying data source of input `data`. Since it might
// be from a shallow copy of the data source, we make a deep copy of the input data and keep
// it's portal. The copy operation is very fast.
vtkm::cont::Algorithm::Copy(data, Data);
this->Data.DeepCopyFrom(data);
}
VTKM_CONT

@ -212,7 +212,7 @@ public:
} //namespace detail
void CylinderExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells,
void CylinderExtractor::ExtractCells(const vtkm::cont::UnknownCellSet& cells,
const vtkm::Float32 radius)
{
vtkm::Id numOfSegments;
@ -222,7 +222,7 @@ void CylinderExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells,
this->SetUniformRadius(radius);
}
void CylinderExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells,
void CylinderExtractor::ExtractCells(const vtkm::cont::UnknownCellSet& cells,
const vtkm::cont::Field& field,
const vtkm::Float32 minRadius,
const vtkm::Float32 maxRadius)
@ -243,7 +243,7 @@ void CylinderExtractor::SetUniformRadius(const vtkm::Float32 radius)
vtkm::cont::Algorithm::Copy(radiusHandle, Radii);
}
void CylinderExtractor::SetCylinderIdsFromCells(const vtkm::cont::DynamicCellSet& cells)
void CylinderExtractor::SetCylinderIdsFromCells(const vtkm::cont::UnknownCellSet& cells)
{
vtkm::Id numCells = cells.GetNumberOfCells();
if (numCells == 0)

@ -34,12 +34,12 @@ public:
//
// Extract all vertex shapes with constant radius
//
void ExtractCells(const vtkm::cont::DynamicCellSet& cells, vtkm::Float32 radius);
void ExtractCells(const vtkm::cont::UnknownCellSet& cells, vtkm::Float32 radius);
//
// Extract all vertex elements with radius based on scalar values
//
void ExtractCells(const vtkm::cont::DynamicCellSet& cells,
void ExtractCells(const vtkm::cont::UnknownCellSet& cells,
const vtkm::cont::Field& field,
const vtkm::Float32 minRadius,
const vtkm::Float32 maxRadius);
@ -57,7 +57,7 @@ protected:
const vtkm::cont::Field& field);
// void SetPointIdsFromCoords(const vtkm::cont::CoordinateSystem& coords);
void SetCylinderIdsFromCells(const vtkm::cont::DynamicCellSet& cells);
void SetCylinderIdsFromCells(const vtkm::cont::UnknownCellSet& cells);
}; // class ShapeIntersector
}

@ -199,7 +199,7 @@ public:
} //namespace detail
void QuadExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells)
void QuadExtractor::ExtractCells(const vtkm::cont::UnknownCellSet& cells)
{
vtkm::Id numOfQuads;
vtkm::rendering::Quadralizer quadrizer;
@ -209,7 +209,7 @@ void QuadExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells)
}
void QuadExtractor::SetQuadIdsFromCells(const vtkm::cont::DynamicCellSet& cells)
void QuadExtractor::SetQuadIdsFromCells(const vtkm::cont::UnknownCellSet& cells)
{
vtkm::Id numCells = cells.GetNumberOfCells();
if (numCells == 0)

@ -26,14 +26,14 @@ protected:
vtkm::cont::ArrayHandle<vtkm::Float32> Radii;
public:
void ExtractCells(const vtkm::cont::DynamicCellSet& cells);
void ExtractCells(const vtkm::cont::UnknownCellSet& cells);
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 5>> GetQuadIds();
vtkm::Id GetNumberOfQuads() const;
protected:
void SetQuadIdsFromCells(const vtkm::cont::DynamicCellSet& cells);
void SetQuadIdsFromCells(const vtkm::cont::UnknownCellSet& cells);
}; // class ShapeIntersector
}

@ -13,9 +13,7 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleCompositeVector.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/rendering/raytracing/ChannelBuffer.h>
#include <vtkm/rendering/raytracing/Worklets.h>
#include <vector>

@ -8,7 +8,7 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/rendering/raytracing/ShapeIntersector.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
namespace vtkm
{

@ -181,13 +181,13 @@ void SphereExtractor::ExtractCoordinates(const vtkm::cont::CoordinateSystem& coo
this->SetVaryingRadius(minRadius, maxRadius, field);
}
void SphereExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells,
void SphereExtractor::ExtractCells(const vtkm::cont::UnknownCellSet& cells,
const vtkm::Float32 radius)
{
this->SetPointIdsFromCells(cells);
this->SetUniformRadius(radius);
}
void SphereExtractor::ExtractCells(const vtkm::cont::DynamicCellSet& cells,
void SphereExtractor::ExtractCells(const vtkm::cont::UnknownCellSet& cells,
const vtkm::cont::Field& field,
const vtkm::Float32 minRadius,
const vtkm::Float32 maxRadius)
@ -212,7 +212,7 @@ void SphereExtractor::SetPointIdsFromCoords(const vtkm::cont::CoordinateSystem&
vtkm::worklet::DispatcherMapField<detail::Iterator>(detail::Iterator()).Invoke(this->PointIds);
}
void SphereExtractor::SetPointIdsFromCells(const vtkm::cont::DynamicCellSet& cells)
void SphereExtractor::SetPointIdsFromCells(const vtkm::cont::UnknownCellSet& cells)
{
using SingleType = vtkm::cont::CellSetSingleType<>;
vtkm::Id numCells = cells.GetNumberOfCells();

@ -42,12 +42,12 @@ public:
//
// Extract all vertex shapes with constant radius
//
void ExtractCells(const vtkm::cont::DynamicCellSet& cells, vtkm::Float32 radius);
void ExtractCells(const vtkm::cont::UnknownCellSet& cells, vtkm::Float32 radius);
//
// Extract all vertex elements with radius based on scalar values
//
void ExtractCells(const vtkm::cont::DynamicCellSet& cells,
void ExtractCells(const vtkm::cont::UnknownCellSet& cells,
const vtkm::cont::Field& field,
const vtkm::Float32 minRadius,
const vtkm::Float32 maxRadius);
@ -64,7 +64,7 @@ protected:
const vtkm::cont::Field& field);
void SetPointIdsFromCoords(const vtkm::cont::CoordinateSystem& coords);
void SetPointIdsFromCells(const vtkm::cont::DynamicCellSet& cells);
void SetPointIdsFromCells(const vtkm::cont::UnknownCellSet& cells);
}; // class ShapeIntersector
}

@ -63,15 +63,21 @@ inline TestEqualResult test_equal_images(
vtkm::io::PrefixStringToFilename(fileNames[0], "test-"));
vtkm::io::WriteImageFile(view->GetCanvas().GetDataSet(), testImageName, "color");
std::stringstream dartXML;
dartXML << "<DartMeasurementFile name=\"TestImage\" type=\"image/png\">";
dartXML << testImageName;
dartXML << "</DartMeasurementFile>\n";
for (const auto& fileName : fileNames)
{
VTKM_LOG_S(vtkm::cont::LogLevel::Info, "testing image file: " << fileName);
TestEqualResult imageResult;
vtkm::cont::DataSet imageDataSet;
const std::string testImagePath = vtkm::cont::testing::Testing::RegressionImagePath(fileName);
try
{
const std::string testImagePath = vtkm::cont::testing::Testing::RegressionImagePath(fileName);
imageDataSet = vtkm::io::ReadImageFile(testImagePath, "baseline-image");
}
catch (const vtkm::cont::ErrorExecution& error)
@ -96,6 +102,10 @@ inline TestEqualResult test_equal_images(
continue;
}
dartXML << "<DartMeasurementFile name=\"BaselineImage\" type=\"image/png\">";
dartXML << testImagePath;
dartXML << "</DartMeasurementFile>\n";
imageDataSet.AddPointField("generated-image", view->GetCanvas().GetColorBuffer());
vtkm::filter::ImageDifference filter;
filter.SetPrimaryField("baseline-image");
@ -117,6 +127,9 @@ inline TestEqualResult test_equal_images(
const std::string diffName = vtkm::cont::testing::Testing::WriteDirPath(
vtkm::io::PrefixStringToFilename(fileName, "diff-"));
vtkm::io::WriteImageFile(resultDataSet, diffName, "image-diff");
dartXML << "<DartMeasurementFile name=\"DifferenceImage\" type=\"image/png\">";
dartXML << diffName;
dartXML << "</DartMeasurementFile>\n";
}
if (imageResult && returnOnPass)
@ -134,6 +147,12 @@ inline TestEqualResult test_equal_images(
}
VTKM_LOG_S(vtkm::cont::LogLevel::Info, "Test Results: " << testResults.GetMergedMessage());
if (!testResults)
{
std::cout << dartXML.str();
}
return testResults;
}
@ -146,37 +165,10 @@ inline TestEqualResult test_equal_images(
const vtkm::FloatDefault& allowedPixelErrorRatio = 0.00025f,
const vtkm::FloatDefault& threshold = 0.05f,
const bool& writeDiff = true)
{
std::vector<std::string> fileNames{ fileName };
return test_equal_images(
view, fileNames, averageRadius, pixelShiftRadius, allowedPixelErrorRatio, threshold, writeDiff);
}
/// \brief Tests multiple images in the format `fileName#.png`
///
/// Using the provided fileName, it splits the extension and prefix into two
/// components and searches through the regression image file path directory
/// for all matching file names with a number specifier starting at 0 incrementing
/// by one.
///
/// For example, if a file `foo.png` is provied, this function will first look
/// for a file foo0.png. If it exists, it will then look for foo1.png and so on
/// until it cannot find a file with a specific number.
///
/// test_equal_images will then be called on the vector of valid fileNames
///
template <typename ViewType>
inline TestEqualResult test_equal_images_matching_name(
const std::shared_ptr<ViewType> view,
const std::string& fileName,
const vtkm::IdComponent& averageRadius = 0,
const vtkm::IdComponent& pixelShiftRadius = 0,
const vtkm::FloatDefault& allowedPixelErrorRatio = 0.00025f,
const vtkm::FloatDefault& threshold = 0.05f,
const bool& writeDiff = true,
const bool& returnOnPass = true)
{
std::vector<std::string> fileNames;
// Check to see if there are multiple versions of the file of the format filenName#.png.
auto found = fileName.rfind(".");
auto prefix = fileName.substr(0, found);
auto suffix = fileName.substr(found, fileName.length());
@ -185,24 +177,33 @@ inline TestEqualResult test_equal_images_matching_name(
{
std::ostringstream fileNameStream;
fileNameStream << prefix << i << suffix;
std::ifstream check(
vtkm::cont::testing::Testing::RegressionImagePath(fileNameStream.str()).c_str());
std::ifstream check(vtkm::cont::testing::Testing::RegressionImagePath(fileNameStream.str()));
if (!check.good())
{
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
"Stopped filename search at: " << fileNameStream.str() << ", beginning testing");
break;
}
fileNames.emplace_back(fileNameStream.str());
fileNames.push_back(fileNameStream.str());
}
return test_equal_images(view,
fileNames,
averageRadius,
pixelShiftRadius,
allowedPixelErrorRatio,
threshold,
writeDiff,
returnOnPass);
// Check to see the filename without a number exists.
{
std::ifstream check(vtkm::cont::testing::Testing::RegressionImagePath(fileName));
if (check.good())
{
fileNames.push_back(fileName);
}
}
// Make sure at least one file exists
if (fileNames.empty())
{
fileNames.push_back(fileName);
}
return test_equal_images(
view, fileNames, averageRadius, pixelShiftRadius, allowedPixelErrorRatio, threshold, writeDiff);
}
#endif // vtk_m_rendering_testing_Testing_h

@ -15,12 +15,11 @@
#include <vtkm/source/PerlinNoise.h>
#include <vtkm/worklet/WorkletMapTopology.h>
namespace vtkm
{
namespace source
{
namespace perlin
#include <time.h>
namespace
{
struct PerlinNoiseWorklet : public vtkm::worklet::WorkletVisitPointsWithCells
{
using ControlSignature = void(CellSetIn, FieldInPoint, WholeArrayIn, FieldOut noise);
@ -39,9 +38,9 @@ struct PerlinNoiseWorklet : public vtkm::worklet::WorkletVisitPointsWithCells
vtkm::Id xi = static_cast<vtkm::Id>(pos[0]) % this->Repeat;
vtkm::Id yi = static_cast<vtkm::Id>(pos[1]) % this->Repeat;
vtkm::Id zi = static_cast<vtkm::Id>(pos[2]) % this->Repeat;
vtkm::FloatDefault xf = pos[0] - xi;
vtkm::FloatDefault yf = pos[1] - yi;
vtkm::FloatDefault zf = pos[2] - zi;
vtkm::FloatDefault xf = static_cast<vtkm::FloatDefault>(pos[0] - xi);
vtkm::FloatDefault yf = static_cast<vtkm::FloatDefault>(pos[1] - yi);
vtkm::FloatDefault zf = static_cast<vtkm::FloatDefault>(pos[2] - zi);
vtkm::FloatDefault u = this->Fade(xf);
vtkm::FloatDefault v = this->Fade(yf);
vtkm::FloatDefault w = this->Fade(zf);
@ -158,7 +157,7 @@ private:
rng.seed(this->Seed);
std::uniform_int_distribution<vtkm::Id> distribution(0, this->TableSize - 1);
vtkm::cont::ArrayHandle<vtkm::FloatDefault> perms;
vtkm::cont::ArrayHandle<vtkm::Id> perms;
perms.Allocate(this->TableSize);
auto permsPortal = perms.WritePortal();
for (auto i = 0; i < permsPortal.GetNumberOfValues(); ++i)
@ -175,9 +174,37 @@ private:
vtkm::IdComponent TableSize;
vtkm::Id Seed;
vtkm::cont::ArrayHandle<vtkm::FloatDefault> Permutations;
vtkm::cont::ArrayHandle<vtkm::Id> Permutations;
};
} // namespace perlin
} // anonymous namespace
namespace vtkm
{
namespace source
{
PerlinNoise::PerlinNoise(vtkm::Id3 dims)
: PerlinNoise(dims, vtkm::Vec3f(0), static_cast<vtkm::IdComponent>(time(NULL)))
{
}
PerlinNoise::PerlinNoise(vtkm::Id3 dims, vtkm::IdComponent seed)
: PerlinNoise(dims, vtkm::Vec3f(0), seed)
{
}
PerlinNoise::PerlinNoise(vtkm::Id3 dims, vtkm::Vec3f origin)
: PerlinNoise(dims, origin, static_cast<vtkm::IdComponent>(time(NULL)))
{
}
PerlinNoise::PerlinNoise(vtkm::Id3 dims, vtkm::Vec3f origin, vtkm::IdComponent seed)
: Dims(dims)
, Origin(origin)
, Seed(seed)
{
}
vtkm::cont::DataSet PerlinNoise::Execute() const
{
@ -198,7 +225,7 @@ vtkm::cont::DataSet PerlinNoise::Execute() const
auto tableSize = static_cast<vtkm::IdComponent>(
vtkm::Max(this->Dims[0], vtkm::Max(this->Dims[1], this->Dims[2])));
perlin::PerlinNoiseField noiseGenerator(tableSize, this->Seed);
PerlinNoiseField noiseGenerator(tableSize, this->Seed);
noiseGenerator.SetOutputFieldName("perlinnoise");
dataSet = noiseGenerator.Execute(dataSet);

@ -30,19 +30,10 @@ class VTKM_SOURCE_EXPORT PerlinNoise final : public vtkm::source::Source
{
public:
///Construct a PerlinNoise with Cell Dimensions
VTKM_CONT
PerlinNoise(vtkm::Id3 dims, vtkm::IdComponent seed)
: PerlinNoise(dims, vtkm::Vec3f(0), seed)
{
}
VTKM_CONT
PerlinNoise(vtkm::Id3 dims, vtkm::Vec3f origin, vtkm::IdComponent seed)
: Dims(dims)
, Origin(origin)
, Seed(seed)
{
}
VTKM_CONT PerlinNoise(vtkm::Id3 dims);
VTKM_CONT PerlinNoise(vtkm::Id3 dims, vtkm::IdComponent seed);
VTKM_CONT PerlinNoise(vtkm::Id3 dims, vtkm::Vec3f origin);
VTKM_CONT PerlinNoise(vtkm::Id3 dims, vtkm::Vec3f origin, vtkm::IdComponent seed);
vtkm::IdComponent GetSeed() const { return this->Seed; }

@ -26,7 +26,6 @@
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/ConvertNumComponentsToOffsets.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/cont/UnknownArrayHandle.h>
@ -584,8 +583,8 @@ public:
{
}
template <typename CellSetList, typename ScalarsArrayHandle>
vtkm::cont::CellSetExplicit<> Run(const vtkm::cont::DynamicCellSetBase<CellSetList>& cellSet,
template <typename CellSetType, typename ScalarsArrayHandle>
vtkm::cont::CellSetExplicit<> Run(const CellSetType& cellSet,
const ScalarsArrayHandle& scalars,
vtkm::Float64 value,
bool invert)
@ -697,13 +696,13 @@ public:
return output;
}
template <typename DynamicCellSet, typename ImplicitFunction>
template <typename CellSetType, typename ImplicitFunction>
class ClipWithImplicitFunction
{
public:
VTKM_CONT
ClipWithImplicitFunction(Clip* clipper,
const DynamicCellSet& cellSet,
const CellSetType& cellSet,
const ImplicitFunction& function,
const bool invert,
vtkm::cont::CellSetExplicit<>* result)
@ -730,21 +729,21 @@ public:
private:
Clip* Clipper;
const DynamicCellSet* CellSet;
const CellSetType* CellSet;
ImplicitFunction Function;
bool Invert;
vtkm::cont::CellSetExplicit<>* Result;
};
template <typename CellSetList, typename ImplicitFunction>
vtkm::cont::CellSetExplicit<> Run(const vtkm::cont::DynamicCellSetBase<CellSetList>& cellSet,
template <typename CellSetType, typename ImplicitFunction>
vtkm::cont::CellSetExplicit<> Run(const CellSetType& cellSet,
const ImplicitFunction& clipFunction,
const vtkm::cont::CoordinateSystem& coords,
const bool invert)
{
vtkm::cont::CellSetExplicit<> output;
ClipWithImplicitFunction<vtkm::cont::DynamicCellSetBase<CellSetList>, ImplicitFunction> clip(
ClipWithImplicitFunction<CellSetType, ImplicitFunction> clip(
this, cellSet, clipFunction, invert, &output);
CastAndCall(coords, clip);

@ -19,6 +19,7 @@
#include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/ImplicitFunction.h>

@ -32,11 +32,12 @@ public:
using ExecutionSignature = void(_1, _2, _3, _4, _5);
using InputDomain = _1;
template <typename ParticleType>
VTKM_EXEC void operator()(const vtkm::Vec3f& pt,
const vtkm::Id& id,
const vtkm::FloatDefault& time,
const vtkm::Id& step,
vtkm::Particle& particle) const
ParticleType& particle) const
{
particle.Pos = pt;
particle.ID = id;

@ -15,6 +15,7 @@
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/WorkletMapTopology.h>

@ -145,7 +145,9 @@ public:
GetSteps() {}
using ControlSignature = void(FieldIn, FieldOut);
using ExecutionSignature = void(_1, _2);
VTKM_EXEC void operator()(const vtkm::Particle& p, vtkm::Id& numSteps) const
template <typename ParticleType>
VTKM_EXEC void operator()(const ParticleType& p, vtkm::Id& numSteps) const
{
numSteps = p.NumSteps;
}
@ -161,7 +163,8 @@ public:
// Offset is number of points in streamline.
// 1 (inital point) + number of steps taken (p.NumSteps - initalNumSteps)
VTKM_EXEC void operator()(const vtkm::Particle& p,
template <typename ParticleType>
VTKM_EXEC void operator()(const ParticleType& p,
const vtkm::Id& initialNumSteps,
vtkm::Id& diff) const
{

@ -20,6 +20,8 @@
#include <vtkm/exec/CellInterpolate.h>
#include <vtkm/exec/ParametricCoordinates.h>
#include <vtkm/io/VTKDataSetReader.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/WorkletMapTopology.h>
namespace
{