Merge branch 'master' into concurrent_union_find

This commit is contained in:
Li-Ta Lo 2020-10-05 09:28:31 -06:00
commit 43aa21df40
202 changed files with 7714 additions and 4653 deletions

@ -49,6 +49,9 @@ foreach(option IN LISTS options)
elseif(no_rendering STREQUAL option)
set(VTKm_ENABLE_RENDERING "OFF" CACHE STRING "")
elseif(no_virtual STREQUAL option)
set(VTKm_NO_DEPRECATED_VIRTUAL "ON" CACHE STRING "")
elseif(examples STREQUAL option)
set(VTKm_ENABLE_EXAMPLES "ON" CACHE STRING "")

@ -17,7 +17,7 @@ build:ubuntu1604_gcc5:
CC: "gcc-5"
CXX: "g++-5"
CMAKE_BUILD_TYPE: RelWithDebInfo
VTKM_SETTINGS: "cuda+pascal"
VTKM_SETTINGS: "cuda+pascal+no_virtual"
test:ubuntu1604_gcc5:
tags:

@ -55,7 +55,7 @@ build:ubuntu1804_gcc7:
variables:
CC: "gcc-7"
CXX: "g++-7"
VTKM_SETTINGS: "cuda+turing+mpi+64bit_floats"
VTKM_SETTINGS: "cuda+turing+mpi+64bit_floats+no_virtual"
test:ubuntu1804_gcc7:
tags:

@ -68,9 +68,9 @@ set(VTKm_VERSION "@VTKm_VERSION@")
set(VTKm_BUILD_SHARED_LIBS "@VTKm_BUILD_SHARED_LIBS@")
set(VTKm_ENABLE_CUDA "@VTKm_ENABLE_CUDA@")
set(VTKm_ENABLE_TBB "@VTKm_ENABLE_TBB@")
set(VTKm_ENABLE_OPENMP "@VTKm_ENABLE_OPENMP@")
set(VTKm_ENABLE_KOKKOS "@VTKm_ENABLE_KOKKOS@")
set(VTKm_ENABLE_OPENMP "@VTKm_ENABLE_OPENMP@")
set(VTKm_ENABLE_TBB "@VTKm_ENABLE_TBB@")
set(VTKm_ENABLE_LOGGING "@VTKm_ENABLE_LOGGING@")
set(VTKm_ENABLE_RENDERING "@VTKm_ENABLE_RENDERING@")
set(VTKm_ENABLE_GL_CONTEXT "@VTKm_ENABLE_GL_CONTEXT@")

@ -110,8 +110,15 @@ function(do_verify root_dir prefix)
)
set(file_exceptions
cont/ColorTablePrivate.hxx
thirdparty/diy/vtkmdiy/cmake/mpi_types.h
# Ignore deprecated virtual classes (which are not installed if VTKm_NO_DEPRECATED_VIRTUAL
# is on). These exceptions can be removed when these files are completely removed.
cont/ArrayHandleVirtual.h
cont/ArrayHandleVirtual.hxx
cont/ArrayHandleVirtualCoordinates.h
cont/StorageVirtual.h
cont/StorageVirtual.hxx
)
#by default every header in a testing directory doesn't need to be installed

@ -73,9 +73,9 @@ endmacro ()
# Configurable Options
vtkm_option(VTKm_ENABLE_CUDA "Enable Cuda support" OFF)
vtkm_option(VTKm_ENABLE_TBB "Enable TBB support" OFF)
vtkm_option(VTKm_ENABLE_OPENMP "Enable OpenMP support" OFF)
vtkm_option(VTKm_ENABLE_KOKKOS "Enable Kokkos support" OFF)
vtkm_option(VTKm_ENABLE_OPENMP "Enable OpenMP support" OFF)
vtkm_option(VTKm_ENABLE_TBB "Enable TBB support" OFF)
vtkm_option(VTKm_ENABLE_RENDERING "Enable rendering library" ON)
vtkm_option(VTKm_ENABLE_BENCHMARKS "Enable VTKm Benchmarking" OFF)
vtkm_option(VTKm_ENABLE_MPI "Enable MPI support" OFF)
@ -108,6 +108,12 @@ vtkm_option(VTKm_NO_ASSERT "Disable assertions in debugging builds." OFF)
# for CUDA devices.
vtkm_option(VTKm_NO_ASSERT_CUDA "Disable assertions for CUDA devices." ON)
# The HIP compiler (as of ROCm 3.7) takes a surprising long time to compile
# kernels with assert in them they generate `printf` calls which are very
# slow ( cause massive register spillage). By default we turn off asserts when
# compiling for HIP devices.
vtkm_option(VTKm_NO_ASSERT_HIP "Disable assertions for HIP devices." ON)
# When VTK-m is embedded into larger projects that wish to make end user
# applications they want to only install libraries and don't want CMake/headers
# installed.
@ -132,6 +138,13 @@ vtkm_option(VTKm_ENABLE_DEVELOPER_FLAGS "Enable compiler flags that are useful w
# Some application might need not to install those, hence this option.
vtkm_option(VTKm_NO_INSTALL_README_LICENSE "disable the installation of README and LICENSE files" OFF)
# We are in the process of deprecating the use of virtual methods because they
# are not well supported on many accelerators. Turn this option on to remove
# the code entirely. Note that the deprecation of virtual methods is work in
# progress, so not all use of virtual methods may be done. In VTK-m 2.0
# virtual methods should be removed entirely and this option will be removed.
vtkm_option(VTKm_NO_DEPRECATED_VIRTUAL "Do not compile support of deprecated virtual methods" OFF)
mark_as_advanced(
VTKm_ENABLE_LOGGING
VTKm_NO_ASSERT
@ -140,6 +153,7 @@ mark_as_advanced(
VTKm_HIDE_PRIVATE_SYMBOLS
VTKm_ENABLE_DEVELOPER_FLAGS
VTKm_NO_INSTALL_README_LICENSE
VTKm_NO_DEPRECATED_VIRTUAL
)
#-----------------------------------------------------------------------------

@ -55,7 +55,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"nvlink warning : .*ArrayPortalVirtual.* has address taken but no possible call to it"
"nvlink warning : .*CellLocatorBoundingIntervalHierarchyExec.* has address taken but no possible call to it"
"nvlink warning : .*CellLocatorRectilinearGrid.* has address taken but no possible call to it"
"nvlink warning : .*CellLocatorUniformBins.* has address taken but no possible call to it"
"nvlink warning : .*CellLocatorTwoLevel.* has address taken but no possible call to it"
"nvlink warning : .*CellLocatorUniformGrid.* has address taken but no possible call to it"
)

@ -13,13 +13,16 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleMultiplexer.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/ImplicitFunctionHandle.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/cont/Timer.h>
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/cont/ArrayHandleVirtual.h>
#endif
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/WorkletMapTopology.h>
@ -433,15 +436,19 @@ void BenchBlackScholesStatic(::benchmark::State& state)
};
VTKM_BENCHMARK_TEMPLATES(BenchBlackScholesStatic, ValueTypes);
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
template <typename ValueType>
void BenchBlackScholesDynamic(::benchmark::State& state)
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
BenchBlackScholesImpl<ValueType> impl{ state };
impl.Run(vtkm::cont::make_ArrayHandleVirtual(impl.StockPrice),
vtkm::cont::make_ArrayHandleVirtual(impl.OptionStrike),
vtkm::cont::make_ArrayHandleVirtual(impl.OptionYears));
VTKM_DEPRECATED_SUPPRESS_END
};
VTKM_BENCHMARK_TEMPLATES(BenchBlackScholesDynamic, ValueTypes);
#endif //VTKM_NO_DEPRECATED_VIRTUAL
template <typename ValueType>
void BenchBlackScholesMultiplexer0(::benchmark::State& state)
@ -537,15 +544,19 @@ void BenchMathStatic(::benchmark::State& state)
};
VTKM_BENCHMARK_TEMPLATES(BenchMathStatic, ValueTypes);
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
template <typename ValueType>
void BenchMathDynamic(::benchmark::State& state)
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
BenchMathImpl<ValueType> impl{ state };
impl.Run(vtkm::cont::make_ArrayHandleVirtual(impl.InputHandle),
vtkm::cont::make_ArrayHandleVirtual(impl.TempHandle1),
vtkm::cont::make_ArrayHandleVirtual(impl.TempHandle2));
VTKM_DEPRECATED_SUPPRESS_END
};
VTKM_BENCHMARK_TEMPLATES(BenchMathDynamic, ValueTypes);
#endif //VTKM_NO_DEPRECATED_VIRTUAL
template <typename ValueType>
void BenchMathMultiplexer0(::benchmark::State& state)
@ -636,13 +647,17 @@ void BenchFusedMathStatic(::benchmark::State& state)
};
VTKM_BENCHMARK_TEMPLATES(BenchFusedMathStatic, ValueTypes);
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
template <typename ValueType>
void BenchFusedMathDynamic(::benchmark::State& state)
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
BenchFusedMathImpl<ValueType> impl{ state };
impl.Run(vtkm::cont::make_ArrayHandleVirtual(impl.InputHandle));
VTKM_DEPRECATED_SUPPRESS_END
};
VTKM_BENCHMARK_TEMPLATES(BenchFusedMathDynamic, ValueTypes);
#endif //VTKM_NO_DEPRECATED_VIRTUAL
template <typename ValueType>
void BenchFusedMathMultiplexer0(::benchmark::State& state)
@ -756,15 +771,19 @@ void BenchEdgeInterpStatic(::benchmark::State& state)
};
VTKM_BENCHMARK_TEMPLATES(BenchEdgeInterpStatic, InterpValueTypes);
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
template <typename ValueType>
void BenchEdgeInterpDynamic(::benchmark::State& state)
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
BenchEdgeInterpImpl<ValueType> impl{ state };
impl.Run(vtkm::cont::make_ArrayHandleVirtual(impl.EdgePairHandle),
vtkm::cont::make_ArrayHandleVirtual(impl.WeightHandle),
vtkm::cont::make_ArrayHandleVirtual(impl.FieldHandle));
VTKM_DEPRECATED_SUPPRESS_END
};
VTKM_BENCHMARK_TEMPLATES(BenchEdgeInterpDynamic, InterpValueTypes);
#endif //VTKM_NO_DEPRECATED_VIRTUAL
struct ImplicitFunctionBenchData
{

@ -26,8 +26,6 @@
#include <vtkm/exec/FunctorBase.h>
#include <vtkm/cont/ColorTable.hxx>
#include <sstream>
#include <string>
#include <vector>

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3d0ddc7c712a6d544db85660cd9d325884892b18d6f0ed451361aaeae2a96413
size 204

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:75b5601eb23b1724d5309e69a51839615bce625f6e7641b52dc3d06e10b0c5ee
size 745

@ -0,0 +1,17 @@
# Virtual methods in execution environment deprecated
The use of classes with any virtual methods in the execution environment is
deprecated. Although we had code to correctly build virtual methods on some
devices such as CUDA, this feature was not universally supported on all
programming models we wish to support. Plus, the implementation of virtual
methods is not hugely convenient on CUDA because the virtual methods could
not be embedded in a library. To get around virtual methods declared in
different libraries, all builds had to be static, and a special linking
step to pull in possible virtual method implementations was required.
For these reasons, VTK-m is no longer relying on virtual methods. (Other
approaches like multiplexers are used instead.) The code will be officially
removed in version 2.0. It is still supported in a deprecated sense (you
should get a warning). However, if you want to build without virtual
methods, you can set the `VTKm_NO_DEPRECATED_VIRTUAL` CMake flag, and they
will not be compiled.

@ -40,11 +40,11 @@ using OldAlias VTKM_DEPRECATED(1.6, "Use NewClass instead.") = NewClass;
```
Functions and methods are marked as deprecated by adding `VTKM_DEPRECATED`
as a modifier before the return value.
as a modifier before the return value and any markup (VTKM_CONT, VTKM_EXEC, or VTKM_EXEC_CONT).
``` cpp
VTKM_EXEC_CONT
VTKM_DEPRECATED(1.6, "You must now specify a tolerance.") void ImportantMethod(double x)
VTKM_EXEC_CONT
{
this->ImportantMethod(x, 1e-6);
}
@ -83,8 +83,8 @@ support this a pair of macros, `VTKM_DEPRECATED_SUPPRESS_BEGIN` and
deprecated items should be wrapped in these macros.
``` cpp
VTKM_EXEC_CONT
VTKM_DEPRECATED(1.6, "You must now specify both a value and tolerance.")
VTKM_EXEC_CONT
void ImportantMethod()
{
// It can be the case that to implement a deprecated method you need to

@ -0,0 +1,12 @@
# Disable asserts for HIP architecture builds
`assert` is supported on recent HIP cards, but compiling it is very slow,
as it triggers the usage of `printf` which. Currently (ROCm 3.7) `printf`
has a severe performance penalty and should be avoided when possible.
By default, the `VTKM_ASSERT` macro has been disabled whenever compiling
for a HIP device via kokkos.
Asserts for HIP devices can be turned back on by turning the
`VTKm_NO_ASSERT_HIP` CMake variable off. Turning this CMake variable off
will enable assertions in HIP kernels unless there is another reason
turning off all asserts (such as a release build).

@ -0,0 +1,109 @@
# UnknownArrayHandle and UncertainArrayHandle for runtime-determined types
Two new classes have been added to VTK-m: `UnknownArrayHandle` and
`UncertainArrayHandle`. These classes serve the same purpose as the set of
`VariantArrayHandle` classes and will replace them.
Motivated mostly by the desire to move away from `ArrayHandleVirtual`, we
have multiple reasons to completely refactor the `VariantArrayHandle`
class. These include changing the implementation, some behavior, and even
the name.
## Motivation
We have several reasons that have accumulated to revisit the implementation
of `VariantArrayHandle`.
### Move away from `ArrayHandleVirtual`
The current implementation of `VariantArrayHandle` internally stores the
array wrapped in an `ArrayHandleVirtual`. That makes sense since you might
as well consolidate the hierarchy of virtual objects into one.
Except `ArrayHandleVirtual` is being deprecated, so it no longer makes
sense to use that internally.
So we will transition the class back to managing the data as typeless on
its own. We will consider using function pointers rather than actual
virtual functions because compilers can be slow in creating lots of virtual
subclasses.
### Reintroduce storage tag lists
The original implementation of `VariantArrayHandle` (which at the time was
called `DynamicArrayHandle`) actually had two type lists: one for the array
value type and one for the storage type. The storage type list was removed
soon after `ArrayHandleVirtual` was introduced because whatever the type of
array it could be access as `ArrayHandleVirtual`.
However, with `ArrayHandleVirtual` being deprecated, this feature is no
longer possible. We are in need again for the list of storage types to try.
Thus, we need to reintroduce this template argument to
`VariantArrayHandle`.
### More clear name
The name of this class has always been unsatisfactory. The first name,
`DynamicArrayHandle`, makes it sound like the data is always changing. The
second name, `VariantArrayHandle`, makes it sound like an array that holds
a value type that can vary (like an `std::variant`).
We can use a more clear name that expresses better that it is holding an
`ArrayHandle` of an _unknown_ type.
### Take advantage of default types for less templating
Once upon a time everything in VTK-m was templated header library. Things
have changed quite a bit since then. The most recent development is the
ability to select the "default types" with CMake configuration that allows
you to select a global set of types you care about during compilation. This
is so units like filters can be compiled into a library with all types we
care about, and we don't have to constantly recompile units.
This means that we are becoming less concerned about maintaining type lists
everywhere. Often we can drop the type list and pass data across libraries.
With that in mind, it makes less sense for `VariantArrayHandle` to actually
be a `using` alias for `VariantArrayHandleBase<VTKM_DEFAULT_TYPE_LIST>`.
In response, we can revert the is-a relationship between the two. Have a
completely typeless version as the base class and have a second version
templated version to express when the type of the array has been partially
narrowed down to given type lists.
## New Name and Structure
The ultimate purpose of this class is to store an `ArrayHandle` where the
value and storage types are unknown. Thus, an appropriate name for the
class is `UnknownArrayHandle`.
`UnknownArrayHandle` is _not_ templated. It simply stores an `ArrayHandle`
in a typeless (`void *`) buffer. It does, however, contain many templated
methods that allow you to query whether the contained array matches given
types, to cast to given types, and to cast and call to a given functor
(from either given type lists or default lists).
Rather than have a virtual class structure to manage the typeless array,
the new management will use function pointers. This has shown to sometimes
improve compile times and generate less code.
Sometimes it is the case that the set of potential types can be narrowed. In
this case, the array ceases to be unknown and becomes _uncertain_. Thus,
the companion class to `UnknownArrayHandle` is `UncertainArrayHandle`.
`UncertainArrayHandle` has two template parameters: a list of potential
value types and a list of potential storage types. The behavior of
`UncertainArrayHandle` matches that of `UnknownArrayHandle` (and might
inherit from it). However, for `CastAndCall` operations, it will use the
type lists defined in its template parameters.
## Serializing UnknownArrayHandle
Because `UnknownArrayHandle` is not templated, it contains some
opportunities to compile things into the `vtkm_cont` library. Templated
methods like `CastAndCall` cannot be, but the specializations of DIY's
serialize can be.
And since it only has to be compiled once into a library, we can spend some
extra time compiling for more types. We don't have to restrict ourselves to
`VTKM_DEFAULT_TYPE_LIST`. We can compile for vtkm::TypeListTagAll.

@ -387,8 +387,8 @@ int main(int argc, char* argv[])
#ifdef WITH_MPI
#ifdef DEBUG_PRINT
// From https://www.unix.com/302983597-post2.html
char* cstr_filename = new char[15];
snprintf(cstr_filename, sizeof(filename), "cout_%d.log", rank);
char cstr_filename[32];
snprintf(cstr_filename, sizeof(cstr_filename), "cout_%d.log", rank);
int out = open(cstr_filename, O_RDWR | O_CREAT | O_APPEND, 0600);
if (-1 == out)
{
@ -417,8 +417,6 @@ int main(int argc, char* argv[])
perror("cannot redirect stderr");
return 255;
}
delete[] cstr_filename;
#endif
#endif
@ -444,23 +442,27 @@ int main(int argc, char* argv[])
// Copy the data into the values array so we can construct a multiblock dataset
// TODO All we should need to do to implement BOV support is to copy the values
// in the values vector and copy the dimensions in the dims vector
vtkm::Id nRows, nCols, nSlices;
vtkm::worklet::contourtree_augmented::GetRowsColsSlices temp;
temp(inDataSet.GetCellSet(), nRows, nCols, nSlices);
dims[0] = nRows;
dims[1] = nCols;
dims[2] = nSlices;
auto tempField = inDataSet.GetField("values").GetData();
values.resize(static_cast<std::size_t>(tempField.GetNumberOfValues()));
auto tempFieldHandle = tempField.AsVirtual<ValueType>().ReadPortal();
for (vtkm::Id i = 0; i < tempField.GetNumberOfValues(); i++)
{
values[static_cast<std::size_t>(i)] = static_cast<ValueType>(tempFieldHandle.Get(i));
}
vtkm::Id3 meshSize;
vtkm::worklet::contourtree_augmented::GetPointDimensions temp;
temp(inDataSet.GetCellSet(), meshSize);
dims[0] = meshSize[0];
dims[1] = meshSize[1];
dims[2] = meshSize[2];
// TODO/FIXME: The following is commented out since it creates a a warning that
// AsVirtual() will no longer be supported. Since this implementation is
// incomplete anyway, it currently makes more sense to comment it out than
// to fix the warning.
// auto tempField = inDataSet.GetField("values").GetData();
// values.resize(static_cast<std::size_t>(tempField.GetNumberOfValues()));
// auto tempFieldHandle = tempField.AsVirtual<ValueType>().ReadPortal();
// for (vtkm::Id i = 0; i < tempField.GetNumberOfValues(); i++)
// {
// values[static_cast<std::size_t>(i)] = static_cast<ValueType>(tempFieldHandle.Get(i));
// }
VTKM_LOG_S(vtkm::cont::LogLevel::Error,
"BOV reader not yet support in MPI mode by this example");
MPI_Finalize();
return EXIT_SUCCESS;
return EXIT_FAILURE;
#endif
}
else // Read ASCII data input
@ -515,6 +517,9 @@ int main(int argc, char* argv[])
dataReadTime = currTime - prevTime;
prevTime = currTime;
// swap dims order
std::swap(dims[0], dims[1]);
#ifndef WITH_MPI // We only need the inDataSet if are not using MPI otherwise we'll constructe a multi-block dataset
// build the input dataset
vtkm::cont::DataSetBuilderUniform dsb;
@ -522,16 +527,16 @@ int main(int argc, char* argv[])
if (nDims == 2)
{
vtkm::Id2 vdims;
vdims[0] = static_cast<vtkm::Id>(dims[1]);
vdims[1] = static_cast<vtkm::Id>(dims[0]);
vdims[0] = static_cast<vtkm::Id>(dims[0]);
vdims[1] = static_cast<vtkm::Id>(dims[1]);
inDataSet = dsb.Create(vdims);
}
// 3D data
else
{
vtkm::Id3 vdims;
vdims[0] = static_cast<vtkm::Id>(dims[1]);
vdims[1] = static_cast<vtkm::Id>(dims[0]);
vdims[0] = static_cast<vtkm::Id>(dims[0]);
vdims[1] = static_cast<vtkm::Id>(dims[1]);
vdims[2] = static_cast<vtkm::Id>(dims[2]);
inDataSet = dsb.Create(vdims);
}
@ -594,8 +599,8 @@ int main(int argc, char* argv[])
{
VTKM_LOG_IF_S(vtkm::cont::LogLevel::Error,
rank == 0,
"Number of ranks to large for data. Use " << lastDimSize / 2
<< "or fewer ranks");
"Number of ranks too large for data. Use " << lastDimSize / 2
<< "or fewer ranks");
MPI_Finalize();
return EXIT_FAILURE;
}
@ -629,8 +634,8 @@ int main(int argc, char* argv[])
if (nDims == 2)
{
vtkm::Id2 vdims;
vdims[0] = static_cast<vtkm::Id>(currBlockSize);
vdims[1] = static_cast<vtkm::Id>(dims[0]);
vdims[0] = static_cast<vtkm::Id>(dims[0]);
vdims[1] = static_cast<vtkm::Id>(currBlockSize);
vtkm::Vec<ValueType, 2> origin(0, blockIndex * blockSize);
vtkm::Vec<ValueType, 2> spacing(1, 1);
ds = dsb.Create(vdims, origin, spacing);
@ -645,8 +650,8 @@ int main(int argc, char* argv[])
else
{
vtkm::Id3 vdims;
vdims[0] = static_cast<vtkm::Id>(dims[0]);
vdims[1] = static_cast<vtkm::Id>(dims[1]);
vdims[0] = static_cast<vtkm::Id>(dims[1]);
vdims[1] = static_cast<vtkm::Id>(dims[0]);
vdims[2] = static_cast<vtkm::Id>(currBlockSize);
vtkm::Vec<ValueType, 3> origin(0, 0, (blockIndex * blockSize));
vtkm::Vec<ValueType, 3> spacing(1, 1, 1);
@ -690,6 +695,21 @@ int main(int argc, char* argv[])
vtkm::Float64 computeContourTreeTime = currTime - prevTime;
prevTime = currTime;
#ifdef WITH_MPI
#ifdef DEBUG_PRINT
std::cout << std::flush;
close(out);
std::cerr << std::flush;
close(err);
dup2(save_out, fileno(stdout));
dup2(save_err, fileno(stderr));
close(save_out);
close(save_err);
#endif
#endif
////////////////////////////////////////////
// Compute the branch decomposition
////////////////////////////////////////////

@ -21,6 +21,8 @@
#define VTKM_NO_ASSERT
#elif defined(VTKM_CUDA_DEVICE_PASS) && defined(VTKM_NO_ASSERT_CUDA)
#define VTKM_NO_ASSERT
#elif defined(VTKM_HIP) && defined(VTKM_NO_ASSERT_HIP)
#define VTKM_NO_ASSERT
#endif
#endif // VTKM_NO_ASSERT

@ -16,7 +16,7 @@ namespace vtkm
template <typename CoordType, int Dim, bool IsTwoSided>
template <int Dim_, typename std::enable_if<Dim_ == 2, int>::type>
Ray<CoordType, Dim, IsTwoSided>::Ray()
VTKM_EXEC_CONT Ray<CoordType, Dim, IsTwoSided>::Ray()
: Origin{ 0.f }
, Direction{ 1.f, 0.f }
{
@ -24,50 +24,42 @@ Ray<CoordType, Dim, IsTwoSided>::Ray()
template <typename CoordType, int Dim, bool IsTwoSided>
template <int Dim_, typename std::enable_if<Dim_ == 3, int>::type>
Ray<CoordType, Dim, IsTwoSided>::Ray()
VTKM_EXEC_CONT Ray<CoordType, Dim, IsTwoSided>::Ray()
: Origin{ 0.f }
, Direction{ 1.f, 0.f, 0.f }
{
}
template <typename CoordType, int Dim, bool IsTwoSided>
Ray<CoordType, Dim, IsTwoSided>::Ray(const LineSegment<CoordType, Dim>& segment)
VTKM_EXEC_CONT Ray<CoordType, Dim, IsTwoSided>::Ray(const LineSegment<CoordType, Dim>& segment)
: Origin(segment.Endpoints[0])
, Direction(vtkm::Normal(segment.Direction()))
{
}
template <typename CoordType, int Dim, bool IsTwoSided>
Ray<CoordType, Dim, IsTwoSided>::Ray(const Vector& point, const Vector& direction)
VTKM_EXEC_CONT Ray<CoordType, Dim, IsTwoSided>::Ray(const Vector& point, const Vector& direction)
: Origin(point)
, Direction(vtkm::Normal(direction))
{
}
template <typename CoordType, int Dim, bool IsTwoSided>
typename Ray<CoordType, Dim, IsTwoSided>::Vector Ray<CoordType, Dim, IsTwoSided>::Evaluate(
CoordType param) const
VTKM_EXEC_CONT typename Ray<CoordType, Dim, IsTwoSided>::Vector
Ray<CoordType, Dim, IsTwoSided>::Evaluate(CoordType param) const
{
auto pointOnLine = this->Origin + this->Direction * param;
return pointOnLine;
}
template <typename CoordType, int Dim, bool IsTwoSided>
bool Ray<CoordType, Dim, IsTwoSided>::IsValid() const
VTKM_EXEC_CONT bool Ray<CoordType, Dim, IsTwoSided>::IsValid() const
{
// At least on Ubuntu 17.10, cuda 9.1 will fail with an internal
// compiler error when calling vtkm::IsInf() here. But the fix
// below works. The fix should be removed as soon as our dashboards
// allow it.
#if __CUDACC_VER_MAJOR__ == 9 && __CUDACC_VER_MINOR__ == 1
return !isinf(this->Direction[0]);
#else
return !vtkm::IsInf(this->Direction[0]);
#endif
}
template <typename CoordType, int Dim, bool IsTwoSided>
CoordType Ray<CoordType, Dim, IsTwoSided>::DistanceTo(const Vector& point) const
VTKM_EXEC_CONT CoordType Ray<CoordType, Dim, IsTwoSided>::DistanceTo(const Vector& point) const
{
Vector closest;
CoordType param;
@ -75,9 +67,9 @@ CoordType Ray<CoordType, Dim, IsTwoSided>::DistanceTo(const Vector& point) const
}
template <typename CoordType, int Dim, bool IsTwoSided>
CoordType Ray<CoordType, Dim, IsTwoSided>::DistanceTo(const Vector& point,
CoordType& param,
Vector& projectedPoint) const
VTKM_EXEC_CONT CoordType Ray<CoordType, Dim, IsTwoSided>::DistanceTo(const Vector& point,
CoordType& param,
Vector& projectedPoint) const
{
const auto& dir = this->Direction;
auto mag2 = vtkm::MagnitudeSquared(dir);
@ -105,9 +97,10 @@ CoordType Ray<CoordType, Dim, IsTwoSided>::DistanceTo(const Vector& point,
template <typename CoordType, int Dim, bool IsTwoSided>
template <bool OtherTwoSided, int Dim_, typename std::enable_if<Dim_ == 2, int>::type>
bool Ray<CoordType, Dim, IsTwoSided>::Intersect(const Ray<CoordType, Dim, OtherTwoSided>& other,
Vector& point,
CoordType tol)
VTKM_EXEC_CONT bool Ray<CoordType, Dim, IsTwoSided>::Intersect(
const Ray<CoordType, Dim, OtherTwoSided>& other,
Vector& point,
CoordType tol)
{
auto d1 = this->Direction;
auto d2 = other.Direction;
@ -139,33 +132,33 @@ bool Ray<CoordType, Dim, IsTwoSided>::Intersect(const Ray<CoordType, Dim, OtherT
template <typename CoordType, int Dim>
template <int Dim_, typename std::enable_if<Dim_ == 2, int>::type>
LineSegment<CoordType, Dim>::LineSegment()
VTKM_EXEC_CONT LineSegment<CoordType, Dim>::LineSegment()
: Endpoints{ { 0.f }, { 1.f, 0.f } }
{
}
template <typename CoordType, int Dim>
template <int Dim_, typename std::enable_if<Dim_ == 3, int>::type>
LineSegment<CoordType, Dim>::LineSegment()
VTKM_EXEC_CONT LineSegment<CoordType, Dim>::LineSegment()
: Endpoints{ { 0.f }, { 1.f, 0.f, 0.f } }
{
}
template <typename CoordType, int Dim>
LineSegment<CoordType, Dim>::LineSegment(const Vector& p0, const Vector& p1)
VTKM_EXEC_CONT LineSegment<CoordType, Dim>::LineSegment(const Vector& p0, const Vector& p1)
: Endpoints{ p0, p1 }
{
}
template <typename CoordType, int Dim>
bool LineSegment<CoordType, Dim>::IsSingular(CoordType tol2) const
VTKM_EXEC_CONT bool LineSegment<CoordType, Dim>::IsSingular(CoordType tol2) const
{
return vtkm::MagnitudeSquared(this->Direction()) < tol2;
}
template <typename CoordType, int Dim>
template <int Dim_, typename std::enable_if<Dim_ == 2, int>::type>
Ray<CoordType, Dim, true> LineSegment<CoordType, Dim>::PerpendicularBisector() const
VTKM_EXEC_CONT Ray<CoordType, Dim, true> LineSegment<CoordType, Dim>::PerpendicularBisector() const
{
const Vector dir = this->Direction();
const Vector perp(-dir[1], dir[0]);
@ -175,13 +168,13 @@ Ray<CoordType, Dim, true> LineSegment<CoordType, Dim>::PerpendicularBisector() c
template <typename CoordType, int Dim>
template <int Dim_, typename std::enable_if<Dim_ == 3, int>::type>
Plane<CoordType> LineSegment<CoordType, Dim>::PerpendicularBisector() const
VTKM_EXEC_CONT Plane<CoordType> LineSegment<CoordType, Dim>::PerpendicularBisector() const
{
return Plane<CoordType>(this->Center(), this->Direction());
}
template <typename CoordType, int Dim>
typename LineSegment<CoordType, Dim>::Vector LineSegment<CoordType, Dim>::Evaluate(
VTKM_EXEC_CONT typename LineSegment<CoordType, Dim>::Vector LineSegment<CoordType, Dim>::Evaluate(
CoordType param) const
{
auto pointOnLine = this->Endpoints[0] * (1.0f - param) + this->Endpoints[1] * param;
@ -189,7 +182,7 @@ typename LineSegment<CoordType, Dim>::Vector LineSegment<CoordType, Dim>::Evalua
}
template <typename CoordType, int Dim>
CoordType LineSegment<CoordType, Dim>::DistanceTo(const Vector& point) const
VTKM_EXEC_CONT CoordType LineSegment<CoordType, Dim>::DistanceTo(const Vector& point) const
{
Vector closest;
CoordType param;
@ -197,9 +190,9 @@ CoordType LineSegment<CoordType, Dim>::DistanceTo(const Vector& point) const
}
template <typename CoordType, int Dim>
CoordType LineSegment<CoordType, Dim>::DistanceTo(const Vector& point,
CoordType& param,
Vector& projectedPoint) const
VTKM_EXEC_CONT CoordType LineSegment<CoordType, Dim>::DistanceTo(const Vector& point,
CoordType& param,
Vector& projectedPoint) const
{
auto dir = this->Endpoints[1] - this->Endpoints[0];
auto mag2 = vtkm::MagnitudeSquared(dir);
@ -224,9 +217,10 @@ CoordType LineSegment<CoordType, Dim>::DistanceTo(const Vector& point,
template <typename CoordType, int Dim>
template <int Dim_, typename std::enable_if<Dim_ == 2, int>::type>
bool LineSegment<CoordType, Dim>::IntersectInfinite(const LineSegment<CoordType, Dim>& other,
Vector& point,
CoordType tol)
VTKM_EXEC_CONT bool LineSegment<CoordType, Dim>::IntersectInfinite(
const LineSegment<CoordType, Dim>& other,
Vector& point,
CoordType tol)
{
auto d1 = this->Direction();
auto d2 = other.Direction();
@ -249,14 +243,14 @@ bool LineSegment<CoordType, Dim>::IntersectInfinite(const LineSegment<CoordType,
// Plane
template <typename CoordType>
Plane<CoordType>::Plane()
VTKM_EXEC_CONT VTKM_EXEC_CONT Plane<CoordType>::Plane()
: Origin{ 0.f, 0.f, 0.f }
, Normal{ 0.f, 0.f, 1.f }
{
}
template <typename CoordType>
Plane<CoordType>::Plane(const Vector& origin, const Vector& normal, CoordType tol2)
VTKM_EXEC_CONT Plane<CoordType>::Plane(const Vector& origin, const Vector& normal, CoordType tol2)
: Origin(origin)
, Normal(vtkm::Normal(normal))
{
@ -268,14 +262,15 @@ Plane<CoordType>::Plane(const Vector& origin, const Vector& normal, CoordType to
}
template <typename CoordType>
CoordType Plane<CoordType>::DistanceTo(const Vector& point) const
VTKM_EXEC_CONT CoordType Plane<CoordType>::DistanceTo(const Vector& point) const
{
auto dist = vtkm::Dot(point - this->Origin, this->Normal);
return dist;
}
template <typename CoordType>
typename Plane<CoordType>::Vector Plane<CoordType>::ClosestPoint(const Vector& point) const
VTKM_EXEC_CONT typename Plane<CoordType>::Vector Plane<CoordType>::ClosestPoint(
const Vector& point) const
{
auto vop = vtkm::Project(point - this->Origin, this->Normal);
auto closest = point - vop;
@ -284,11 +279,11 @@ typename Plane<CoordType>::Vector Plane<CoordType>::ClosestPoint(const Vector& p
template <typename CoordType>
template <bool IsTwoSided>
bool Plane<CoordType>::Intersect(const Ray<CoordType, 3, IsTwoSided>& ray,
CoordType& parameter,
Vector& point,
bool& lineInPlane,
CoordType tol) const
VTKM_EXEC_CONT bool Plane<CoordType>::Intersect(const Ray<CoordType, 3, IsTwoSided>& ray,
CoordType& parameter,
Vector& point,
bool& lineInPlane,
CoordType tol) const
{
CoordType d0 = this->DistanceTo(ray.Origin);
CoordType dirDot = vtkm::Dot(this->Normal, ray.Direction);
@ -330,19 +325,19 @@ bool Plane<CoordType>::Intersect(const Ray<CoordType, 3, IsTwoSided>& ray,
}
template <typename CoordType>
bool Plane<CoordType>::Intersect(const LineSegment<CoordType>& segment,
CoordType& parameter,
bool& lineInPlane) const
VTKM_EXEC_CONT bool Plane<CoordType>::Intersect(const LineSegment<CoordType>& segment,
CoordType& parameter,
bool& lineInPlane) const
{
Vector point;
return this->Intersect(segment, parameter, point, lineInPlane);
}
template <typename CoordType>
bool Plane<CoordType>::Intersect(const LineSegment<CoordType>& segment,
CoordType& parameter,
Vector& point,
bool& lineInPlane) const
VTKM_EXEC_CONT bool Plane<CoordType>::Intersect(const LineSegment<CoordType>& segment,
CoordType& parameter,
Vector& point,
bool& lineInPlane) const
{
CoordType d0 = this->DistanceTo(segment.Endpoints[0]);
CoordType d1 = this->DistanceTo(segment.Endpoints[1]);
@ -394,10 +389,10 @@ bool Plane<CoordType>::Intersect(const LineSegment<CoordType>& segment,
}
template <typename CoordType>
bool Plane<CoordType>::Intersect(const Plane<CoordType>& other,
Ray<CoordType, 3, true>& ray,
bool& coincident,
CoordType tol2) const
VTKM_EXEC_CONT bool Plane<CoordType>::Intersect(const Plane<CoordType>& other,
Ray<CoordType, 3, true>& ray,
bool& coincident,
CoordType tol2) const
{
auto dir = vtkm::Cross(this->Normal, other.Normal);
auto mag2 = vtkm::MagnitudeSquared(dir);
@ -434,27 +429,27 @@ bool Plane<CoordType>::Intersect(const Plane<CoordType>& other,
// Sphere
template <typename CoordType, int Dim>
Sphere<CoordType, Dim>::Sphere()
VTKM_EXEC_CONT Sphere<CoordType, Dim>::Sphere()
: Center{ 0.f }
, Radius(static_cast<CoordType>(1.f))
{
}
template <typename CoordType, int Dim>
Sphere<CoordType, Dim>::Sphere(const Vector& center, CoordType radius)
VTKM_EXEC_CONT Sphere<CoordType, Dim>::Sphere(const Vector& center, CoordType radius)
: Center(center)
, Radius(radius <= 0.f ? static_cast<CoordType>(-1.0f) : radius)
{
}
template <typename CoordType, int Dim>
bool Sphere<CoordType, Dim>::Contains(const Vector& point, CoordType tol2) const
VTKM_EXEC_CONT bool Sphere<CoordType, Dim>::Contains(const Vector& point, CoordType tol2) const
{
return this->Classify(point, tol2) < 0;
}
template <typename CoordType, int Dim>
int Sphere<CoordType, Dim>::Classify(const Vector& point, CoordType tol2) const
VTKM_EXEC_CONT int Sphere<CoordType, Dim>::Classify(const Vector& point, CoordType tol2) const
{
if (!this->IsValid())
{
@ -469,16 +464,17 @@ int Sphere<CoordType, Dim>::Classify(const Vector& point, CoordType tol2) const
// Construction techniques
template <typename CoordType, bool IsTwoSided>
vtkm::Plane<CoordType> make_PlaneFromPointAndLine(const vtkm::Vec<CoordType, 3>& point,
const vtkm::Ray<CoordType, 3, IsTwoSided>& ray,
CoordType tol2)
VTKM_EXEC_CONT vtkm::Plane<CoordType> make_PlaneFromPointAndLine(
const vtkm::Vec<CoordType, 3>& point,
const vtkm::Ray<CoordType, 3, IsTwoSided>& ray,
CoordType tol2)
{
auto tmpDir = point - ray.Origin;
return vtkm::Plane<CoordType>(point, vtkm::Cross(ray.Direction, tmpDir), tol2);
}
template <typename CoordType>
vtkm::Plane<CoordType> make_PlaneFromPointAndLineSegment(
VTKM_EXEC_CONT vtkm::Plane<CoordType> make_PlaneFromPointAndLineSegment(
const vtkm::Vec<CoordType, 3>& point,
const vtkm::LineSegment3<CoordType>& segment,
CoordType tol2)
@ -488,10 +484,11 @@ vtkm::Plane<CoordType> make_PlaneFromPointAndLineSegment(
}
template <typename CoordType>
vtkm::Circle<CoordType> make_CircleFrom3Points(const typename vtkm::Vec<CoordType, 2>& p0,
const typename vtkm::Vec<CoordType, 2>& p1,
const typename vtkm::Vec<CoordType, 2>& p2,
CoordType tol)
VTKM_EXEC_CONT vtkm::Circle<CoordType> make_CircleFrom3Points(
const typename vtkm::Vec<CoordType, 2>& p0,
const typename vtkm::Vec<CoordType, 2>& p1,
const typename vtkm::Vec<CoordType, 2>& p2,
CoordType tol)
{
constexpr int Dim = 2;
using Vector = typename vtkm::Circle<CoordType>::Vector;
@ -518,11 +515,11 @@ vtkm::Circle<CoordType> make_CircleFrom3Points(const typename vtkm::Vec<CoordTyp
}
template <typename CoordType>
vtkm::Sphere<CoordType, 3> make_SphereFrom4Points(const vtkm::Vec<CoordType, 3>& a0,
const vtkm::Vec<CoordType, 3>& a1,
const vtkm::Vec<CoordType, 3>& a2,
const vtkm::Vec<CoordType, 3>& a3,
CoordType tol)
VTKM_EXEC_CONT vtkm::Sphere<CoordType, 3> make_SphereFrom4Points(const vtkm::Vec<CoordType, 3>& a0,
const vtkm::Vec<CoordType, 3>& a1,
const vtkm::Vec<CoordType, 3>& a2,
const vtkm::Vec<CoordType, 3>& a3,
CoordType tol)
{
// Choose p3 such that the min(p3 - p[012]) is larger than any other choice of p3.
// From: http://steve.hollasch.net/cgindex/geometry/sphere4pts.html,

@ -129,6 +129,13 @@ public:
VTKM_EXEC_CONT
Particle() {}
VTKM_EXEC_CONT Particle(const vtkm::Particle& rhs)
: ParticleBase(rhs)
{
// This must not be defaulted, since defaulted copy constructors are
// troublesome with CUDA __host__ __device__ markup.
}
VTKM_EXEC_CONT ~Particle() noexcept override
{
// This must not be defaulted, since defaulted virtual destructors are
@ -146,6 +153,19 @@ public:
{
}
VTKM_EXEC_CONT Particle& operator=(const vtkm::Particle& rhs)
{
// This must not be defaulted, since defaulted assignment operators are
// troublesome with CUDA __host__ __device__ markup.
if (&rhs == this)
{
return *this;
}
vtkm::ParticleBase::operator=(rhs);
return *this;
}
VTKM_EXEC_CONT
vtkm::Vec3f Next(const vtkm::VecVariable<vtkm::Vec3f, 2>& vectors,
const vtkm::FloatDefault& length) override

@ -196,119 +196,15 @@ using FloatDefault = vtkm::Float64;
using FloatDefault = vtkm::Float32;
#endif
namespace internal
{
//-----------------------------------------------------------------------------
/// Placeholder class for when a type is not applicable.
///
struct NullType
{
};
//-----------------------------------------------------------------------------
template <vtkm::IdComponent Size>
struct VecComponentWiseUnaryOperation
{
template <typename T, typename UnaryOpType>
inline VTKM_EXEC_CONT T operator()(const T& v, const UnaryOpType& unaryOp) const
{
T result;
for (vtkm::IdComponent i = 0; i < Size; ++i)
{
result[i] = unaryOp(v[i]);
}
return result;
}
};
template <>
struct VecComponentWiseUnaryOperation<1>
{
template <typename T, typename UnaryOpType>
inline VTKM_EXEC_CONT T operator()(const T& v, const UnaryOpType& unaryOp) const
{
return T(unaryOp(v[0]));
}
};
template <>
struct VecComponentWiseUnaryOperation<2>
{
template <typename T, typename UnaryOpType>
inline VTKM_EXEC_CONT T operator()(const T& v, const UnaryOpType& unaryOp) const
{
return T(unaryOp(v[0]), unaryOp(v[1]));
}
};
template <>
struct VecComponentWiseUnaryOperation<3>
{
template <typename T, typename UnaryOpType>
inline VTKM_EXEC_CONT T operator()(const T& v, const UnaryOpType& unaryOp) const
{
return T(unaryOp(v[0]), unaryOp(v[1]), unaryOp(v[2]));
}
};
template <>
struct VecComponentWiseUnaryOperation<4>
{
template <typename T, typename UnaryOpType>
inline VTKM_EXEC_CONT T operator()(const T& v, const UnaryOpType& unaryOp) const
{
return T(unaryOp(v[0]), unaryOp(v[1]), unaryOp(v[2]), unaryOp(v[3]));
}
};
template <typename T, typename BinaryOpType, typename ReturnT = T>
struct BindLeftBinaryOp
{
// Warning: a reference.
const T& LeftValue;
const BinaryOpType BinaryOp;
VTKM_EXEC_CONT
BindLeftBinaryOp(const T& leftValue, BinaryOpType binaryOp = BinaryOpType())
: LeftValue(leftValue)
, BinaryOp(binaryOp)
{
}
template <typename RightT>
VTKM_EXEC_CONT ReturnT operator()(const RightT& rightValue) const
{
return static_cast<ReturnT>(this->BinaryOp(this->LeftValue, static_cast<T>(rightValue)));
}
private:
void operator=(const BindLeftBinaryOp<T, BinaryOpType, ReturnT>&) = delete;
};
template <typename T, typename BinaryOpType, typename ReturnT = T>
struct BindRightBinaryOp
{
// Warning: a reference.
const T& RightValue;
const BinaryOpType BinaryOp;
VTKM_EXEC_CONT
BindRightBinaryOp(const T& rightValue, BinaryOpType binaryOp = BinaryOpType())
: RightValue(rightValue)
, BinaryOp(binaryOp)
{
}
template <typename LeftT>
VTKM_EXEC_CONT ReturnT operator()(const LeftT& leftValue) const
{
return static_cast<ReturnT>(this->BinaryOp(static_cast<T>(leftValue), this->RightValue));
}
private:
void operator=(const BindRightBinaryOp<T, BinaryOpType, ReturnT>&) = delete;
};
} // namespace internal
// Disable conversion warnings for Add, Subtract, Multiply, Divide on GCC only.
@ -717,7 +613,6 @@ public:
return this->Components[idx];
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename OtherComponentType, typename OtherClass>
inline VTKM_EXEC_CONT DerivedClass
@ -1664,94 +1559,6 @@ inline VTKM_EXEC_CONT T ReduceProduct(const vtkm::Vec<T, 4>& a)
template <typename U, typename V>
struct Pair;
template <typename T, vtkm::IdComponent Size>
inline VTKM_EXEC_CONT vtkm::Vec<T, Size> operator*(T scalar, const vtkm::Vec<T, Size>& vec)
{
return vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec, vtkm::internal::BindLeftBinaryOp<T, vtkm::Multiply>(scalar));
}
template <typename T, vtkm::IdComponent Size>
inline VTKM_EXEC_CONT vtkm::Vec<T, Size> operator*(const vtkm::Vec<T, Size>& vec, T scalar)
{
return vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec, vtkm::internal::BindRightBinaryOp<T, vtkm::Multiply>(scalar));
}
template <typename T, vtkm::IdComponent Size>
inline VTKM_EXEC_CONT vtkm::Vec<T, Size> operator*(vtkm::Float64 scalar,
const vtkm::Vec<T, Size>& vec)
{
return vtkm::Vec<T, Size>(vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec, vtkm::internal::BindLeftBinaryOp<vtkm::Float64, vtkm::Multiply, T>(scalar)));
}
template <typename T, vtkm::IdComponent Size>
inline VTKM_EXEC_CONT vtkm::Vec<T, Size> operator*(const vtkm::Vec<T, Size>& vec,
vtkm::Float64 scalar)
{
return vtkm::Vec<T, Size>(vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec, vtkm::internal::BindRightBinaryOp<vtkm::Float64, vtkm::Multiply, T>(scalar)));
}
template <vtkm::IdComponent Size>
inline VTKM_EXEC_CONT vtkm::Vec<vtkm::Float64, Size> operator*(
vtkm::Float64 scalar,
const vtkm::Vec<vtkm::Float64, Size>& vec)
{
return vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec, vtkm::internal::BindLeftBinaryOp<vtkm::Float64, vtkm::Multiply>(scalar));
}
template <vtkm::IdComponent Size>
inline VTKM_EXEC_CONT vtkm::Vec<vtkm::Float64, Size> operator*(
const vtkm::Vec<vtkm::Float64, Size>& vec,
vtkm::Float64 scalar)
{
return vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec, vtkm::internal::BindRightBinaryOp<vtkm::Float64, vtkm::Multiply>(scalar));
}
template <typename T, vtkm::IdComponent Size>
inline VTKM_EXEC_CONT vtkm::Vec<T, Size> operator/(const vtkm::Vec<T, Size>& vec, T scalar)
{
return vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec, vtkm::internal::BindRightBinaryOp<T, vtkm::Divide>(scalar));
}
template <typename T, vtkm::IdComponent Size>
inline VTKM_EXEC_CONT vtkm::Vec<T, Size> operator/(const vtkm::Vec<T, Size>& vec,
vtkm::Float64 scalar)
{
return vtkm::Vec<T, Size>(vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec, vtkm::internal::BindRightBinaryOp<vtkm::Float64, vtkm::Divide, T>(scalar)));
}
template <vtkm::IdComponent Size>
inline VTKM_EXEC_CONT vtkm::Vec<vtkm::Float64, Size> operator/(
const vtkm::Vec<vtkm::Float64, Size>& vec,
vtkm::Float64 scalar)
{
return vtkm::internal::VecComponentWiseUnaryOperation<Size>()(
vec, vtkm::internal::BindRightBinaryOp<vtkm::Float64, vtkm::Divide>(scalar));
}
// clang-format off
// The enable_if for this operator is effectively disabling the negate
// operator for Vec of unsigned integers. Another approach would be
// to use enable_if<!is_unsigned>. That would be more inclusive but would
// also allow other types like Vec<Vec<unsigned> >. If necessary, we could
// change this implementation to be more inclusive.
template <typename T, vtkm::IdComponent Size>
inline VTKM_EXEC_CONT
typename std::enable_if<(std::is_floating_point<T>::value || std::is_signed<T>::value),
vtkm::Vec<T, Size>>::type
operator-(const vtkm::Vec<T, Size>& x)
{
return vtkm::internal::VecComponentWiseUnaryOperation<Size>()(x, vtkm::Negate());
}
// clang-format on
/// Helper function for printing out vectors during testing.
///
template <typename T, vtkm::IdComponent Size>
@ -1773,7 +1580,8 @@ inline VTKM_EXEC_CONT std::ostream& operator<<(std::ostream& stream, const vtkm:
return stream << "[" << vec.first << "," << vec.second << "]";
}
} // End of namespace vtkm
#include <vtkm/internal/VecOperators.h>
// Declared inside of vtkm namespace so that the operator work with ADL lookup
#endif //vtk_m_Types_h

@ -108,7 +108,7 @@ VTKM_CONT void ArrayCopyImpl(const vtkm::cont::ArrayHandle<T, S>& source,
vtkm::cont::ArrayHandle<T, S>& destination,
std::true_type /* New style */)
{
source.DeepCopy(destination);
destination.DeepCopyFrom(source);
}
} // namespace detail

@ -1391,16 +1391,16 @@ public:
/// \brief Deep copies the data in the array.
///
/// Takes the data that is in this array and copies that data into the provided
/// \a destination.
/// Takes the data that is in \a source and copies that data into this array.
///
VTKM_CONT void DeepCopy(vtkm::cont::ArrayHandleNewStyle<ValueType, StorageTag>& destination) const
VTKM_CONT void DeepCopyFrom(
const vtkm::cont::ArrayHandleNewStyle<ValueType, StorageTag>& source) const
{
VTKM_ASSERT(this->Buffers.size() == destination.Buffers.size());
VTKM_ASSERT(this->Buffers.size() == source.Buffers.size());
for (std::size_t bufferIndex = 0; bufferIndex < this->Buffers.size(); ++bufferIndex)
{
this->Buffers[bufferIndex].DeepCopy(destination.Buffers[bufferIndex]);
this->Buffers[bufferIndex].DeepCopyFrom(source.Buffers[bufferIndex]);
}
}

@ -67,13 +67,12 @@ struct AllAreArrayHandles
// `vtkm::Vec<Float32, 3>`. This also validates that all members have the same `ValueType`.
template <typename ExpectedValueType, typename ArrayType>
constexpr bool CheckValueType()
struct CheckValueType
{
VTKM_STATIC_ASSERT_MSG((std::is_same<ExpectedValueType, typename ArrayType::ValueType>::value),
"ArrayHandleCompositeVector must be built from "
"ArrayHandles with the same ValueTypes.");
return std::is_same<ExpectedValueType, typename ArrayType::ValueType>::value;
}
};
template <typename ArrayType0, typename... ArrayTypes>
struct GetValueType
@ -81,9 +80,7 @@ struct GetValueType
static constexpr vtkm::IdComponent COUNT =
static_cast<vtkm::IdComponent>(sizeof...(ArrayTypes)) + 1;
using ComponentType = typename ArrayType0::ValueType;
static constexpr std::array<bool, sizeof...(ArrayTypes) + 1> ValueCheck{
{ true, CheckValueType<ComponentType, ArrayTypes>()... }
};
using ValueCheck = vtkm::List<CheckValueType<ComponentType, ArrayTypes>...>;
using ValueType = vtkm::Vec<ComponentType, COUNT>;
};

@ -176,9 +176,9 @@ struct MultiplexerShrinkFunctor
struct MultiplexerReleaseResourcesFunctor
{
template <typename ArrayHandleType>
VTKM_CONT vtkm::Id operator()(ArrayHandleType&& array) const
VTKM_CONT void operator()(ArrayHandleType&& array) const
{
return array.ReleaseResources();
array.ReleaseResources();
}
};
@ -334,6 +334,10 @@ public:
}
VTKM_CONT ArrayHandleVariantType& GetArrayHandleVariant() { return this->ArrayHandleVariant; }
VTKM_CONT const ArrayHandleVariantType& GetArrayHandleVariant() const
{
return this->ArrayHandleVariant;
}
};

@ -15,6 +15,8 @@ namespace vtkm
namespace cont
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
#define VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(T) \
template class VTKM_CONT_EXPORT ArrayHandle<T, StorageTagVirtual>; \
template class VTKM_CONT_EXPORT ArrayHandleVirtual<T>; \
@ -38,5 +40,8 @@ VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Float32);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Float64);
#undef VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE
VTKM_DEPRECATED_SUPPRESS_END
}
} //namespace vtkm::cont

@ -20,14 +20,19 @@
#include <memory>
#ifdef VTKM_NO_DEPRECATED_VIRTUAL
#error "ArrayHandleVirtual is removed. Do not include ArrayHandleVirtual.h"
#endif
namespace vtkm
{
namespace cont
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <typename T>
class VTKM_ALWAYS_EXPORT ArrayHandleVirtual
class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6) ArrayHandleVirtual
: public vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>
{
using StorageType = vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagVirtual>;
@ -267,6 +272,7 @@ VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Float64);
#undef VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT
#endif //vtk_m_cont_ArrayHandleVirtual_cxx
VTKM_DEPRECATED_SUPPRESS_END
}
} //namespace vtkm::cont

@ -13,6 +13,7 @@
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/TryExecute.h>
VTKM_DEPRECATED_SUPPRESS_BEGIN
namespace vtkm
{
namespace cont
@ -37,6 +38,7 @@ ArrayHandleType inline ArrayHandleVirtual<T>::CastToType(
}
}
} // namespace vtkm::cont
VTKM_DEPRECATED_SUPPRESS_END
#include <vtkm/cont/ArrayHandleConstant.h>
@ -45,6 +47,7 @@ ArrayHandleType inline ArrayHandleVirtual<T>::CastToType(
//=============================================================================
// Specializations of serialization related classes
/// @cond SERIALIZATION
VTKM_DEPRECATED_SUPPRESS_BEGIN
namespace mangled_diy_namespace
{
@ -178,5 +181,6 @@ struct Serialization<vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>>
};
} // mangled_diy_namespace
VTKM_DEPRECATED_SUPPRESS_END
#endif

@ -22,11 +22,17 @@
#include <memory>
#include <type_traits>
#ifdef VTKM_NO_DEPRECATED_VIRTUAL
#error "ArrayHandleVirtualCoordiantes is removed. Do not include ArrayHandleVirtualCoordinates.h"
#endif
namespace vtkm
{
namespace cont
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
/// ArrayHandleVirtualCoordinates is a specialization of ArrayHandle.
class VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Virtual ArrayHandles are being phased out.")
ArrayHandleVirtualCoordinates final : public vtkm::cont::ArrayHandleVirtual<vtkm::Vec3f>
@ -35,17 +41,13 @@ public:
VTKM_ARRAY_HANDLE_SUBCLASS_NT(ArrayHandleVirtualCoordinates,
(vtkm::cont::ArrayHandleVirtual<vtkm::Vec3f>));
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <typename T, typename S>
explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle<T, S>& ah)
: vtkm::cont::ArrayHandleVirtual<vtkm::Vec3f>(vtkm::cont::make_ArrayHandleCast<ValueType>(ah))
{
}
VTKM_DEPRECATED_SUPPRESS_END
};
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::ArrayHandleVirtualCoordinates& coords,
Functor&& f,

@ -16,9 +16,12 @@
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleCompositeVector.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/DeviceAdapterTag.h>
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/cont/ArrayHandleVirtual.h>
#endif
namespace vtkm
{
namespace cont
@ -87,10 +90,14 @@ VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float64, 4, vtkm::cont::StorageTagBas
#undef VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_T
#undef VTK_M_ARRAY_RANGE_COMPUTE_EXPORT_VEC
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandleVirtual<vtkm::Vec3f>& input,
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny());
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
VTKM_DEPRECATED_SUPPRESS_BEGIN
VTKM_CONT VTKM_DEPRECATED(1.6, "ArrayHandleVirtual no longer supported.")
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandleVirtual<vtkm::Vec3f>& input,
vtkm::cont::DeviceAdapterId device = vtkm::cont::DeviceAdapterTagAny());
VTKM_DEPRECATED_SUPPRESS_END
#endif //VTKM_NO_DEPRECATED_VIRTUAL
VTKM_CONT_EXPORT VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandle<vtkm::Vec3f,

@ -94,6 +94,8 @@ inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeImpl(
} // namespace detail
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
VTKM_DEPRECATED_SUPPRESS_BEGIN
VTKM_CONT
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandleVirtual<vtkm::Vec3f>& input,
@ -132,6 +134,8 @@ inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
return detail::ArrayRangeComputeImpl(input, device);
}
}
VTKM_DEPRECATED_SUPPRESS_END
#endif //VTKM_NO_DEPRECATED_VIRTUAL
template <typename ArrayHandleType>
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(const ArrayHandleType& input,

@ -59,7 +59,7 @@ public:
AssignerPartitionedDataSet(vtkm::Id num_partitions);
VTKM_CONT
virtual ~AssignerPartitionedDataSet();
~AssignerPartitionedDataSet() override;
///@{
/// vtkmdiy::Assigner API implementation.

@ -41,8 +41,6 @@ set(headers
ArrayHandleTransform.h
ArrayHandleUniformPointCoordinates.h
ArrayHandleView.h
ArrayHandleVirtual.h
ArrayHandleVirtualCoordinates.h
ArrayHandleZip.h
ArrayPortal.h
ArrayPortalToIterators.h
@ -57,6 +55,7 @@ set(headers
CellLocatorBoundingIntervalHierarchy.h
CellLocatorGeneral.h
CellLocatorRectilinearGrid.h
CellLocatorTwoLevel.h
CellLocatorUniformBins.h
CellLocatorUniformGrid.h
CellSet.h
@ -68,6 +67,7 @@ set(headers
CellSetSingleType.h
CellSetStructured.h
ColorTable.h
ColorTableMap.h
ColorTableSamples.h
CoordinateSystem.h
DataSet.h
@ -103,6 +103,7 @@ set(headers
PartitionedDataSet.h
PointLocator.h
PointLocatorUniformGrid.h
PointLocatorSparseGrid.h
RuntimeDeviceInformation.h
RuntimeDeviceTracker.h
Serialization.h
@ -111,27 +112,25 @@ set(headers
StorageImplicit.h
StorageList.h
StorageListTag.h
StorageVirtual.h
Timer.h
Token.h
TryExecute.h
SerializableTypeString.h
UncertainArrayHandle.h
UnknownArrayHandle.h
VariantArrayHandle.h
VirtualObjectHandle.h
)
set(template_sources
ArrayHandle.hxx
ArrayHandleVirtual.hxx
ArrayRangeCompute.hxx
CellSetExplicit.hxx
CellSetExtrude.hxx
CellSetStructured.hxx
ColorTable.hxx
FieldRangeCompute.hxx
FieldRangeGlobalCompute.hxx
ParticleArrayCopy.hxx
StorageVirtual.hxx
VirtualObjectHandle.hxx
)
@ -160,7 +159,6 @@ set(sources
# 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
ArrayHandleVirtual.cxx
ArrayRangeCompute.cxx
AssignerPartitionedDataSet.cxx
BoundsCompute.cxx
@ -169,7 +167,7 @@ set(sources
CellLocatorBoundingIntervalHierarchy.cxx
CellLocatorGeneral.cxx
CellLocatorRectilinearGrid.cxx
CellLocatorUniformBins.cxx
CellLocatorTwoLevel.cxx
CellLocatorUniformGrid.cxx
CellSet.cxx
CellSetExplicit.cxx
@ -181,18 +179,35 @@ set(sources
DataSetBuilderExplicit.cxx
DataSetBuilderRectilinear.cxx
DataSetBuilderUniform.cxx
internal/VariantArrayHandleContainer.cxx
Field.cxx
FieldRangeCompute.cxx
FieldRangeGlobalCompute.cxx
PartitionedDataSet.cxx
PointLocator.cxx
PointLocatorUniformGrid.cxx
PointLocatorSparseGrid.cxx
RuntimeDeviceInformation.cxx
StorageVirtual.cxx
Timer.cxx
UnknownArrayHandle.cxx
)
if (NOT VTKm_NO_DEPRECATED_VIRTUAL)
set(headers ${headers}
ArrayHandleVirtual.h
ArrayHandleVirtualCoordinates.h
StorageVirtual.h
)
set(template_sources ${template_sources}
ArrayHandleVirtual.hxx
StorageVirtual.hxx
)
set(device_sources ${device_sources}
ArrayHandleVirtual.cxx
StorageVirtual.cxx
)
endif()
#-----------------------------------------------------------------------------
# Set up default types, which can be custom configured by other build systems.
vtkm_get_kit_name(kit_name kit_dir)

@ -19,11 +19,13 @@ namespace vtkm
namespace cont
{
class CoordinateSystem;
class Field;
template <typename T, typename S>
class ArrayHandle;
class CoordinateSystem;
class Field;
class UnknownArrayHandle;
template <vtkm::IdComponent>
class CellSetStructured;
@ -65,6 +67,13 @@ void CastAndCall(const vtkm::cont::ArrayHandle<T, U>& handle, Functor&& f, Args&
f(handle, std::forward<Args>(args)...);
}
/// A specialization of CastAndCall for UnknownArrayHandle.
/// Since we have no hints on the types, use VTKM_DEFAULT_TYPE_LIST
/// and VTKM_DEFAULT_STORAGE_LIST.
// actually implemented in vtkm/cont/UnknownArrayHandle
template <typename Functor, typename... Args>
void CastAndCall(const UnknownArrayHandle& handle, Functor&& f, Args&&... args);
/// A specialization of CastAndCall for basic CellSetStructured types,
/// Since the type is already known no deduction is needed.
/// This specialization is used to simplify numerous worklet algorithms

@ -13,7 +13,7 @@
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/CellLocatorRectilinearGrid.h>
#include <vtkm/cont/CellLocatorUniformBins.h>
#include <vtkm/cont/CellLocatorTwoLevel.h>
#include <vtkm/cont/CellLocatorUniformGrid.h>
#include <vtkm/cont/CellSetStructured.h>
@ -46,9 +46,9 @@ void DefaultConfigurator(std::unique_ptr<vtkm::cont::CellLocator>& locator,
locator.reset(new vtkm::cont::CellLocatorRectilinearGrid);
}
}
else if (!dynamic_cast<vtkm::cont::CellLocatorUniformBins*>(locator.get()))
else if (!dynamic_cast<vtkm::cont::CellLocatorTwoLevel*>(locator.get()))
{
locator.reset(new vtkm::cont::CellLocatorUniformBins);
locator.reset(new vtkm::cont::CellLocatorTwoLevel);
}
locator->SetCellSet(cellSet);

@ -7,7 +7,7 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/CellLocatorUniformBins.h>
#include <vtkm/cont/CellLocatorTwoLevel.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayCopy.h>
@ -345,7 +345,7 @@ namespace cont
//----------------------------------------------------------------------------
/// Builds the cell locator lookup structure
///
VTKM_CONT void CellLocatorUniformBins::Build()
VTKM_CONT void CellLocatorTwoLevel::Build()
{
vtkm::cont::Invoker invoke;
@ -453,53 +453,53 @@ VTKM_CONT void CellLocatorUniformBins::Build()
}
//----------------------------------------------------------------------------
struct CellLocatorUniformBins::MakeExecObject
struct CellLocatorTwoLevel::MakeExecObject
{
template <typename CellSetType, typename DeviceAdapter>
VTKM_CONT void operator()(const CellSetType& cellSet,
DeviceAdapter,
vtkm::cont::Token& token,
const CellLocatorUniformBins& self) const
const CellLocatorTwoLevel& self) const
{
auto execObject =
new vtkm::exec::CellLocatorUniformBins<CellSetType, DeviceAdapter>(self.TopLevel,
self.LeafDimensions,
self.LeafStartIndex,
self.CellStartIndex,
self.CellCount,
self.CellIds,
cellSet,
self.GetCoordinates(),
token);
new vtkm::exec::CellLocatorTwoLevel<CellSetType, DeviceAdapter>(self.TopLevel,
self.LeafDimensions,
self.LeafStartIndex,
self.CellStartIndex,
self.CellCount,
self.CellIds,
cellSet,
self.GetCoordinates(),
token);
self.ExecutionObjectHandle.Reset(execObject);
}
};
struct CellLocatorUniformBins::PrepareForExecutionFunctor
struct CellLocatorTwoLevel::PrepareForExecutionFunctor
{
template <typename DeviceAdapter>
VTKM_CONT bool operator()(DeviceAdapter,
vtkm::cont::Token& token,
const CellLocatorUniformBins& self) const
const CellLocatorTwoLevel& self) const
{
self.GetCellSet().CastAndCall(MakeExecObject{}, DeviceAdapter{}, token, self);
return true;
}
};
VTKM_CONT const vtkm::exec::CellLocator* CellLocatorUniformBins::PrepareForExecution(
VTKM_CONT const vtkm::exec::CellLocator* CellLocatorTwoLevel::PrepareForExecution(
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
if (!vtkm::cont::TryExecuteOnDevice(device, PrepareForExecutionFunctor(), token, *this))
{
throwFailedRuntimeDeviceTransfer("CellLocatorUniformBins", device);
throwFailedRuntimeDeviceTransfer("CellLocatorTwoLevel", device);
}
return this->ExecutionObjectHandle.PrepareForExecution(device, token);
}
//----------------------------------------------------------------------------
void CellLocatorUniformBins::PrintSummary(std::ostream& out) const
void CellLocatorTwoLevel::PrintSummary(std::ostream& out) const
{
out << "DensityL1: " << this->DensityL1 << "\n";
out << "DensityL2: " << this->DensityL2 << "\n";

@ -0,0 +1,93 @@
//============================================================================
// 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_CellLocatorTwoLevel_h
#define vtk_m_cont_CellLocatorTwoLevel_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CellLocator.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/exec/CellLocatorTwoLevel.h>
namespace vtkm
{
namespace cont
{
/// \brief A locator that uses 2 nested levels of grids.
///
/// `CellLocatorTwoLevel` creates a cell search structure using two levels of structured
/// grids. The first level is a coarse grid that covers the entire region of the data.
/// It is expected that the distributions of dataset cells in this coarse grid will be
/// very uneven. Within each bin of the coarse grid, a second level grid is defined within
/// the spatial bounds of the coarse bin. The size of this second level grid is proportional
/// to the number of cells in the first level. In this way, the second level grids adapt
/// to the distribution of cells being located. The adaption is not perfect, but it is
/// has very good space efficiency and is fast to generate and use.
///
/// The algorithm used in `CellLocatorTwoLevel` is described in the following publication:
///
/// Javor Kalojanov, Markus Billeter, and Philipp Slusallek. "Two-Level Grids for Ray Tracing
/// on GPUs." _Computer Graphics Forum_, 2011, pages 307-314. DOI 10.1111/j.1467-8659.2011.01862.x
///
class VTKM_CONT_EXPORT CellLocatorTwoLevel : public vtkm::cont::CellLocator
{
public:
CellLocatorTwoLevel()
: DensityL1(32.0f)
, DensityL2(2.0f)
{
}
/// Get/Set the desired approximate number of cells per level 1 bin
///
void SetDensityL1(vtkm::FloatDefault val)
{
this->DensityL1 = val;
this->SetModified();
}
vtkm::FloatDefault GetDensityL1() const { return this->DensityL1; }
/// Get/Set the desired approximate number of cells per level 1 bin
///
void SetDensityL2(vtkm::FloatDefault val)
{
this->DensityL2 = val;
this->SetModified();
}
vtkm::FloatDefault GetDensityL2() const { return this->DensityL2; }
void PrintSummary(std::ostream& out) const;
const vtkm::exec::CellLocator* PrepareForExecution(vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const override;
private:
VTKM_CONT void Build() override;
vtkm::FloatDefault DensityL1, DensityL2;
vtkm::internal::cl_uniform_bins::Grid TopLevel;
vtkm::cont::ArrayHandle<vtkm::internal::cl_uniform_bins::DimVec3> LeafDimensions;
vtkm::cont::ArrayHandle<vtkm::Id> LeafStartIndex;
vtkm::cont::ArrayHandle<vtkm::Id> CellStartIndex;
vtkm::cont::ArrayHandle<vtkm::Id> CellCount;
vtkm::cont::ArrayHandle<vtkm::Id> CellIds;
mutable vtkm::cont::VirtualObjectHandle<vtkm::exec::CellLocator> ExecutionObjectHandle;
struct MakeExecObject;
struct PrepareForExecutionFunctor;
};
}
} // vtkm::cont
#endif // vtk_m_cont_CellLocatorTwoLevel_h

@ -10,283 +10,21 @@
#ifndef vtk_m_cont_CellLocatorUniformBins_h
#define vtk_m_cont_CellLocatorUniformBins_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CellLocator.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/exec/CellInside.h>
#include <vtkm/exec/ParametricCoordinates.h>
#include <vtkm/Math.h>
#include <vtkm/Types.h>
#include <vtkm/VecFromPortalPermute.h>
#include <vtkm/VecTraits.h>
namespace vtkm
{
namespace internal
{
namespace cl_uniform_bins
{
using DimensionType = vtkm::Int16;
using DimVec3 = vtkm::Vec<DimensionType, 3>;
using FloatVec3 = vtkm::Vec3f;
struct Grid
{
DimVec3 Dimensions;
FloatVec3 Origin;
FloatVec3 BinSize;
};
struct Bounds
{
FloatVec3 Min;
FloatVec3 Max;
};
VTKM_EXEC inline vtkm::Id ComputeFlatIndex(const DimVec3& idx, const DimVec3 dim)
{
return idx[0] + (dim[0] * (idx[1] + (dim[1] * idx[2])));
}
VTKM_EXEC inline Grid ComputeLeafGrid(const DimVec3& idx, const DimVec3& dim, const Grid& l1Grid)
{
return { dim,
l1Grid.Origin + (static_cast<FloatVec3>(idx) * l1Grid.BinSize),
l1Grid.BinSize / static_cast<FloatVec3>(dim) };
}
template <typename PointsVecType>
VTKM_EXEC inline Bounds ComputeCellBounds(const PointsVecType& points)
{
using CoordsType = typename vtkm::VecTraits<PointsVecType>::ComponentType;
auto numPoints = vtkm::VecTraits<PointsVecType>::GetNumberOfComponents(points);
CoordsType minp = points[0], maxp = points[0];
for (vtkm::IdComponent i = 1; i < numPoints; ++i)
{
minp = vtkm::Min(minp, points[i]);
maxp = vtkm::Max(maxp, points[i]);
}
return { FloatVec3(minp), FloatVec3(maxp) };
}
}
}
} // vtkm::internal::cl_uniform_bins
namespace vtkm
{
namespace exec
{
//--------------------------------------------------------------------
template <typename CellSetType, typename DeviceAdapter>
class VTKM_ALWAYS_EXPORT CellLocatorUniformBins : public vtkm::exec::CellLocator
{
private:
using DimVec3 = vtkm::internal::cl_uniform_bins::DimVec3;
using FloatVec3 = vtkm::internal::cl_uniform_bins::FloatVec3;
template <typename T>
using ArrayPortalConst =
typename vtkm::cont::ArrayHandle<T>::template ExecutionTypes<DeviceAdapter>::PortalConst;
using CoordsPortalType =
typename vtkm::cont::CoordinateSystem::MultiplexerArrayType::ExecutionTypes<
DeviceAdapter>::PortalConst;
using CellSetP2CExecType =
decltype(std::declval<CellSetType>().PrepareForInput(DeviceAdapter{},
vtkm::TopologyElementTagCell{},
vtkm::TopologyElementTagPoint{},
std::declval<vtkm::cont::Token&>()));
// TODO: This function may return false positives for non 3D cells as the
// tests are done on the projection of the point on the cell. Extra checks
// should be added to test if the point actually falls on the cell.
template <typename CellShapeTag, typename CoordsType>
VTKM_EXEC static vtkm::ErrorCode PointInsideCell(FloatVec3 point,
CellShapeTag cellShape,
CoordsType cellPoints,
FloatVec3& parametricCoordinates,
bool& inside)
{
auto bounds = vtkm::internal::cl_uniform_bins::ComputeCellBounds(cellPoints);
if (point[0] >= bounds.Min[0] && point[0] <= bounds.Max[0] && point[1] >= bounds.Min[1] &&
point[1] <= bounds.Max[1] && point[2] >= bounds.Min[2] && point[2] <= bounds.Max[2])
{
VTKM_RETURN_ON_ERROR(vtkm::exec::WorldCoordinatesToParametricCoordinates(
cellPoints, point, cellShape, parametricCoordinates));
inside = vtkm::exec::CellInside(parametricCoordinates, cellShape);
}
else
{
inside = false;
}
// Return success error code even point is not inside this cell
return vtkm::ErrorCode::Success;
}
public:
VTKM_CONT CellLocatorUniformBins(const vtkm::internal::cl_uniform_bins::Grid& topLevelGrid,
const vtkm::cont::ArrayHandle<DimVec3>& leafDimensions,
const vtkm::cont::ArrayHandle<vtkm::Id>& leafStartIndex,
const vtkm::cont::ArrayHandle<vtkm::Id>& cellStartIndex,
const vtkm::cont::ArrayHandle<vtkm::Id>& cellCount,
const vtkm::cont::ArrayHandle<vtkm::Id>& cellIds,
const CellSetType& cellSet,
const vtkm::cont::CoordinateSystem& coords,
vtkm::cont::Token& token)
: TopLevel(topLevelGrid)
, LeafDimensions(leafDimensions.PrepareForInput(DeviceAdapter{}, token))
, LeafStartIndex(leafStartIndex.PrepareForInput(DeviceAdapter{}, token))
, CellStartIndex(cellStartIndex.PrepareForInput(DeviceAdapter{}, token))
, CellCount(cellCount.PrepareForInput(DeviceAdapter{}, token))
, CellIds(cellIds.PrepareForInput(DeviceAdapter{}, token))
, CellSet(cellSet.PrepareForInput(DeviceAdapter{},
vtkm::TopologyElementTagCell{},
vtkm::TopologyElementTagPoint{},
token))
, Coords(coords.GetDataAsMultiplexer().PrepareForInput(DeviceAdapter{}, token))
{
}
VTKM_EXEC_CONT virtual ~CellLocatorUniformBins() noexcept override
{
// This must not be defaulted, since defaulted virtual destructors are
// troublesome with CUDA __host__ __device__ markup.
}
VTKM_EXEC
vtkm::ErrorCode FindCell(const FloatVec3& point,
vtkm::Id& cellId,
FloatVec3& parametric) const override
{
using namespace vtkm::internal::cl_uniform_bins;
cellId = -1;
DimVec3 binId3 = static_cast<DimVec3>((point - this->TopLevel.Origin) / this->TopLevel.BinSize);
if (binId3[0] >= 0 && binId3[0] < this->TopLevel.Dimensions[0] && binId3[1] >= 0 &&
binId3[1] < this->TopLevel.Dimensions[1] && binId3[2] >= 0 &&
binId3[2] < this->TopLevel.Dimensions[2])
{
vtkm::Id binId = ComputeFlatIndex(binId3, this->TopLevel.Dimensions);
auto ldim = this->LeafDimensions.Get(binId);
if (!ldim[0] || !ldim[1] || !ldim[2])
{
return vtkm::ErrorCode::CellNotFound;
}
auto leafGrid = ComputeLeafGrid(binId3, ldim, this->TopLevel);
DimVec3 leafId3 = static_cast<DimVec3>((point - leafGrid.Origin) / leafGrid.BinSize);
// precision issues may cause leafId3 to be out of range so clamp it
leafId3 = vtkm::Max(DimVec3(0), vtkm::Min(ldim - DimVec3(1), leafId3));
vtkm::Id leafStart = this->LeafStartIndex.Get(binId);
vtkm::Id leafId = leafStart + ComputeFlatIndex(leafId3, leafGrid.Dimensions);
vtkm::Id start = this->CellStartIndex.Get(leafId);
vtkm::Id end = start + this->CellCount.Get(leafId);
for (vtkm::Id i = start; i < end; ++i)
{
vtkm::Id cid = this->CellIds.Get(i);
auto indices = this->CellSet.GetIndices(cid);
auto pts = vtkm::make_VecFromPortalPermute(&indices, this->Coords);
FloatVec3 pc;
bool inside;
VTKM_RETURN_ON_ERROR(
PointInsideCell(point, this->CellSet.GetCellShape(cid), pts, pc, inside));
if (inside)
{
cellId = cid;
parametric = pc;
return vtkm::ErrorCode::Success;
}
}
}
return vtkm::ErrorCode::CellNotFound;
}
private:
vtkm::internal::cl_uniform_bins::Grid TopLevel;
ArrayPortalConst<DimVec3> LeafDimensions;
ArrayPortalConst<vtkm::Id> LeafStartIndex;
ArrayPortalConst<vtkm::Id> CellStartIndex;
ArrayPortalConst<vtkm::Id> CellCount;
ArrayPortalConst<vtkm::Id> CellIds;
CellSetP2CExecType CellSet;
CoordsPortalType Coords;
};
}
} // vtkm::exec
#include <vtkm/Deprecated.h>
#include <vtkm/cont/CellLocatorTwoLevel.h>
namespace vtkm
{
namespace cont
{
//----------------------------------------------------------------------------
class VTKM_CONT_EXPORT CellLocatorUniformBins : public vtkm::cont::CellLocator
struct VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Replaced with CellLocatorTwoLevel.")
CellLocatorUniformBins : vtkm::cont::CellLocatorTwoLevel
{
public:
CellLocatorUniformBins()
: DensityL1(32.0f)
, DensityL2(2.0f)
{
}
/// Get/Set the desired approximate number of cells per level 1 bin
///
void SetDensityL1(vtkm::FloatDefault val)
{
this->DensityL1 = val;
this->SetModified();
}
vtkm::FloatDefault GetDensityL1() const { return this->DensityL1; }
/// Get/Set the desired approximate number of cells per level 1 bin
///
void SetDensityL2(vtkm::FloatDefault val)
{
this->DensityL2 = val;
this->SetModified();
}
vtkm::FloatDefault GetDensityL2() const { return this->DensityL2; }
void PrintSummary(std::ostream& out) const;
const vtkm::exec::CellLocator* PrepareForExecution(vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const override;
private:
VTKM_CONT void Build() override;
vtkm::FloatDefault DensityL1, DensityL2;
vtkm::internal::cl_uniform_bins::Grid TopLevel;
vtkm::cont::ArrayHandle<vtkm::internal::cl_uniform_bins::DimVec3> LeafDimensions;
vtkm::cont::ArrayHandle<vtkm::Id> LeafStartIndex;
vtkm::cont::ArrayHandle<vtkm::Id> CellStartIndex;
vtkm::cont::ArrayHandle<vtkm::Id> CellCount;
vtkm::cont::ArrayHandle<vtkm::Id> CellIds;
mutable vtkm::cont::VirtualObjectHandle<vtkm::exec::CellLocator> ExecutionObjectHandle;
struct MakeExecObject;
struct PrepareForExecutionFunctor;
};
}
} // vtkm::cont
#endif // vtk_m_cont_CellLocatorUniformBins_h
}
} // namespace vtkm::cont
#endif //vtk_m_cont_CellLocatorUniformBins_h

File diff suppressed because it is too large Load Diff

@ -17,43 +17,35 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ColorTableSamples.h>
#include <vtkm/cont/ExecutionObjectBase.h>
#include <vtkm/exec/ColorTable.h>
#include <set>
namespace vtkm
{
namespace exec
{
//forward declare exec objects
class ColorTableBase;
}
namespace cont
{
template <typename T>
class VirtualObjectHandle;
namespace detail
{
struct ColorTableInternals;
}
enum struct ColorSpace
struct VTKM_DEPRECATED(1.6, "Use vtkm::ColorSpace.") ColorSpace
{
RGB,
HSV,
HSV_WRAP,
LAB,
DIVERGING
static constexpr vtkm::ColorSpace RGB = vtkm::ColorSpace::RGB;
static constexpr vtkm::ColorSpace HSV = vtkm::ColorSpace::HSV;
static constexpr vtkm::ColorSpace HSV_WRAP = vtkm::ColorSpace::HSVWrap;
static constexpr vtkm::ColorSpace LAB = vtkm::ColorSpace::Lab;
static constexpr vtkm::ColorSpace DIVERGING = vtkm::ColorSpace::Diverging;
};
/// \brief Color Table for coloring arbitrary fields
///
///
/// The vtkm::cont::ColorTable allows for color mapping in RGB or HSV space and
/// The `vtkm::cont::ColorTable` allows for color mapping in RGB or HSV space and
/// uses a piecewise hermite functions to allow opacity interpolation that can be
/// piecewise constant, piecewise linear, or somewhere in-between
/// (a modified piecewise hermite function that squishes the function
@ -76,51 +68,77 @@ enum struct ColorSpace
/// will default to to Midpoint = 0.5 (halfway between the control points) and
/// Sharpness = 0.0 (linear).
///
/// ColorTable also contains which ColorSpace should be used for interpolation
/// ColorTable also contains which ColorSpace should be used for interpolation.
/// The color space is selected with the `vtkm::ColorSpace` enumeration.
/// Currently the valid ColorSpaces are:
/// - RGB
/// - HSV
/// - HSV_WRAP
/// - LAB
/// - Diverging
/// - `RGB`
/// - `HSV`
/// - `HSVWrap`
/// - `Lab`
/// - `Diverging`
///
/// In HSV_WRAP mode, it will take the shortest path
/// In `HSVWrap` mode, it will take the shortest path
/// in Hue (going back through 0 if that is the shortest way around the hue
/// circle) whereas HSV will not go through 0 (in order the
/// match the current functionality of vtkLookupTable). In Lab mode,
/// circle) whereas HSV will not go through 0 (in order to
/// match the current functionality of `vtkLookupTable`). In `Lab` mode,
/// it will take the shortest path in the Lab color space with respect to the
/// CIE Delta E 2000 color distance measure. Diverging is a special
/// CIE Delta E 2000 color distance measure. `Diverging` is a special
/// mode where colors will pass through white when interpolating between two
/// saturated colors.
///
/// To map a field from a vtkm::cont::DataSet through the color and opacity transfer
/// functions and into a RGB or RGBA array you should use vtkm::filter::FieldToColor.
/// To map a field from a `vtkm::cont::DataSet` through the color and opacity transfer
/// functions and into a RGB or RGBA array you should use `vtkm::filter::FieldToColor`.
///
class VTKM_CONT_EXPORT ColorTable
/// Note that modifications of `vtkm::cont::ColorTable` are not thread safe. You should
/// not modify a `ColorTable` simultaneously in 2 or more threads. Also, you should not
/// modify a `ColorTable` that might be used in the execution environment. However,
/// the `ColorTable` can be used in multiple threads and on multiple devices as long
/// as no modifications are made.
///
class VTKM_CONT_EXPORT ColorTable : public vtkm::cont::ExecutionObjectBase
{
std::shared_ptr<detail::ColorTableInternals> Impl;
std::shared_ptr<detail::ColorTableInternals> Internals;
public:
enum struct Preset
{
DEFAULT,
COOL_TO_WARM,
COOL_TO_WARM_EXTENDED,
VIRIDIS,
INFERNO,
PLASMA,
BLACK_BODY_RADIATION,
X_RAY,
GREEN,
BLACK_BLUE_WHITE,
BLUE_TO_ORANGE,
GRAY_TO_RED,
COLD_AND_HOT,
BLUE_GREEN_ORANGE,
YELLOW_GRAY_BLUE,
RAINBOW_UNIFORM,
JET,
RAINBOW_DESATURATED
Default,
CoolToWarm,
CoolToWarmExtended,
Viridis,
Inferno,
Plasma,
BlackBodyRadiation,
XRay,
Green,
BlackBlueWhite,
BlueToOrange,
GrayToRed,
ColdAndHot,
BlueGreenOrange,
YellowGrayBlue,
RainbowUniform,
Jet,
RainbowDesaturated,
DEFAULT VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Default."),
COOL_TO_WARM VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::CoolToWarm."),
COOL_TO_WARM_EXTENDED VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::CoolToWarmExtended."),
VIRIDIS VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Viridis."),
INFERNO VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Inferno."),
PLASMA VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Plasma."),
BLACK_BODY_RADIATION VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlackBodyRadiation."),
X_RAY VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::XRay."),
GREEN VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Green."),
BLACK_BLUE_WHITE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlackBlueWhite."),
BLUE_TO_ORANGE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlueToOrange."),
GRAY_TO_RED VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::GrayToRed."),
COLD_AND_HOT VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::ColdAndHot."),
BLUE_GREEN_ORANGE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::BlueGreenOrange."),
YELLOW_GRAY_BLUE VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::YellowGrayBlue."),
RAINBOW_UNIFORM VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::RainbowUniform."),
JET VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::Jet."),
RAINBOW_DESATURATED VTKM_DEPRECATED(1.6, "Use vtkm::ColorTable::Preset::RainbowDesaturated.")
};
/// \brief Construct a color table from a preset
@ -130,7 +148,7 @@ public:
///
/// Note: these are a select set of the presets you can get by providing a string identifier.
///
ColorTable(vtkm::cont::ColorTable::Preset preset = vtkm::cont::ColorTable::Preset::DEFAULT);
ColorTable(vtkm::cont::ColorTable::Preset preset = vtkm::cont::ColorTable::Preset::Default);
/// \brief Construct a color table from a preset color table
///
@ -165,41 +183,42 @@ public:
///
/// Note: The color table will have 0 entries
/// Note: The alpha table will have 0 entries
explicit ColorTable(ColorSpace space);
explicit ColorTable(vtkm::ColorSpace space);
/// Construct a color table with a 2 positions
///
/// Note: The color table will have 2 entries of rgb = {1.0,1.0,1.0}
/// Note: The alpha table will have 2 entries of alpha = 1.0 with linear
/// interpolation
ColorTable(const vtkm::Range& range, ColorSpace space = ColorSpace::LAB);
ColorTable(const vtkm::Range& range, vtkm::ColorSpace space = vtkm::ColorSpace::Lab);
/// Construct a color table with 2 positions
//
/// Note: The alpha table will have 2 entries of alpha = 1.0 with linear
/// interpolation
ColorTable(const vtkm::Range& range,
const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
ColorSpace space = ColorSpace::LAB);
const vtkm::Vec3f_32& rgb1,
const vtkm::Vec3f_32& rgb2,
vtkm::ColorSpace space = vtkm::ColorSpace::Lab);
/// Construct color and alpha and table with 2 positions
///
/// Note: The alpha table will use linear interpolation
ColorTable(const vtkm::Range& range,
const vtkm::Vec<float, 4>& rgba1,
const vtkm::Vec<float, 4>& rgba2,
ColorSpace space = ColorSpace::LAB);
const vtkm::Vec4f_32& rgba1,
const vtkm::Vec4f_32& rgba2,
vtkm::ColorSpace space = vtkm::ColorSpace::Lab);
/// Construct a color table with a list of colors and alphas. For this version you must also
/// specify a name.
///
/// This constructor is mostly used for presets.
ColorTable(const std::string& name,
vtkm::cont::ColorSpace colorSpace,
const vtkm::Vec<double, 3>& nanColor,
const std::vector<double>& rgbPoints,
const std::vector<double>& alphaPoints = { 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.5, 0.0 });
ColorTable(
const std::string& name,
vtkm::ColorSpace colorSpace,
const vtkm::Vec3f_64& nanColor,
const std::vector<vtkm::Float64>& rgbPoints,
const std::vector<vtkm::Float64>& alphaPoints = { 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.5, 0.0 });
~ColorTable();
@ -257,8 +276,8 @@ public:
ColorTable MakeDeepCopy();
///
ColorSpace GetColorSpace() const;
void SetColorSpace(ColorSpace space);
vtkm::ColorSpace GetColorSpace() const;
void SetColorSpace(vtkm::ColorSpace space);
/// If clamping is disabled values that lay out side
/// the color table range are colored based on Below
@ -274,19 +293,19 @@ public:
/// that is below the given range
///
/// Default value is {0,0,0}
void SetBelowRangeColor(const vtkm::Vec<float, 3>& c);
const vtkm::Vec<float, 3>& GetBelowRangeColor() const;
void SetBelowRangeColor(const vtkm::Vec3f_32& c);
const vtkm::Vec3f_32& GetBelowRangeColor() const;
/// Color to use when clamping is disabled for any value
/// that is above the given range
///
/// Default value is {0,0,0}
void SetAboveRangeColor(const vtkm::Vec<float, 3>& c);
const vtkm::Vec<float, 3>& GetAboveRangeColor() const;
void SetAboveRangeColor(const vtkm::Vec3f_32& c);
const vtkm::Vec3f_32& GetAboveRangeColor() const;
///
void SetNaNColor(const vtkm::Vec<float, 3>& c);
const vtkm::Vec<float, 3>& GetNaNColor() const;
void SetNaNColor(const vtkm::Vec3f_32& c);
const vtkm::Vec3f_32& GetNaNColor() const;
/// Remove all existing values in both color and alpha tables.
/// Does not remove the clamping, below, and above range state or colors.
@ -321,40 +340,40 @@ public:
///
/// Note: rgb values need to be between 0 and 1.0 (inclusive).
/// Return the index of the point (0 based), or -1 osn error.
vtkm::Int32 AddPoint(double x, const vtkm::Vec<float, 3>& rgb);
vtkm::Int32 AddPoint(vtkm::Float64 x, const vtkm::Vec3f_32& rgb);
/// Adds a point to the color function. If the point already exists, it
/// will be updated to the new value.
///
/// Note: hsv values need to be between 0 and 1.0 (inclusive).
/// Return the index of the point (0 based), or -1 on error.
vtkm::Int32 AddPointHSV(double x, const vtkm::Vec<float, 3>& hsv);
vtkm::Int32 AddPointHSV(vtkm::Float64 x, const vtkm::Vec3f_32& hsv);
/// Add a line segment to the color function. All points which lay between x1 and x2
/// (inclusive) are removed from the function.
///
/// Note: rgb1, and rgb2 values need to be between 0 and 1.0 (inclusive).
/// Return the index of the point x1 (0 based), or -1 on error.
vtkm::Int32 AddSegment(double x1,
const vtkm::Vec<float, 3>& rgb1,
double x2,
const vtkm::Vec<float, 3>& rgb2);
vtkm::Int32 AddSegment(vtkm::Float64 x1,
const vtkm::Vec3f_32& rgb1,
vtkm::Float64 x2,
const vtkm::Vec3f_32& rgb2);
/// Add a line segment to the color function. All points which lay between x1 and x2
/// (inclusive) are removed from the function.
///
/// Note: hsv1, and hsv2 values need to be between 0 and 1.0 (inclusive)
/// Return the index of the point x1 (0 based), or -1 on error
vtkm::Int32 AddSegmentHSV(double x1,
const vtkm::Vec<float, 3>& hsv1,
double x2,
const vtkm::Vec<float, 3>& hsv2);
vtkm::Int32 AddSegmentHSV(vtkm::Float64 x1,
const vtkm::Vec3f_32& hsv1,
vtkm::Float64 x2,
const vtkm::Vec3f_32& hsv2);
/// Get the location, and rgb information for an existing point in the opacity function.
///
/// Note: components 1-3 are rgb and will have values between 0 and 1.0 (inclusive)
/// Return the index of the point (0 based), or -1 on error.
bool GetPoint(vtkm::Int32 index, vtkm::Vec<double, 4>&) const;
bool GetPoint(vtkm::Int32 index, vtkm::Vec4f_64&) const;
/// Update the location, and rgb information for an existing point in the color function.
/// If the location value for the index is modified the point is removed from
@ -362,12 +381,12 @@ public:
///
/// Note: components 1-3 are rgb and must have values between 0 and 1.0 (inclusive).
/// Return the new index of the updated point (0 based), or -1 on error.
vtkm::Int32 UpdatePoint(vtkm::Int32 index, const vtkm::Vec<double, 4>&);
vtkm::Int32 UpdatePoint(vtkm::Int32 index, const vtkm::Vec4f_64&);
/// Remove the Color function point that exists at exactly x
///
/// Return true if the point x exists and has been removed
bool RemovePoint(double x);
bool RemovePoint(vtkm::Float64 x);
/// Remove the Color function point n
///
@ -385,14 +404,20 @@ public:
///
/// Note: alpha needs to be a value between 0 and 1.0 (inclusive).
/// Return the index of the point (0 based), or -1 on error.
vtkm::Int32 AddPointAlpha(double x, float alpha) { return AddPointAlpha(x, alpha, 0.5f, 0.0f); }
vtkm::Int32 AddPointAlpha(vtkm::Float64 x, vtkm::Float32 alpha)
{
return AddPointAlpha(x, alpha, 0.5f, 0.0f);
}
/// Adds a point to the opacity function. If the point already exists, it
/// will be updated to the new value.
///
/// Note: alpha, midpoint, and sharpness values need to be between 0 and 1.0 (inclusive)
/// Return the index of the point (0 based), or -1 on error.
vtkm::Int32 AddPointAlpha(double x, float alpha, float midpoint, float sharpness);
vtkm::Int32 AddPointAlpha(vtkm::Float64 x,
vtkm::Float32 alpha,
vtkm::Float32 midpoint,
vtkm::Float32 sharpness);
/// Add a line segment to the opacity function. All points which lay between x1 and x2
/// (inclusive) are removed from the function. Uses a midpoint of
@ -400,9 +425,12 @@ public:
///
/// Note: alpha values need to be between 0 and 1.0 (inclusive)
/// Return the index of the point x1 (0 based), or -1 on error
vtkm::Int32 AddSegmentAlpha(double x1, float alpha1, double x2, float alpha2)
vtkm::Int32 AddSegmentAlpha(vtkm::Float64 x1,
vtkm::Float32 alpha1,
vtkm::Float64 x2,
vtkm::Float32 alpha2)
{
vtkm::Vec<float, 2> mid_sharp(0.5f, 0.0f);
vtkm::Vec2f_32 mid_sharp(0.5f, 0.0f);
return AddSegmentAlpha(x1, alpha1, x2, alpha2, mid_sharp, mid_sharp);
}
@ -411,19 +439,19 @@ public:
///
/// Note: alpha, midpoint, and sharpness values need to be between 0 and 1.0 (inclusive)
/// Return the index of the point x1 (0 based), or -1 on error
vtkm::Int32 AddSegmentAlpha(double x1,
float alpha1,
double x2,
float alpha2,
const vtkm::Vec<float, 2>& mid_sharp1,
const vtkm::Vec<float, 2>& mid_sharp2);
vtkm::Int32 AddSegmentAlpha(vtkm::Float64 x1,
vtkm::Float32 alpha1,
vtkm::Float64 x2,
vtkm::Float32 alpha2,
const vtkm::Vec2f_32& mid_sharp1,
const vtkm::Vec2f_32& mid_sharp2);
/// Get the location, alpha, midpoint and sharpness information for an existing
/// point in the opacity function.
///
/// Note: alpha, midpoint, and sharpness values all will be between 0 and 1.0 (inclusive)
/// Return the index of the point (0 based), or -1 on error.
bool GetPointAlpha(vtkm::Int32 index, vtkm::Vec<double, 4>&) const;
bool GetPointAlpha(vtkm::Int32 index, vtkm::Vec4f_64&) const;
/// Update the location, alpha, midpoint and sharpness information for an existing
/// point in the opacity function.
@ -432,12 +460,12 @@ public:
///
/// Note: alpha, midpoint, and sharpness values need to be between 0 and 1.0 (inclusive)
/// Return the new index of the updated point (0 based), or -1 on error.
vtkm::Int32 UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec<double, 4>&);
vtkm::Int32 UpdatePointAlpha(vtkm::Int32 index, const vtkm::Vec4f_64&);
/// Remove the Opacity function point that exists at exactly x
///
/// Return true if the point x exists and has been removed
bool RemovePointAlpha(double x);
bool RemovePointAlpha(vtkm::Float64 x);
/// Remove the Opacity function point n
///
@ -447,9 +475,9 @@ public:
/// Returns the number of points in the alpha function
vtkm::Int32 GetNumberOfPointsAlpha() const;
/// Fill the Color table from a double pointer
/// Fill the Color table from a vtkm::Float64 pointer
///
/// The double pointer is required to have the layout out of [X1, R1,
/// The vtkm::Float64 pointer is required to have the layout out of [X1, R1,
/// G1, B1, X2, R2, G2, B2, ..., Xn, Rn, Gn, Bn] where n is the
/// number of nodes.
/// This will remove any existing color control points.
@ -458,11 +486,11 @@ public:
///
/// Note: This is provided as a interoperability method with VTK
/// Will return false and not modify anything if n is <= 0 or ptr == nullptr
bool FillColorTableFromDataPointer(vtkm::Int32 n, const double* ptr);
bool FillColorTableFromDataPointer(vtkm::Int32 n, const vtkm::Float64* ptr);
/// Fill the Color table from a float pointer
/// Fill the Color table from a vtkm::Float32 pointer
///
/// The double pointer is required to have the layout out of [X1, R1,
/// The vtkm::Float64 pointer is required to have the layout out of [X1, R1,
/// G1, B1, X2, R2, G2, B2, ..., Xn, Rn, Gn, Bn] where n is the
/// number of nodes.
/// This will remove any existing color control points.
@ -471,11 +499,11 @@ public:
///
/// Note: This is provided as a interoperability method with VTK
/// Will return false and not modify anything if n is <= 0 or ptr == nullptr
bool FillColorTableFromDataPointer(vtkm::Int32 n, const float* ptr);
bool FillColorTableFromDataPointer(vtkm::Int32 n, const vtkm::Float32* ptr);
/// Fill the Opacity table from a double pointer
/// Fill the Opacity table from a vtkm::Float64 pointer
///
/// The double pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2,
/// The vtkm::Float64 pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2,
/// ..., Xn, An, Mn, Sn] where n is the number of nodes. The Xi values represent the value to
/// map, the Ai values represent alpha (opacity) value, the Mi values represent midpoints, and
/// the Si values represent sharpness. Use 0.5 for midpoint and 0.0 for sharpness to have linear
@ -486,11 +514,11 @@ public:
/// Note: n represents the length of the array, so ( n/4 == number of control points )
///
/// Will return false and not modify anything if n is <= 0 or ptr == nullptr
bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const double* ptr);
bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Float64* ptr);
/// Fill the Opacity table from a float pointer
/// Fill the Opacity table from a vtkm::Float32 pointer
///
/// The float pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2,
/// The vtkm::Float32 pointer is required to have the layout out of [X1, A1, M1, S1, X2, A2, M2, S2,
/// ..., Xn, An, Mn, Sn] where n is the number of nodes. The Xi values represent the value to
/// map, the Ai values represent alpha (opacity) value, the Mi values represent midpoints, and
/// the Si values represent sharpness. Use 0.5 for midpoint and 0.0 for sharpness to have linear
@ -501,229 +529,91 @@ public:
/// Note: n represents the length of the array, so ( n/4 == number of control points )
///
/// Will return false and not modify anything if n is <= 0 or ptr == nullptr
bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const float* ptr);
/// \brief Sample each value through an intermediate lookup/sample table to generate RGBA colors
///
/// Each value in \c values is binned based on its value in relationship to the range
/// of the color table and will use the color value at that bin from the \c samples.
/// To generate the lookup table use \c Sample .
///
/// Here is a simple example.
/// \code{.cpp}
///
/// vtkm::cont::ColorTableSamplesRGBA samples;
/// vtkm::cont::ColorTable table("black-body radiation");
/// table.Sample(256, samples);
/// vtkm::cont::ArrayHandle<vtkm::Vec4ui_8> colors;
/// table.Map(input, samples, colors);
///
/// \endcode
template <typename T, typename S>
inline bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const;
/// \brief Sample each value through an intermediate lookup/sample table to generate RGB colors
///
/// Each value in \c values is binned based on its value in relationship to the range
/// of the color table and will use the color value at that bin from the \c samples.
/// To generate the lookup table use \c Sample .
///
/// Here is a simple example.
/// \code{.cpp}
///
/// vtkm::cont::ColorTableSamplesRGB samples;
/// vtkm::cont::ColorTable table("black-body radiation");
/// table.Sample(256, samples);
/// vtkm::cont::ArrayHandle<vtkm::Vec3ui_8> colors;
/// table.Map(input, samples, colors);
///
/// \endcode
template <typename T, typename S>
inline bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbaOut) const;
/// \brief Use magnitude of a vector with a sample table to generate RGBA colors
///
template <typename T, int N, typename S>
inline bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const;
/// \brief Use magnitude of a vector with a sample table to generate RGB colors
///
template <typename T, int N, typename S>
inline bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbaOut) const;
/// \brief Use a single component of a vector with a sample table to generate RGBA colors
///
template <typename T, int N, typename S>
inline bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const;
/// \brief Use a single component of a vector with a sample table to generate RGB colors
///
template <typename T, int N, typename S>
inline bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut) const;
/// \brief Interpolate each value through the color table to generate RGBA colors
///
/// Each value in \c values will be sampled through the entire color table
/// to determine a color.
///
/// Note: This is more costly than using Sample/Map with the generated intermediate lookup table
template <typename T, typename S>
inline bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const;
/// \brief Interpolate each value through the color table to generate RGB colors
///
/// Each value in \c values will be sampled through the entire color table
/// to determine a color.
///
/// Note: This is more costly than using Sample/Map with the generated intermediate lookup table
template <typename T, typename S>
inline bool Map(const vtkm::cont::ArrayHandle<T, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut) const;
/// \brief Use magnitude of a vector to generate RGBA colors
///
template <typename T, int N, typename S>
inline bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const;
/// \brief Use magnitude of a vector to generate RGB colors
///
template <typename T, int N, typename S>
inline bool MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut) const;
/// \brief Use a single component of a vector to generate RGBA colors
///
template <typename T, int N, typename S>
inline bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const;
/// \brief Use a single component of a vector to generate RGB colors
///
template <typename T, int N, typename S>
inline bool MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut) const;
bool FillOpacityTableFromDataPointer(vtkm::Int32 n, const vtkm::Float32* ptr);
/// \brief generate RGB colors using regular spaced samples along the range.
///
/// Will use the current range of the color table to generate evenly spaced
/// values using either vtkm::Float32 or vtkm::Float64 space.
/// Will use vtkm::Float32 space when the difference between the float and double
/// values when the range is within float space and the following are within a tolerance:
/// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64
/// values when the range is within vtkm::Float32 space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((max-min) / numSamples) * numSamples
///
/// Note: This will return false if the number of samples is less than 2
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGBA& samples,
double tolerance = 0.002) const;
bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::Float64 tolerance = 0.002) const;
/// \brief generate a sample lookup table using regular spaced samples along the range.
///
/// Will use the current range of the color table to generate evenly spaced
/// values using either vtkm::Float32 or vtkm::Float64 space.
/// Will use vtkm::Float32 space when the difference between the float and double
/// values when the range is within float space and the following are within a tolerance:
/// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64
/// values when the range is within vtkm::Float32 space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((max-min) / numSamples) * numSamples
///
/// Note: This will return false if the number of samples is less than 2
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGB& samples,
double tolerance = 0.002) const;
bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::Float64 tolerance = 0.002) const;
/// \brief generate RGBA colors using regular spaced samples along the range.
///
/// Will use the current range of the color table to generate evenly spaced
/// values using either vtkm::Float32 or vtkm::Float64 space.
/// Will use vtkm::Float32 space when the difference between the float and double
/// values when the range is within float space and the following are within a tolerance:
/// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64
/// values when the range is within vtkm::Float32 space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((max-min) / numSamples) * numSamples
///
/// Note: This will return false if the number of samples is less than 2
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& colors,
double tolerance = 0.002) const;
bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& colors,
vtkm::Float64 tolerance = 0.002) const;
/// \brief generate RGB colors using regular spaced samples along the range.
///
/// Will use the current range of the color table to generate evenly spaced
/// values using either vtkm::Float32 or vtkm::Float64 space.
/// Will use vtkm::Float32 space when the difference between the float and double
/// values when the range is within float space and the following are within a tolerance:
/// Will use vtkm::Float32 space when the difference between the vtkm::Float32 and vtkm::Float64
/// values when the range is within vtkm::Float32 space and the following are within a tolerance:
///
/// - (max-min) / numSamples
/// - ((max-min) / numSamples) * numSamples
///
/// Note: This will return false if the number of samples is less than 2
inline bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& colors,
double tolerance = 0.002) const;
bool Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& colors,
vtkm::Float64 tolerance = 0.002) const;
/// \brief returns a virtual object pointer of the exec color table
///
/// This pointer is only valid as long as the ColorTable is unmodified
inline const vtkm::exec::ColorTableBase* PrepareForExecution(vtkm::cont::DeviceAdapterId deviceId,
vtkm::cont::Token& token) const;
vtkm::exec::ColorTable PrepareForExecution(vtkm::cont::DeviceAdapterId deviceId,
vtkm::cont::Token& token) const;
VTKM_DEPRECATED(1.6, "PrepareForExecution now requires a vtkm::cont::Token object")
inline const vtkm::exec::ColorTableBase* PrepareForExecution(
vtkm::cont::DeviceAdapterId deviceId) const;
inline vtkm::exec::ColorTable PrepareForExecution(vtkm::cont::DeviceAdapterId deviceId) const;
/// \brief returns the modified count for the virtual object handle of the exec color table
/// \brief Returns the modified count for changes of the color table
///
/// The `ModifiedCount` of the color table starts at 1 and gets incremented
/// every time a change is made to the color table.
/// The modified count allows consumers of a shared color table to keep track
/// if the color table has been modified since the last time they used it.
/// This is important for consumers that need to sample the color table.
/// You only want to resample the color table if changes have been made.
vtkm::Id GetModifiedCount() const;
struct TransferState
{
bool NeedsTransfer;
vtkm::exec::ColorTableBase* Portal;
const vtkm::cont::ArrayHandle<double>& ColorPosHandle;
const vtkm::cont::ArrayHandle<vtkm::Vec<float, 3>>& ColorRGBHandle;
const vtkm::cont::ArrayHandle<double>& OpacityPosHandle;
const vtkm::cont::ArrayHandle<float>& OpacityAlphaHandle;
const vtkm::cont::ArrayHandle<vtkm::Vec<float, 2>>& OpacityMidSharpHandle;
};
private:
bool NeedToCreateExecutionColorTable() const;
//takes ownership of the pointer passed in
void UpdateExecutionColorTable(
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>*) const;
ColorTable::TransferState GetExecutionDataForTransfer() const;
vtkm::exec::ColorTableBase* GetControlRepresentation() const;
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase> const* GetExecutionHandle() const;
void UpdateArrayHandles() const;
};
}
} //namespace vtkm::cont

@ -1,425 +0,0 @@
//============================================================================
// 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_ColorTable_hxx
#define vtk_m_cont_ColorTable_hxx
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/worklet/colorconversion/LookupTable.h>
#include <vtkm/worklet/colorconversion/Portals.h>
#include <vtkm/worklet/colorconversion/TransferFunction.h>
#include <vtkm/exec/ColorTable.h>
namespace vtkm
{
namespace cont
{
namespace detail
{
template <typename T>
inline T* get_ptr(T* t)
{
return t;
}
#if defined(VTKM_MSVC)
//ArrayPortalToIteratorBegin could be returning a checked_array_iterator so
//we need to grab the underlying pointer
template <typename T>
inline T* get_ptr(stdext::checked_array_iterator<T*> t)
{
return t.base();
}
#endif
struct transfer_color_table_to_device
{
template <typename DeviceAdapter>
inline bool operator()(DeviceAdapter device,
vtkm::cont::ColorTable::TransferState&& state,
vtkm::cont::Token& token) const
{
auto p1 = state.ColorPosHandle.PrepareForInput(device, token);
auto p2 = state.ColorRGBHandle.PrepareForInput(device, token);
auto p3 = state.OpacityPosHandle.PrepareForInput(device, token);
auto p4 = state.OpacityAlphaHandle.PrepareForInput(device, token);
auto p5 = state.OpacityMidSharpHandle.PrepareForInput(device, token);
//The rest of the data member on portal are set when-ever the user
//modifies the ColorTable instance and don't need to specified here
state.Portal->ColorSize = static_cast<vtkm::Int32>(state.ColorPosHandle.GetNumberOfValues());
state.Portal->OpacitySize =
static_cast<vtkm::Int32>(state.OpacityPosHandle.GetNumberOfValues());
state.Portal->ColorNodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p1));
state.Portal->RGB = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p2));
state.Portal->ONodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p3));
state.Portal->Alpha = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p4));
state.Portal->MidSharp = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p5));
state.Portal->Modified();
return true;
}
};
struct map_color_table
{
template <typename DeviceAdapter, typename ColorTable, typename... Args>
inline bool operator()(DeviceAdapter device, ColorTable&& colors, Args&&... args) const
{
vtkm::cont::Token token;
vtkm::worklet::colorconversion::TransferFunction transfer(
colors->PrepareForExecution(device, token));
vtkm::cont::Invoker invoke(device);
invoke(transfer, std::forward<Args>(args)...);
return true;
}
};
}
//---------------------------------------------------------------------------
template <typename T, typename S>
bool ColorTable::Map(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const
{
if (samples.NumberOfSamples <= 0)
{
return false;
}
vtkm::worklet::colorconversion::LookupTable lookupTable(samples);
vtkm::cont::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{});
invoke(lookupTable, values, samples.Samples, rgbaOut);
return true;
}
//---------------------------------------------------------------------------
template <typename T, typename S>
bool ColorTable::Map(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut) const
{
if (samples.NumberOfSamples <= 0)
{
return false;
}
vtkm::worklet::colorconversion::LookupTable lookupTable(samples);
vtkm::cont::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{});
invoke(lookupTable, values, samples.Samples, rgbOut);
return true;
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(
vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), samples, rgbaOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(
vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), samples, rgbOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(
vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), samples, rgbaOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(
vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), samples, rgbOut);
}
//---------------------------------------------------------------------------
template <typename T, typename S>
bool ColorTable::Map(const vtkm::cont::ArrayHandle<T, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const
{
return vtkm::cont::TryExecute(detail::map_color_table{}, this, values, rgbaOut);
}
//---------------------------------------------------------------------------
template <typename T, typename S>
bool ColorTable::Map(const vtkm::cont::ArrayHandle<T, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut) const
{
return vtkm::cont::TryExecute(detail::map_color_table{}, this, values, rgbOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), rgbaOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), rgbOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), rgbaOut);
}
//---------------------------------------------------------------------------
template <typename T, int N, typename S>
bool ColorTable::MapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut) const
{
using namespace vtkm::worklet::colorconversion;
return this->Map(vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), rgbOut);
}
namespace
{
template <typename T>
inline vtkm::cont::ArrayHandle<T> buildSampleHandle(vtkm::Int32 numSamples,
T start,
T end,
T inc,
bool appendNanAndRangeColors)
{
//number of samples + end + appendNanAndRangeColors
vtkm::Int32 allocationSize = (appendNanAndRangeColors) ? numSamples + 5 : numSamples + 1;
vtkm::cont::ArrayHandle<T> handle;
handle.Allocate(allocationSize);
auto portal = handle.WritePortal();
vtkm::Id index = 0;
//Insert the below range first
if (appendNanAndRangeColors)
{
portal.Set(index++, std::numeric_limits<T>::lowest()); //below
}
//add number of samples which doesn't account for the end
T value = start;
for (vtkm::Int32 i = 0; i < numSamples; ++i, ++index, value += inc)
{
portal.Set(index, value);
}
portal.Set(index++, end);
if (appendNanAndRangeColors)
{
//push back the last value again so that when lookups near the max value
//occur we don't need to clamp as if they are out-of-bounds they will
//land in the extra 'end' color
portal.Set(index++, end);
portal.Set(index++, std::numeric_limits<T>::max()); //above
portal.Set(index++, vtkm::Nan<T>()); //nan
}
return handle;
}
template <typename ColorTable, typename OutputColors>
inline bool sampleColorTable(const ColorTable* self,
vtkm::Int32 numSamples,
OutputColors& colors,
double tolerance,
bool appendNanAndRangeColors)
{
vtkm::Range r = self->GetRange();
//We want the samples to start at Min, and end at Max so that means
//we want actually to interpolate numSample - 1 values. For example
//for range 0 - 1, we want the values 0, 0.5, and 1.
const double d_samples = static_cast<double>(numSamples - 1);
const double d_delta = r.Length() / d_samples;
if (r.Min > static_cast<double>(std::numeric_limits<float>::lowest()) &&
r.Max < static_cast<double>(std::numeric_limits<float>::max()))
{
//we can try and see if float space has enough resolution
const float f_samples = static_cast<float>(numSamples - 1);
const float f_start = static_cast<float>(r.Min);
const float f_delta = static_cast<float>(r.Length()) / f_samples;
const float f_end = f_start + (f_delta * f_samples);
if (vtkm::Abs(static_cast<double>(f_end) - r.Max) <= tolerance &&
vtkm::Abs(static_cast<double>(f_delta) - d_delta) <= tolerance)
{
auto handle =
buildSampleHandle((numSamples - 1), f_start, f_end, f_delta, appendNanAndRangeColors);
return self->Map(handle, colors);
}
}
//otherwise we need to use double space
auto handle = buildSampleHandle((numSamples - 1), r.Min, r.Max, d_delta, appendNanAndRangeColors);
return self->Map(handle, colors);
}
}
//---------------------------------------------------------------------------
bool ColorTable::Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGBA& samples,
double tolerance) const
{
if (numSamples <= 1)
{
return false;
}
samples.NumberOfSamples = numSamples;
samples.SampleRange = this->GetRange();
return sampleColorTable(this, numSamples, samples.Samples, tolerance, true);
}
//---------------------------------------------------------------------------
bool ColorTable::Sample(vtkm::Int32 numSamples,
vtkm::cont::ColorTableSamplesRGB& samples,
double tolerance) const
{
if (numSamples <= 1)
{
return false;
}
samples.NumberOfSamples = numSamples;
samples.SampleRange = this->GetRange();
return sampleColorTable(this, numSamples, samples.Samples, tolerance, true);
}
//---------------------------------------------------------------------------
bool ColorTable::Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& colors,
double tolerance) const
{
if (numSamples <= 1)
{
return false;
}
return sampleColorTable(this, numSamples, colors, tolerance, false);
}
//---------------------------------------------------------------------------
bool ColorTable::Sample(vtkm::Int32 numSamples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& colors,
double tolerance) const
{
if (numSamples <= 1)
{
return false;
}
return sampleColorTable(this, numSamples, colors, tolerance, false);
}
//---------------------------------------------------------------------------
const vtkm::exec::ColorTableBase* ColorTable::PrepareForExecution(
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token) const
{
//Build the ColorTable instance that is needed for execution
if (this->NeedToCreateExecutionColorTable())
{
auto space = this->GetColorSpace();
auto hostPortal = this->GetControlRepresentation();
//Remove any existing host and execution data. The allocation of the
//virtual object handle needs to occur in the .hxx so that it happens
//in the same library as the user and will be a valid virtual object
using HandleType = vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>;
switch (space)
{
case vtkm::cont::ColorSpace::RGB:
{
this->UpdateExecutionColorTable(
new HandleType(static_cast<vtkm::exec::ColorTableRGB*>(hostPortal), false));
break;
}
case vtkm::cont::ColorSpace::HSV:
{
this->UpdateExecutionColorTable(
new HandleType(static_cast<vtkm::exec::ColorTableHSV*>(hostPortal), false));
break;
}
case vtkm::cont::ColorSpace::HSV_WRAP:
{
this->UpdateExecutionColorTable(
new HandleType(static_cast<vtkm::exec::ColorTableHSVWrap*>(hostPortal), false));
break;
}
case vtkm::cont::ColorSpace::LAB:
{
this->UpdateExecutionColorTable(
new HandleType(static_cast<vtkm::exec::ColorTableLab*>(hostPortal), false));
break;
}
case vtkm::cont::ColorSpace::DIVERGING:
{
this->UpdateExecutionColorTable(
new HandleType(static_cast<vtkm::exec::ColorTableDiverging*>(hostPortal), false));
break;
}
}
}
//transfer ColorTable and all related data
auto&& info = this->GetExecutionDataForTransfer();
if (info.NeedsTransfer)
{
bool transfered = vtkm::cont::TryExecuteOnDevice(
device, detail::transfer_color_table_to_device{}, std::move(info), token);
if (!transfered)
{
throwFailedRuntimeDeviceTransfer("ColorTable", device);
}
}
return this->GetExecutionHandle()->PrepareForExecution(device, token);
}
const vtkm::exec::ColorTableBase* ColorTable::PrepareForExecution(
vtkm::cont::DeviceAdapterId device) const
{
vtkm::cont::Token token;
return this->PrepareForExecution(device, token);
}
}
}
#endif

226
vtkm/cont/ColorTableMap.h Normal file

@ -0,0 +1,226 @@
//============================================================================
// 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_ColorTableMap_h
#define vtk_m_cont_ColorTableMap_h
#include <vtkm/cont/ArrayHandleCounting.h>
#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>
#include <vtkm/worklet/colorconversion/Portals.h>
#include <vtkm/worklet/colorconversion/TransferFunction.h>
#include <vtkm/exec/ColorTable.h>
namespace vtkm
{
namespace cont
{
/// \brief Sample each value through an intermediate lookup/sample table to generate RGBA colors
///
/// Each value in \c values is binned based on its value in relationship to the range
/// of the color table and will use the color value at that bin from the \c samples.
/// To generate the lookup table use \c Sample .
///
/// Here is a simple example.
/// \code{.cpp}
///
/// vtkm::cont::ColorTableSamplesRGBA samples;
/// vtkm::cont::ColorTable table("black-body radiation");
/// table.Sample(256, samples);
/// vtkm::cont::ArrayHandle<vtkm::Vec4ui_8> colors;
/// vtkm::cont::ColorTableMap(input, samples, colors);
///
/// \endcode
template <typename T, typename S>
bool ColorTableMap(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut)
{
if (samples.NumberOfSamples <= 0)
{
return false;
}
vtkm::worklet::colorconversion::LookupTable lookupTable(samples);
vtkm::cont::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{});
invoke(lookupTable, values, samples.Samples, rgbaOut);
return true;
}
/// \brief Sample each value through an intermediate lookup/sample table to generate RGB colors
///
/// Each value in \c values is binned based on its value in relationship to the range
/// of the color table and will use the color value at that bin from the \c samples.
/// To generate the lookup table use \c Sample .
///
/// Here is a simple example.
/// \code{.cpp}
///
/// vtkm::cont::ColorTableSamplesRGB samples;
/// vtkm::cont::ColorTable table("black-body radiation");
/// table.Sample(256, samples);
/// vtkm::cont::ArrayHandle<vtkm::Vec3ui_8> colors;
/// vtkm::cont::ColorTableMap(input, samples, colors);
///
/// \endcode
template <typename T, typename S>
bool ColorTableMap(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut)
{
if (samples.NumberOfSamples <= 0)
{
return false;
}
vtkm::worklet::colorconversion::LookupTable lookupTable(samples);
vtkm::cont::Invoker invoke(vtkm::cont::DeviceAdapterTagAny{});
invoke(lookupTable, values, samples.Samples, rgbOut);
return true;
}
/// \brief Use magnitude of a vector with a sample table to generate RGBA colors
///
template <typename T, int N, typename S>
bool ColorTableMapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut)
{
using namespace vtkm::worklet::colorconversion;
return vtkm::cont::ColorTableMap(
vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), samples, rgbaOut);
}
/// \brief Use magnitude of a vector with a sample table to generate RGB colors
///
template <typename T, int N, typename S>
bool ColorTableMapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut)
{
using namespace vtkm::worklet::colorconversion;
return vtkm::cont::ColorTableMap(
vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), samples, rgbOut);
}
/// \brief Use a single component of a vector with a sample table to generate RGBA colors
///
template <typename T, int N, typename S>
bool ColorTableMapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTableSamplesRGBA& samples,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut)
{
using namespace vtkm::worklet::colorconversion;
return vtkm::cont::ColorTableMap(
vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), samples, rgbaOut);
}
/// \brief Use a single component of a vector with a sample table to generate RGB colors
///
template <typename T, int N, typename S>
bool ColorTableMapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTableSamplesRGB& samples,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut)
{
using namespace vtkm::worklet::colorconversion;
return vtkm::cont::ColorTableMap(
vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), samples, rgbOut);
}
/// \brief Interpolate each value through the color table to generate RGBA colors
///
/// Each value in \c values will be sampled through the entire color table
/// to determine a color.
///
/// Note: This is more costly than using Sample/Map with the generated intermediate lookup table
template <typename T, typename S>
bool ColorTableMap(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTable& table,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut)
{
vtkm::cont::Invoker invoke;
invoke(vtkm::worklet::colorconversion::TransferFunction{}, values, table, rgbaOut);
return true;
}
/// \brief Interpolate each value through the color table to generate RGB colors
///
/// Each value in \c values will be sampled through the entire color table
/// to determine a color.
///
/// Note: This is more costly than using Sample/Map with the generated intermediate lookup table
template <typename T, typename S>
bool ColorTableMap(const vtkm::cont::ArrayHandle<T, S>& values,
const vtkm::cont::ColorTable& table,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut)
{
vtkm::cont::Invoker invoke;
invoke(vtkm::worklet::colorconversion::TransferFunction{}, values, table, rgbOut);
return true;
}
/// \brief Use magnitude of a vector to generate RGBA colors
///
template <typename T, int N, typename S>
bool ColorTableMapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTable& table,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut)
{
using namespace vtkm::worklet::colorconversion;
return vtkm::cont::ColorTableMap(
vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), table, rgbaOut);
}
/// \brief Use magnitude of a vector to generate RGB colors
///
template <typename T, int N, typename S>
bool ColorTableMapMagnitude(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
const vtkm::cont::ColorTable& table,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut)
{
using namespace vtkm::worklet::colorconversion;
return vtkm::cont::ColorTableMap(
vtkm::cont::make_ArrayHandleTransform(values, MagnitudePortal()), table, rgbOut);
}
/// \brief Use a single component of a vector to generate RGBA colors
///
template <typename T, int N, typename S>
bool ColorTableMapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTable& table,
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8>& rgbaOut)
{
using namespace vtkm::worklet::colorconversion;
return vtkm::cont::ColorTableMap(
vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), table, rgbaOut);
}
/// \brief Use a single component of a vector to generate RGB colors
///
template <typename T, int N, typename S>
bool ColorTableMapComponent(const vtkm::cont::ArrayHandle<vtkm::Vec<T, N>, S>& values,
vtkm::IdComponent comp,
const vtkm::cont::ColorTable& table,
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8>& rgbOut)
{
using namespace vtkm::worklet::colorconversion;
return vtkm::cont::ColorTableMap(
vtkm::cont::make_ArrayHandleTransform(values, ComponentPortal(comp)), table, rgbOut);
}
}
}
#endif // vtk_m_cont_ColorTableMap_h

@ -24,28 +24,28 @@ namespace cont
namespace internal
{
static vtkm::cont::ColorTable::Preset DEFAULT_PRESET = vtkm::cont::ColorTable::Preset::VIRIDIS;
static vtkm::cont::ColorTable::Preset DEFAULT_PRESET = vtkm::cont::ColorTable::Preset::Viridis;
std::string GetColorSpaceString(vtkm::cont::ColorSpace space)
std::string GetColorSpaceString(vtkm::ColorSpace space)
{
switch (space)
{
case vtkm::cont::ColorSpace::RGB:
case vtkm::ColorSpace::RGB:
return std::string("RGB");
case vtkm::cont::ColorSpace::HSV:
case vtkm::ColorSpace::HSV:
return std::string("HSV");
case vtkm::cont::ColorSpace::HSV_WRAP:
return std::string("HSV_WRAP");
case vtkm::cont::ColorSpace::LAB:
case vtkm::ColorSpace::HSVWrap:
return std::string("HSVWrap");
case vtkm::ColorSpace::Lab:
return std::string("Lab");
case vtkm::cont::ColorSpace::DIVERGING:
case vtkm::ColorSpace::Diverging:
return std::string("Diverging");
}
throw vtkm::cont::ErrorBadValue("Encountered invalid color space.");
}
vtkm::cont::ColorSpace GetColorSpaceEnum(const std::string& colorSpaceString)
vtkm::ColorSpace GetColorSpaceEnum(const std::string& colorSpaceString)
{
std::string spaceString = colorSpaceString;
@ -56,27 +56,27 @@ vtkm::cont::ColorSpace GetColorSpaceEnum(const std::string& colorSpaceString)
if (spaceString == "rgb")
{
return vtkm::cont::ColorSpace::RGB;
return vtkm::ColorSpace::RGB;
}
if (spaceString == "hsv")
{
return vtkm::cont::ColorSpace::HSV;
return vtkm::ColorSpace::HSV;
}
if ((spaceString == "hsv_wrap") || (spaceString == "hsv-wrap") || (spaceString == "hsvwrap"))
{
return vtkm::cont::ColorSpace::HSV_WRAP;
return vtkm::ColorSpace::HSVWrap;
}
if (spaceString == "lab")
{
return vtkm::cont::ColorSpace::LAB;
return vtkm::ColorSpace::Lab;
}
if (spaceString == "diverging")
{
return vtkm::cont::ColorSpace::DIVERGING;
return vtkm::ColorSpace::Diverging;
}
std::stringstream message;
@ -116,7 +116,7 @@ struct ColorTablePreset
{
vtkm::cont::ColorTable::Preset Preset;
std::string Name;
vtkm::cont::ColorSpace ColorSpace;
vtkm::ColorSpace ColorSpace;
vtkm::Vec<double, 3> NanColor;
std::vector<double> RGBPoints;
std::vector<double> AlphaPoints;
@ -124,13 +124,13 @@ struct ColorTablePreset
VTKM_CONT
ColorTablePreset(vtkm::cont::ColorTable::Preset preset,
std::string&& name,
vtkm::cont::ColorSpace colorSpace,
vtkm::ColorSpace colorSpace,
vtkm::Vec<double, 3>&& nanColor,
std::vector<double>&& rgbPoints,
std::vector<double>&& alphaPoints = { 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.5, 0.0 })
: Preset(preset)
, Name(std::move(name))
, ColorSpace(std::move(colorSpace))
, ColorSpace(colorSpace)
, NanColor(std::move(nanColor))
, RGBPoints(std::move(rgbPoints))
, AlphaPoints(std::move(alphaPoints))
@ -148,9 +148,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
{
// clang-format off
presets = std::vector<ColorTablePreset>{
{ vtkm::cont::ColorTable::Preset::COOL_TO_WARM,
{ vtkm::cont::ColorTable::Preset::CoolToWarm,
"Cool to Warm",
vtkm::cont::ColorSpace::DIVERGING,
vtkm::ColorSpace::Diverging,
{ 1, 1, 0 },
{
0, 0.23137254902, 0.298039215686, 0.752941176471,
@ -158,9 +158,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 0.705882352941, 0.0156862745098, 0.149019607843
}
},
{ vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED,
{ vtkm::cont::ColorTable::Preset::CoolToWarmExtended,
"Cool to Warm Extended",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0.25, 0, 0 },
{
0, 0, 0, 0.34902,
@ -200,9 +200,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 0.34902, 0.070588, 0.211765
}
},
{ vtkm::cont::ColorTable::Preset::VIRIDIS,
{ vtkm::cont::ColorTable::Preset::Viridis,
"Viridis",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 1, 0, 0 },
{
0.000000, 0.282365, 0.000000, 0.331010,
@ -463,9 +463,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.952999, 0.912545, 0.110859
}
},
{ vtkm::cont::ColorTable::Preset::INFERNO,
{ vtkm::cont::ColorTable::Preset::Inferno,
"Inferno",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0, 1, 0 },
{
0.000000, 0.002811, 0.000240, 0.013985,
@ -726,9 +726,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.959400, 1.002963, 0.640626
}
},
{ vtkm::cont::ColorTable::Preset::PLASMA,
{ vtkm::cont::ColorTable::Preset::Plasma,
"Plasma",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0, 1, 0 },
{
0.000000, 0.185001, 0.000000, 0.530073,
@ -989,9 +989,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.894058, 0.982254, 0.081069
}
},
{ vtkm::cont::ColorTable::Preset::BLACK_BODY_RADIATION,
{ vtkm::cont::ColorTable::Preset::BlackBodyRadiation,
"Black-Body Radiation",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 0, 0.498039215686, 1 },
{
0, 0, 0, 0,
@ -1000,15 +1000,15 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 1, 1, 1
}
},
{ vtkm::cont::ColorTable::Preset::X_RAY,
{ vtkm::cont::ColorTable::Preset::XRay,
"X Ray",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 1, 0, 0 },
{ 0, 1, 1, 1, 1, 0, 0, 0 }
},
{ vtkm::cont::ColorTable::Preset::GREEN,
{ vtkm::cont::ColorTable::Preset::Green,
"Green",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0.25, 0, 0 },
{
0.00, 0.054902, 0.109804, 0.121569,
@ -1034,9 +1034,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.00, 1.000000, 0.984314, 0.901961
}
},
{ vtkm::cont::ColorTable::Preset::BLACK_BLUE_WHITE,
{ vtkm::cont::ColorTable::Preset::BlackBlueWhite,
"Black - Blue - White",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 1, 1, 0 },
{
0, 0, 0, 0,
@ -1045,9 +1045,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 1, 1, 1
}
},
{ vtkm::cont::ColorTable::Preset::BLUE_TO_ORANGE,
{ vtkm::cont::ColorTable::Preset::BlueToOrange,
"Blue to Orange",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0.25, 0, 0 },
{
0.000000, 0.086275, 0.003922, 0.298039,
@ -1098,9 +1098,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.188235, 0.000000, 0.070588
}
},
{vtkm::cont::ColorTable::Preset::GRAY_TO_RED,
{vtkm::cont::ColorTable::Preset::GrayToRed,
"Gray to Red",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0, 0.498039215686, 1 },
{
0.000000, 0.101961, 0.101961, 0.101961,
@ -1122,9 +1122,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.403922, 0.000000, 0.121569
}
},
{ vtkm::cont::ColorTable::Preset::COLD_AND_HOT,
{ vtkm::cont::ColorTable::Preset::ColdAndHot,
"Cold and Hot",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 1, 1, 0 },
{
0, 0, 1, 1,
@ -1134,9 +1134,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 1, 1, 0
}
},
{ vtkm::cont::ColorTable::Preset::BLUE_GREEN_ORANGE,
{ vtkm::cont::ColorTable::Preset::BlueGreenOrange,
"Blue - Green - Orange",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0.25, 0.0, 0.0 },
{
0.0,0.831373,0.909804,0.980392,
@ -1191,9 +1191,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.0,0.45098,0.007843,0.0
}
},
{ vtkm::cont::ColorTable::Preset::YELLOW_GRAY_BLUE,
{ vtkm::cont::ColorTable::Preset::YellowGrayBlue,
"Yellow - Gray - Blue",
vtkm::cont::ColorSpace::LAB,
vtkm::ColorSpace::Lab,
{ 0.25, 0, 0 },
{
0.000000, 0.301961, 0.047059, 0.090196,
@ -1253,9 +1253,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000, 0.890196, 0.956863, 0.984314
}
},
{ vtkm::cont::ColorTable::Preset::RAINBOW_UNIFORM,
{ vtkm::cont::ColorTable::Preset::RainbowUniform,
"Rainbow Uniform",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 1, 0, 0 },
{
0.000000,0.020000,0.381300,0.998100,
@ -1303,9 +1303,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1.000000,0.683700,0.050000,0.413900
}
},
{ vtkm::cont::ColorTable::Preset::JET,
{ vtkm::cont::ColorTable::Preset::Jet,
"Jet",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 0.25, 0, 0 },
{
0, 0, 0, 0.5625,
@ -1317,9 +1317,9 @@ VTKM_CONT void BuildColorTablePresetsVector(std::vector<ColorTablePreset>& prese
1, 0.5, 0, 0
}
},
{ vtkm::cont::ColorTable::Preset::RAINBOW_DESATURATED,
{ vtkm::cont::ColorTable::Preset::RainbowDesaturated,
"Rainbow Desaturated",
vtkm::cont::ColorSpace::RGB,
vtkm::ColorSpace::RGB,
{ 1, 1, 0 },
{
0, 0.278431372549, 0.278431372549, 0.858823529412,
@ -1357,7 +1357,7 @@ namespace internal
VTKM_CONT_EXPORT
bool LoadColorTablePreset(vtkm::cont::ColorTable::Preset preset, vtkm::cont::ColorTable& table)
{
if (preset == vtkm::cont::ColorTable::Preset::DEFAULT)
if (preset == vtkm::cont::ColorTable::Preset::Default)
{
preset = DEFAULT_PRESET;
}
@ -1369,7 +1369,52 @@ bool LoadColorTablePreset(vtkm::cont::ColorTable::Preset preset, vtkm::cont::Col
return true;
}
}
return false;
VTKM_DEPRECATED_SUPPRESS_BEGIN
// Handle deprecated names
switch (preset)
{
case vtkm::cont::ColorTable::Preset::DEFAULT:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Default, table);
case vtkm::cont::ColorTable::Preset::COOL_TO_WARM:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::CoolToWarm, table);
case vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::CoolToWarmExtended, table);
case vtkm::cont::ColorTable::Preset::VIRIDIS:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Viridis, table);
case vtkm::cont::ColorTable::Preset::INFERNO:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Inferno, table);
case vtkm::cont::ColorTable::Preset::PLASMA:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Plasma, table);
case vtkm::cont::ColorTable::Preset::BLACK_BODY_RADIATION:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlackBodyRadiation, table);
case vtkm::cont::ColorTable::Preset::X_RAY:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::XRay, table);
case vtkm::cont::ColorTable::Preset::GREEN:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Green, table);
case vtkm::cont::ColorTable::Preset::BLACK_BLUE_WHITE:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlackBlueWhite, table);
case vtkm::cont::ColorTable::Preset::BLUE_TO_ORANGE:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlueToOrange, table);
case vtkm::cont::ColorTable::Preset::GRAY_TO_RED:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::GrayToRed, table);
case vtkm::cont::ColorTable::Preset::COLD_AND_HOT:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::ColdAndHot, table);
case vtkm::cont::ColorTable::Preset::BLUE_GREEN_ORANGE:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::BlueGreenOrange, table);
case vtkm::cont::ColorTable::Preset::YELLOW_GRAY_BLUE:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::YellowGrayBlue, table);
case vtkm::cont::ColorTable::Preset::RAINBOW_UNIFORM:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::RainbowUniform, table);
case vtkm::cont::ColorTable::Preset::JET:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::Jet, table);
case vtkm::cont::ColorTable::Preset::RAINBOW_DESATURATED:
return LoadColorTablePreset(vtkm::cont::ColorTable::Preset::RainbowDesaturated, table);
default:
// Should not get here.
return false;
}
VTKM_DEPRECATED_SUPPRESS_END
}
VTKM_CONT_EXPORT std::set<std::string> GetPresetNames()

@ -1,295 +0,0 @@
//============================================================================
// 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/Range.h>
#include <vtkm/Types.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/exec/ColorTable.h>
#include <limits>
#include <vector>
namespace vtkm
{
namespace cont
{
namespace detail
{
struct ColorTableInternals
{
std::string Name;
ColorSpace CSpace = ColorSpace::LAB;
vtkm::Range TableRange = { 1.0, 0.0 };
//Host side version of the ColorTableBase. This holds data such as:
// NanColor
// BelowRangeColor
// AboveRangeColor
// UseClamping
// BelowRangeColor
// AboveRangeColor
//Note the pointers inside the host side portal are not valid, as they
//are execution pointers
std::unique_ptr<vtkm::exec::ColorTableBase> HostSideCache;
//Execution side version of the ColorTableBase.
std::unique_ptr<vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>> ExecHandle;
std::vector<double> ColorNodePos;
std::vector<vtkm::Vec<float, 3>> ColorRGB;
std::vector<double> OpacityNodePos;
std::vector<float> OpacityAlpha;
std::vector<vtkm::Vec<float, 2>> OpacityMidSharp;
vtkm::cont::ArrayHandle<double> ColorPosHandle;
vtkm::cont::ArrayHandle<vtkm::Vec<float, 3>> ColorRGBHandle;
vtkm::cont::ArrayHandle<double> OpacityPosHandle;
vtkm::cont::ArrayHandle<float> OpacityAlphaHandle;
vtkm::cont::ArrayHandle<vtkm::Vec<float, 2>> OpacityMidSharpHandle;
bool ColorArraysChanged = true;
bool OpacityArraysChanged = true;
bool HostSideCacheChanged = true;
void RecalculateRange()
{
vtkm::Range r;
if (this->ColorNodePos.size() > 0)
{
r.Include(this->ColorNodePos.front());
r.Include(this->ColorNodePos.back());
}
if (this->OpacityNodePos.size() > 0)
{
r.Include(this->OpacityNodePos.front());
r.Include(this->OpacityNodePos.back());
}
this->TableRange = r;
}
};
} //namespace detail
namespace
{
template <typename T>
struct MinDelta
{
};
// This value seems to work well for float ranges we have tested
template <>
struct MinDelta<float>
{
static constexpr int value = 2048;
};
template <>
struct MinDelta<double>
{
static constexpr vtkm::Int64 value = 2048L;
};
// Reperesents the following:
// T m = std::numeric_limits<T>::min();
// EquivSizeIntT im;
// std::memcpy(&im, &m, sizeof(T));
//
template <typename EquivSizeIntT>
struct MinRepresentable
{
};
template <>
struct MinRepresentable<float>
{
static constexpr int value = 8388608;
};
template <>
struct MinRepresentable<double>
{
static constexpr vtkm::Int64 value = 4503599627370496L;
};
inline bool rangeAlmostEqual(const vtkm::Range& r)
{
vtkm::Int64 irange[2];
// needs to be a memcpy to avoid strict aliasing issues, doing a count
// of 2*sizeof(T) to couple both values at the same time
std::memcpy(irange, &r.Min, sizeof(vtkm::Int64));
std::memcpy(irange + 1, &r.Max, sizeof(vtkm::Int64));
// determine the absolute delta between these two numbers.
const vtkm::Int64 delta = std::abs(irange[1] - irange[0]);
// If the numbers are not nearly equal, we don't touch them. This avoids running into
// pitfalls like BUG PV #17152.
return (delta < 1024) ? true : false;
}
template <typename T>
inline double expandRange(T r[2])
{
constexpr bool is_float32_type = std::is_same<T, vtkm::Float32>::value;
using IRange = typename std::conditional<is_float32_type, vtkm::Int32, vtkm::Int64>::type;
IRange irange[2];
// needs to be a memcpy to avoid strict aliasing issues, doing a count
// of 2*sizeof(T) to couple both values at the same time
std::memcpy(irange, r, sizeof(T) * 2);
const bool denormal = !std::isnormal(r[0]);
const IRange minInt = MinRepresentable<T>::value;
const IRange minDelta = denormal ? minInt + MinDelta<T>::value : MinDelta<T>::value;
// determine the absolute delta between these two numbers.
const vtkm::Int64 delta = std::abs(irange[1] - irange[0]);
// if our delta is smaller than the min delta push out the max value
// so that it is equal to minRange + minDelta. When our range is entirely
// negative we should instead subtract from our max, to max a larger negative
// value
if (delta < minDelta)
{
if (irange[0] < 0)
{
irange[1] = irange[0] - minDelta;
}
else
{
irange[1] = irange[0] + minDelta;
}
T result;
std::memcpy(&result, irange + 1, sizeof(T));
return static_cast<double>(result);
}
return static_cast<double>(r[1]);
}
inline vtkm::Range adjustRange(const vtkm::Range& r)
{
const bool spans_zero_boundary = r.Min < 0 && r.Max > 0;
if (spans_zero_boundary)
{ // nothing needs to be done, but this check is required.
// if we convert into integer space the delta difference will overflow
// an integer
return r;
}
if (rangeAlmostEqual(r))
{
return r;
}
// range should be left untouched as much as possible to
// to avoid loss of precision whenever possible. That is why
// we only modify the Max value
vtkm::Range result = r;
if (r.Min > static_cast<double>(std::numeric_limits<float>::lowest()) &&
r.Max < static_cast<double>(std::numeric_limits<float>::max()))
{ //We've found it best to offset it in float space if the numbers
//lay inside that representable range
float frange[2] = { static_cast<float>(r.Min), static_cast<float>(r.Max) };
result.Max = expandRange(frange);
}
else
{
double drange[2] = { r.Min, r.Max };
result.Max = expandRange(drange);
}
return result;
}
inline vtkm::Vec<float, 3> hsvTorgb(const vtkm::Vec<float, 3>& hsv)
{
vtkm::Vec<float, 3> rgb;
constexpr float onethird = 1.0f / 3.0f;
constexpr float onesixth = 1.0f / 6.0f;
constexpr float twothird = 2.0f / 3.0f;
constexpr float fivesixth = 5.0f / 6.0f;
// compute RGB from HSV
if (hsv[0] > onesixth && hsv[0] <= onethird) // green/red
{
rgb[1] = 1.0f;
rgb[0] = (onethird - hsv[0]) * 6.0f;
rgb[2] = 0.0f;
}
else if (hsv[0] > onethird && hsv[0] <= 0.5f) // green/blue
{
rgb[1] = 1.0f;
rgb[2] = (hsv[0] - onethird) * 6.0f;
rgb[0] = 0.0f;
}
else if (hsv[0] > 0.5 && hsv[0] <= twothird) // blue/green
{
rgb[2] = 1.0f;
rgb[1] = (twothird - hsv[0]) * 6.0f;
rgb[0] = 0.0f;
}
else if (hsv[0] > twothird && hsv[0] <= fivesixth) // blue/red
{
rgb[2] = 1.0f;
rgb[0] = (hsv[0] - twothird) * 6.0f;
rgb[1] = 0.0f;
}
else if (hsv[0] > fivesixth && hsv[0] <= 1.0) // red/blue
{
rgb[0] = 1.0f;
rgb[2] = (1.0f - hsv[0]) * 6.0f;
rgb[1] = 0.0f;
}
else // red/green
{
rgb[0] = 1.0f;
rgb[1] = hsv[0] * 6;
rgb[2] = 0.0f;
}
// add Saturation to the equation.
rgb[0] = (hsv[1] * rgb[0] + (1.0f - hsv[1]));
rgb[1] = (hsv[1] * rgb[1] + (1.0f - hsv[1]));
rgb[2] = (hsv[1] * rgb[2] + (1.0f - hsv[1]));
rgb[0] *= hsv[2];
rgb[1] *= hsv[2];
rgb[2] *= hsv[2];
return rgb;
}
// clang-format off
inline bool outside_vrange(double x) { return x < 0.0 || x > 1.0; }
inline bool outside_vrange(const vtkm::Vec<double, 2>& x)
{ return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0; }
inline bool outside_vrange(const vtkm::Vec<double, 3>& x)
{ return x[0] < 0.0 || x[0] > 1.0 || x[1] < 0.0 || x[1] > 1.0 || x[2] < 0.0 || x[2] > 1.0; }
inline bool outside_vrange(float x) { return x < 0.0f || x > 1.0f; }
inline bool outside_vrange(const vtkm::Vec<float, 2>& x)
{ return x[0] < 0.0f || x[0] > 1.0f || x[1] < 0.0f || x[1] > 1.0f; }
inline bool outside_vrange(const vtkm::Vec<float, 3>& x)
{ return x[0] < 0.0f || x[0] > 1.0f || x[1] < 0.0f || x[1] > 1.0f || x[2] < 0.0f || x[2] > 1.0f; }
inline bool outside_range() { return false; }
template <typename T>
inline bool outside_range(T&& t) { return outside_vrange(t); }
template <typename T, typename U>
inline bool outside_range(T&& t, U&& u) { return outside_vrange(t) || outside_vrange(u); }
template <typename T, typename U, typename V, typename... Args>
inline bool outside_range(T&& t, U&& u, V&& v, Args&&... args)
{
return outside_vrange(t) || outside_vrange(u) || outside_vrange(v) ||
outside_range(std::forward<Args>(args)...);
}
// clang-format on
}
} //namespace cont
} //namespace vtkm

@ -16,6 +16,7 @@ namespace vtkm
namespace cont
{
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
namespace detail
{
@ -27,6 +28,7 @@ vtkm::cont::ArrayHandleVirtualCoordinates CoordDataDepWrapper::ToArray() const
VTKM_DEPRECATED_SUPPRESS_END
} // namespace detail
#endif //VTKM_NO_DEPRECATED_VIRTUAL
VTKM_CONT CoordinateSystem::CoordinateSystem()
: Superclass()
@ -52,10 +54,19 @@ CoordinateSystem::CoordinateSystem(std::string name,
{
}
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
VTKM_CONT vtkm::cont::detail::CoordDataDepWrapper CoordinateSystem::GetData() const
{
return vtkm::cont::detail::CoordDataDepWrapper(this->Superclass::GetData());
}
#else //!VTKM_NO_DEPRECATED_VIRTUAL
VTKM_CONT vtkm::cont::VariantArrayHandleBase<vtkm::TypeListFieldVec3> CoordinateSystem::GetData()
const
{
return vtkm::cont::VariantArrayHandleBase<vtkm::TypeListFieldVec3>(this->Superclass::GetData());
}
#endif //!VTKM_NO_DEPRECATED_VIRTUAL
VTKM_CONT vtkm::cont::CoordinateSystem::MultiplexerArrayType
CoordinateSystem::GetDataAsMultiplexer() const

@ -14,15 +14,19 @@
#include <vtkm/Deprecated.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
#include <vtkm/cont/CastAndCall.h>
#include <vtkm/cont/Field.h>
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
#endif
namespace vtkm
{
namespace cont
{
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
namespace detail
{
@ -117,6 +121,7 @@ VTKM_CONT VTKM_DEPRECATED(
vtkm::cont::printSummary_ArrayHandle(coordArray, out, full);
}
VTKM_DEPRECATED_SUPPRESS_END
#endif //VTKM_NO_DEPRECATED_VIRTUAL
class VTKM_CONT_EXPORT CoordinateSystem : public vtkm::cont::Field
{
@ -146,7 +151,11 @@ public:
VTKM_CONT
vtkm::Id GetNumberOfPoints() const { return this->GetNumberOfValues(); }
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
VTKM_CONT detail::CoordDataDepWrapper GetData() const;
#else
VTKM_CONT vtkm::cont::VariantArrayHandleBase<vtkm::TypeListFieldVec3> GetData() const;
#endif
private:
#ifdef VTKM_USE_DOUBLE_PRECISION
@ -267,11 +276,14 @@ struct DynamicTransformTraits<vtkm::cont::CoordinateSystem>
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
};
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
template <>
struct DynamicTransformTraits<vtkm::cont::detail::CoordDataDepWrapper>
{
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
};
#endif //VTKM_NO_DEPRECATED_VIRTUAL
} // namespace internal
} // namespace cont
@ -283,12 +295,14 @@ struct DynamicTransformTraits<vtkm::cont::detail::CoordDataDepWrapper>
namespace mangled_diy_namespace
{
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
template <>
struct Serialization<vtkm::cont::detail::CoordDataDepWrapper>
: public Serialization<
vtkm::cont::VariantArrayHandleBase<vtkm::List<vtkm::Vec3f_32, vtkm::Vec3f_64>>>
{
};
#endif //VTKM_NO_DEPRECATED_VIRTUAL
template <>
struct Serialization<vtkm::cont::CoordinateSystem>

@ -17,7 +17,7 @@
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/PointLocatorUniformGrid.h>
#include <vtkm/cont/PointLocatorSparseGrid.h>
namespace vtkm
{
@ -59,7 +59,7 @@ private:
} // internal
void PointLocatorUniformGrid::Build()
void PointLocatorSparseGrid::Build()
{
if (this->IsRangeInvalid())
{
@ -96,11 +96,11 @@ void PointLocatorUniformGrid::Build()
vtkm::cont::Algorithm::LowerBounds(cellIds, cell_ids_counting, this->CellLower);
}
struct PointLocatorUniformGrid::PrepareExecutionObjectFunctor
struct PointLocatorSparseGrid::PrepareExecutionObjectFunctor
{
template <typename DeviceAdapter>
VTKM_CONT bool operator()(DeviceAdapter,
const vtkm::cont::PointLocatorUniformGrid& self,
const vtkm::cont::PointLocatorSparseGrid& self,
ExecutionObjectHandleType& handle,
vtkm::cont::Token& token) const
{
@ -110,8 +110,8 @@ struct PointLocatorUniformGrid::PrepareExecutionObjectFunctor
auto rmax = vtkm::make_Vec(static_cast<vtkm::FloatDefault>(self.Range[0].Max),
static_cast<vtkm::FloatDefault>(self.Range[1].Max),
static_cast<vtkm::FloatDefault>(self.Range[2].Max));
vtkm::exec::PointLocatorUniformGrid<DeviceAdapter>* h =
new vtkm::exec::PointLocatorUniformGrid<DeviceAdapter>(
vtkm::exec::PointLocatorSparseGrid<DeviceAdapter>* h =
new vtkm::exec::PointLocatorSparseGrid<DeviceAdapter>(
rmin,
rmax,
self.Dims,
@ -124,7 +124,7 @@ struct PointLocatorUniformGrid::PrepareExecutionObjectFunctor
}
};
VTKM_CONT void PointLocatorUniformGrid::PrepareExecutionObject(
VTKM_CONT void PointLocatorSparseGrid::PrepareExecutionObject(
ExecutionObjectHandleType& execObjHandle,
vtkm::cont::DeviceAdapterId deviceId,
vtkm::cont::Token& token) const
@ -133,7 +133,7 @@ VTKM_CONT void PointLocatorUniformGrid::PrepareExecutionObject(
deviceId, PrepareExecutionObjectFunctor(), *this, execObjHandle, token);
if (!success)
{
throwFailedRuntimeDeviceTransfer("PointLocatorUniformGrid", deviceId);
throwFailedRuntimeDeviceTransfer("PointLocatorSparseGrid", deviceId);
}
}
}

@ -0,0 +1,102 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#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/PointLocator.h>
#include <vtkm/exec/PointLocatorSparseGrid.h>
namespace vtkm
{
namespace cont
{
/// \brief A locator that bins points in a sparsely stored grid.
///
/// `PointLocatorSparseGrid` creates a very dense logical grid over the region containing
/// the points of the provided data set. Although this logical grid has uniform structure,
/// it is stored sparsely. So, it is expected that most of the bins in the structure will
/// be empty but not explicitly stored. This makes `PointLocatorSparseGrid` a good
/// representation for unstructured or irregular collections of points.
///
/// The algorithm used in `PointLocatorSparseGrid` is described in the following publication:
///
/// Abhishek Yenpure, Hank Childs, and Kenneth Moreland. "Efficient Point Merging Using Data
/// Parallel Techniques." In _Eurographics Symposium on Parallel Graphics and Visualization
/// (EGPGV)_, June 2019. DOI 10.2312/pgv.20191112.
///
class VTKM_CONT_EXPORT PointLocatorSparseGrid : public vtkm::cont::PointLocator
{
public:
using RangeType = vtkm::Vec<vtkm::Range, 3>;
void SetRange(const RangeType& range)
{
if (this->Range != range)
{
this->Range = range;
this->SetModified();
}
}
const RangeType& GetRange() const { return this->Range; }
void SetComputeRangeFromCoordinates()
{
if (!this->IsRangeInvalid())
{
this->Range = { { 0.0, -1.0 } };
this->SetModified();
}
}
void SetNumberOfBins(const vtkm::Id3& bins)
{
if (this->Dims != bins)
{
this->Dims = bins;
this->SetModified();
}
}
const vtkm::Id3& GetNumberOfBins() const { return this->Dims; }
protected:
void Build() override;
struct PrepareExecutionObjectFunctor;
VTKM_CONT void PrepareExecutionObject(ExecutionObjectHandleType& execObjHandle,
vtkm::cont::DeviceAdapterId deviceId,
vtkm::cont::Token& token) const override;
bool IsRangeInvalid() const
{
return (this->Range[0].Max < this->Range[0].Min) || (this->Range[1].Max < this->Range[1].Min) ||
(this->Range[2].Max < this->Range[2].Min);
}
private:
RangeType Range = { { 0.0, -1.0 } };
vtkm::Id3 Dims = { 32 };
vtkm::cont::ArrayHandle<vtkm::Id> PointIds;
vtkm::cont::ArrayHandle<vtkm::Id> CellLower;
vtkm::cont::ArrayHandle<vtkm::Id> CellUpper;
};
}
}
#endif //vtk_m_cont_PointLocatorSparseGrid_h

@ -10,79 +10,21 @@
#ifndef vtk_m_cont_PointLocatorUniformGrid_h
#define vtk_m_cont_PointLocatorUniformGrid_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/Deprecated.h>
#include <vtkm/cont/PointLocator.h>
#include <vtkm/exec/PointLocatorUniformGrid.h>
#include <vtkm/cont/PointLocatorSparseGrid.h>
namespace vtkm
{
namespace cont
{
class VTKM_CONT_EXPORT PointLocatorUniformGrid : public vtkm::cont::PointLocator
struct VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6, "Replaced with PointLocatorSparseGrid.")
PointLocatorUniformGrid : vtkm::cont::PointLocatorSparseGrid
{
public:
using RangeType = vtkm::Vec<vtkm::Range, 3>;
void SetRange(const RangeType& range)
{
if (this->Range != range)
{
this->Range = range;
this->SetModified();
}
}
const RangeType& GetRange() const { return this->Range; }
void SetComputeRangeFromCoordinates()
{
if (!this->IsRangeInvalid())
{
this->Range = { { 0.0, -1.0 } };
this->SetModified();
}
}
void SetNumberOfBins(const vtkm::Id3& bins)
{
if (this->Dims != bins)
{
this->Dims = bins;
this->SetModified();
}
}
const vtkm::Id3& GetNumberOfBins() const { return this->Dims; }
protected:
void Build() override;
struct PrepareExecutionObjectFunctor;
VTKM_CONT void PrepareExecutionObject(ExecutionObjectHandleType& execObjHandle,
vtkm::cont::DeviceAdapterId deviceId,
vtkm::cont::Token& token) const override;
bool IsRangeInvalid() const
{
return (this->Range[0].Max < this->Range[0].Min) || (this->Range[1].Max < this->Range[1].Min) ||
(this->Range[2].Max < this->Range[2].Min);
}
private:
RangeType Range = { { 0.0, -1.0 } };
vtkm::Id3 Dims = { 32 };
vtkm::cont::ArrayHandle<vtkm::Id> PointIds;
vtkm::cont::ArrayHandle<vtkm::Id> CellLower;
vtkm::cont::ArrayHandle<vtkm::Id> CellUpper;
};
}
}
#endif //vtk_m_cont_PointLocatorUniformGrid_h

@ -50,7 +50,13 @@ namespace cont
/// To implement your own StorageTag, you first must create a tag class (an
/// empty struct) defining your tag (i.e. struct VTKM_ALWAYS_EXPORT StorageTagMyAlloc { };). Then
/// provide a partial template specialization of vtkm::cont::internal::Storage
/// for your new tag.
/// for your new tag. Note that because the StorageTag is being used for
/// template specialization, storage tags cannot use inheritance (or, rather,
/// inheritance won't have any effect). You can, however, have a partial template
/// specialization of vtkm::cont::internal::Storage inherit from a different
/// specialization. So, for example, you could not have StorageTagFoo inherit from
/// StorageTagBase, but you could have vtkm::cont::internal::Storage<T, StorageTagFoo>
/// inherit from vtkm::cont::internal::Storage<T, StorageTagBase>.
///
struct VTKM_ALWAYS_EXPORT StorageTag___
{

@ -20,6 +20,10 @@
#include <typeinfo>
#ifdef VTKM_NO_DEPRECATED_VIRTUAL
#error "ArrayHandleVirtual is removed. Do not include StorageVirtual.h"
#endif
namespace vtkm
{
namespace cont
@ -58,7 +62,7 @@ namespace vtkm
namespace cont
{
struct VTKM_ALWAYS_EXPORT StorageTagVirtual
struct VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(1.6) StorageTagVirtual
{
};
@ -256,6 +260,7 @@ private:
} // namespace detail
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <typename T>
class VTKM_ALWAYS_EXPORT Storage<T, vtkm::cont::StorageTagVirtual>
{
@ -315,6 +320,7 @@ private:
{
}
};
VTKM_DEPRECATED_SUPPRESS_END
} // namespace internal
}

@ -235,6 +235,7 @@ void StorageVirtualImpl<T, S>::TransferPortalForOutput(
}
} // namespace detail
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <typename T>
void Storage<T, vtkm::cont::StorageTagVirtual>::Allocate(vtkm::Id numberOfValues)
{
@ -433,6 +434,7 @@ struct ArrayTransfer<T, vtkm::cont::StorageTagVirtual, Device> : detail::ArrayTr
return this->Superclass::PrepareForInPlace(Device());
}
};
VTKM_DEPRECATED_SUPPRESS_END
}
}
} // namespace vtkm::cont::internal

@ -0,0 +1,229 @@
//============================================================================
// 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_UncertainArrayHandle_h
#define vtk_m_cont_UncertainArrayHandle_h
#include <vtkm/cont/UnknownArrayHandle.h>
namespace vtkm
{
namespace cont
{
/// \brief An ArrayHandle of an uncertain value type and storage.
///
/// `UncertainArrayHandle` holds an `ArrayHandle` object using runtime polymorphism
/// to manage different value and storage types. It behaves like its superclass,
/// `UnknownArrayHandle`, except that it also contains two template parameters that
/// provide `vtkm::List`s of potential value and storage types, respectively.
///
/// These potential value and storage types come into play when the `CastAndCall`
/// method is called (or the `UncertainArrayHandle` is used in the
/// `vtkm::cont::CastAndCall` function). In this case, the `CastAndCall` will
/// search for `ArrayHandle`s of types that match these two lists.
///
/// Both `UncertainArrayHandle` and `UnknownArrayHandle` have a method named
/// `ResetTypes` that redefine the lists of potential value and storage types
/// by returning a new `UncertainArrayHandle` containing the same `ArrayHandle`
/// but with the new value and storage type lists.
///
template <typename ValueTypeList, typename StorageTypeList>
class VTKM_ALWAYS_EXPORT UncertainArrayHandle : public vtkm::cont::UnknownArrayHandle
{
VTKM_IS_LIST(ValueTypeList);
VTKM_IS_LIST(StorageTypeList);
VTKM_STATIC_ASSERT_MSG((!std::is_same<ValueTypeList, vtkm::ListUniversal>::value),
"Cannot use vtkm::ListUniversal with UncertainArrayHandle.");
VTKM_STATIC_ASSERT_MSG((!std::is_same<StorageTypeList, vtkm::ListUniversal>::value),
"Cannot use vtkm::ListUniversal with UncertainArrayHandle.");
using Superclass = UnknownArrayHandle;
using Thisclass = UncertainArrayHandle<ValueTypeList, StorageTypeList>;
public:
VTKM_CONT UncertainArrayHandle() = default;
template <typename T, typename S>
VTKM_CONT UncertainArrayHandle(const vtkm::cont::ArrayHandle<T, S>& array)
: Superclass(array)
{
}
explicit VTKM_CONT UncertainArrayHandle(const vtkm::cont::UnknownArrayHandle& src)
: Superclass(src)
{
}
UncertainArrayHandle(const Thisclass&) = default;
template <typename OtherValues, typename OtherStorage>
VTKM_CONT UncertainArrayHandle(const UncertainArrayHandle<OtherValues, OtherStorage>& src)
: Superclass(src)
{
}
/// \brief Create a new array of the same type as this array.
///
/// This method creates a new array that is the same type as this one and
/// returns a new `UncertainArrayHandle` for it. This method is convenient when
/// creating output arrays that should be the same type as some input array.
///
VTKM_CONT Thisclass NewInstance() const { return Thisclass(this->Superclass::NewInstance()); }
/// Like `ResetTypes` except it only resets the value types.
///
template <typename NewValueTypeList>
VTKM_CONT UncertainArrayHandle<NewValueTypeList, StorageTypeList> ResetValueTypes(
NewValueTypeList = NewValueTypeList{}) const
{
return this->ResetTypes<NewValueTypeList, StorageTypeList>();
}
/// Like `ResetTypes` except it only resets the storage types.
///
template <typename NewStorageTypeList>
VTKM_CONT UncertainArrayHandle<ValueTypeList, NewStorageTypeList> ResetStorageTypes(
NewStorageTypeList = NewStorageTypeList{}) const
{
return this->ResetTypes<ValueTypeList, NewStorageTypeList>();
}
/// \brief Call a functor using the underlying array type.
///
/// `CastAndCall` attempts to cast the held array to a specific value type,
/// and then calls the given functor with the cast array.
///
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCall(Functor&& functor, Args&&... args) const
{
this->CastAndCallForTypes<ValueTypeList, StorageTypeList>(std::forward<Functor>(functor),
std::forward<Args>(args)...);
}
};
// Defined here to avoid circular dependencies between UnknownArrayHandle and UncertainArrayHandle.
template <typename NewValueTypeList, typename NewStorageTypeList>
VTKM_CONT vtkm::cont::UncertainArrayHandle<NewValueTypeList, NewStorageTypeList>
UnknownArrayHandle::ResetTypes(NewValueTypeList, NewStorageTypeList) const
{
return vtkm::cont::UncertainArrayHandle<NewValueTypeList, NewStorageTypeList>(*this);
}
namespace internal
{
template <typename ValueTypeList, typename StorageTypeList>
struct DynamicTransformTraits<vtkm::cont::UncertainArrayHandle<ValueTypeList, StorageTypeList>>
{
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
};
} // namespace internal
}
} // namespace vtkm::cont
//=============================================================================
// Specializations of serialization related classes
/// @cond SERIALIZATION
namespace vtkm
{
namespace cont
{
template <typename ValueTypeList, typename StorageTypeList>
struct SerializableTypeString<vtkm::cont::UncertainArrayHandle<ValueTypeList, StorageTypeList>>
{
static VTKM_CONT std::string Get()
{
return SerializableTypeString<vtkm::cont::UnknownArrayHandle>::Get();
}
};
}
} // namespace vtkm::cont
namespace mangled_diy_namespace
{
namespace internal
{
struct UncertainArrayHandleSerializeFunctor
{
template <typename ArrayHandleType>
void operator()(const ArrayHandleType& ah, BinaryBuffer& bb) const
{
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<ArrayHandleType>::Get());
vtkmdiy::save(bb, ah);
}
};
struct UncertainArrayHandleDeserializeFunctor
{
template <typename T, typename S>
void operator()(vtkm::List<T, S>,
vtkm::cont::UnknownArrayHandle& unknownArray,
const std::string& typeString,
bool& success,
BinaryBuffer& bb) const
{
using ArrayHandleType = vtkm::cont::ArrayHandle<T, S>;
if (!success && (typeString == vtkm::cont::SerializableTypeString<ArrayHandleType>::Get()))
{
ArrayHandleType knownArray;
vtkmdiy::load(bb, knownArray);
unknownArray = knownArray;
success = true;
}
}
};
} // internal
template <typename ValueTypeList, typename StorageTypeList>
struct Serialization<vtkm::cont::UncertainArrayHandle<ValueTypeList, StorageTypeList>>
{
using Type = vtkm::cont::UncertainArrayHandle<ValueTypeList, StorageTypeList>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj)
{
obj.CastAndCall(internal::UncertainArrayHandleSerializeFunctor{}, bb);
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& obj)
{
std::string typeString;
vtkmdiy::load(bb, typeString);
bool success = false;
vtkm::ListForEach(internal::UncertainArrayHandleDeserializeFunctor{},
vtkm::cont::detail::ListAllArrayTypes<ValueTypeList, StorageTypeList>{},
obj,
typeString,
success,
bb);
if (!success)
{
throw vtkm::cont::ErrorBadType(
"Error deserializing Unknown/UncertainArrayHandle. Message TypeString: " + typeString);
}
}
};
} // namespace mangled_diy_namespace
/// @endcond SERIALIZATION
#endif //vtk_m_cont_UncertainArrayHandle_h

@ -0,0 +1,138 @@
//============================================================================
// 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/UnknownArrayHandle.h>
#include <vtkm/cont/ArrayHandleBasic.h>
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleGroupVec.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/ArrayHandleReverse.h>
#include <vtkm/cont/ArrayHandleSOA.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/UncertainArrayHandle.h>
using UnknownSerializationTypes = vtkm::TypeListAll;
using UnknownSerializationStorage =
vtkm::ListAppend<VTKM_DEFAULT_STORAGE_LIST,
vtkm::List<vtkm::cont::StorageTagBasic,
vtkm::cont::StorageTagCartesianProduct<vtkm::cont::StorageTagBasic,
vtkm::cont::StorageTagBasic,
vtkm::cont::StorageTagBasic>,
vtkm::cont::StorageTagConstant,
vtkm::cont::StorageTagCounting,
vtkm::cont::StorageTagIndex,
vtkm::cont::StorageTagGroupVec<vtkm::cont::StorageTagBasic, 2>,
vtkm::cont::StorageTagGroupVec<vtkm::cont::StorageTagBasic, 3>,
vtkm::cont::StorageTagGroupVec<vtkm::cont::StorageTagBasic, 4>,
vtkm::cont::StorageTagPermutation<vtkm::cont::StorageTagBasic,
vtkm::cont::StorageTagBasic>,
vtkm::cont::StorageTagReverse<vtkm::cont::StorageTagBasic>,
vtkm::cont::StorageTagSOA,
vtkm::cont::StorageTagUniformPoints>>;
namespace vtkm
{
namespace cont
{
namespace detail
{
std::shared_ptr<UnknownAHContainer> UnknownAHContainer::MakeNewInstance() const
{
// Start by doing an invalid copy to create a new container, then swap out the pointer
// to the array handle to make sure that each object will delete its own ArrayHandle
// when they get destroyed.
std::shared_ptr<UnknownAHContainer> newContainer(new UnknownAHContainer(*this));
newContainer->ArrayHandlePointer = this->NewInstance();
return newContainer;
}
} // namespace detail
VTKM_CONT bool UnknownArrayHandle::IsValueTypeImpl(std::type_index type) const
{
if (!this->Container)
{
return false;
}
// Needs optimization based on platform. OSX cannot compare typeid across translation units?
return this->Container->ValueType == type;
}
VTKM_CONT bool UnknownArrayHandle::IsStorageTypeImpl(std::type_index type) const
{
if (!this->Container)
{
return false;
}
// Needs optimization based on platform. OSX cannot compare typeid across translation units?
return this->Container->StorageType == type;
}
namespace detail
{
VTKM_CONT_EXPORT void ThrowCastAndCallException(const vtkm::cont::UnknownArrayHandle& ref,
const std::type_info& type)
{
std::ostringstream out;
out << "Could not find appropriate cast for array in CastAndCall.\n"
"Array: ";
ref.PrintSummary(out);
out << "TypeList: " << type.name() << "\n";
throw vtkm::cont::ErrorBadValue(out.str());
}
} // namespace detail
}
} // namespace vtkm::cont
//=============================================================================
// Specializations of serialization related classes
namespace vtkm
{
namespace cont
{
std::string SerializableTypeString<vtkm::cont::UnknownArrayHandle>::Get()
{
return "UnknownAH";
}
}
} // namespace vtkm::cont
namespace mangled_diy_namespace
{
void Serialization<vtkm::cont::UnknownArrayHandle>::save(BinaryBuffer& bb,
const vtkm::cont::UnknownArrayHandle& obj)
{
vtkmdiy::save(bb, obj.ResetTypes<UnknownSerializationTypes, UnknownSerializationStorage>());
}
void Serialization<vtkm::cont::UnknownArrayHandle>::load(BinaryBuffer& bb,
vtkm::cont::UnknownArrayHandle& obj)
{
vtkm::cont::UncertainArrayHandle<UnknownSerializationTypes, UnknownSerializationStorage>
uncertainArray;
vtkmdiy::load(bb, uncertainArray);
obj = uncertainArray;
}
} // namespace mangled_diy_namespace

@ -0,0 +1,669 @@
//============================================================================
// 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_UnknownArrayHandle_h
#define vtk_m_cont_UnknownArrayHandle_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleMultiplexer.h>
#include <vtkm/cont/DefaultTypes.h>
#include <memory>
#include <typeindex>
namespace vtkm
{
namespace cont
{
namespace detail
{
template <typename T, typename S>
static void UnknownAHDelete(void* mem)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
delete arrayHandle;
}
template <typename T, typename S>
static void* UnknownADNewInstance()
{
return new vtkm::cont::ArrayHandle<T, S>;
}
template <typename T, typename S>
static vtkm::Id UnknownAHNumberOfValues(void* mem)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
return arrayHandle->GetNumberOfValues();
}
template <typename T, typename StaticSize = typename vtkm::VecTraits<T>::IsSizeStatic>
struct UnknownAHNumberOfComponentsImpl;
template <typename T>
struct UnknownAHNumberOfComponentsImpl<T, vtkm::VecTraitsTagSizeStatic>
{
static constexpr vtkm::IdComponent Value = vtkm::VecTraits<T>::NUM_COMPONENTS;
};
template <typename T>
struct UnknownAHNumberOfComponentsImpl<T, vtkm::VecTraitsTagSizeVariable>
{
static constexpr vtkm::IdComponent Value = 0;
};
template <typename T>
static vtkm::IdComponent UnknownAHNumberOfComponents()
{
return UnknownAHNumberOfComponentsImpl<T>::Value;
}
template <typename T, typename S>
static void UnknownAHReleaseResources(void* mem)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
arrayHandle->ReleaseResources();
}
template <typename T, typename S>
static void UnknownAHReleaseResourcesExecution(void* mem)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
arrayHandle->ReleaseResourcesExecution();
}
template <typename T, typename S>
static void UnknownAHPrintSummary(void* mem, std::ostream& out, bool full)
{
using AH = vtkm::cont::ArrayHandle<T, S>;
AH* arrayHandle = reinterpret_cast<AH*>(mem);
vtkm::cont::printSummary_ArrayHandle(*arrayHandle, out, full);
}
struct VTKM_CONT_EXPORT UnknownAHContainer;
struct MakeUnknownAHContainerFunctor
{
template <typename T, typename S>
std::shared_ptr<UnknownAHContainer> operator()(const vtkm::cont::ArrayHandle<T, S>& array) const;
};
struct VTKM_CONT_EXPORT UnknownAHContainer
{
void* ArrayHandlePointer;
std::type_index ValueType;
std::type_index StorageType;
using DeleteType = void(void*);
DeleteType* DeleteFunction;
using NewInstanceType = void*();
NewInstanceType& NewInstance;
using NumberOfValuesType = vtkm::Id(void*);
NumberOfValuesType* NumberOfValues;
using NumberOfComponentsType = vtkm::IdComponent();
NumberOfComponentsType* NumberOfComponents;
using ReleaseResourcesType = void(void*);
ReleaseResourcesType* ReleaseResources;
ReleaseResourcesType* ReleaseResourcesExecution;
using PrintSummaryType = void(void*, std::ostream&, bool);
PrintSummaryType* PrintSummary;
void operator=(const UnknownAHContainer&) = delete;
~UnknownAHContainer() { this->DeleteFunction(this->ArrayHandlePointer); }
std::shared_ptr<UnknownAHContainer> MakeNewInstance() const;
template <typename T, typename S>
static std::shared_ptr<UnknownAHContainer> Make(const vtkm::cont::ArrayHandle<T, S>& array)
{
return std::shared_ptr<UnknownAHContainer>(new UnknownAHContainer(array));
}
template <typename TargetT, typename SourceT, typename SourceS>
static std::shared_ptr<UnknownAHContainer> Make(
const vtkm::cont::ArrayHandle<TargetT, vtkm::cont::StorageTagCast<SourceT, SourceS>>& array)
{
return Make(array.GetStorage().GetArray());
}
template <typename T, typename... Ss>
static std::shared_ptr<UnknownAHContainer> Make(
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagMultiplexer<Ss...>>& array)
{
auto&& variant = array.GetStorage().GetArrayHandleVariant();
if (variant.IsValid())
{
return variant.CastAndCall(MakeUnknownAHContainerFunctor{});
}
else
{
return std::shared_ptr<UnknownAHContainer>{};
}
}
private:
UnknownAHContainer(const UnknownAHContainer&) = default;
template <typename T, typename S>
explicit UnknownAHContainer(const vtkm::cont::ArrayHandle<T, S>& array)
: ArrayHandlePointer(new vtkm::cont::ArrayHandle<T, S>(array))
, ValueType(typeid(T))
, StorageType(typeid(S))
, DeleteFunction(detail::UnknownAHDelete<T, S>)
, NewInstance(detail::UnknownADNewInstance<T, S>)
, NumberOfValues(detail::UnknownAHNumberOfValues<T, S>)
, NumberOfComponents(detail::UnknownAHNumberOfComponents<T>)
, ReleaseResources(detail::UnknownAHReleaseResources<T, S>)
, ReleaseResourcesExecution(detail::UnknownAHReleaseResourcesExecution<T, S>)
, PrintSummary(detail::UnknownAHPrintSummary<T, S>)
{
}
};
template <typename T, typename S>
inline std::shared_ptr<UnknownAHContainer> MakeUnknownAHContainerFunctor::operator()(
const vtkm::cont::ArrayHandle<T, S>& array) const
{
return UnknownAHContainer::Make(array);
};
} // namespace detail
// Forward declaration. Include UncertainArrayHandle.h if using this.
template <typename ValueTypeList, typename StorageTypeList>
class UncertainArrayHandle;
/// \brief An ArrayHandle of an unknown value type and storage.
///
/// `UnknownArrayHandle` holds an `ArrayHandle` object using runtime polymorphism
/// to manage different value and storage types rather than compile-time templates.
/// This adds a programming convenience that helps avoid a proliferation of
/// templates. It also provides the management necessary to interface VTK-m with
/// data sources where types will not be known until runtime and is the storage
/// mechanism for classes like `DataSet` and `Field` that can hold numerous
/// types.
///
/// To interface between the runtime polymorphism and the templated algorithms
/// in VTK-m, `UnknownArrayHandle` contains a method named `CastAndCallForTypes`
/// that determines the correct type from some known list of value types and
/// storage. This mechanism is used internally by VTK-m's worklet invocation
/// mechanism to determine the type when running algorithms.
///
/// If the `UnknownArrayHandle` is used in a context where the possible array
/// types can be whittled down to a finite list (or you have to), you can
/// specify lists of value types and storage using the `ResetTypesAndStorage`
/// method. This will convert this object to an `UncertainArrayHandle` of the
/// given types. In cases where a finite set of types need to specified but
/// there is no known subset, `VTKM_DEFAULT_TYPE_LIST` and
/// `VTKM_DEFAULT_STORAGE_LIST` can be used.
///
/// `ArrayHandleCast` and `ArrayHandleMultiplexer` are treated special. If
/// the `UnknownArrayHandle` is set to an `ArrayHandle` of one of these
/// types, it will actually store the `ArrayHandle` contained. Likewise,
/// if the `ArrayHandle` is retrieved as one of these types, it will
/// automatically convert it if possible.
///
class VTKM_CONT_EXPORT UnknownArrayHandle
{
std::shared_ptr<detail::UnknownAHContainer> Container;
VTKM_CONT bool IsValueTypeImpl(std::type_index type) const;
VTKM_CONT bool IsStorageTypeImpl(std::type_index type) const;
public:
VTKM_CONT UnknownArrayHandle() = default;
UnknownArrayHandle(const UnknownArrayHandle&) = default;
template <typename T, typename S>
VTKM_CONT UnknownArrayHandle(const vtkm::cont::ArrayHandle<T, S>& array)
: Container(detail::UnknownAHContainer::Make(array))
{
}
UnknownArrayHandle& operator=(const vtkm::cont::UnknownArrayHandle&) = default;
/// \brief Create a new array of the same type as this array.
///
/// This method creates a new array that is the same type as this one and
/// returns a new `UnknownArrayHandle` for it. This method is convenient when
/// creating output arrays that should be the same type as some input array.
///
VTKM_CONT UnknownArrayHandle NewInstance() const
{
UnknownArrayHandle newArray;
if (this->Container)
{
newArray.Container = this->Container->MakeNewInstance();
}
return newArray;
}
/// Returns true if this array matches the ValueType template argument.
///
template <typename ValueType>
VTKM_CONT bool IsValueType() const
{
return this->IsValueTypeImpl(typeid(ValueType));
}
/// Returns true if this array matches the StorageType template argument.
///
template <typename StorageType>
VTKM_CONT bool IsStorageType() const
{
return this->IsStorageTypeImpl(typeid(StorageType));
}
/// Returns true if this array matches the ArrayHandleType template argument.
///
template <typename ArrayHandleType>
VTKM_CONT bool IsType() const
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
return (this->IsValueType<typename ArrayHandleType::ValueType>() &&
this->IsStorageType<typename ArrayHandleType::StorageTag>());
}
/// \brief Assigns potential value and storage types.
///
/// Calling this method will return an `UncertainArrayHandle` with the provided
/// value and storage type lists. The returned object will hold the same
/// `ArrayHandle`, but `CastAndCall`s on the returned object will be constrained
/// to the given types.
///
// Defined in UncertainArrayHandle.h
template <typename NewValueTypeList, typename NewStorageTypeList>
VTKM_CONT vtkm::cont::UncertainArrayHandle<NewValueTypeList, NewStorageTypeList> ResetTypes(
NewValueTypeList = NewValueTypeList{},
NewStorageTypeList = NewStorageTypeList{}) const;
/// \brief Returns the number of values in the array.
///
VTKM_CONT vtkm::Id GetNumberOfValues() const
{
if (this->Container)
{
return this->Container->NumberOfValues(this->Container->ArrayHandlePointer);
}
else
{
return 0;
}
}
/// \brief Returns the number of components for each value in the array.
///
/// If the array holds `vtkm::Vec` objects, this will return the number of components
/// in each value. If the array holds a basic C type (such as `float`), this will return 1.
/// If the array holds `Vec`-like objects that have the number of components that can vary
/// at runtime, this method will return 0 (because there is no consistent answer).
///
VTKM_CONT vtkm::IdComponent GetNumberOfComponents() const
{
if (this->Container)
{
return this->Container->NumberOfComponents();
}
else
{
return 0;
}
}
/// \brief Determine if the contained array can be passed to the given array type.
///
/// This method will return true if calling `AsArrayHandle` of the given type will
/// succeed. The 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 such as an `ArrayHandleMultiplexer` that can contain the array.
///
template <typename ArrayHandleType>
VTKM_CONT bool CanConvert() const;
// MSVC will issue deprecation warnings here if this template is instantiated with
// a deprecated class even if the template is used from a section of code where
// deprecation warnings are suppressed. This is annoying behavior since this template
// has no control over what class it is used with. To get around it, we have to
// suppress all deprecation warnings here.
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_BEGIN
#endif
///@{
/// 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.
///
template <typename T, typename S>
VTKM_CONT void AsArrayHandle(vtkm::cont::ArrayHandle<T, S>& array) const
{
using ArrayType = vtkm::cont::ArrayHandle<T, S>;
if (!this->IsType<ArrayType>())
{
VTKM_LOG_CAST_FAIL(*this, decltype(array));
throwFailedDynamicCast(vtkm::cont::TypeToString(*this), vtkm::cont::TypeToString(array));
}
array = *reinterpret_cast<ArrayType*>(this->Container->ArrayHandlePointer);
}
template <typename T, typename... Ss>
VTKM_CONT void AsArrayHandle(
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagMultiplexer<Ss...>>& array) const;
template <typename TargetT, typename SourceT, typename SourceS>
VTKM_CONT void AsArrayHandle(
vtkm::cont::ArrayHandle<TargetT, vtkm::cont::StorageTagCast<SourceT, SourceS>>& array) const
{
using ContainedArrayType = vtkm::cont::ArrayHandle<SourceT, SourceS>;
array = vtkm::cont::ArrayHandleCast<TargetT, ContainedArrayType>(
this->AsArrayHandle<ContainedArrayType>());
}
template <typename ArrayType>
VTKM_CONT ArrayType AsArrayHandle() const
{
VTKM_IS_ARRAY_HANDLE(ArrayType);
ArrayType array;
this->AsArrayHandle(array);
return array;
}
///@}
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_END
#endif
/// \brief Call a functor using the underlying array type.
///
/// `CastAndCall` attempts to cast the held array to a specific value type,
/// and then calls the given functor with the cast array. You must specify
/// the `TypeList` and `StorageList` as template arguments.
///
template <typename TypeList, typename StorageList, typename Functor, typename... Args>
VTKM_CONT void CastAndCallForTypes(Functor&& functor, Args&&... args) const;
/// Releases any resources being used in the execution environment (that are
/// not being shared by the control environment).
///
VTKM_CONT void ReleaseResourcesExecution() const
{
if (this->Container)
{
this->Container->ReleaseResourcesExecution(this->Container->ArrayHandlePointer);
}
}
/// Releases all resources in both the control and execution environments.
///
VTKM_CONT void ReleaseResources() const
{
if (this->Container)
{
this->Container->ReleaseResources(this->Container->ArrayHandlePointer);
}
}
VTKM_CONT void PrintSummary(std::ostream& out, bool full = false) const
{
if (this->Container)
{
this->Container->PrintSummary(this->Container->ArrayHandlePointer, out, full);
}
else
{
out << "null UnknownArrayHandle" << std::endl;
}
}
};
//=============================================================================
// Out of class implementations
namespace detail
{
template <typename T, typename S>
struct UnknownArrayHandleCanConvert
{
VTKM_CONT bool operator()(const vtkm::cont::UnknownArrayHandle& array) const
{
return array.IsType<vtkm::cont::ArrayHandle<T, S>>();
}
};
template <typename TargetT, typename SourceT, typename SourceS>
struct UnknownArrayHandleCanConvert<TargetT, vtkm::cont::StorageTagCast<SourceT, SourceS>>
{
VTKM_CONT bool operator()(const vtkm::cont::UnknownArrayHandle& array) const
{
return UnknownArrayHandleCanConvert<SourceT, SourceS>{}(array);
}
};
template <typename T>
struct UnknownArrayHandleCanConvertTry
{
template <typename S>
VTKM_CONT void operator()(S, const vtkm::cont::UnknownArrayHandle& array, bool& canConvert) const
{
canConvert |= UnknownArrayHandleCanConvert<T, S>{}(array);
}
};
template <typename T, typename... Ss>
struct UnknownArrayHandleCanConvert<T, vtkm::cont::StorageTagMultiplexer<Ss...>>
{
VTKM_CONT bool operator()(const vtkm::cont::UnknownArrayHandle& array) const
{
bool canConvert = false;
vtkm::ListForEach(UnknownArrayHandleCanConvertTry<T>{}, vtkm::List<Ss...>{}, array, canConvert);
return canConvert;
}
};
} // namespace detail
template <typename ArrayHandleType>
VTKM_CONT bool UnknownArrayHandle::CanConvert() const
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
return detail::UnknownArrayHandleCanConvert<typename ArrayHandleType::ValueType,
typename ArrayHandleType::StorageTag>{}(*this);
}
namespace detail
{
struct UnknownArrayHandleMultplexerCastTry
{
template <typename T, typename S, typename... Ss>
VTKM_CONT void operator()(
S,
const vtkm::cont::UnknownArrayHandle& unknownArray,
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagMultiplexer<Ss...>>& outputArray,
bool& converted) const
{
using ArrayType = vtkm::cont::ArrayHandle<T, S>;
if (unknownArray.CanConvert<ArrayType>())
{
if (converted && !unknownArray.IsType<ArrayType>())
{
// The array has already been converted and pushed in the multiplexer. It is
// possible that multiple array types can be put in the ArrayHandleMultiplexer
// (for example, and ArrayHandle or an ArrayHandle that has been cast). Exact
// matches will override other matches (hence, the second part of the condition),
// but at this point we have already found a better array to put inside.
return;
}
outputArray.GetStorage().SetArray(unknownArray.AsArrayHandle<ArrayType>());
converted = true;
}
}
};
} // namespace detail
template <typename T, typename... Ss>
void UnknownArrayHandle::AsArrayHandle(
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagMultiplexer<Ss...>>& array) const
{
bool converted = false;
vtkm::ListForEach(
detail::UnknownArrayHandleMultplexerCastTry{}, vtkm::List<Ss...>{}, *this, array, converted);
if (!converted)
{
VTKM_LOG_CAST_FAIL(*this, decltype(array));
throwFailedDynamicCast(vtkm::cont::TypeToString(*this), vtkm::cont::TypeToString(array));
}
}
namespace detail
{
struct UnknownArrayHandleTry
{
template <typename T, typename S, typename Functor, typename... Args>
void operator()(vtkm::List<T, S>,
Functor&& f,
bool& called,
const vtkm::cont::UnknownArrayHandle& unknownArray,
Args&&... args) const
{
using DerivedArrayType = vtkm::cont::ArrayHandle<T, S>;
if (!called && unknownArray.IsType<DerivedArrayType>())
{
called = true;
DerivedArrayType derivedArray;
unknownArray.AsArrayHandle(derivedArray);
VTKM_LOG_CAST_SUCC(unknownArray, derivedArray);
// If you get a compile error here, it means that you have called CastAndCall for a
// vtkm::cont::UnknownArrayHandle and the arguments of the functor do not match those
// being passed. This is often because it is calling the functor with an ArrayHandle
// type that was not expected. Either add overloads to the functor to accept all
// possible array types or constrain the types tried for the CastAndCall. Note that
// the functor will be called with an array of type vtkm::cont::ArrayHandle<T, S>.
// Directly using a subclass of ArrayHandle (e.g. vtkm::cont::ArrayHandleConstant<T>)
// might not work.
f(derivedArray, std::forward<Args>(args)...);
}
}
};
template <typename T>
struct IsUndefinedArrayType
{
};
template <typename T, typename S>
struct IsUndefinedArrayType<vtkm::List<T, S>> : vtkm::cont::internal::IsInvalidArrayHandle<T, S>
{
};
template <typename ValueTypeList, typename StorageTypeList>
using ListAllArrayTypes =
vtkm::ListRemoveIf<vtkm::ListCross<ValueTypeList, StorageTypeList>, IsUndefinedArrayType>;
VTKM_CONT_EXPORT void ThrowCastAndCallException(const vtkm::cont::UnknownArrayHandle&,
const std::type_info&);
} // namespace detail
template <typename TypeList, typename StorageTagList, typename Functor, typename... Args>
VTKM_CONT void UnknownArrayHandle::CastAndCallForTypes(Functor&& f, Args&&... args) const
{
using crossProduct = detail::ListAllArrayTypes<TypeList, StorageTagList>;
bool called = false;
vtkm::ListForEach(detail::UnknownArrayHandleTry{},
crossProduct{},
std::forward<Functor>(f),
called,
*this,
std::forward<Args>(args)...);
if (!called)
{
// throw an exception
VTKM_LOG_CAST_FAIL(*this, TypeList);
detail::ThrowCastAndCallException(*this, typeid(TypeList));
}
}
template <typename Functor, typename... Args>
void CastAndCall(const UnknownArrayHandle& handle, Functor&& f, Args&&... args)
{
handle.CastAndCallForTypes<VTKM_DEFAULT_TYPE_LIST, VTKM_DEFAULT_STORAGE_LIST>(
std::forward<Functor>(f), std::forward<Args>(args)...);
}
namespace internal
{
template <>
struct DynamicTransformTraits<vtkm::cont::UnknownArrayHandle>
{
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
};
} // namespace internal
}
} // namespace vtkm::cont
//=============================================================================
// Specializations of serialization related classes
/// @cond SERIALIZATION
namespace vtkm
{
namespace cont
{
template <>
struct VTKM_CONT_EXPORT SerializableTypeString<vtkm::cont::UnknownArrayHandle>
{
static VTKM_CONT std::string Get();
};
}
} // namespace vtkm::cont
namespace mangled_diy_namespace
{
template <>
struct VTKM_CONT_EXPORT Serialization<vtkm::cont::UnknownArrayHandle>
{
public:
static VTKM_CONT void save(BinaryBuffer& bb, const vtkm::cont::UnknownArrayHandle& obj);
static VTKM_CONT void load(BinaryBuffer& bb, vtkm::cont::UnknownArrayHandle& obj);
};
} // namespace mangled_diy_namespace
/// @endcond SERIALIZATION
#endif //vtk_m_cont_UnknownArrayHandle_h

@ -17,20 +17,84 @@
#include <vtkm/cont/ArrayHandleMultiplexer.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/CastAndCall.h>
#include <vtkm/cont/DefaultTypes.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/StorageList.h>
#include <vtkm/cont/UncertainArrayHandle.h>
#include <vtkm/cont/UnknownArrayHandle.h>
#include <vtkm/cont/internal/VariantArrayHandleContainer.h>
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/cont/ArrayHandleVirtual.h>
#endif //VTKM_NO_DEPRECATED_VIRTUAL
namespace vtkm
{
namespace cont
{
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
namespace internal
{
namespace variant
{
VTKM_DEPRECATED_SUPPRESS_BEGIN
struct ForceCastToVirtual
{
template <typename SrcValueType, typename Storage, typename DstValueType>
VTKM_CONT typename std::enable_if<std::is_same<SrcValueType, DstValueType>::value>::type
operator()(const vtkm::cont::ArrayHandle<SrcValueType, Storage>& input,
vtkm::cont::ArrayHandleVirtual<DstValueType>& output) const
{ // ValueTypes match
output = vtkm::cont::make_ArrayHandleVirtual<DstValueType>(input);
}
template <typename SrcValueType, typename Storage, typename DstValueType>
VTKM_CONT typename std::enable_if<!std::is_same<SrcValueType, DstValueType>::value>::type
operator()(const vtkm::cont::ArrayHandle<SrcValueType, Storage>& input,
vtkm::cont::ArrayHandleVirtual<DstValueType>& output) const
{ // ValueTypes do not match
this->ValidateWidthAndCast<SrcValueType, DstValueType>(input, output);
}
private:
template <typename S,
typename D,
typename InputType,
vtkm::IdComponent SSize = vtkm::VecTraits<S>::NUM_COMPONENTS,
vtkm::IdComponent DSize = vtkm::VecTraits<D>::NUM_COMPONENTS>
VTKM_CONT typename std::enable_if<SSize == DSize>::type ValidateWidthAndCast(
const InputType& input,
vtkm::cont::ArrayHandleVirtual<D>& output) const
{ // number of components match
auto casted = vtkm::cont::make_ArrayHandleCast<D>(input);
output = vtkm::cont::make_ArrayHandleVirtual<D>(casted);
}
template <typename S,
typename D,
vtkm::IdComponent SSize = vtkm::VecTraits<S>::NUM_COMPONENTS,
vtkm::IdComponent DSize = vtkm::VecTraits<D>::NUM_COMPONENTS>
VTKM_CONT typename std::enable_if<SSize != DSize>::type ValidateWidthAndCast(
const ArrayHandleBase&,
ArrayHandleBase&) const
{ // number of components do not match
std::ostringstream str;
str << "VariantArrayHandle::AsVirtual: Cannot cast from " << vtkm::cont::TypeToString<S>()
<< " to " << vtkm::cont::TypeToString<D>()
<< "; "
"number of components must match exactly.";
throw vtkm::cont::ErrorBadType(str.str());
}
};
VTKM_DEPRECATED_SUPPRESS_END
}
} // namespace internal::variant
#endif //VTKM_NO_DEPRECATED_VIRTUAL
/// \brief VariantArrayHandle superclass holding common operations.
///
/// `VariantArrayHandleCommon` is a superclass to all `VariantArrayHandleBase`
@ -40,43 +104,28 @@ namespace cont
///
/// See the documentation of `VariantArrayHandleBase` for more information.
///
class VTKM_ALWAYS_EXPORT VariantArrayHandleCommon
class VTKM_ALWAYS_EXPORT VariantArrayHandleCommon : public vtkm::cont::UnknownArrayHandle
{
std::shared_ptr<vtkm::cont::internal::VariantArrayHandleContainerBase> ArrayContainer;
using Superclass = vtkm::cont::UnknownArrayHandle;
public:
using Superclass::Superclass;
VTKM_CONT VariantArrayHandleCommon() = default;
template <typename T, typename Storage>
VTKM_CONT VariantArrayHandleCommon(const vtkm::cont::ArrayHandle<T, Storage>& array)
: ArrayContainer(std::make_shared<internal::VariantArrayHandleContainer<T>>(
vtkm::cont::ArrayHandleVirtual<T>{ array }))
VTKM_CONT VariantArrayHandleCommon(const vtkm::cont::UnknownArrayHandle& array)
: Superclass(array)
{
}
template <typename T>
VTKM_CONT VariantArrayHandleCommon(
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>& array)
: ArrayContainer(std::make_shared<internal::VariantArrayHandleContainer<T>>(array))
{
}
/// Returns true if this array matches the array handle type passed in.
///
template <typename ArrayHandleType>
VTKM_CONT bool IsType() const
{
return internal::variant::IsType<ArrayHandleType>(this->ArrayContainer.get());
}
/// Returns true if this array matches the ValueType type passed in.
///
template <typename T>
VTKM_CONT bool IsValueType() const
{
return internal::variant::IsValueType<T>(this->ArrayContainer.get());
}
// MSVC will issue deprecation warnings here if this template is instantiated with
// a deprecated class even if the template is used from a section of code where
// deprecation warnings are suppressed. This is annoying behavior since this template
// has no control over what class it is used with. To get around it, we have to
// suppress all deprecation warnings here.
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_BEGIN
#endif
/// Returns this array cast to the given \c ArrayHandle type. Throws \c
/// ErrorBadType if the cast does not work. Use \c IsType
/// to check if the cast can happen.
@ -84,19 +133,11 @@ public:
template <typename ArrayHandleType>
VTKM_CONT ArrayHandleType Cast() const
{
// MSVC will issue deprecation warnings if this templated method is instantiated with
// a deprecated class here even if the method is called from a section of code where
// deprecation warnings are suppressed. This is annoying behavior since this templated
// method has no control over what class it is used from. To get around it, we have to
// suppress all deprecation warnings here.
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_BEGIN
#endif
return internal::variant::Cast<ArrayHandleType>(this->ArrayContainer.get());
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_END
#endif
return this->AsArrayHandle<ArrayHandleType>();
}
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_END
#endif
/// \brief Call a functor using the underlying array type.
///
@ -106,8 +147,13 @@ public:
/// calling differs from that of the `CastAndCall` methods of subclasses.)
///
template <typename TypeList, typename StorageList, typename Functor, typename... Args>
VTKM_CONT void CastAndCall(Functor&& functor, Args&&... args) const;
VTKM_CONT void CastAndCall(Functor&& functor, Args&&... args) const
{
this->CastAndCallForTypes<TypeList, StorageList>(std::forward<Functor>(functor),
std::forward<Args>(args)...);
}
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
/// Returns this array cast to a `ArrayHandleVirtual` of the given type.
/// This will perform type conversions as necessary, and will log warnings
/// if the conversion is lossy.
@ -117,10 +163,12 @@ public:
/// the CastAndCall. You can also specify a list of types to try as the optional
/// third template argument.
///
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <typename T,
typename StorageList = VTKM_DEFAULT_STORAGE_LIST,
typename TypeList = vtkm::List<T>>
VTKM_CONT vtkm::cont::ArrayHandleVirtual<T> AsVirtual() const
VTKM_CONT VTKM_DEPRECATED(1.6, "ArrayHandleVirtual is no longer supported.")
vtkm::cont::ArrayHandleVirtual<T> AsVirtual() const
{
VTKM_IS_LIST(StorageList);
VTKM_IS_LIST(TypeList);
@ -129,6 +177,8 @@ public:
this->CastAndCall<TypeList, StorageList>(caster, output);
return output;
}
VTKM_DEPRECATED_SUPPRESS_END
#endif //VTKM_NO_DEPRECATED_VIRTUAL
/// Returns this array cast to a `ArrayHandleMultiplexer` of the given type.
/// This will attempt to cast the internal array to each supported type of
@ -141,7 +191,10 @@ public:
///
///@{
template <typename... T>
VTKM_CONT void AsMultiplexer(vtkm::cont::ArrayHandleMultiplexer<T...>& result) const;
VTKM_CONT void AsMultiplexer(vtkm::cont::ArrayHandleMultiplexer<T...>& result) const
{
this->AsArrayHandle(result);
}
template <typename ArrayHandleMultiplexerType>
VTKM_CONT ArrayHandleMultiplexerType AsMultiplexer() const
@ -175,40 +228,8 @@ public:
///
VTKM_CONT VariantArrayHandleCommon NewInstance() const
{
VariantArrayHandleCommon instance;
instance.ArrayContainer = this->ArrayContainer->NewInstance();
return instance;
return VariantArrayHandleCommon(this->Superclass::NewInstance());
}
/// Releases any resources being used in the execution environment (that are
/// not being shared by the control environment).
///
void ReleaseResourcesExecution() { return this->ArrayContainer->ReleaseResourcesExecution(); }
/// Releases all resources in both the control and execution environments.
///
void ReleaseResources() { return this->ArrayContainer->ReleaseResources(); }
/// \brief Get the number of components in each array value.
///
/// This method will query the array type for the number of components in
/// each value of the array. The number of components is determined by
/// the \c VecTraits::NUM_COMPONENTS trait class.
///
VTKM_CONT
vtkm::IdComponent GetNumberOfComponents() const
{
return this->ArrayContainer->GetNumberOfComponents();
}
/// \brief Get the number of values in the array.
///
VTKM_CONT
vtkm::Id GetNumberOfValues() const { return this->ArrayContainer->GetNumberOfValues(); }
VTKM_CONT
void PrintSummary(std::ostream& out) const { this->ArrayContainer->PrintSummary(out); }
};
/// \brief Holds an array handle without having to specify template parameters.
@ -263,6 +284,18 @@ public:
{
}
VTKM_CONT explicit VariantArrayHandleBase(const vtkm::cont::UnknownArrayHandle& src)
: Superclass(src)
{
}
template <typename StorageList>
VTKM_CONT VariantArrayHandleBase(
const vtkm::cont::UncertainArrayHandle<TypeList, StorageList>& src)
: Superclass(src)
{
}
VTKM_CONT VariantArrayHandleBase(const VariantArrayHandleBase&) = default;
VTKM_CONT VariantArrayHandleBase(VariantArrayHandleBase&&) noexcept = default;
@ -276,7 +309,13 @@ public:
VariantArrayHandleBase<TypeList>& operator=(VariantArrayHandleBase<TypeList>&&) noexcept =
default;
VTKM_CONT operator vtkm::cont::UncertainArrayHandle<TypeList, VTKM_DEFAULT_STORAGE_LIST>() const
{
return vtkm::cont::UncertainArrayHandle<TypeList, VTKM_DEFAULT_STORAGE_LIST>(*this);
}
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
/// Returns this array cast to a \c ArrayHandleVirtual of the given type.
/// This will perform type conversions as necessary, and will log warnings
/// if the conversion is lossy.
@ -285,11 +324,15 @@ public:
/// be specified in the second template parameter, which will be passed to
/// the CastAndCall.
///
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <typename T, typename StorageList = VTKM_DEFAULT_STORAGE_LIST>
VTKM_CONT vtkm::cont::ArrayHandleVirtual<T> AsVirtual() const
VTKM_CONT VTKM_DEPRECATED(1.6, "ArrayHandleVirtual is no longer suported.")
vtkm::cont::ArrayHandleVirtual<T> AsVirtual() const
{
return this->Superclass::AsVirtual<T, StorageList, TypeList>();
}
VTKM_DEPRECATED_SUPPRESS_END
#endif //VTKM_NO_DEPRECATED_VIRTUAL
/// Changes the types to try casting to when resolving this variant array,
/// which is specified with a list tag like those in TypeList.h. Since C++
@ -392,207 +435,6 @@ VTKM_CONT inline ArrayHandleType Cast(const vtkm::cont::VariantArrayHandleBase<T
return variant.template Cast<ArrayHandleType>();
}
//=============================================================================
// Out of class implementations
namespace detail
{
struct VariantArrayHandleTry
{
template <typename T, typename Storage, typename Functor, typename... Args>
void operator()(vtkm::List<T, Storage>,
Functor&& f,
bool& called,
const vtkm::cont::internal::VariantArrayHandleContainerBase& container,
Args&&... args) const
{
using DerivedArrayType = vtkm::cont::ArrayHandle<T, Storage>;
if (!called && vtkm::cont::internal::variant::IsType<DerivedArrayType>(&container))
{
called = true;
const auto* derivedContainer =
static_cast<const vtkm::cont::internal::VariantArrayHandleContainer<T>*>(&container);
DerivedArrayType derivedArray = derivedContainer->Array.template Cast<DerivedArrayType>();
VTKM_LOG_CAST_SUCC(container, derivedArray);
// If you get a compile error here, it means that you have called CastAndCall for a
// vtkm::cont::VariantArrayHandle and the arguments of the functor do not match those
// being passed. This is often because it is calling the functor with an ArrayHandle
// type that was not expected. Either add overloads to the functor to accept all
// possible array types or constrain the types tried for the CastAndCall. Note that
// the functor will be called with an array of type vtkm::cont::ArrayHandle<T, S>.
// Directly using a subclass of ArrayHandle (e.g. vtkm::cont::ArrayHandleConstant<T>)
// might not work.
f(derivedArray, std::forward<Args>(args)...);
}
}
};
template <typename T>
struct IsUndefinedStorage
{
};
template <typename T, typename U>
struct IsUndefinedStorage<vtkm::List<T, U>> : vtkm::cont::internal::IsInvalidArrayHandle<T, U>
{
};
template <typename TypeList, typename StorageList>
using ListDynamicTypes =
vtkm::ListRemoveIf<vtkm::ListCross<TypeList, StorageList>, IsUndefinedStorage>;
} // namespace detail
template <typename TypeList, typename StorageTagList, typename Functor, typename... Args>
VTKM_CONT void VariantArrayHandleCommon::CastAndCall(Functor&& f, Args&&... args) const
{
using crossProduct = detail::ListDynamicTypes<TypeList, StorageTagList>;
bool called = false;
const auto& ref = *this->ArrayContainer;
vtkm::ListForEach(detail::VariantArrayHandleTry{},
crossProduct{},
std::forward<Functor>(f),
called,
ref,
std::forward<Args>(args)...);
if (!called)
{
// throw an exception
VTKM_LOG_CAST_FAIL(*this, TypeList);
detail::ThrowCastAndCallException(ref, typeid(TypeList));
}
}
namespace detail
{
struct VariantArrayHandleTryMultiplexer
{
template <typename T, typename Storage, typename... ArrayTypes>
VTKM_CONT void operator()(const vtkm::cont::ArrayHandle<T, Storage>&,
const vtkm::cont::VariantArrayHandleCommon& self,
vtkm::cont::ArrayHandleMultiplexer<ArrayTypes...>& result) const
{
vtkm::cont::ArrayHandle<T, Storage> targetArray;
bool foundArray = false;
this->FetchArray(targetArray, self, foundArray, result.IsValid());
if (foundArray)
{
result.SetArray(targetArray);
VTKM_LOG_CAST_SUCC(self, result);
}
}
private:
template <typename T, typename Storage>
VTKM_CONT void FetchArrayExact(vtkm::cont::ArrayHandle<T, Storage>& targetArray,
const vtkm::cont::VariantArrayHandleCommon& self,
bool& foundArray) const
{
using ArrayType = vtkm::cont::ArrayHandle<T, Storage>;
if (self.IsType<ArrayType>())
{
targetArray = self.Cast<ArrayType>();
foundArray = true;
}
else
{
foundArray = false;
}
}
template <typename T, typename Storage>
VTKM_CONT void FetchArray(vtkm::cont::ArrayHandle<T, Storage>& targetArray,
const vtkm::cont::VariantArrayHandleCommon& self,
bool& foundArray,
bool vtkmNotUsed(foundArrayInPreviousCall)) const
{
this->FetchArrayExact(targetArray, self, foundArray);
}
// Special condition for transformed arrays. Instead of pulling out the
// transform, pull out the array that is being transformed.
template <typename T, typename SrcArray, typename ForwardTransform, typename ReverseTransform>
VTKM_CONT void FetchArray(
vtkm::cont::ArrayHandle<
T,
vtkm::cont::internal::StorageTagTransform<SrcArray, ForwardTransform, ReverseTransform>>&
targetArray,
const vtkm::cont::VariantArrayHandleCommon& self,
bool& foundArray,
bool foundArrayInPreviousCall) const
{
// Attempt to get the array itself first
this->FetchArrayExact(targetArray, self, foundArray);
// Try to get the array to be transformed first, but only do so if the array was not already
// found in another call to this functor. This is to give precedence to getting the array
// exactly rather than creating our own transform.
if (!foundArray && !foundArrayInPreviousCall)
{
SrcArray srcArray;
this->FetchArray(srcArray, self, foundArray, foundArrayInPreviousCall);
if (foundArray)
{
targetArray =
vtkm::cont::ArrayHandleTransform<SrcArray, ForwardTransform, ReverseTransform>(srcArray);
}
}
}
// Special condition for cast arrays. Instead of pulling out an ArrayHandleCast, pull out
// the array that is being cast.
template <typename TargetT, typename SourceT, typename SourceStorage>
VTKM_CONT void FetchArray(
vtkm::cont::ArrayHandle<TargetT, vtkm::cont::StorageTagCast<SourceT, SourceStorage>>&
targetArray,
const vtkm::cont::VariantArrayHandleCommon& self,
bool& foundArray,
bool foundArrayInPreviousCall) const
{
// Attempt to get the array itself first
this->FetchArrayExact(targetArray, self, foundArray);
// Try to get the array to be transformed first, but only do so if the array was not already
// found in another call to this functor. This is to give precedence to getting the array
// exactly rather than creating our own transform.
if (!foundArray && !foundArrayInPreviousCall)
{
using SrcArray = vtkm::cont::ArrayHandle<SourceT, SourceStorage>;
SrcArray srcArray;
this->FetchArray(srcArray, self, foundArray, foundArrayInPreviousCall);
if (foundArray)
{
targetArray =
vtkm::cont::ArrayHandleCast<TargetT, vtkm::cont::ArrayHandle<SourceT, SourceStorage>>(
srcArray);
}
}
}
};
} // namespace detail
template <typename... T>
inline VTKM_CONT void VariantArrayHandleCommon::AsMultiplexer(
vtkm::cont::ArrayHandleMultiplexer<T...>& result) const
{
// Make sure IsValid is clear
result = vtkm::cont::ArrayHandleMultiplexer<T...>{};
vtkm::ListForEach(detail::VariantArrayHandleTryMultiplexer{}, vtkm::List<T...>{}, *this, result);
if (!result.IsValid())
{
// Could not put the class into the multiplexer. Throw an exception.
VTKM_LOG_CAST_FAIL(*this, vtkm::List<T...>);
detail::ThrowAsMultiplexerException(*this->ArrayContainer, { typeid(T).name()... });
}
}
namespace internal
{
@ -612,72 +454,24 @@ struct DynamicTransformTraits<vtkm::cont::VariantArrayHandleBase<TypeList>>
namespace mangled_diy_namespace
{
namespace internal
{
struct VariantArrayHandleSerializeFunctor
{
template <typename ArrayHandleType>
void operator()(const ArrayHandleType& ah, BinaryBuffer& bb) const
{
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<ArrayHandleType>::Get());
vtkmdiy::save(bb, ah);
}
};
struct VariantArrayHandleDeserializeFunctor
{
template <typename T, typename S, typename TypeList>
void operator()(vtkm::List<T, S>,
vtkm::cont::VariantArrayHandleBase<TypeList>& dh,
const std::string& typeString,
bool& success,
BinaryBuffer& bb) const
{
using ArrayHandleType = vtkm::cont::ArrayHandle<T, S>;
if (!success && (typeString == vtkm::cont::SerializableTypeString<ArrayHandleType>::Get()))
{
ArrayHandleType ah;
vtkmdiy::load(bb, ah);
dh = vtkm::cont::VariantArrayHandleBase<TypeList>(ah);
success = true;
}
}
};
} // internal
template <typename TypeList>
struct Serialization<vtkm::cont::VariantArrayHandleBase<TypeList>>
{
private:
using Type = vtkm::cont::VariantArrayHandleBase<TypeList>;
using ImplObject = vtkm::cont::UncertainArrayHandle<TypeList, VTKM_DEFAULT_STORAGE_LIST>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj)
{
obj.CastAndCall(internal::VariantArrayHandleSerializeFunctor{}, bb);
vtkmdiy::save(bb, ImplObject(obj));
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& obj)
{
std::string typeString;
vtkmdiy::load(bb, typeString);
bool success = false;
vtkm::ListForEach(internal::VariantArrayHandleDeserializeFunctor{},
vtkm::cont::detail::ListDynamicTypes<TypeList, VTKM_DEFAULT_STORAGE_LIST>{},
obj,
typeString,
success,
bb);
if (!success)
{
throw vtkm::cont::ErrorBadType(
"Error deserializing VariantArrayHandle. Message TypeString: " + typeString);
}
ImplObject implObj;
vtkmdiy::load(bb, implObj);
obj = implObj;
}
};

@ -35,6 +35,15 @@ struct TransportTagArrayIn
template <typename ContObjectType, typename Device>
struct Transport<vtkm::cont::arg::TransportTagArrayIn, ContObjectType, Device>
{
// MSVC will issue deprecation warnings here if this template is instantiated with
// a deprecated class even if the template is used from a section of code where
// deprecation warnings are suppressed. This is annoying behavior since this template
// has no control over what class it is used with. To get around it, we have to
// suppress all deprecation warnings here.
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_BEGIN
#endif
VTKM_IS_ARRAY_HANDLE(ContObjectType);
using ExecObjectType = decltype(
@ -54,6 +63,10 @@ struct Transport<vtkm::cont::arg::TransportTagArrayIn, ContObjectType, Device>
return object.PrepareForInput(Device(), token);
}
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_END
#endif
};
}
}

@ -36,6 +36,15 @@ struct TransportTagArrayInOut
template <typename ContObjectType, typename Device>
struct Transport<vtkm::cont::arg::TransportTagArrayInOut, ContObjectType, Device>
{
// MSVC will issue deprecation warnings here if this template is instantiated with
// a deprecated class even if the template is used from a section of code where
// deprecation warnings are suppressed. This is annoying behavior since this template
// has no control over what class it is used with. To get around it, we have to
// suppress all deprecation warnings here.
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_BEGIN
#endif
// If you get a compile error here, it means you tried to use an object that
// is not an array handle as an argument that is expected to be one.
VTKM_IS_ARRAY_HANDLE(ContObjectType);
@ -57,6 +66,10 @@ struct Transport<vtkm::cont::arg::TransportTagArrayInOut, ContObjectType, Device
return object.PrepareForInPlace(Device(), token);
}
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_END
#endif
};
}
}

@ -35,6 +35,15 @@ struct TransportTagArrayOut
template <typename ContObjectType, typename Device>
struct Transport<vtkm::cont::arg::TransportTagArrayOut, ContObjectType, Device>
{
// MSVC will issue deprecation warnings here if this template is instantiated with
// a deprecated class even if the template is used from a section of code where
// deprecation warnings are suppressed. This is annoying behavior since this template
// has no control over what class it is used with. To get around it, we have to
// suppress all deprecation warnings here.
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_BEGIN
#endif
// If you get a compile error here, it means you tried to use an object that
// is not an array handle as an argument that is expected to be one.
VTKM_IS_ARRAY_HANDLE(ContObjectType);
@ -53,6 +62,10 @@ struct Transport<vtkm::cont::arg::TransportTagArrayOut, ContObjectType, Device>
{
return object.PrepareForOutput(outputRange, Device(), token);
}
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_END
#endif
};
}
}

@ -13,8 +13,11 @@
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayHandle.h>
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/StorageVirtual.h>
#endif
#include <vtkm/cont/arg/Transport.h>
@ -64,6 +67,8 @@ struct Transport<vtkm::cont::arg::TransportTagAtomicArray,
}
};
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <typename T, typename Device>
struct Transport<vtkm::cont::arg::TransportTagAtomicArray,
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>,
@ -99,6 +104,8 @@ struct Transport<vtkm::cont::arg::TransportTagAtomicArray,
return obj.PrepareForExecution(Device());
}
};
VTKM_DEPRECATED_SUPPRESS_END
#endif //VTKM_NO_DEPRECATED_VIRTUAL
}
}
} // namespace vtkm::cont::arg

@ -40,6 +40,15 @@ struct TransportTagWholeArrayIn
template <typename ContObjectType, typename Device>
struct Transport<vtkm::cont::arg::TransportTagWholeArrayIn, ContObjectType, Device>
{
// MSVC will issue deprecation warnings here if this template is instantiated with
// a deprecated class even if the template is used from a section of code where
// deprecation warnings are suppressed. This is annoying behavior since this template
// has no control over what class it is used with. To get around it, we have to
// suppress all deprecation warnings here.
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_BEGIN
#endif
// If you get a compile error here, it means you tried to use an object that
// is not an array handle as an argument that is expected to be one.
VTKM_IS_ARRAY_HANDLE(ContObjectType);
@ -62,6 +71,10 @@ struct Transport<vtkm::cont::arg::TransportTagWholeArrayIn, ContObjectType, Devi
return ExecObjectType(array, token);
}
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_END
#endif
};
}
}

@ -42,6 +42,15 @@ struct TransportTagWholeArrayInOut
template <typename ContObjectType, typename Device>
struct Transport<vtkm::cont::arg::TransportTagWholeArrayInOut, ContObjectType, Device>
{
// MSVC will issue deprecation warnings here if this template is instantiated with
// a deprecated class even if the template is used from a section of code where
// deprecation warnings are suppressed. This is annoying behavior since this template
// has no control over what class it is used with. To get around it, we have to
// suppress all deprecation warnings here.
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_BEGIN
#endif
// If you get a compile error here, it means you tried to use an object that
// is not an array handle as an argument that is expected to be one.
VTKM_IS_ARRAY_HANDLE(ContObjectType);
@ -64,6 +73,10 @@ struct Transport<vtkm::cont::arg::TransportTagWholeArrayInOut, ContObjectType, D
return ExecObjectType(array, token);
}
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_END
#endif
};
}
}

@ -42,6 +42,15 @@ struct TransportTagWholeArrayOut
template <typename ContObjectType, typename Device>
struct Transport<vtkm::cont::arg::TransportTagWholeArrayOut, ContObjectType, Device>
{
// MSVC will issue deprecation warnings here if this template is instantiated with
// a deprecated class even if the template is used from a section of code where
// deprecation warnings are suppressed. This is annoying behavior since this template
// has no control over what class it is used with. To get around it, we have to
// suppress all deprecation warnings here.
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_BEGIN
#endif
// If you get a compile error here, it means you tried to use an object that
// is not an array handle as an argument that is expected to be one.
VTKM_IS_ARRAY_HANDLE(ContObjectType);
@ -64,6 +73,10 @@ struct Transport<vtkm::cont::arg::TransportTagWholeArrayOut, ContObjectType, Dev
return ExecObjectType(array, array.GetNumberOfValues(), token);
}
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_END
#endif
};
}
}

@ -15,10 +15,12 @@
#include <vtkm/List.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/StorageVirtual.h>
#include <vtkm/cont/AtomicArray.h>
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/cont/StorageVirtual.h>
#endif //VTKM_NO_DEPRECATED_VIRTUAL
namespace vtkm
{
namespace cont
@ -44,11 +46,15 @@ struct TypeCheck<TypeCheckTagAtomicArray, vtkm::cont::ArrayHandle<T, vtkm::cont:
static constexpr bool value = vtkm::ListHas<vtkm::cont::AtomicArrayTypeList, T>::value;
};
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
VTKM_DEPRECATED_SUPPRESS_BEGIN
template <typename T>
struct TypeCheck<TypeCheckTagAtomicArray, vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>>
{
static constexpr bool value = vtkm::ListHas<vtkm::cont::AtomicArrayTypeList, T>::value;
};
VTKM_DEPRECATED_SUPPRESS_END
#endif //VTKM_NO_DEPRECATED_VIRTUAL
}
}
} // namespace vtkm::cont::arg

@ -12,10 +12,9 @@ set(unit_tests
UnitTestCudaArrayHandle.cu
UnitTestCudaArrayHandleFancy.cu
UnitTestCudaArrayHandleMultiplexer.cu
UnitTestCudaArrayHandleVirtualCoordinates.cu
UnitTestCudaBitField.cu
UnitTestCudaCellLocatorRectilinearGrid.cu
UnitTestCudaCellLocatorUniformBins.cu
UnitTestCudaCellLocatorTwoLevel.cu
UnitTestCudaCellLocatorUniformGrid.cu
UnitTestCudaComputeRange.cu
UnitTestCudaColorTable.cu
@ -26,7 +25,7 @@ set(unit_tests
UnitTestCudaIterators.cu
UnitTestCudaMathEdgeCases.cu
UnitTestCudaShareUserProvidedManagedMemory.cu
UnitTestCudaPointLocatorUniformGrid.cu
UnitTestCudaPointLocatorSparseGrid.cu
UnitTestCudaVirtualObjectHandle.cu
)
vtkm_unit_tests(SOURCES ${unit_tests} LABEL "CUDA" LIBRARIES vtkm_worklet)

@ -1,20 +0,0 @@
//============================================================================
// 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/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h>
int UnitTestCudaArrayHandleVirtualCoordinates(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagCuda{});
return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates<
vtkm::cont::DeviceAdapterTagCuda>::Run(argc, argv);
}

@ -8,12 +8,12 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/testing/TestingCellLocatorUniformBins.h>
#include <vtkm/cont/testing/TestingCellLocatorTwoLevel.h>
int UnitTestCudaCellLocatorUniformBins(int argc, char* argv[])
int UnitTestCudaCellLocatorTwoLevel(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagCuda{});
return vtkm::cont::testing::Testing::Run(
TestingCellLocatorUniformBins<vtkm::cont::DeviceAdapterTagCuda>, argc, argv);
TestingCellLocatorTwoLevel<vtkm::cont::DeviceAdapterTagCuda>, argc, argv);
}

@ -8,12 +8,12 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/testing/TestingPointLocatorUniformGrid.h>
#include <vtkm/cont/testing/TestingPointLocatorSparseGrid.h>
int UnitTestCudaPointLocatorUniformGrid(int argc, char* argv[])
int UnitTestCudaPointLocatorSparseGrid(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagCuda{});
return vtkm::cont::testing::Testing::Run(
TestingPointLocatorUniformGrid<vtkm::cont::DeviceAdapterTagCuda>(), argc, argv);
TestingPointLocatorSparseGrid<vtkm::cont::DeviceAdapterTagCuda>(), argc, argv);
}

@ -768,61 +768,64 @@ void Buffer::Enqueue(const vtkm::cont::Token& token) const
detail::BufferHelper::Enqueue(this->Internals, lock, token);
}
void Buffer::DeepCopy(vtkm::cont::internal::Buffer& dest) const
void Buffer::DeepCopyFrom(const vtkm::cont::internal::Buffer& src) const
{
// A Token should not be declared within the scope of a lock. when the token goes out of scope
// it will attempt to aquire the lock, which is undefined behavior of the thread already has
// the lock.
vtkm::cont::Token token;
{
LockType srcLock = this->Internals->GetLock();
const vtkm::cont::internal::Buffer& dest = *this;
LockType srcLock = src.Internals->GetLock();
LockType destLock = dest.Internals->GetLock();
detail::BufferHelper::WaitToRead(this->Internals, srcLock, token);
detail::BufferHelper::WaitToRead(src.Internals, srcLock, token);
// If we are on a device, copy there.
for (auto&& deviceBuffer : this->Internals->GetDeviceBuffers(srcLock))
for (auto&& deviceBuffer : src.Internals->GetDeviceBuffers(srcLock))
{
if (deviceBuffer.second.UpToDate)
{
detail::BufferHelper::CopyOnDevice(
deviceBuffer.first, this->Internals, srcLock, dest.Internals, destLock, token);
deviceBuffer.first, src.Internals, srcLock, dest.Internals, destLock, token);
return;
}
}
// If we are here, there were no devices to copy on. Copy on host if possible.
if (this->Internals->GetHostBuffer(srcLock).UpToDate)
if (src.Internals->GetHostBuffer(srcLock).UpToDate)
{
detail::BufferHelper::CopyOnHost(this->Internals, srcLock, dest.Internals, destLock, token);
detail::BufferHelper::CopyOnHost(src.Internals, srcLock, dest.Internals, destLock, token);
}
else
{
// Nothing actually allocated. Just create allocation for dest. (Allocation happens lazily.)
detail::BufferHelper::SetNumberOfBytes(dest.Internals,
destLock,
this->Internals->GetNumberOfBytes(srcLock),
src.Internals->GetNumberOfBytes(srcLock),
vtkm::CopyFlag::Off,
token);
if (this->Internals->MetaData)
if (src.Internals->MetaData)
{
dest.Internals->MetaData = this->Internals->MetaData->DeepCopy();
dest.Internals->MetaData = src.Internals->MetaData->DeepCopy();
}
}
}
}
void Buffer::DeepCopy(vtkm::cont::internal::Buffer& dest, vtkm::cont::DeviceAdapterId device) const
void Buffer::DeepCopyFrom(const vtkm::cont::internal::Buffer& src,
vtkm::cont::DeviceAdapterId device) const
{
// A Token should not be declared within the scope of a lock. when the token goes out of scope
// it will attempt to aquire the lock, which is undefined behavior of the thread already has
// the lock.
vtkm::cont::Token token;
{
LockType srcLock = this->Internals->GetLock();
LockType destLock = dest.Internals->GetLock();
LockType srcLock = src.Internals->GetLock();
LockType destLock = this->Internals->GetLock();
detail::BufferHelper::CopyOnDevice(
device, this->Internals, srcLock, dest.Internals, destLock, token);
device, this->Internals, srcLock, this->Internals, destLock, token);
}
}

@ -226,15 +226,15 @@ public:
VTKM_CONT void Enqueue(const vtkm::cont::Token& token) const;
/// @{
/// \brief Copies the data from this buffer to the target buffer.
/// \brief Copies the data from the provided buffer into this buffer.
///
/// If a device is given, then the copy will be preferred for that device. Otherwise, a device
/// already containing the data will be used for the copy. If no such device exists, the host
/// will be used.
///
VTKM_CONT void DeepCopy(vtkm::cont::internal::Buffer& dest) const;
VTKM_CONT void DeepCopy(vtkm::cont::internal::Buffer& dest,
vtkm::cont::DeviceAdapterId device) const;
VTKM_CONT void DeepCopyFrom(const vtkm::cont::internal::Buffer& source) const;
VTKM_CONT void DeepCopyFrom(const vtkm::cont::internal::Buffer& source,
vtkm::cont::DeviceAdapterId device) const;
/// @}
/// \brief Resets the `Buffer` to the memory allocated at the `BufferInfo`.

@ -33,7 +33,6 @@ set(headers
ReverseConnectivityBuilder.h
StorageError.h
TransferInfo.h
VariantArrayHandleContainer.h
VirtualObjectTransfer.h
VirtualObjectTransferInstantiate.h
VirtualObjectTransferShareWithControl.h

@ -1,68 +0,0 @@
//============================================================================
// 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 <sstream>
#include <typeindex>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/internal/VariantArrayHandleContainer.h>
namespace vtkm
{
namespace cont
{
namespace internal
{
VariantArrayHandleContainerBase::VariantArrayHandleContainerBase()
: TypeIndex(typeid(nullptr))
{
}
VariantArrayHandleContainerBase::VariantArrayHandleContainerBase(const std::type_info& typeinfo)
: TypeIndex(typeinfo)
{
}
VariantArrayHandleContainerBase::~VariantArrayHandleContainerBase() {}
}
namespace detail
{
VTKM_CONT_EXPORT void ThrowCastAndCallException(
const vtkm::cont::internal::VariantArrayHandleContainerBase& ref,
const std::type_info& type)
{
std::ostringstream out;
out << "Could not find appropriate cast for array in CastAndCall.\n"
"Array: ";
ref.PrintSummary(out);
out << "TypeList: " << type.name() << "\n";
throw vtkm::cont::ErrorBadValue(out.str());
}
VTKM_CONT_EXPORT void ThrowAsMultiplexerException(
const vtkm::cont::internal::VariantArrayHandleContainerBase& ref,
const std::initializer_list<std::string>& arrayTypes)
{
std::ostringstream out;
out << "Could not find appropriate cast for array in AsMultiplexer.\n"
"Array: ";
ref.PrintSummary(out);
out << "Supported arrays:\n";
for (auto&& type : arrayTypes)
{
out << " " << type << "\n";
}
throw vtkm::cont::ErrorBadValue(out.str());
}
}
}
} // namespace vtkm::cont::detail

@ -1,301 +0,0 @@
//============================================================================
// 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_VariantArrayHandleContainer_h
#define vtk_m_cont_VariantArrayHandleContainer_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/ArrayHandleVirtual.hxx>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/VecTraits.h>
#include <memory>
#include <sstream>
#include <typeindex>
namespace vtkm
{
namespace cont
{
// Forward declaration needed for GetContainer
template <typename TypeList>
class VariantArrayHandleBase;
namespace internal
{
/// \brief Base class for VariantArrayHandleContainer
///
struct VTKM_CONT_EXPORT VariantArrayHandleContainerBase
{
std::type_index TypeIndex;
VariantArrayHandleContainerBase();
explicit VariantArrayHandleContainerBase(const std::type_info& hash);
// This must exist so that subclasses are destroyed correctly.
virtual ~VariantArrayHandleContainerBase();
virtual vtkm::Id GetNumberOfValues() const = 0;
virtual vtkm::IdComponent GetNumberOfComponents() const = 0;
virtual void ReleaseResourcesExecution() = 0;
virtual void ReleaseResources() = 0;
virtual void PrintSummary(std::ostream& out) const = 0;
virtual std::shared_ptr<VariantArrayHandleContainerBase> NewInstance() const = 0;
};
/// \brief ArrayHandle container that can use C++ run-time type information.
///
/// The \c VariantArrayHandleContainer holds ArrayHandle objects
/// (with different template parameters) so that it can polymorphically answer
/// simple questions about the object.
///
template <typename T>
struct VTKM_ALWAYS_EXPORT VariantArrayHandleContainer final : public VariantArrayHandleContainerBase
{
vtkm::cont::ArrayHandleVirtual<T> Array;
mutable vtkm::IdComponent NumberOfComponents = 0;
VariantArrayHandleContainer()
: VariantArrayHandleContainerBase(typeid(T))
, Array()
{
}
VariantArrayHandleContainer(const vtkm::cont::ArrayHandleVirtual<T>& array)
: VariantArrayHandleContainerBase(typeid(T))
, Array(array)
{
}
~VariantArrayHandleContainer<T>() override = default;
vtkm::Id GetNumberOfValues() const override { return this->Array.GetNumberOfValues(); }
vtkm::IdComponent GetNumberOfComponents() const override
{
// Cache number of components to avoid unnecessary device to host transfers of the array.
// Also assumes that the number of components is constant accross all elements and
// throughout the life of the array.
if (this->NumberOfComponents == 0)
{
this->NumberOfComponents =
this->GetNumberOfComponents(typename vtkm::VecTraits<T>::IsSizeStatic{});
}
return this->NumberOfComponents;
}
void ReleaseResourcesExecution() override { this->Array.ReleaseResourcesExecution(); }
void ReleaseResources() override { this->Array.ReleaseResources(); }
void PrintSummary(std::ostream& out) const override
{
vtkm::cont::printSummary_ArrayHandle(this->Array, out);
}
std::shared_ptr<VariantArrayHandleContainerBase> NewInstance() const override
{
return std::make_shared<VariantArrayHandleContainer<T>>(this->Array.NewInstance());
}
private:
vtkm::IdComponent GetNumberOfComponents(VecTraitsTagSizeStatic) const
{
return vtkm::VecTraits<T>::NUM_COMPONENTS;
}
vtkm::IdComponent GetNumberOfComponents(VecTraitsTagSizeVariable) const
{
return (this->Array.GetNumberOfValues() == 0)
? 0
: vtkm::VecTraits<T>::GetNumberOfComponents(this->Array.ReadPortal().Get(0));
}
};
namespace variant
{
// One instance of a template class cannot access the private members of
// another instance of a template class. However, I want to be able to copy
// construct a VariantArrayHandle from another VariantArrayHandle of any other
// type. Since you cannot partially specialize friendship, use this accessor
// class to get at the internals for the copy constructor.
struct GetContainer
{
template <typename TypeList>
VTKM_CONT static const std::shared_ptr<VariantArrayHandleContainerBase>& Extract(
const vtkm::cont::VariantArrayHandleBase<TypeList>& src)
{
return src.ArrayContainer;
}
};
template <typename T>
VTKM_CONT bool IsValueType(const VariantArrayHandleContainerBase* container)
{
if (container == nullptr)
{ //you can't use typeid on nullptr of polymorphic types
return false;
}
//needs optimizations based on platform. !OSX can use typeid
return container->TypeIndex == std::type_index(typeid(T));
// return (nullptr != dynamic_cast<const VariantArrayHandleContainer<T>*>(container));
}
template <typename ArrayHandleType>
VTKM_CONT inline bool IsType(const VariantArrayHandleContainerBase* container)
{ //container could be nullptr
using T = typename ArrayHandleType::ValueType;
if (!IsValueType<T>(container))
{
return false;
}
const auto* derived = static_cast<const VariantArrayHandleContainer<T>*>(container);
return vtkm::cont::IsType<ArrayHandleType>(derived->Array);
}
template <typename T, typename S>
struct VTKM_ALWAYS_EXPORT Caster
{
vtkm::cont::ArrayHandle<T, S> operator()(const VariantArrayHandleContainerBase* container) const
{
//This needs to be reworked
using ArrayHandleType = vtkm::cont::ArrayHandle<T, S>;
if (!IsValueType<T>(container))
{
VTKM_LOG_CAST_FAIL(container, ArrayHandleType);
throwFailedDynamicCast(vtkm::cont::TypeToString(container),
vtkm::cont::TypeToString<ArrayHandleType>());
}
const auto* derived = static_cast<const VariantArrayHandleContainer<T>*>(container);
return vtkm::cont::Cast<vtkm::cont::ArrayHandle<T, S>>(derived->Array);
}
};
template <typename T>
struct VTKM_ALWAYS_EXPORT Caster<T, vtkm::cont::StorageTagVirtual>
{
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual> operator()(
const VariantArrayHandleContainerBase* container) const
{
if (!IsValueType<T>(container))
{
VTKM_LOG_CAST_FAIL(container, vtkm::cont::ArrayHandleVirtual<T>);
throwFailedDynamicCast(vtkm::cont::TypeToString(container),
vtkm::cont::TypeToString<vtkm::cont::ArrayHandleVirtual<T>>());
}
// Technically, this method returns a copy of the \c ArrayHandle. But
// because \c ArrayHandle acts like a shared pointer, it is valid to
// do the copy.
const auto* derived = static_cast<const VariantArrayHandleContainer<T>*>(container);
VTKM_LOG_CAST_SUCC(container, derived->Array);
return derived->Array;
}
};
// MSVC will issue deprecation warnings here if this template is instantiated with
// a deprecated class even if the template is used from a section of code where
// deprecation warnings are suppressed. This is annoying behavior since this template
// has no control over what class it is used with. To get around it, we have to
// suppress all deprecation warnings here.
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_BEGIN
#endif
template <typename ArrayHandleType>
VTKM_CONT ArrayHandleType Cast(const VariantArrayHandleContainerBase* container)
{ //container could be nullptr
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
using Type = typename ArrayHandleType::ValueType;
using Storage = typename ArrayHandleType::StorageTag;
auto ret = Caster<Type, Storage>{}(container);
return ArrayHandleType(std::move(ret));
}
#ifdef VTKM_MSVC
VTKM_DEPRECATED_SUPPRESS_END
#endif
struct ForceCastToVirtual
{
template <typename SrcValueType, typename Storage, typename DstValueType>
VTKM_CONT typename std::enable_if<std::is_same<SrcValueType, DstValueType>::value>::type
operator()(const vtkm::cont::ArrayHandle<SrcValueType, Storage>& input,
vtkm::cont::ArrayHandleVirtual<DstValueType>& output) const
{ // ValueTypes match
output = vtkm::cont::make_ArrayHandleVirtual<DstValueType>(input);
}
template <typename SrcValueType, typename Storage, typename DstValueType>
VTKM_CONT typename std::enable_if<!std::is_same<SrcValueType, DstValueType>::value>::type
operator()(const vtkm::cont::ArrayHandle<SrcValueType, Storage>& input,
vtkm::cont::ArrayHandleVirtual<DstValueType>& output) const
{ // ValueTypes do not match
this->ValidateWidthAndCast<SrcValueType, DstValueType>(input, output);
}
private:
template <typename S,
typename D,
typename InputType,
vtkm::IdComponent SSize = vtkm::VecTraits<S>::NUM_COMPONENTS,
vtkm::IdComponent DSize = vtkm::VecTraits<D>::NUM_COMPONENTS>
VTKM_CONT typename std::enable_if<SSize == DSize>::type ValidateWidthAndCast(
const InputType& input,
vtkm::cont::ArrayHandleVirtual<D>& output) const
{ // number of components match
auto casted = vtkm::cont::make_ArrayHandleCast<D>(input);
output = vtkm::cont::make_ArrayHandleVirtual<D>(casted);
}
template <typename S,
typename D,
vtkm::IdComponent SSize = vtkm::VecTraits<S>::NUM_COMPONENTS,
vtkm::IdComponent DSize = vtkm::VecTraits<D>::NUM_COMPONENTS>
VTKM_CONT typename std::enable_if<SSize != DSize>::type ValidateWidthAndCast(
const ArrayHandleBase&,
ArrayHandleBase&) const
{ // number of components do not match
std::ostringstream str;
str << "VariantArrayHandle::AsVirtual: Cannot cast from " << vtkm::cont::TypeToString<S>()
<< " to " << vtkm::cont::TypeToString<D>()
<< "; "
"number of components must match exactly.";
throw vtkm::cont::ErrorBadType(str.str());
}
};
} // namespace variant
} // namespace internal
namespace detail
{
VTKM_CONT_EXPORT void ThrowCastAndCallException(
const vtkm::cont::internal::VariantArrayHandleContainerBase&,
const std::type_info&);
VTKM_CONT_EXPORT void ThrowAsMultiplexerException(
const vtkm::cont::internal::VariantArrayHandleContainerBase& ref,
const std::initializer_list<std::string>& arrayTypes);
} // namespace detail
}
} //namespace vtkm::cont
#endif

@ -119,7 +119,7 @@ void DoTest()
std::cout << "Copy uninitialized buffer" << std::endl;
{
vtkm::cont::internal::Buffer copy;
buffer.DeepCopy(copy);
copy.DeepCopyFrom(buffer);
VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == 0);
VTKM_TEST_ASSERT(CheckMetaData(copy));
}
@ -135,7 +135,7 @@ void DoTest()
std::cout << "Copy sized but uninitialized buffer" << std::endl;
{
vtkm::cont::internal::Buffer copy;
buffer.DeepCopy(copy);
copy.DeepCopyFrom(buffer);
VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == BUFFER_SIZE);
VTKM_TEST_ASSERT(CheckMetaData(copy));
VTKM_TEST_ASSERT(!copy.IsAllocatedOnHost());
@ -162,7 +162,7 @@ void DoTest()
{
vtkm::cont::Token token;
vtkm::cont::internal::Buffer copy;
buffer.DeepCopy(copy);
copy.DeepCopyFrom(buffer);
VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == BUFFER_SIZE);
VTKM_TEST_ASSERT(CheckMetaData(copy));
VTKM_TEST_ASSERT(copy.IsAllocatedOnHost());
@ -225,7 +225,7 @@ void DoTest()
{
vtkm::cont::Token token;
vtkm::cont::internal::Buffer copy;
buffer.DeepCopy(copy);
copy.DeepCopyFrom(buffer);
VTKM_TEST_ASSERT(copy.GetNumberOfBytes() == BUFFER_SIZE);
VTKM_TEST_ASSERT(CheckMetaData(copy));
VTKM_TEST_ASSERT(!copy.IsAllocatedOnHost());

@ -12,10 +12,9 @@ set(unit_tests
UnitTestKokkosArrayHandle.cxx
UnitTestKokkosArrayHandleFancy.cxx
UnitTestKokkosArrayHandleMultiplexer.cxx
UnitTestKokkosArrayHandleVirtualCoordinates.cxx
UnitTestKokkosBitField.cxx
UnitTestKokkosCellLocatorRectilinearGrid.cxx
UnitTestKokkosCellLocatorUniformBins.cxx
UnitTestKokkosCellLocatorTwoLevel.cxx
UnitTestKokkosCellLocatorUniformGrid.cxx
UnitTestKokkosComputeRange.cxx
UnitTestKokkosColorTable.cxx
@ -23,7 +22,7 @@ set(unit_tests
UnitTestKokkosDataSetSingleType.cxx
UnitTestKokkosDeviceAdapter.cxx
UnitTestKokkosImplicitFunction.cxx
UnitTestKokkosPointLocatorUniformGrid.cxx
UnitTestKokkosPointLocatorSparseGrid.cxx
UnitTestKokkosVirtualObjectHandle.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests} LABEL "KOKKOS" LIBRARIES vtkm_worklet)

@ -1,20 +0,0 @@
//============================================================================
// 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/kokkos/DeviceAdapterKokkos.h>
#include <vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h>
int UnitTestKokkosArrayHandleVirtualCoordinates(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagKokkos{});
return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates<
vtkm::cont::DeviceAdapterTagKokkos>::Run(argc, argv);
}

@ -8,12 +8,12 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/testing/TestingCellLocatorUniformBins.h>
#include <vtkm/cont/testing/TestingCellLocatorTwoLevel.h>
int UnitTestKokkosCellLocatorUniformBins(int argc, char* argv[])
int UnitTestKokkosCellLocatorTwoLevel(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagKokkos{});
return vtkm::cont::testing::Testing::Run(
TestingCellLocatorUniformBins<vtkm::cont::DeviceAdapterTagKokkos>, argc, argv);
TestingCellLocatorTwoLevel<vtkm::cont::DeviceAdapterTagKokkos>, argc, argv);
}

@ -8,12 +8,12 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/testing/TestingPointLocatorUniformGrid.h>
#include <vtkm/cont/testing/TestingPointLocatorSparseGrid.h>
int UnitTestKokkosPointLocatorUniformGrid(int argc, char* argv[])
int UnitTestKokkosPointLocatorSparseGrid(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagKokkos{});
return vtkm::cont::testing::Testing::Run(
TestingPointLocatorUniformGrid<vtkm::cont::DeviceAdapterTagKokkos>(), argc, argv);
TestingPointLocatorSparseGrid<vtkm::cont::DeviceAdapterTagKokkos>(), argc, argv);
}

@ -379,9 +379,9 @@ struct ReduceHelper
// This gives faster code for floats and non-trivial types.
template <typename ReturnType, typename IterType, typename FunctorType>
static ReturnType DoParallelReduction(IterType data,
vtkm::Id numVals,
int tid,
int numThreads,
const vtkm::Id& numVals,
const int& tid,
const int& numThreads,
FunctorType f,
std::false_type /* isIntegral */)
{
@ -389,18 +389,24 @@ struct ReduceHelper
ReturnType accum = f(data[2 * tid], data[2 * tid + 1]);
const vtkm::Id offset = numThreads * 2;
const vtkm::Id end = std::max(vtkm::Id(((numVals / 4) * 4) - 4), offset);
const vtkm::Id end = std::max(((numVals / 4) * 4) - 4, offset);
const vtkm::Id unrollEnd = end - ((end - offset) % 4);
vtkm::Id i = offset;
// When initializing the looping iterator to a non integral type, intel compilers will
// convert the iterator type to an unsigned value
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
VTKM_OPENMP_DIRECTIVE(for schedule(static))
for (i = offset; i < unrollEnd; i += 4)
#pragma GCC diagnostic pop
{
const auto t1 = f(data[i], data[i + 1]);
const auto t2 = f(data[i + 2], data[i + 3]);
accum = f(accum, t1);
accum = f(accum, t2);
}
// Let the last thread mop up any remaining values as it would
// have just accessed the adjacent data
if (tid == numThreads - 1)
@ -418,18 +424,21 @@ struct ReduceHelper
// hurt performance.
template <typename ReturnType, typename IterType, typename FunctorType>
static ReturnType DoParallelReduction(IterType data,
vtkm::Id numVals,
int tid,
int numThreads,
const vtkm::Id& numVals,
const int& tid,
const int& numThreads,
FunctorType f,
std::true_type /* isIntegral */)
{
// Use the first (numThreads*2) values for initializing:
ReturnType accum = f(data[2 * tid], data[2 * tid + 1]);
// Assign each thread chunks of the remaining values for local reduction
// Assign each thread chunks of the remaining values for local reduction
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-conversion"
VTKM_OPENMP_DIRECTIVE(for schedule(static))
for (vtkm::Id i = numThreads * 2; i < numVals; i++)
#pragma GCC diagnostic pop
{
accum = f(accum, data[i]);
}

@ -12,10 +12,9 @@ set(unit_tests
UnitTestOpenMPArrayHandle.cxx
UnitTestOpenMPArrayHandleFancy.cxx
UnitTestOpenMPArrayHandleMultiplexer.cxx
UnitTestOpenMPArrayHandleVirtualCoordinates.cxx
UnitTestOpenMPBitField.cxx
UnitTestOpenMPCellLocatorRectilinearGrid.cxx
UnitTestOpenMPCellLocatorUniformBins.cxx
UnitTestOpenMPCellLocatorTwoLevel.cxx
UnitTestOpenMPCellLocatorUniformGrid.cxx
UnitTestOpenMPColorTable.cxx
UnitTestOpenMPComputeRange.cxx
@ -23,7 +22,7 @@ set(unit_tests
UnitTestOpenMPDataSetSingleType.cxx
UnitTestOpenMPDeviceAdapter.cxx
UnitTestOpenMPImplicitFunction.cxx
UnitTestOpenMPPointLocatorUniformGrid.cxx
UnitTestOpenMPPointLocatorSparseGrid.cxx
UnitTestOpenMPVirtualObjectHandle.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests}

@ -1,19 +0,0 @@
//============================================================================
// 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/openmp/DeviceAdapterOpenMP.h>
#include <vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h>
int UnitTestOpenMPArrayHandleVirtualCoordinates(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagOpenMP{});
return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates<
vtkm::cont::DeviceAdapterTagOpenMP>::Run(argc, argv);
}

@ -8,12 +8,12 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/openmp/DeviceAdapterOpenMP.h>
#include <vtkm/cont/testing/TestingCellLocatorUniformBins.h>
#include <vtkm/cont/testing/TestingCellLocatorTwoLevel.h>
int UnitTestOpenMPCellLocatorUniformBins(int argc, char* argv[])
int UnitTestOpenMPCellLocatorTwoLevel(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagOpenMP{});
return vtkm::cont::testing::Testing::Run(
TestingCellLocatorUniformBins<vtkm::cont::DeviceAdapterTagOpenMP>, argc, argv);
TestingCellLocatorTwoLevel<vtkm::cont::DeviceAdapterTagOpenMP>, argc, argv);
}

@ -8,12 +8,12 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/openmp/DeviceAdapterOpenMP.h>
#include <vtkm/cont/testing/TestingPointLocatorUniformGrid.h>
#include <vtkm/cont/testing/TestingPointLocatorSparseGrid.h>
int UnitTestOpenMPPointLocatorUniformGrid(int argc, char* argv[])
int UnitTestOpenMPPointLocatorSparseGrid(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagOpenMP{});
return vtkm::cont::testing::Testing::Run(
TestingPointLocatorUniformGrid<vtkm::cont::DeviceAdapterTagOpenMP>(), argc, argv);
TestingPointLocatorSparseGrid<vtkm::cont::DeviceAdapterTagOpenMP>(), argc, argv);
}

@ -12,10 +12,9 @@ set(unit_tests
UnitTestSerialArrayHandle.cxx
UnitTestSerialArrayHandleFancy.cxx
UnitTestSerialArrayHandleMultiplexer.cxx
UnitTestSerialArrayHandleVirtualCoordinates.cxx
UnitTestSerialBitField.cxx
UnitTestSerialCellLocatorRectilinearGrid.cxx
UnitTestSerialCellLocatorUniformBins.cxx
UnitTestSerialCellLocatorTwoLevel.cxx
UnitTestSerialCellLocatorUniformGrid.cxx
UnitTestSerialComputeRange.cxx
UnitTestSerialColorTable.cxx
@ -23,7 +22,7 @@ set(unit_tests
UnitTestSerialDataSetSingleType.cxx
UnitTestSerialDeviceAdapter.cxx
UnitTestSerialImplicitFunction.cxx
UnitTestSerialPointLocatorUniformGrid.cxx
UnitTestSerialPointLocatorSparseGrid.cxx
UnitTestSerialVirtualObjectHandle.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests}

@ -1,21 +0,0 @@
//============================================================================
// 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/RuntimeDeviceTracker.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h>
int UnitTestSerialArrayHandleVirtualCoordinates(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagSerial{});
return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates<
vtkm::cont::DeviceAdapterTagSerial>::Run(argc, argv);
}

@ -9,12 +9,12 @@
//============================================================================
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/testing/TestingCellLocatorUniformBins.h>
#include <vtkm/cont/testing/TestingCellLocatorTwoLevel.h>
int UnitTestSerialCellLocatorUniformBins(int argc, char* argv[])
int UnitTestSerialCellLocatorTwoLevel(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagSerial{});
return vtkm::cont::testing::Testing::Run(
TestingCellLocatorUniformBins<vtkm::cont::DeviceAdapterTagSerial>, argc, argv);
TestingCellLocatorTwoLevel<vtkm::cont::DeviceAdapterTagSerial>, argc, argv);
}

@ -8,12 +8,12 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/testing/TestingPointLocatorUniformGrid.h>
#include <vtkm/cont/testing/TestingPointLocatorSparseGrid.h>
int UnitTestSerialPointLocatorUniformGrid(int argc, char* argv[])
int UnitTestSerialPointLocatorSparseGrid(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagSerial{});
return vtkm::cont::testing::Testing::Run(
TestingPointLocatorUniformGrid<vtkm::cont::DeviceAdapterTagSerial>(), argc, argv);
TestingPointLocatorSparseGrid<vtkm::cont::DeviceAdapterTagSerial>(), argc, argv);
}

@ -12,10 +12,9 @@ set(unit_tests
UnitTestTBBArrayHandle.cxx
UnitTestTBBArrayHandleFancy.cxx
UnitTestTBBArrayHandleMultiplexer.cxx
UnitTestTBBArrayHandleVirtualCoordinates.cxx
UnitTestTBBBitField.cxx
UnitTestTBBCellLocatorRectilinearGrid.cxx
UnitTestTBBCellLocatorUniformBins.cxx
UnitTestTBBCellLocatorTwoLevel.cxx
UnitTestTBBCellLocatorUniformGrid.cxx
UnitTestTBBColorTable.cxx
UnitTestTBBComputeRange.cxx
@ -23,7 +22,7 @@ set(unit_tests
UnitTestTBBDataSetSingleType.cxx
UnitTestTBBDeviceAdapter.cxx
UnitTestTBBImplicitFunction.cxx
UnitTestTBBPointLocatorUniformGrid.cxx
UnitTestTBBPointLocatorSparseGrid.cxx
UnitTestTBBVirtualObjectHandle.cxx
)

@ -1,20 +0,0 @@
//============================================================================
// 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/tbb/DeviceAdapterTBB.h>
#include <vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h>
int UnitTestTBBArrayHandleVirtualCoordinates(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagTBB{});
return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates<
vtkm::cont::DeviceAdapterTagTBB>::Run(argc, argv);
}

@ -8,12 +8,12 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/testing/TestingCellLocatorUniformBins.h>
#include <vtkm/cont/testing/TestingCellLocatorTwoLevel.h>
int UnitTestTBBCellLocatorUniformBins(int argc, char* argv[])
int UnitTestTBBCellLocatorTwoLevel(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagTBB{});
return vtkm::cont::testing::Testing::Run(
TestingCellLocatorUniformBins<vtkm::cont::DeviceAdapterTagTBB>, argc, argv);
TestingCellLocatorTwoLevel<vtkm::cont::DeviceAdapterTagTBB>, argc, argv);
}

@ -8,12 +8,12 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/testing/TestingPointLocatorUniformGrid.h>
#include <vtkm/cont/testing/TestingPointLocatorSparseGrid.h>
int UnitTestTBBPointLocatorUniformGrid(int argc, char* argv[])
int UnitTestTBBPointLocatorSparseGrid(int argc, char* argv[])
{
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
tracker.ForceDevice(vtkm::cont::DeviceAdapterTagTBB{});
return vtkm::cont::testing::Testing::Run(
TestingPointLocatorUniformGrid<vtkm::cont::DeviceAdapterTagTBB>(), argc, argv);
TestingPointLocatorSparseGrid<vtkm::cont::DeviceAdapterTagTBB>(), argc, argv);
}

@ -14,9 +14,8 @@ set(headers
Testing.h
TestingArrayHandles.h
TestingArrayHandleMultiplexer.h
TestingArrayHandleVirtualCoordinates.h
TestingCellLocatorRectilinearGrid.h
TestingCellLocatorUniformBins.h
TestingCellLocatorTwoLevel.h
TestingCellLocatorUniformGrid.h
TestingColorTable.h
TestingComputeRange.h
@ -25,7 +24,7 @@ set(headers
TestingDataSetSingleType.h
TestingFancyArrayHandles.h
TestingImplicitFunction.h
TestingPointLocatorUniformGrid.h
TestingPointLocatorSparseGrid.h
TestingSerialization.h
TestingVirtualObjectHandle.h
)
@ -88,6 +87,7 @@ set(unit_tests
UnitTestTimer.cxx
UnitTestToken.cxx
UnitTestTryExecute.cxx
UnitTestUnknownArrayHandle.cxx
UnitTestVariantArrayHandle.cxx
)

@ -43,12 +43,14 @@ public:
vtkm::cont::DataSet Make2DUniformDataSet0();
vtkm::cont::DataSet Make2DUniformDataSet1();
vtkm::cont::DataSet Make2DUniformDataSet2();
vtkm::cont::DataSet Make2DUniformDataSet3();
// 3D uniform datasets.
vtkm::cont::DataSet Make3DUniformDataSet0();
vtkm::cont::DataSet Make3DUniformDataSet1();
vtkm::cont::DataSet Make3DUniformDataSet2();
vtkm::cont::DataSet Make3DUniformDataSet3(const vtkm::Id3 dims = vtkm::Id3(10));
vtkm::cont::DataSet Make3DUniformDataSet4();
vtkm::cont::DataSet Make3DRegularDataSet0();
vtkm::cont::DataSet Make3DRegularDataSet1();
@ -177,7 +179,7 @@ inline vtkm::cont::DataSet MakeTestDataSet::Make2DUniformDataSet0()
return dataSet;
}
//Make a simple 2D, 16 cell uniform dataset.
//Make a simple 2D, 16 cell uniform dataset (5x5.txt)
inline vtkm::cont::DataSet MakeTestDataSet::Make2DUniformDataSet1()
{
vtkm::cont::DataSetBuilderUniform dsb;
@ -233,6 +235,29 @@ inline vtkm::cont::DataSet MakeTestDataSet::Make2DUniformDataSet2()
return dataSet;
}
//Make a simple 2D, 56 cell uniform dataset. (8x9test.txt)
inline vtkm::cont::DataSet MakeTestDataSet::Make2DUniformDataSet3()
{
vtkm::cont::DataSetBuilderUniform dsb;
constexpr vtkm::Id2 dimensions(9, 8);
vtkm::cont::DataSet dataSet = dsb.Create(dimensions);
constexpr vtkm::Id nVerts = 72;
constexpr vtkm::Float32 pointvar[nVerts] = {
29.0f, 37.0f, 39.0f, 70.0f, 74.0f, 84.0f, 38.0f, 36.0f, 26.0f, 27.0f, 100.0f, 49.0f,
72.0f, 85.0f, 89.0f, 83.0f, 28.0f, 24.0f, 25.0f, 47.0f, 50.0f, 73.0f, 86.0f, 90.0f,
71.0f, 82.0f, 22.0f, 23.0f, 75.0f, 79.0f, 48.0f, 69.0f, 87.0f, 88.0f, 81.0f, 18.0f,
19.0f, 76.0f, 80.0f, 78.0f, 46.0f, 68.0f, 67.0f, 40.0f, 16.0f, 17.0f, 41.0f, 77.0f,
45.0f, 35.0f, 20.0f, 21.0f, 32.0f, 15.0f, 13.0f, 42.0f, 43.0f, 44.0f, 34.0f, 33.0f,
31.0f, 30.0f, 14.0f, 12.0f, 11.0f, 10.0f, 9.0f, 8.0f, 7.0f, 6.0f, 5.0f, 0.0f
};
dataSet.AddPointField("pointvar", pointvar, nVerts);
return dataSet;
}
//Make a simple 3D, 4 cell uniform dataset.
inline vtkm::cont::DataSet MakeTestDataSet::Make3DUniformDataSet0()
{
@ -254,7 +279,7 @@ inline vtkm::cont::DataSet MakeTestDataSet::Make3DUniformDataSet0()
return dataSet;
}
//Make a simple 3D, 64 cell uniform dataset.
//Make a simple 3D, 64 cell uniform dataset. (5b 5x5x5)
inline vtkm::cont::DataSet MakeTestDataSet::Make3DUniformDataSet1()
{
vtkm::cont::DataSetBuilderUniform dsb;
@ -372,6 +397,39 @@ inline vtkm::cont::DataSet MakeTestDataSet::Make3DUniformDataSet3(const vtkm::Id
return dataSet;
}
//Make a simple 3D, 120 cell uniform dataset. (This is the data set from
//Make3DUniformDataSet1 upsampled from 5x5x to 5x6x7.)
inline vtkm::cont::DataSet MakeTestDataSet::Make3DUniformDataSet4()
{
vtkm::cont::DataSetBuilderUniform dsb;
constexpr vtkm::Id3 dimensions(5, 6, 7);
vtkm::cont::DataSet dataSet = dsb.Create(dimensions);
constexpr vtkm::Id nVerts = 210;
constexpr vtkm::Float32 pointvar[nVerts] = {
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.53f, 0.48f, 0.45f,
0.0f, 0.0f, 0.64f, 0.56f, 0.61f, 0.0f, 0.0f, 0.61f, 0.56f, 0.64f, 0.0f, 0.0f, 0.45f,
0.48f, 0.53f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.73f, 0.61f, 0.63f, 0.0f, 0.0f, 0.85f, 0.66f, 0.78f, 0.0f, 0.0f, 0.80f, 0.64f,
0.83f, 0.0f, 0.0f, 0.61f, 0.59f, 0.71f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.60f, 0.40f, 0.53f, 0.0f, 0.0f, 0.63f, 0.29f, 0.53f,
0.0f, 0.0f, 0.57f, 0.25f, 0.55f, 0.0f, 0.0f, 0.48f, 0.32f, 0.56f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.72f, 0.60f, 0.61f, 0.0f,
0.0f, 0.84f, 0.64f, 0.76f, 0.0f, 0.0f, 0.78f, 0.62f, 0.81f, 0.0f, 0.0f, 0.60f, 0.57f,
0.70f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.52f, 0.46f, 0.44f, 0.0f, 0.0f, 0.63f, 0.54f, 0.59f, 0.0f, 0.0f, 0.59f, 0.54f, 0.63f,
0.0f, 0.0f, 0.44f, 0.46f, 0.52f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f
};
dataSet.AddPointField("pointvar", pointvar, nVerts);
return dataSet;
}
inline vtkm::cont::DataSet MakeTestDataSet::Make2DRectilinearDataSet0()
{
vtkm::cont::DataSetBuilderRectilinear dsb;

@ -22,6 +22,7 @@
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/UnknownArrayHandle.h>
#include <vtkm/cont/VariantArrayHandle.h>
#include <vtkm/thirdparty/diy/diy.h>
@ -380,6 +381,39 @@ struct TestEqualArrayHandle
{
array2.CastAndCall(*this, array1, result);
}
template <typename T, typename StorageTag>
VTKM_CONT void operator()(const vtkm::cont::ArrayHandle<T, StorageTag>& array1,
const vtkm::cont::UnknownArrayHandle& array2,
TestEqualResult& result) const
{
array2.CastAndCallForTypes<vtkm::List<T>, vtkm::List<VTKM_DEFAULT_STORAGE_TAG, StorageTag>>(
*this, array1, result);
}
template <typename T, typename StorageTag>
VTKM_CONT void operator()(const vtkm::cont::UnknownArrayHandle& array1,
const vtkm::cont::ArrayHandle<T, StorageTag>& array2,
TestEqualResult& result) const
{
array1.CastAndCallForTypes<vtkm::List<T>, vtkm::List<VTKM_DEFAULT_STORAGE_TAG, StorageTag>>(
*this, array2, result);
}
VTKM_CONT void operator()(const vtkm::cont::UnknownArrayHandle& array1,
const vtkm::cont::UnknownArrayHandle& array2,
TestEqualResult& result) const
{
array2.CastAndCallForTypes<vtkm::TypeListAll, VTKM_DEFAULT_STORAGE_LIST>(*this, array1, result);
}
template <typename TypeList, typename StorageList>
VTKM_CONT void operator()(const vtkm::cont::UncertainArrayHandle<TypeList, StorageList>& array1,
const vtkm::cont::UncertainArrayHandle<TypeList, StorageList>& array2,
TestEqualResult& result) const
{
array2.CastAndCall(*this, array1, result);
}
};
} // detail

@ -1,152 +0,0 @@
//============================================================================
// 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_testing_TestingArrayHandleVirtualCoordinates_h
#define vtk_m_cont_testing_TestingArrayHandleVirtualCoordinates_h
// This is testing deprecated functionality. It is left to make sure that old code
// still works, but will be removed if ArrayHandleVirtualCoordinates is removed.
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
VTKM_DEPRECATED_SUPPRESS_BEGIN
namespace vtkm
{
namespace cont
{
namespace testing
{
namespace
{
struct CopyWorklet : public vtkm::worklet::WorkletMapField
{
using ControlSignature = void(FieldIn in, FieldOut out);
using ExecutionSignature = _2(_1);
template <typename T>
VTKM_EXEC T operator()(const T& in) const
{
return in;
}
};
// A dummy worklet
struct DoubleWorklet : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn in);
typedef void ExecutionSignature(_1);
using InputDomain = _1;
template <typename T>
VTKM_EXEC void operator()(T& in) const
{
in = in * 2;
}
};
template <typename T, typename S>
inline void TestVirtualAccess(const vtkm::cont::ArrayHandle<T, S>& in,
vtkm::cont::ArrayHandle<T>& out)
{
vtkm::worklet::DispatcherMapField<CopyWorklet>().Invoke(
vtkm::cont::ArrayHandleVirtualCoordinates(in), vtkm::cont::ArrayHandleVirtualCoordinates(out));
VTKM_TEST_ASSERT(test_equal_portals(in.ReadPortal(), out.ReadPortal()),
"Input and output portals don't match");
}
} // anonymous namespace
template <typename DeviceAdapter>
class TestingArrayHandleVirtualCoordinates
{
private:
using ArrayHandleRectilinearCoords =
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>;
static void TestAll()
{
using PointType = vtkm::Vec3f;
static constexpr vtkm::Id length = 64;
vtkm::cont::ArrayHandle<PointType> out;
std::cout << "Testing basic ArrayHandle as input\n";
vtkm::cont::ArrayHandle<PointType> a1;
a1.Allocate(length);
for (vtkm::Id i = 0; i < length; ++i)
{
a1.WritePortal().Set(i, TestValue(i, PointType()));
}
TestVirtualAccess(a1, out);
std::cout << "Testing ArrayHandleUniformPointCoordinates as input\n";
auto t = vtkm::cont::ArrayHandleUniformPointCoordinates(vtkm::Id3(4, 4, 4));
TestVirtualAccess(t, out);
std::cout << "Testing ArrayHandleCartesianProduct as input\n";
vtkm::cont::ArrayHandle<vtkm::FloatDefault> c1, c2, c3;
c1.Allocate(length);
c2.Allocate(length);
c3.Allocate(length);
auto portal = a1.ReadPortal();
for (vtkm::Id i = 0; i < length; ++i)
{
auto p = portal.Get(i);
c1.WritePortal().Set(i, p[0]);
c2.WritePortal().Set(i, p[1]);
c3.WritePortal().Set(i, p[2]);
}
TestVirtualAccess(vtkm::cont::make_ArrayHandleCartesianProduct(c1, c2, c3), out);
std::cout << "Testing resources releasing on ArrayHandleVirtualCoordinates\n";
vtkm::cont::ArrayHandleVirtualCoordinates virtualC =
vtkm::cont::ArrayHandleVirtualCoordinates(a1);
vtkm::worklet::DispatcherMapField<DoubleWorklet>().Invoke(a1);
virtualC.ReleaseResourcesExecution();
VTKM_TEST_ASSERT(a1.GetNumberOfValues() == length,
"ReleaseResourcesExecution"
" should not change the number of values on the Arrayhandle");
VTKM_TEST_ASSERT(
virtualC.GetNumberOfValues() == length,
"ReleaseResources"
" should set the number of values on the ArrayHandleVirtualCoordinates to be 0");
virtualC.ReleaseResources();
VTKM_TEST_ASSERT(a1.GetNumberOfValues() == 0,
"ReleaseResources"
" should set the number of values on the Arrayhandle to be 0");
}
public:
static int Run(int argc, char* argv[])
{
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(DeviceAdapter());
return vtkm::cont::testing::Testing::Run(TestAll, argc, argv);
}
};
}
}
} // vtkm::cont::testing
VTKM_DEPRECATED_SUPPRESS_END
#endif // vtk_m_cont_testing_TestingArrayHandleVirtualCoordinates_h

@ -7,11 +7,11 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_cont_testing_TestingCellLocatorUniformBins_h
#define vtk_m_cont_testing_TestingCellLocatorUniformBins_h
#ifndef vtk_m_cont_testing_TestingCellLocatorTwoLevel_h
#define vtk_m_cont_testing_TestingCellLocatorTwoLevel_h
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/CellLocatorUniformBins.h>
#include <vtkm/cont/CellLocatorTwoLevel.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/cont/testing/Testing.h>
@ -188,7 +188,7 @@ void TestCellLocator(const vtkm::Vec<vtkm::Id, DIMENSIONS>& dim, vtkm::Id number
std::cout << "Testing " << DIMENSIONS << "D dataset with " << ds.GetNumberOfCells() << " cells\n";
vtkm::cont::CellLocatorUniformBins locator;
vtkm::cont::CellLocatorTwoLevel locator;
locator.SetDensityL1(64.0f);
locator.SetDensityL2(1.0f);
locator.SetCellSet(ds.GetCellSet());
@ -222,7 +222,7 @@ void TestCellLocator(const vtkm::Vec<vtkm::Id, DIMENSIONS>& dim, vtkm::Id number
} // anonymous
template <typename DeviceAdapter>
void TestingCellLocatorUniformBins()
void TestingCellLocatorTwoLevel()
{
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(DeviceAdapter());
@ -234,4 +234,4 @@ void TestingCellLocatorUniformBins()
TestCellLocator(vtkm::Id2(18), 512); // 2D dataset
}
#endif // vtk_m_cont_testing_TestingCellLocatorUniformBins_h
#endif // vtk_m_cont_testing_TestingCellLocatorTwoLevel_h

@ -12,15 +12,13 @@
#include <vtkm/Types.h>
#include <vtkm/cont/ColorTable.h>
#include <vtkm/cont/ColorTableMap.h>
#include <vtkm/cont/ColorTableSamples.h>
#include <vtkm/cont/testing/Testing.h>
// Required for implementation of ArrayRangeCompute for "odd" arrays
#include <vtkm/cont/ArrayRangeCompute.hxx>
// Required for implementation of ColorTable
#include <vtkm/cont/ColorTable.hxx>
#include <algorithm>
#include <iostream>
@ -59,9 +57,9 @@ public:
vtkm::Range range{ 0.0, 1.0 };
vtkm::Vec<float, 3> rgb1{ 0.0f, 0.0f, 0.0f };
vtkm::Vec<float, 3> rgb2{ 1.0f, 1.0f, 1.0f };
auto rgbspace = vtkm::cont::ColorSpace::RGB;
auto hsvspace = vtkm::cont::ColorSpace::HSV;
auto diverging = vtkm::cont::ColorSpace::DIVERGING;
auto rgbspace = vtkm::ColorSpace::RGB;
auto hsvspace = vtkm::ColorSpace::HSV;
auto diverging = vtkm::ColorSpace::Diverging;
vtkm::cont::ColorTable table(rgbspace);
VTKM_TEST_ASSERT(table.GetColorSpace() == rgbspace, "color space not saved");
@ -90,10 +88,10 @@ public:
static void TestLoadPresets()
{
vtkm::Range range{ 0.0, 1.0 };
auto rgbspace = vtkm::cont::ColorSpace::RGB;
auto hsvspace = vtkm::cont::ColorSpace::HSV;
auto labspace = vtkm::cont::ColorSpace::LAB;
auto diverging = vtkm::cont::ColorSpace::DIVERGING;
auto rgbspace = vtkm::ColorSpace::RGB;
auto hsvspace = vtkm::ColorSpace::HSV;
auto labspace = vtkm::ColorSpace::Lab;
auto diverging = vtkm::ColorSpace::Diverging;
{
vtkm::cont::ColorTable table(rgbspace);
@ -103,7 +101,7 @@ public:
VTKM_TEST_ASSERT(table.GetRange() == range, "color range not correct after loading preset");
VTKM_TEST_ASSERT(table.GetNumberOfPoints() == 3);
VTKM_TEST_ASSERT(table.LoadPreset(vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED));
VTKM_TEST_ASSERT(table.LoadPreset(vtkm::cont::ColorTable::Preset::CoolToWarmExtended));
VTKM_TEST_ASSERT(table.GetColorSpace() == labspace,
"color space not switched when loading preset");
VTKM_TEST_ASSERT(table.GetRange() == range, "color range not correct after loading preset");
@ -140,24 +138,24 @@ public:
VTKM_TEST_ASSERT(table.GetNumberOfPoints() > 0, "Issue loading preset ", name);
}
auto presetEnum = { vtkm::cont::ColorTable::Preset::DEFAULT,
vtkm::cont::ColorTable::Preset::COOL_TO_WARM,
vtkm::cont::ColorTable::Preset::COOL_TO_WARM_EXTENDED,
vtkm::cont::ColorTable::Preset::VIRIDIS,
vtkm::cont::ColorTable::Preset::INFERNO,
vtkm::cont::ColorTable::Preset::PLASMA,
vtkm::cont::ColorTable::Preset::BLACK_BODY_RADIATION,
vtkm::cont::ColorTable::Preset::X_RAY,
vtkm::cont::ColorTable::Preset::GREEN,
vtkm::cont::ColorTable::Preset::BLACK_BLUE_WHITE,
vtkm::cont::ColorTable::Preset::BLUE_TO_ORANGE,
vtkm::cont::ColorTable::Preset::GRAY_TO_RED,
vtkm::cont::ColorTable::Preset::COLD_AND_HOT,
vtkm::cont::ColorTable::Preset::BLUE_GREEN_ORANGE,
vtkm::cont::ColorTable::Preset::YELLOW_GRAY_BLUE,
vtkm::cont::ColorTable::Preset::RAINBOW_UNIFORM,
vtkm::cont::ColorTable::Preset::JET,
vtkm::cont::ColorTable::Preset::RAINBOW_DESATURATED };
auto presetEnum = { vtkm::cont::ColorTable::Preset::Default,
vtkm::cont::ColorTable::Preset::CoolToWarm,
vtkm::cont::ColorTable::Preset::CoolToWarmExtended,
vtkm::cont::ColorTable::Preset::Viridis,
vtkm::cont::ColorTable::Preset::Inferno,
vtkm::cont::ColorTable::Preset::Plasma,
vtkm::cont::ColorTable::Preset::BlackBodyRadiation,
vtkm::cont::ColorTable::Preset::XRay,
vtkm::cont::ColorTable::Preset::Green,
vtkm::cont::ColorTable::Preset::BlackBlueWhite,
vtkm::cont::ColorTable::Preset::BlueToOrange,
vtkm::cont::ColorTable::Preset::GrayToRed,
vtkm::cont::ColorTable::Preset::ColdAndHot,
vtkm::cont::ColorTable::Preset::BlueGreenOrange,
vtkm::cont::ColorTable::Preset::YellowGrayBlue,
vtkm::cont::ColorTable::Preset::RainbowUniform,
vtkm::cont::ColorTable::Preset::Jet,
vtkm::cont::ColorTable::Preset::RainbowDesaturated };
for (vtkm::cont::ColorTable::Preset preset : presetEnum)
{
vtkm::cont::ColorTable table(preset);
@ -172,7 +170,7 @@ public:
vtkm::Range range{ 0.0, 1.0 };
vtkm::Vec<float, 3> rgb1{ 0.0f, 1.0f, 0.0f };
vtkm::Vec<float, 3> rgb2{ 1.0f, 0.0f, 1.0f };
auto rgbspace = vtkm::cont::ColorSpace::RGB;
auto rgbspace = vtkm::ColorSpace::RGB;
vtkm::cont::ColorTable table(range, rgb1, rgb2, rgbspace);
VTKM_TEST_ASSERT(table.GetClamping() == true, "clamping not setup properly");
@ -180,7 +178,7 @@ public:
auto field = vtkm::cont::make_ArrayHandle({ -1, 0, 1, 2 });
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8> colors;
const bool ran = table.Map(field, colors);
const bool ran = vtkm::cont::ColorTableMap(field, table, colors);
VTKM_TEST_ASSERT(ran, "color table failed to execute");
//verify that we clamp the values to the expected range
@ -194,7 +192,7 @@ public:
vtkm::Range range{ -1.0, 2.0 };
vtkm::Vec<float, 3> rgb1{ 0.0f, 1.0f, 0.0f };
vtkm::Vec<float, 3> rgb2{ 1.0f, 0.0f, 1.0f };
auto rgbspace = vtkm::cont::ColorSpace::RGB;
auto rgbspace = vtkm::ColorSpace::RGB;
vtkm::cont::ColorTable table(range, rgb1, rgb2, rgbspace);
table.SetClampingOff();
@ -203,7 +201,7 @@ public:
auto field = vtkm::cont::make_ArrayHandle({ -2, -1, 2, 3 });
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8> colors;
const bool ran = table.Map(field, colors);
const bool ran = vtkm::cont::ColorTableMap(field, table, colors);
VTKM_TEST_ASSERT(ran, "color table failed to execute");
//verify that both the above and below range colors are used,
@ -215,7 +213,7 @@ public:
//verify that we can specify custom above and below range colors
table.SetAboveRangeColor(vtkm::Vec<float, 3>{ 1.0f, 0.0f, 0.0f }); //red
table.SetBelowRangeColor(vtkm::Vec<float, 3>{ 0.0f, 0.0f, 1.0f }); //green
const bool ran2 = table.Map(field, colors);
const bool ran2 = vtkm::cont::ColorTableMap(field, table, colors);
VTKM_TEST_ASSERT(ran2, "color table failed to execute");
CheckColors(colors, { { 0, 0, 255 }, { 0, 255, 0 }, { 255, 0, 255 }, { 255, 0, 0 } });
}
@ -228,7 +226,7 @@ public:
//implement a blue2yellow color table
vtkm::Vec<float, 3> rgb1{ 0.0f, 0.0f, 1.0f };
vtkm::Vec<float, 3> rgb2{ 1.0f, 1.0f, 0.0f };
auto lab = vtkm::cont::ColorSpace::LAB;
auto lab = vtkm::ColorSpace::Lab;
vtkm::cont::ColorTable table(range, rgb1, rgb2, lab);
table.AddPoint(0.0, vtkm::Vec<float, 3>{ 0.5f, 0.5f, 0.5f });
@ -248,7 +246,7 @@ public:
auto field = vtkm::cont::make_ArrayHandle({ 0, 10, 20, 30, 40, 50 });
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8> colors;
const bool ran = newTable.Map(field, colors);
const bool ran = vtkm::cont::ColorTableMap(field, newTable, colors);
VTKM_TEST_ASSERT(ran, "color table failed to execute");
//values confirmed with ParaView 5.4
@ -266,7 +264,7 @@ public:
std::cout << "Test Add Points" << std::endl;
vtkm::Range range{ -20, 20.0 };
auto rgbspace = vtkm::cont::ColorSpace::RGB;
auto rgbspace = vtkm::ColorSpace::RGB;
vtkm::cont::ColorTable table(rgbspace);
table.AddPoint(-10.0, vtkm::Vec<float, 3>{ 0.0f, 1.0f, 1.0f });
@ -280,7 +278,7 @@ public:
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8> colors;
auto field = vtkm::cont::make_ArrayHandle({ 10.0f, -5.0f, -15.0f });
const bool ran = table.Map(field, colors);
const bool ran = vtkm::cont::ColorTableMap(field, table, colors);
VTKM_TEST_ASSERT(ran, "color table failed to execute");
CheckColors(colors, { { 0, 0, 128 }, { 0, 128, 255 }, { 128, 255, 255 } });
@ -291,9 +289,9 @@ public:
std::cout << "Test Add Segments" << std::endl;
vtkm::Range range{ 0.0, 50.0 };
auto diverging = vtkm::cont::ColorSpace::DIVERGING;
auto diverging = vtkm::ColorSpace::Diverging;
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::COOL_TO_WARM);
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::CoolToWarm);
VTKM_TEST_ASSERT(table.GetColorSpace() == diverging,
"color space not switched when loading preset");
@ -315,7 +313,7 @@ public:
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8> colors;
auto field = vtkm::cont::make_ArrayHandle({ 0, 10, 20, 30, 40, 50 });
const bool ran = table.Map(field, colors);
const bool ran = vtkm::cont::ColorTableMap(field, table, colors);
VTKM_TEST_ASSERT(ran, "color table failed to execute");
//values confirmed with ParaView 5.4
@ -332,7 +330,7 @@ public:
{
std::cout << "Test Remove Points" << std::endl;
auto hsv = vtkm::cont::ColorSpace::HSV;
auto hsv = vtkm::ColorSpace::HSV;
vtkm::cont::ColorTable table(hsv);
//implement Blue to Red Rainbow color table
@ -356,7 +354,7 @@ public:
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8> colors;
auto field = vtkm::cont::make_ArrayHandle({ 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f });
const bool ran = table.Map(field, colors);
const bool ran = vtkm::cont::ColorTableMap(field, table, colors);
VTKM_TEST_ASSERT(ran, "color table failed to execute");
//values confirmed with ParaView 5.4
@ -370,8 +368,8 @@ public:
std::cout << " Change Color Space" << std::endl;
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8> colors_rgb;
table.SetColorSpace(vtkm::cont::ColorSpace::RGB);
table.Map(field, colors_rgb);
table.SetColorSpace(vtkm::ColorSpace::RGB);
vtkm::cont::ColorTableMap(field, table, colors_rgb);
CheckColors(colors_rgb,
{ { 0, 0, 255 },
@ -386,7 +384,7 @@ public:
{
std::cout << "Test Opacity Only Points" << std::endl;
auto hsv = vtkm::cont::ColorSpace::HSV;
auto hsv = vtkm::ColorSpace::HSV;
vtkm::cont::ColorTable table(hsv);
//implement only a color table
@ -411,7 +409,7 @@ public:
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8> colors;
auto field = vtkm::cont::make_ArrayHandle({ 0.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f });
const bool ran = table.Map(field, colors);
const bool ran = vtkm::cont::ColorTableMap(field, table, colors);
VTKM_TEST_ASSERT(ran, "color table failed to execute");
//values confirmed with ParaView 5.4
@ -430,7 +428,7 @@ public:
using namespace vtkm::worklet::colorconversion;
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::GREEN);
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::Green);
VTKM_TEST_ASSERT((table.GetRange() == vtkm::Range{ 0.0, 1.0 }),
"loading linear green table failed with wrong range");
VTKM_TEST_ASSERT((table.GetNumberOfPoints() == 21),
@ -439,13 +437,8 @@ public:
auto samples = vtkm::cont::make_ArrayHandle({ 0.0, 0.5, 1.0 });
vtkm::cont::ArrayHandle<vtkm::Vec4ui_8> colors;
{
vtkm::cont::Token token;
TransferFunction transfer(table.PrepareForExecution(DeviceAdapterTag{}, token));
vtkm::worklet::DispatcherMapField<TransferFunction> dispatcher(transfer);
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(samples, colors);
}
vtkm::cont::Invoker invoke;
invoke(TransferFunction{}, samples, table, colors);
CheckColors(colors, { { 14, 28, 31, 255 }, { 21, 150, 21, 255 }, { 255, 251, 230, 255 } });
}
@ -454,7 +447,7 @@ public:
{
std::cout << "Test Sampling" << std::endl;
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::GREEN);
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::Green);
VTKM_TEST_ASSERT((table.GetRange() == vtkm::Range{ 0.0, 1.0 }),
"loading linear green table failed with wrong range");
VTKM_TEST_ASSERT((table.GetNumberOfPoints() == 21),
@ -473,7 +466,7 @@ public:
//build a color table with clamping off and verify that sampling works
vtkm::Range range{ 0.0, 50.0 };
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::COOL_TO_WARM);
vtkm::cont::ColorTable table(vtkm::cont::ColorTable::Preset::CoolToWarm);
table.RescaleToRange(range);
table.SetClampingOff();
table.SetAboveRangeColor(vtkm::Vec<float, 3>{ 1.0f, 0.0f, 0.0f }); //red
@ -485,7 +478,7 @@ public:
vtkm::cont::ArrayHandle<vtkm::Vec3ui_8> colors;
auto field = vtkm::cont::make_ArrayHandle({ -1, 0, 10, 20, 30, 40, 50, 60 });
const bool ran = table.Map(field, samples, colors);
const bool ran = vtkm::cont::ColorTableMap(field, samples, colors);
VTKM_TEST_ASSERT(ran, "color table failed to execute");
//values confirmed with ParaView 5.4

@ -8,15 +8,14 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtk_m_cont_testing_TestingPointLocatorUniformGrid_h
#define vtk_m_cont_testing_TestingPointLocatorUniformGrid_h
#ifndef vtk_m_cont_testing_TestingPointLocatorSparseGrid_h
#define vtk_m_cont_testing_TestingPointLocatorSparseGrid_h
#include <random>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/cont/PointLocatorUniformGrid.h>
#include <vtkm/exec/PointLocatorUniformGrid.h>
#include <vtkm/cont/PointLocatorSparseGrid.h>
////brute force method /////
template <typename CoordiVecT, typename CoordiPortalT, typename CoordiT>
@ -65,7 +64,7 @@ public:
}
};
class PointLocatorUniformGridWorklet : public vtkm::worklet::WorkletMapField
class PointLocatorSparseGridWorklet : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn qcIn,
@ -76,7 +75,7 @@ public:
typedef void ExecutionSignature(_1, _2, _3, _4);
VTKM_CONT
PointLocatorUniformGridWorklet() {}
PointLocatorSparseGridWorklet() {}
template <typename CoordiVecType, typename Locator>
VTKM_EXEC void operator()(const CoordiVecType& qc,
@ -89,7 +88,7 @@ public:
};
template <typename DeviceAdapter>
class TestingPointLocatorUniformGrid
class TestingPointLocatorSparseGrid
{
public:
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
@ -122,7 +121,7 @@ public:
vtkm::cont::CoordinateSystem coord("points", coordi_Handle);
vtkm::cont::PointLocatorUniformGrid pointLocatorUG;
vtkm::cont::PointLocatorSparseGrid pointLocatorUG;
pointLocatorUG.SetCoordinates(coord);
pointLocatorUG.SetRange({ { 0.0, 10.0 } });
pointLocatorUG.SetNumberOfBins({ 5, 5, 5 });
@ -150,9 +149,9 @@ public:
vtkm::cont::ArrayHandle<vtkm::Id> nnId_Handle;
vtkm::cont::ArrayHandle<vtkm::FloatDefault> nnDis_Handle;
PointLocatorUniformGridWorklet pointLocatorUniformGridWorklet;
vtkm::worklet::DispatcherMapField<PointLocatorUniformGridWorklet> locatorDispatcher(
pointLocatorUniformGridWorklet);
PointLocatorSparseGridWorklet pointLocatorSparseGridWorklet;
vtkm::worklet::DispatcherMapField<PointLocatorSparseGridWorklet> locatorDispatcher(
pointLocatorSparseGridWorklet);
locatorDispatcher.SetDevice(DeviceAdapter());
locatorDispatcher.Invoke(qc_Handle, locator, nnId_Handle, nnDis_Handle);
@ -193,4 +192,4 @@ public:
}
};
#endif // vtk_m_cont_testing_TestingPointLocatorUniformGrid_h
#endif // vtk_m_cont_testing_TestingPointLocatorSparseGrid_h

@ -66,7 +66,7 @@ struct CopyValue : public vtkm::worklet::WorkletMapField
typedef _2 ExecutionSignature(_1);
template <typename T>
T&& operator()(T&& t) const
VTKM_EXEC_CONT T&& operator()(T&& t) const
{
return std::forward<T>(t);
}

@ -10,7 +10,11 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/ArrayHandleVirtual.hxx>
#endif
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
@ -24,6 +28,9 @@
#include <algorithm>
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
VTKM_DEPRECATED_SUPPRESS_BEGIN
namespace UnitTestArrayHandleVirtualDetail
{
@ -245,8 +252,17 @@ void TestArrayHandleVirtual()
} // end namespace UnitTestArrayHandleVirtualDetail
VTKM_DEPRECATED_SUPPRESS_END
#endif //VTKM_NO_DEPRECATED_VIRTUAL
int UnitTestArrayHandleVirtual(int argc, char* argv[])
{
#ifndef VTKM_NO_DEPRECATED_VIRTUAL
using namespace UnitTestArrayHandleVirtualDetail;
return vtkm::cont::testing::Testing::Run(TestArrayHandleVirtual, argc, argv);
#else
(void)argc;
(void)argv;
return 0;
#endif
}

@ -8,7 +8,6 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/CellSetStructured.h>
@ -94,22 +93,22 @@ struct IsNoExceptHandle
void operator()(T) const
{
using HandleType = vtkm::cont::ArrayHandle<T>;
using VirtualType = vtkm::cont::ArrayHandleVirtual<T>;
using MultiplexerType = vtkm::cont::ArrayHandleMultiplexer<HandleType>;
//verify the handle type
is_noexcept_movable<HandleType>();
is_noexcept_movable<VirtualType>();
is_noexcept_movable<MultiplexerType>();
//verify the input portals of the handle
is_noexcept_movable<decltype(std::declval<HandleType>().PrepareForInput(
vtkm::cont::DeviceAdapterTagSerial{}, std::declval<vtkm::cont::Token&>()))>();
is_noexcept_movable<decltype(std::declval<VirtualType>().PrepareForInput(
is_noexcept_movable<decltype(std::declval<MultiplexerType>().PrepareForInput(
vtkm::cont::DeviceAdapterTagSerial{}, std::declval<vtkm::cont::Token&>()))>();
//verify the output portals of the handle
is_noexcept_movable<decltype(std::declval<HandleType>().PrepareForOutput(
2, vtkm::cont::DeviceAdapterTagSerial{}, std::declval<vtkm::cont::Token&>()))>();
is_noexcept_movable<decltype(std::declval<VirtualType>().PrepareForOutput(
is_noexcept_movable<decltype(std::declval<MultiplexerType>().PrepareForOutput(
2, vtkm::cont::DeviceAdapterTagSerial{}, std::declval<vtkm::cont::Token&>()))>();
}
};
@ -136,14 +135,11 @@ void TestContDataTypesHaveMoveSemantics()
vtkm::testing::Testing::TryTypes(IsNoExceptHandle{}, ::vtkmComplexCustomTypes{});
//verify the DataSet, Field, CoordinateSystem, and ArrayHandleVirtualCoordinates
//verify the DataSet, Field, and CoordinateSystem
//all have efficient storage in containers such as std::vector
is_noexcept_movable<vtkm::cont::DataSet>();
is_noexcept_movable<vtkm::cont::Field>();
is_noexcept_movable<vtkm::cont::CoordinateSystem>();
VTKM_DEPRECATED_SUPPRESS_BEGIN
is_noexcept_movable<vtkm::cont::ArrayHandleVirtualCoordinates>();
VTKM_DEPRECATED_SUPPRESS_END
//verify the CellSetStructured, and CellSetExplicit
//have efficient storage in containers such as std::vector

Some files were not shown because too many files have changed in this diff Show More