Merge topic 'virtual_fancy_handles'

19c623bfa Add changelogs for ArrayHandleVirtual and VariantArrayHandle
3445047f9 Refactor vtkm::cont::ArrayHandleAny into vtkm::cont::ArrayHandleVirtual
7a5e32be7 Update VTKmCompilerFlags to suppress stack-size-warnings on CUDA 9+
bef70820c Update new worklets to work with ArrayHandleVariant
1f2abbc9c vtkm::cont::IsType and vtkm::cont::Cast support VariantArrayHandle
acf825b27 Correct IsType and Cast on ArrayHandleVirtual to work on OSX.
7b9fa975f Rename: IsVirtualType to IsValueType.
deb4946a4 Make sure vtk-m libraries under CUDA 8 are always built statically
...

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Kenneth Moreland <kmorel@sandia.gov>
Merge-request: !1454
This commit is contained in:
Robert Maynard 2018-12-27 21:30:55 +00:00 committed by Kitware Robot
commit 448ec29265
148 changed files with 3676 additions and 2178 deletions

@ -101,7 +101,7 @@ if(VTKM_COMPILER_IS_MSVC)
#Setup MSVC warnings with CUDA and CXX
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CXX>:-wd4702 -wd4505>)
if(TARGET vtkm::cuda)
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-wd4702,-wd4505 -Xcudafe=--display_error_number,--diag_suppress=1394,--diag_suppress=766>)
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-wd4702,-wd4505 -Xcudafe=--diag_suppress=1394,--diag_suppress=766>)
endif()
if(MSVC_VERSION LESS 1900)
@ -124,7 +124,7 @@ elseif(VTKM_COMPILER_IS_ICC)
elseif(VTKM_COMPILER_IS_GNU OR VTKM_COMPILER_IS_CLANG)
set(cxx_flags -Wall -Wno-long-long -Wcast-align -Wconversion -Wchar-subscripts -Wextra -Wpointer-arith -Wformat -Wformat-security -Wshadow -Wunused-parameter -fno-common)
set(cuda_flags -Xcudafe=--display_error_number -Xcompiler=-Wall,-Wno-unknown-pragmas,-Wno-unused-local-typedefs,-Wno-unused-local-typedefs,-Wno-unused-function,-Wno-long-long,-Wcast-align,-Wconversion,-Wchar-subscripts,-Wpointer-arith,-Wformat,-Wformat-security,-Wshadow,-Wunused-parameter,-fno-common)
set(cuda_flags -Xcompiler=-Wall,-Wno-unknown-pragmas,-Wno-unused-local-typedefs,-Wno-unused-local-typedefs,-Wno-unused-function,-Wno-long-long,-Wcast-align,-Wconversion,-Wchar-subscripts,-Wpointer-arith,-Wformat,-Wformat-security,-Wshadow,-Wunused-parameter,-fno-common)
#GCC 5, 6 don't properly handle strict-overflow suppression through pragma's.
#Instead of suppressing around the location of the strict-overflow you
@ -142,6 +142,19 @@ elseif(VTKM_COMPILER_IS_GNU OR VTKM_COMPILER_IS_CLANG)
endif()
endif()
#common warnings for all platforms when building cuda
if(TARGET vtkm::cuda)
if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER 8.99.0)
#nvcc 9 introduced specific controls to disable the stack size warning
#otherwise we let the warning occur. We have to set this in CMAKE_CUDA_FLAGS
#as it is passed to the device link step, unlike compile_options
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xnvlink=--suppress-stack-size-warning")
endif()
set(display_error_nums -Xcudafe=--display_error_number)
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CUDA>:${suppress_nvlink_stack_size_warnings} ${display_error_nums}>)
endif()
if(NOT VTKm_INSTALL_ONLY_LIBRARIES)
install(TARGETS vtkm_compiler_flags vtkm_developer_flags EXPORT ${VTKm_EXPORT_NAME})
endif()

@ -134,6 +134,17 @@ if(VTKm_ENABLE_CUDA AND NOT TARGET vtkm::cuda)
add_library(vtkm::cuda UNKNOWN IMPORTED GLOBAL)
endif()
# Workaround issue with CUDA 8.X where virtual don't work when building
# VTK-m as shared. We don't want to force BUILD_SHARED_LIBS to a specific
# value as that could impact other projects that embed VTK-m. Instead what
# we do is make sure that libraries built by vtkm_library() are static
# if they use cuda
if(CMAKE_CUDA_COMPILER_VERSION VERSION_LESS 9.0)
set_target_properties(vtkm::cuda PROPERTIES REQUIRES_STATIC_BUILDS TRUE)
else()
set_target_properties(vtkm::cuda PROPERTIES REQUIRES_STATIC_BUILDS FALSE)
endif()
set_target_properties(vtkm::cuda PROPERTIES
INTERFACE_COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:CUDA>:--expt-relaxed-constexpr>
)

@ -269,6 +269,7 @@ endfunction(vtkm_declare_headers)
# [WRAP_FOR_CUDA <source_list>]
# )
function(vtkm_library)
set(options STATIC SHARED)
set(oneValueArgs NAME)
set(multiValueArgs SOURCES HEADERS TEMPLATE_SOURCES WRAP_FOR_CUDA)
cmake_parse_arguments(VTKm_LIB
@ -281,19 +282,46 @@ function(vtkm_library)
endif()
set(lib_name ${VTKm_LIB_NAME})
if(VTKm_LIB_STATIC)
set(VTKm_LIB_type STATIC)
else()
if(VTKm_LIB_SHARED)
set(VTKm_LIB_type SHARED)
endif()
#if cuda requires static libaries force
#them no matter what
if(TARGET vtkm::cuda)
get_target_property(force_static vtkm::cuda REQUIRES_STATIC_BUILDS)
if(force_static)
set(VTKm_LIB_type STATIC)
message("Forcing ${lib_name} to be built statically as we are using CUDA 8.X, which doesn't support virtuals sufficiently in dynamic libraries.")
endif()
endif()
endif()
if(TARGET vtkm::cuda)
vtkm_compile_as_cuda(cu_srcs ${VTKm_LIB_WRAP_FOR_CUDA})
set(VTKm_LIB_WRAP_FOR_CUDA ${cu_srcs})
endif()
add_library(${lib_name}
${VTKm_LIB_type}
${VTKm_LIB_SOURCES}
${VTKm_LIB_HEADERS}
${VTKm_LIB_TEMPLATE_SOURCES}
${VTKm_LIB_WRAP_FOR_CUDA}
)
#when building either static or shared we want pic code
set_target_properties(${lib_name} PROPERTIES POSITION_INDEPENDENT_CODE ON)
#specify when building with cuda we want separable compilation
set_property(TARGET ${lib_name} PROPERTY CUDA_SEPARABLE_COMPILATION ON)
#specify where to place the built library
set_property(TARGET ${lib_name} PROPERTY ARCHIVE_OUTPUT_DIRECTORY ${VTKm_LIBRARY_OUTPUT_PATH})
set_property(TARGET ${lib_name} PROPERTY LIBRARY_OUTPUT_DIRECTORY ${VTKm_LIBRARY_OUTPUT_PATH})
@ -446,11 +474,20 @@ function(vtkm_unit_tests)
endif()
add_executable(${test_prog} ${test_prog}.cxx ${VTKm_UT_SOURCES})
set_property(TARGET ${test_prog} PROPERTY CUDA_SEPARABLE_COMPILATION ON)
set_property(TARGET ${test_prog} PROPERTY ARCHIVE_OUTPUT_DIRECTORY ${VTKm_LIBRARY_OUTPUT_PATH})
set_property(TARGET ${test_prog} PROPERTY LIBRARY_OUTPUT_DIRECTORY ${VTKm_LIBRARY_OUTPUT_PATH})
set_property(TARGET ${test_prog} PROPERTY RUNTIME_OUTPUT_DIRECTORY ${VTKm_EXECUTABLE_OUTPUT_PATH})
target_link_libraries(${test_prog} PRIVATE vtkm_cont ${VTKm_UT_LIBRARIES})
#Starting in CMake 3.13, cmake will properly drop duplicate libraries
#from the link line so this workaround can be dropped
if (CMAKE_VERSION VERSION_LESS 3.13 AND "vtkm_rendering" IN_LIST VTKm_UT_LIBRARIES)
list(REMOVE_ITEM VTKm_UT_LIBRARIES "vtkm_cont")
target_link_libraries(${test_prog} PRIVATE ${VTKm_UT_LIBRARIES})
else()
target_link_libraries(${test_prog} PRIVATE vtkm_cont ${VTKm_UT_LIBRARIES})
endif()
foreach(current_backend ${all_backends})
set (device_command_line_argument --device=${current_backend})

@ -37,6 +37,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"CONTRIBUTING.md.*warning"
"CodingConventions.md.*warning"
# disable PTX warning about recursive functions. These look like they can't be silenced
# without disabling all PTX warnings, show hide them on the dashboard.
# We explicitly only suppress specific worklets so we can see when new recursive
@ -45,4 +46,13 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"ptxas warning : Stack size for entry function.*BoundingIntervalHierarchy.*"
"ptxas warning : Stack size for entry function.*CoordinatesPortal.*"
"ptxas warning : Stack size for entry function.*CellRangesExtracter.*"
# disable nvlink warnings about virtual functions. The Stack size warnings can only
# be silenced in CUDA >=9, without disabling all nvlink warnings.
"nvlink warning : Stack size for entry function.*NearestNeighborSearch.*"
"nvlink warning : Stack size for entry function.*ArrayPortalRef.*"
"nvlink warning : Stack size for entry function.*ArrayPortalWrapper.*"
"nvlink warning : .*ArrayPortalWrapper.* has address taken but no possible call to it"
"nvlink warning : .*ArrayPortalVirtual.* has address taken but no possible call to it"
)

@ -23,9 +23,9 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/ImplicitFunctionHandle.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/cont/VariantArrayHandle.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
@ -309,7 +309,6 @@ struct ValueTypes : vtkm::ListTagBase<vtkm::Float32, vtkm::Float64>
struct InterpValueTypes : vtkm::ListTagBase<vtkm::Float32, vtkm::Vec<vtkm::Float32, 3>>
{
};
using StorageListTag = ::vtkm::cont::StorageListTagBasic;
/// This class runs a series of micro-benchmarks to measure
/// performance of different field operations
@ -318,14 +317,11 @@ class BenchmarkFieldAlgorithms
{
using StorageTag = vtkm::cont::StorageTagBasic;
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>;
using Timer = vtkm::cont::Timer<DeviceAdapterTag>;
using ValueDynamicHandle = vtkm::cont::DynamicArrayHandleBase<ValueTypes, StorageListTag>;
using InterpDynamicHandle = vtkm::cont::DynamicArrayHandleBase<InterpValueTypes, StorageListTag>;
using IdDynamicHandle =
vtkm::cont::DynamicArrayHandleBase<vtkm::TypeListTagIndex, StorageListTag>;
using ValueVariantHandle = vtkm::cont::VariantArrayHandleBase<ValueTypes>;
using InterpVariantHandle = vtkm::cont::VariantArrayHandleBase<InterpValueTypes>;
using IdVariantHandle = vtkm::cont::VariantArrayHandleBase<vtkm::TypeListTagIndex>;
private:
template <typename Value>
@ -402,9 +398,9 @@ private:
VTKM_CONT
vtkm::Float64 operator()()
{
ValueDynamicHandle dstocks(this->StockPrice);
ValueDynamicHandle dstrikes(this->OptionStrike);
ValueDynamicHandle doptions(this->OptionYears);
ValueVariantHandle dstocks(this->StockPrice);
ValueVariantHandle dstrikes(this->OptionStrike);
ValueVariantHandle doptions(this->OptionYears);
vtkm::cont::ArrayHandle<Value> callResultHandle, putResultHandle;
const Value RISKFREE = 0.02f;
@ -488,9 +484,9 @@ private:
vtkm::cont::ArrayHandle<Value> temp1;
vtkm::cont::ArrayHandle<Value> temp2;
vtkm::cont::DynamicArrayHandleBase<MathTypes, StorageListTag> dinput(this->InputHandle);
ValueDynamicHandle dtemp1(temp1);
ValueDynamicHandle dtemp2(temp2);
vtkm::cont::VariantArrayHandleBase<MathTypes> dinput(this->InputHandle);
ValueVariantHandle dtemp1(temp1);
ValueVariantHandle dtemp2(temp2);
Timer timer;
@ -564,7 +560,7 @@ private:
{
using MathTypes = vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 3>, vtkm::Vec<vtkm::Float64, 3>>;
vtkm::cont::DynamicArrayHandleBase<MathTypes, StorageListTag> dinput(this->InputHandle);
vtkm::cont::VariantArrayHandleBase<MathTypes> dinput(this->InputHandle);
vtkm::cont::ArrayHandle<Value, StorageTag> result;
@ -666,9 +662,9 @@ private:
VTKM_CONT
vtkm::Float64 operator()()
{
InterpDynamicHandle dfield(this->FieldHandle);
InterpDynamicHandle dweight(this->WeightHandle);
IdDynamicHandle dedges(this->EdgePairHandle);
InterpVariantHandle dfield(this->FieldHandle);
InterpVariantHandle dweight(this->WeightHandle);
IdVariantHandle dedges(this->EdgePairHandle);
vtkm::cont::ArrayHandle<Value> result;
Timer timer;

@ -147,8 +147,6 @@ using FieldTypes = vtkm::ListTagBase<vtkm::Float32,
vtkm::Vec<vtkm::Float32, 3>,
vtkm::Vec<vtkm::Float64, 3>>;
using FieldStorage = vtkm::ListTagBase<vtkm::cont::StorageTagBasic>;
using StructuredCellList = vtkm::ListTagBase<vtkm::cont::CellSetStructured<3>>;
using UnstructuredCellList =
@ -158,26 +156,16 @@ using AllCellList = vtkm::ListTagJoin<StructuredCellList, UnstructuredCellList>;
using CoordinateList = vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 3>, vtkm::Vec<vtkm::Float64, 3>>;
using CoordinateStorage =
vtkm::ListTagBase<vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag,
vtkm::cont::StorageTagBasic>;
using DeviceAdapters = vtkm::ListTagBase<Device>;
class BenchmarkFilterPolicy : public vtkm::filter::PolicyBase<BenchmarkFilterPolicy>
{
public:
using FieldTypeList = FieldTypes;
using FieldStorageList = FieldStorage;
using StructuredCellSetList = StructuredCellList;
using UnstructuredCellSetList = UnstructuredCellList;
using AllCellSetList = AllCellList;
using CoordinateTypeList = CoordinateList;
using CoordinateStorageList = CoordinateStorage;
using DeviceAdapterList = DeviceAdapters;
};
// Class implementing all filter benchmarks:
@ -852,7 +840,7 @@ public:
}
};
// Get the number of components in a DynamicArrayHandle, ArrayHandle, or Field's
// Get the number of components in a VariantArrayHandle, ArrayHandle, or Field's
// ValueType.
struct NumberOfComponents
{

@ -136,7 +136,6 @@ struct ValueTypes
: vtkm::ListTagBase<vtkm::UInt32, vtkm::Int32, vtkm::Int64, vtkm::Float32, vtkm::Float64>
{
};
using StorageListTag = ::vtkm::cont::StorageListTagBasic;
/// This class runs a series of micro-benchmarks to measure
/// performance of different field operations
@ -145,11 +144,9 @@ class BenchmarkTopologyAlgorithms
{
using StorageTag = vtkm::cont::StorageTagBasic;
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>;
using Timer = vtkm::cont::Timer<DeviceAdapterTag>;
using ValueDynamicHandle = vtkm::cont::DynamicArrayHandleBase<ValueTypes, StorageListTag>;
using ValueVariantHandle = vtkm::cont::VariantArrayHandleBase<ValueTypes>;
private:
template <typename T, typename Enable = void>
@ -245,7 +242,7 @@ private:
vtkm::cont::CellSetStructured<3> cellSet;
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
ValueDynamicHandle dinput(this->InputHandle);
ValueVariantHandle dinput(this->InputHandle);
vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer;
@ -324,7 +321,7 @@ private:
vtkm::cont::CellSetStructured<3> cellSet;
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
ValueDynamicHandle dinput(this->InputHandle);
ValueVariantHandle dinput(this->InputHandle);
vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer;
@ -372,7 +369,7 @@ private:
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
vtkm::cont::ArrayHandle<vtkm::IdComponent, StorageTag> result;
ValueDynamicHandle dinput(this->InputHandle);
ValueVariantHandle dinput(this->InputHandle);
Timer timer;

@ -17,7 +17,7 @@
## Laboratory (LANL), the U.S. Government retains certain rights in
## this software.
##============================================================================
function(add_benchmark name files)
function(add_benchmark name files lib)
set(benchmarks )
add_executable(${name}_SERIAL ${files})
@ -49,7 +49,7 @@ function(add_benchmark name files)
endif()
foreach(benchmark ${benchmarks})
target_link_libraries(${benchmark} PRIVATE vtkm_cont)
target_link_libraries(${benchmark} PRIVATE ${lib})
set_target_properties(${benchmark} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${VTKm_EXECUTABLE_OUTPUT_PATH}
)
@ -69,19 +69,9 @@ set(benchmarks
)
foreach (benchmark ${benchmarks})
add_benchmark(${benchmark} ${benchmark}.cxx)
add_benchmark(${benchmark} ${benchmark}.cxx vtkm_cont)
endforeach ()
if(TARGET vtkm_rendering)
add_benchmark(BenchmarkRayTracing BenchmarkRayTracing.cxx)
target_link_libraries(BenchmarkRayTracing_SERIAL PRIVATE vtkm_rendering)
if(TARGET BenchmarkRayTracing_TBB)
target_link_libraries(BenchmarkRayTracing_TBB PRIVATE vtkm_rendering)
endif()
if(TARGET BenchmarkRayTracing_OPENMP)
target_link_libraries(BenchmarkRayTracing_OPENMP PRIVATE vtkm_rendering)
endif()
if(TARGET BenchmarkRayTracing_CUDA)
target_link_libraries(BenchmarkRayTracing_CUDA PRIVATE vtkm_rendering)
endif()
add_benchmark(BenchmarkRayTracing BenchmarkRayTracing.cxx vtkm_rendering)
endif()

@ -0,0 +1,45 @@
# Add vtkm::cont::ArrayHandleVirtual
Added a new class named `ArrayHandleVirtual` that allows you to type erase an
ArrayHandle storage type by using virtual calls. This simplification makes
storing `Fields` and `Coordinates` significantly easier as VTK-m doesn't
need to deduce both the storage and value type when executing worklets.
To construct an `ArrayHandleVirtual` one can do one of the following:
```cpp
vtkm::cont::ArrayHandle<vtkm::Float32> pressure;
vtkm::cont::ArrayHandleConstant<vtkm::Float32> constant(42.0f);
// constrcut from an array handle
vtkm::cont::ArrayHandleVirtual<vtkm::Float32> v(pressure);
// or assign from an array handle
v = constant;
```
To help maintain performance `ArrayHandleVirtual` provides a collection of helper
functions/methods to query and cast back to the concrete storage and value type:
```cpp
vtkm::cont::ArrayHandleConstant<vtkm::Float32> constant(42.0f);
vtkm::cont::ArrayHandleVirtual<vtkm::Float32> v = constant;
bool isConstant = vtkm::cont::IsType< decltype(constant) >(v);
if(isConstant)
vtkm::cont::ArrayHandleConstant<vtkm::Float32> t = vtkm::cont::Cast< decltype(constant) >(v);
```
Lastly, a common operation of calling code using `ArrayHandleVirtual` is a desire to construct a new instance
of an existing virtual handle with the same storage type. This can be done by using the `NewInstance` method
as seen below
```cpp
vtkm::cont::ArrayHandle<vtkm::Float32> pressure;
vtkm::cont::ArrayHandleVirtual<vtkm::Float32> v = pressure;
vtkm::cont::ArrayHandleVirtual<vtkm::Float32> newArray = v->NewInstance();
bool isConstant = vtkm::cont::IsType< vtkm::cont::ArrayHandle<vtkm::Float32> >(newArray); //will be true
```

@ -0,0 +1,9 @@
# vtkm::cont::ArrayHandleZip provides a consistent API even with non-writable handles
Previously ArrayHandleZip could not wrap an implicit handle and provide a consistent experience.
The primary issue was that if you tried to use the PortalType returned by GetPortalControl() you
would get a compile failure. This would occur as the PortalType returned would try to call `Set`
on an ImplicitPortal which doesn't have a set method.
Now with this change, the `ZipPortal` use SFINAE to determine if `Set` and `Get` should call the
underlying zipped portals.

@ -0,0 +1,4 @@
# VTK-m now requires CUDA separable compilation to build
With the introduction of `vtkm::cont::ArrayHandleVirtual` and the related infrastructure, vtk-m now
requires that all CUDA code be compiled using separable compilation ( -rdc ).

@ -0,0 +1,43 @@
# vtkm::cont::VariantArrayHandle replaces vtkm::cont::DynamicArrayHandle
`ArrayHandleVariant` replaces `DynamicArrayHandle` as the primary method
for holding onto a type erased `vtkm::cont::ArrayHandle`. The major difference
between the two implementations is how they handle the Storage component of
an array handle.
`DynamicArrayHandle` approach was to find the fully deduced type of the `ArrayHandle`
meaning it would check all value and storage types it knew about until it found a match.
This cross product of values and storages would cause significant compilation times when
a `DynamicArrayHandle` had multiple storage types.
`VariantArrayHandle` approach is to only deduce the value type of the `ArrayHandle` and
return a `vtkm::cont::ArrayHandleVirtual` which uses polymorpishm to hide the actual
storage type. This approach allows for better compile times, and for calling code
to always expect an `ArrayHandleVirtual` instead of the fully deduced type. This conversion
to `ArrayHandleVirtual` is usually done internally within VTK-m when a worklet or filter
is invoked.
In certain cases users of `VariantArrayHandle` want to be able to access the concrete
`ArrayHandle<T,S>` and not have it wrapped in a `ArrayHandleVirtual`. For those occurrences
`VariantArrayHandle` provides a collection of helper functions/methods to query and
cast back to the concrete storage and value type:
```cpp
vtkm::cont::ArrayHandleConstant<vtkm::Float32> constant(42.0f);
vtkm::cont::ArrayHandleVariant v(constant);
bool isConstant = vtkm::cont::IsType< decltype(constant) >(v);
if(isConstant)
vtkm::cont::ArrayHandleConstant<vtkm::Float32> t = vtkm::cont::Cast< decltype(constant) >(v);
```
Lastly, a common operation of calling code using `VariantArrayHandle` is a desire to construct a new instance
of an existing virtual handle with the same storage type. This can be done by using the `NewInstance` method
as seen below
```cpp
vtkm::cont::ArrayHandle<vtkm::Float32> pressure;
vtkm::cont::ArrayHandleVariant v(pressure);
vtkm::cont::ArrayHandleVariant newArray = v->NewInstance();
bool isConstant = vtkm::cont::IsType< decltype(pressure) >(newArray); //will be true
```

@ -38,11 +38,11 @@ namespace
struct FieldMapper
{
vtkm::cont::DynamicArrayHandle& Output;
vtkm::cont::VariantArrayHandle& Output;
vtkm::worklet::Clip& Worklet;
bool IsCellField;
FieldMapper(vtkm::cont::DynamicArrayHandle& output,
FieldMapper(vtkm::cont::VariantArrayHandle& output,
vtkm::worklet::Clip& worklet,
bool isCellField)
: Output(output)
@ -90,7 +90,7 @@ int main(int argc, char* argv[])
bool invertClip = false;
vtkm::cont::CellSetExplicit<> outputCellSet =
clip.Run(input.GetCellSet(0),
scalarField.GetData().ResetTypeList(vtkm::TypeListTagScalarAll()),
scalarField.GetData().ResetTypes(vtkm::TypeListTagScalarAll()),
clipValue,
invertClip);
vtkm::Float64 clipTime = timer.GetElapsedTime();
@ -124,7 +124,7 @@ int main(int argc, char* argv[])
continue;
}
vtkm::cont::DynamicArrayHandle outField;
vtkm::cont::VariantArrayHandle outField;
FieldMapper fieldMapper(outField, clip, isCellField);
inField.GetData().CastAndCall(fieldMapper);
output.AddField(vtkm::cont::Field(inField.GetName(), inField.GetAssociation(), outField));

@ -64,12 +64,11 @@ public:
VTKM_CONT
vtkm::Range GetComputedRange() const { return this->ComputedRange; }
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
template <typename T, typename StorageType, typename DerivedPolicy>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
const vtkm::filter::PolicyBase<DerivedPolicy>& policy);
//@{
/// when operating on vtkm::cont::MultiBlock, we

@ -123,13 +123,12 @@ inline VTKM_CONT HistogramMPI::HistogramMPI()
}
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
template <typename T, typename StorageType, typename DerivedPolicy>
inline VTKM_CONT vtkm::cont::DataSet HistogramMPI::DoExecute(
const vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter& device)
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
vtkm::cont::ArrayHandle<vtkm::Id> binArray;
T delta;
@ -142,12 +141,11 @@ inline VTKM_CONT vtkm::cont::DataSet HistogramMPI::DoExecute(
static_cast<T>(this->ComputedRange.Min),
static_cast<T>(this->ComputedRange.Max),
delta,
binArray,
device);
binArray);
}
else
{
worklet.Run(field, this->NumberOfBins, this->ComputedRange, delta, binArray, device);
worklet.Run(field, this->NumberOfBins, this->ComputedRange, delta, binArray);
}
this->BinDelta = static_cast<vtkm::Float64>(delta);

@ -47,7 +47,6 @@
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/io/writer/VTKDataSetWriter.h>
static bool printProgress = true;

@ -58,6 +58,7 @@ set(headers
VecAxisAlignedPointCoordinates.h
VecFromPortal.h
VecFromPortalPermute.h
VecFromVirtPortal.h
VectorAnalysis.h
VecTraits.h
VecVariable.h

@ -75,10 +75,55 @@ public:
}
private:
const IndexVecType* Indices;
const IndexVecType* const Indices;
PortalType Portal;
};
template <typename IndexVecType, typename PortalType>
class VecFromPortalPermute<IndexVecType, const PortalType*>
{
public:
using ComponentType = typename std::remove_const<typename PortalType::ValueType>::type;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
VecFromPortalPermute() {}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
VecFromPortalPermute(const IndexVecType* indices, const PortalType* const portal)
: Indices(indices)
, Portal(portal)
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::IdComponent GetNumberOfComponents() const { return this->Indices->GetNumberOfComponents(); }
VTKM_SUPPRESS_EXEC_WARNINGS
template <vtkm::IdComponent DestSize>
VTKM_EXEC_CONT void CopyInto(vtkm::Vec<ComponentType, DestSize>& dest) const
{
vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->GetNumberOfComponents());
for (vtkm::IdComponent index = 0; index < numComponents; index++)
{
dest[index] = (*this)[index];
}
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ComponentType operator[](vtkm::IdComponent index) const
{
return this->Portal->Get((*this->Indices)[index]);
}
private:
const IndexVecType* const Indices;
const PortalType* const Portal;
};
template <typename IndexVecType, typename PortalType>
struct TypeTraits<vtkm::VecFromPortalPermute<IndexVecType, PortalType>>
{
@ -134,6 +179,14 @@ inline VTKM_EXEC VecFromPortalPermute<IndexVecType, PortalType> make_VecFromPort
return VecFromPortalPermute<IndexVecType, PortalType>(index, portal);
}
template <typename IndexVecType, typename PortalType>
inline VTKM_EXEC VecFromPortalPermute<IndexVecType, const PortalType*> make_VecFromPortalPermute(
const IndexVecType* index,
const PortalType* const portal)
{
return VecFromPortalPermute<IndexVecType, const PortalType*>(index, portal);
}
} // namespace vtkm
#endif //vtk_m_VecFromPortalPermute_h

79
vtkm/VecFromVirtPortal.h Normal file

@ -0,0 +1,79 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_VecFromVirtPortal_h
#define vtk_m_VecFromVirtPortal_h
#include <vtkm/Types.h>
#include <vtkm/VecFromPortal.h>
#include <vtkm/internal/ArrayPortalVirtual.h>
namespace vtkm
{
/// \brief A short variable-length array from a window in an ArrayPortal.
///
/// The \c VecFromPortal class is a Vec-like class that holds an array portal
/// and exposes a small window of that portal as if it were a \c Vec.
///
template <typename T>
class VTKM_ALWAYS_EXPORT VecFromVirtPortal
{
using RefType = vtkm::internal::ArrayPortalValueReference<vtkm::ArrayPortalRef<T>>;
public:
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
VecFromVirtPortal(const vtkm::ArrayPortalRef<T>* portal,
vtkm::IdComponent numComponents,
vtkm::Id offset)
: Portal(portal)
, NumComponents(numComponents)
, Offset(offset)
{
}
VTKM_EXEC_CONT
vtkm::IdComponent GetNumberOfComponents() const { return this->NumComponents; }
template <vtkm::IdComponent DestSize>
VTKM_EXEC_CONT void CopyInto(vtkm::Vec<T, DestSize>& dest) const
{
vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->NumComponents);
for (vtkm::IdComponent index = 0; index < numComponents; index++)
{
dest[index] = this->Portal->Get(index + this->Offset);
}
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
RefType operator[](vtkm::IdComponent index) const
{
return RefType(*this->Portal, index + this->Offset);
}
private:
const vtkm::ArrayPortalRef<T>* Portal = nullptr;
vtkm::IdComponent NumComponents = 0;
vtkm::Id Offset = 0;
};
}
#endif

@ -50,16 +50,14 @@ struct VTKM_ALWAYS_EXPORT Cast
template <typename T, typename ArrayHandleType>
class ArrayHandleCast
: public vtkm::cont::ArrayHandleTransform<ArrayHandleType,
internal::Cast<typename ArrayHandleType::ValueType, T>,
internal::Cast<T, typename ArrayHandleType::ValueType>>
internal::Cast<typename ArrayHandleType::ValueType, T>>
{
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleCast,
(ArrayHandleCast<T, ArrayHandleType>),
(vtkm::cont::ArrayHandleTransform<ArrayHandleType,
internal::Cast<typename ArrayHandleType::ValueType, T>,
internal::Cast<T, typename ArrayHandleType::ValueType>>));
internal::Cast<typename ArrayHandleType::ValueType, T>>));
ArrayHandleCast(const ArrayHandleType& handle)
: Superclass(handle)
@ -125,9 +123,7 @@ struct TypeString<vtkm::cont::internal::Cast<T1, T2>>
template <typename T, typename AH>
struct TypeString<vtkm::cont::ArrayHandleCast<T, AH>>
: TypeString<
vtkm::cont::ArrayHandleTransform<AH,
vtkm::cont::internal::Cast<typename AH::ValueType, T>,
vtkm::cont::internal::Cast<T, typename AH::ValueType>>>
vtkm::cont::ArrayHandleTransform<AH, vtkm::cont::internal::Cast<typename AH::ValueType, T>>>
{
};
}
@ -147,9 +143,7 @@ struct Serialization<vtkm::cont::internal::Cast<T1, T2>>
template <typename T, typename AH>
struct Serialization<vtkm::cont::ArrayHandleCast<T, AH>>
: Serialization<
vtkm::cont::ArrayHandleTransform<AH,
vtkm::cont::internal::Cast<typename AH::ValueType, T>,
vtkm::cont::internal::Cast<T, typename AH::ValueType>>>
vtkm::cont::ArrayHandleTransform<AH, vtkm::cont::internal::Cast<typename AH::ValueType, T>>>
{
};

@ -115,7 +115,8 @@ private:
/// array at that position.
///
template <class FunctorType>
class ArrayHandleImplicit : public detail::ArrayHandleImplicitTraits<FunctorType>::Superclass
class VTKM_ALWAYS_EXPORT ArrayHandleImplicit
: public detail::ArrayHandleImplicitTraits<FunctorType>::Superclass
{
private:
using ArrayTraits = typename detail::ArrayHandleImplicitTraits<FunctorType>;

@ -0,0 +1,461 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_ArrayHandleVirtual_h
#define vtk_m_cont_ArrayHandleVirtual_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/cont/StorageAny.h>
#include <vtkm/cont/StorageVirtual.h>
#include <memory>
namespace vtkm
{
namespace cont
{
/// Specialization of ArrayHandle for virtual storage.
template <typename T>
class VTKM_ALWAYS_EXPORT ArrayHandle<T, ::vtkm::cont::StorageTagVirtual>
: public vtkm::cont::internal::ArrayHandleBase
{
public:
using StorageTag = vtkm::cont::StorageTagVirtual;
using StorageType = vtkm::cont::internal::Storage<void, vtkm::cont::StorageTagVirtual>;
using ValueType = T;
using PortalControl = vtkm::ArrayPortalRef<T>;
using PortalConstControl = vtkm::ArrayPortalRef<T>;
template <typename Device>
struct ExecutionTypes
{
using Portal = vtkm::ArrayPortalRef<T>;
using PortalConst = vtkm::ArrayPortalRef<T>;
};
///Construct a invalid ArrayHandleVirtual that has nullptr storage
VTKM_CONT ArrayHandle()
: Storage(nullptr)
{
}
///Construct a valid ArrayHandleVirtual from an existing ArrayHandle
///that doesn't derive from ArrayHandleVirtual.
///Note left non-explicit to allow:
///
/// std::vector<vtkm::cont::ArrayHandleVirtual<vtkm::Float64>> vectorOfArrays;
/// //Make basic array.
/// vtkm::cont::ArrayHandle<vtkm::Float64> basicArray;
/// //Fill basicArray...
/// vectorOfArrays.push_back(basicArray);
///
/// // Make fancy array.
/// vtkm::cont::ArrayHandleCounting<vtkm::Float64> fancyArray(-1.0, 0.1, ARRAY_SIZE);
/// vectorOfArrays.push_back(fancyArray);
template <typename S>
ArrayHandle(const vtkm::cont::ArrayHandle<T, S>& ah)
: Storage(std::make_shared<vtkm::cont::StorageAny<T, S>>(ah))
{
using is_base = std::is_base_of<vtkm::cont::StorageVirtual, S>;
static_assert(!is_base::value, "Wrong specialization for ArrayHandleVirtual selected");
}
///Copy an existing ArrayHandleVirtual into this instance
ArrayHandle(const ArrayHandle<T, vtkm::cont::StorageTagVirtual>& src) = default;
/// virtual destructor, as required to make sure derived classes that
/// might have member variables are properly cleaned up.
//
virtual ~ArrayHandle() = default;
///Move existing shared_ptr of vtkm::cont::StorageVirtual to be
///owned by this ArrayHandleVirtual.
///This is generally how derived class construct a valid ArrayHandleVirtual
template <typename DerivedStorage>
explicit ArrayHandle(std::shared_ptr<DerivedStorage>&& storage) noexcept
: Storage(std::move(storage))
{
using is_base = std::is_base_of<vtkm::cont::StorageVirtual, DerivedStorage>;
static_assert(is_base::value,
"Storage for ArrayHandleVirtual needs to derive from vtkm::cont::StorageVirual");
}
///Move existing unique_ptr of vtkm::cont::StorageVirtual to be
///owned by this ArrayHandleVirtual.
///This is how a derived class construct a valid ArrayHandleVirtual
template <typename DerivedStorage>
explicit ArrayHandle(std::unique_ptr<DerivedStorage>&& storage) noexcept
: Storage(std::move(storage))
{
using is_base = std::is_base_of<vtkm::cont::StorageVirtual, DerivedStorage>;
static_assert(is_base::value,
"Storage for ArrayHandleVirtual needs to derive from vtkm::cont::StorageVirual");
}
///move from one virtual array handle to another
ArrayHandle(ArrayHandle<T, vtkm::cont::StorageTagVirtual>&& src) noexcept
: Storage(std::move(src.Storage))
{
}
///move from one a non-virtual array handle to virtual array handle
template <typename S>
ArrayHandle(ArrayHandle<T, S>&& src) noexcept
: Storage(std::make_shared<vtkm::cont::StorageAny<T, S>>(std::move(src)))
{
}
VTKM_CONT ArrayHandle<T, vtkm::cont::StorageTagVirtual>& operator=(
const ArrayHandle<T, vtkm::cont::StorageTagVirtual>& src) = default;
template <typename S>
VTKM_CONT ArrayHandle<T, vtkm::cont::StorageTagVirtual>& operator=(const ArrayHandle<T, S>& src)
{
this->Storage = std::make_shared<vtkm::cont::StorageAny<T, S>>(src);
return *this;
}
VTKM_CONT ArrayHandle<T, vtkm::cont::StorageTagVirtual>& operator=(
ArrayHandle<T, vtkm::cont::StorageTagVirtual>&& src) noexcept
{
this->Storage = std::move(src.Storage);
return *this;
}
template <typename S>
VTKM_CONT ArrayHandle<T, vtkm::cont::StorageTagVirtual>& operator=(
ArrayHandle<T, S>&& src) noexcept
{
this->Storage = std::make_shared<vtkm::cont::StorageAny<T, S>>(std::move(src));
return *this;
}
/// Like a pointer, two \c ArrayHandles are considered equal if they point
/// to the same location in memory.
///
VTKM_CONT
bool operator==(const ArrayHandle<T, StorageTag>& rhs) const
{
return (this->Storage == rhs.Storage);
}
VTKM_CONT
bool operator!=(const ArrayHandle<T, StorageTag>& rhs) const
{
return (this->Storage != rhs.Storage);
}
template <typename VT, typename ST>
VTKM_CONT bool operator==(const ArrayHandle<VT, ST>&) const
{
return false; // different valuetype and/or storage
}
template <typename VT, typename ST>
VTKM_CONT bool operator!=(const ArrayHandle<VT, ST>&) const
{
return true; // different valuetype and/or storage
}
/// Returns true if this array's storage matches the type passed in.
///
template <typename ArrayHandleType>
VTKM_CONT bool IsType() const
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
using VT = typename ArrayHandleType::ValueType;
static_assert(
std::is_same<VT, T>::value,
"ArrayHandleVirtual<ValueType> can only be casted to an ArrayHandle of the same ValueType.");
//We need to determine if we are checking that `ArrayHandleType`
//is a virtual array handle since that is an easy check.
//Or if we have to go ask the storage if they are holding
//
using ST = typename ArrayHandleType::StorageTag;
using is_base = std::is_same<vtkm::cont::StorageTagVirtual, ST>;
return this->IsSameType<ArrayHandleType>(is_base{});
}
/// 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.
///
template <typename ArrayHandleType>
VTKM_CONT ArrayHandleType Cast() const
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
using VT = typename ArrayHandleType::ValueType;
static_assert(
std::is_same<VT, T>::value,
"ArrayHandleVirtual<ValueType> can only be casted to an ArrayHandle of the same ValueType.");
//We need to determine if we are checking that `ArrayHandleType`
//is a virtual array handle since that is an easy check.
//Or if we have to go ask the storage if they are holding
//
using ST = typename ArrayHandleType::StorageTag;
using is_base = std::is_same<vtkm::cont::StorageTagVirtual, ST>;
return this->CastToType<ArrayHandleType>(is_base{});
}
/// Returns a new instance of an ArrayHandleVirtual with the same storage
///
VTKM_CONT ArrayHandle<T, ::vtkm::cont::StorageTagVirtual> NewInstance() const
{
return (this->Storage)
? ArrayHandle<T, ::vtkm::cont::StorageTagVirtual>(this->Storage->NewInstance())
: ArrayHandle<T, ::vtkm::cont::StorageTagVirtual>();
}
/// Returns a view on the internal storage of the ArrayHandleVirtual
///
VTKM_CONT const StorageType* GetStorage() const { return this->Storage.get(); }
/// Get the array portal of the control array.
/// Since worklet invocations are asynchronous and this routine is a synchronization point,
/// exceptions maybe thrown for errors from previously executed worklets.
///
PortalControl GetPortalControl()
{
return make_ArrayPortalRef(
static_cast<const vtkm::ArrayPortalVirtual<T>*>(this->Storage->GetPortalControl()),
this->GetNumberOfValues());
}
/// Get the array portal of the control array.
/// Since worklet invocations are asynchronous and this routine is a synchronization point,
/// exceptions maybe thrown for errors from previously executed worklets.
///
PortalConstControl GetPortalConstControl() const
{
return make_ArrayPortalRef(
static_cast<const vtkm::ArrayPortalVirtual<T>*>(this->Storage->GetPortalConstControl()),
this->GetNumberOfValues());
}
/// Returns the number of entries in the array.
///
vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }
/// \brief Allocates an array large enough to hold the given number of values.
///
/// The allocation may be done on an already existing array, but can wipe out
/// any data already in the array. This method can throw
/// ErrorBadAllocation if the array cannot be allocated or
/// ErrorBadValue if the allocation is not feasible (for example, the
/// array storage is read-only).
///
VTKM_CONT
void Allocate(vtkm::Id numberOfValues) { return this->Storage->Allocate(numberOfValues); }
/// \brief Reduces the size of the array without changing its values.
///
/// This method allows you to resize the array without reallocating it. The
/// number of entries in the array is changed to \c numberOfValues. The data
/// in the array (from indices 0 to \c numberOfValues - 1) are the same, but
/// \c numberOfValues must be equal or less than the preexisting size
/// (returned from GetNumberOfValues). That is, this method can only be used
/// to shorten the array, not lengthen.
void Shrink(vtkm::Id numberOfValues) { return this->Storage->Shrink(numberOfValues); }
/// Releases any resources being used in the execution environment (that are
/// not being shared by the control environment).
///
void ReleaseResourcesExecution() { return this->Storage->ReleaseResourcesExecution(); }
/// Releases all resources in both the control and execution environments.
///
void ReleaseResources() { return this->Storage->ReleaseResources(); }
/// Prepares this array to be used as an input to an operation in the
/// execution environment. If necessary, copies data to the execution
/// environment. Can throw an exception if this array does not yet contain
/// any data. Returns a portal that can be used in code running in the
/// execution environment.
///
/// Return a ArrayPortalRef that wraps the real virtual portal. We need a stack object for
/// the following reasons:
/// 1. Device Adapter algorithms only support const AH<T,S>& and not const AH<T,S>*
/// 2. Devices will want to get the length of a portal before execution, but for CUDA
/// we can't ask this information of the portal as it only valid on the device, instead
/// we have to store this information also in the ref wrapper
vtkm::ArrayPortalRef<T> PrepareForInput(vtkm::cont::DeviceAdapterId devId) const
{
return make_ArrayPortalRef(
static_cast<const vtkm::ArrayPortalVirtual<T>*>(this->Storage->PrepareForInput(devId)),
this->GetNumberOfValues());
}
/// Prepares (allocates) this array to be used as an output from an operation
/// in the execution environment. The internal state of this class is set to
/// have valid data in the execution array with the assumption that the array
/// will be filled soon (i.e. before any other methods of this object are
/// called). Returns a portal that can be used in code running in the
/// execution environment.
///
vtkm::ArrayPortalRef<T> PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId)
{
return make_ArrayPortalRef(static_cast<const vtkm::ArrayPortalVirtual<T>*>(
this->Storage->PrepareForOutput(numberOfValues, devId)),
numberOfValues);
}
/// Prepares this array to be used in an in-place operation (both as input
/// and output) in the execution environment. If necessary, copies data to
/// the execution environment. Can throw an exception if this array does not
/// yet contain any data. Returns a portal that can be used in code running
/// in the execution environment.
///
vtkm::ArrayPortalRef<T> PrepareForInPlace(vtkm::cont::DeviceAdapterId devId)
{
return make_ArrayPortalRef(
static_cast<const vtkm::ArrayPortalVirtual<T>*>(this->Storage->PrepareForInPlace(devId)),
this->GetNumberOfValues());
}
/// Returns the DeviceAdapterId for the current device. If there is no device
/// with an up-to-date copy of the data, VTKM_DEVICE_ADAPTER_UNDEFINED is
/// returned.
VTKM_CONT
DeviceAdapterId GetDeviceAdapterId() const { return this->Storage->GetDeviceAdapterId(); }
protected:
std::shared_ptr<StorageType> Storage = nullptr;
private:
template <typename ArrayHandleType>
bool IsSameType(std::true_type vtkmNotUsed(inheritsFromArrayHandleVirtual)) const
{
//All classes that derive from ArrayHandleVirtual have virtual methods so we can use
//typeid directly.
//needs optimizations based on platform. !OSX can use typeid
return nullptr != dynamic_cast<const ArrayHandleType*>(this);
}
template <typename ArrayHandleType>
bool IsSameType(std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const;
template <typename ArrayHandleType>
ArrayHandleType CastToType(std::true_type vtkmNotUsed(inheritsFromArrayHandleVirtual)) const
{
//All classes that derive from ArrayHandleVirtual have virtual methods so we can use
//dynamic_cast directly
if (!this->Storage)
{
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeName<ArrayHandleType>());
}
const ArrayHandleType* derived = dynamic_cast<const ArrayHandleType*>(this);
if (!derived)
{
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeName<ArrayHandleType>());
}
VTKM_LOG_CAST_SUCC(*this, derived);
return *derived;
}
template <typename ArrayHandleType>
ArrayHandleType CastToType(std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const;
};
//=============================================================================
// Better name for the type
template <typename T>
using ArrayHandleVirtual = vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>;
//=============================================================================
/// A convenience function for creating an ArrayHandleVirtual.
template <typename T, typename S>
VTKM_CONT vtkm::cont::ArrayHandleVirtual<T> make_ArrayHandleVirtual(
const vtkm::cont::ArrayHandle<T, S>& ah)
{
return vtkm::cont::ArrayHandleVirtual<T>(ah);
}
//=============================================================================
// Free function casting helpers
template <typename ArrayHandleType, typename T>
VTKM_CONT inline bool IsType(const vtkm::cont::ArrayHandleVirtual<T>& virtHandle)
{
return virtHandle.template IsType<ArrayHandleType>();
}
template <typename ArrayHandleType, typename T>
VTKM_CONT inline ArrayHandleType Cast(const vtkm::cont::ArrayHandleVirtual<T>& virtHandle)
{
return virtHandle.template Cast<ArrayHandleType>();
}
//=============================================================================
// Specializations of CastAndCall to help make sure ArrayHandleVirtual
// holding a ArrayHandleUniformPointCoordinates works properly
template <typename Functor, typename... Args>
void CastAndCall(vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>> coords,
Functor&& f,
Args&&... args)
{
using HandleType = ArrayHandleUniformPointCoordinates;
using T = typename HandleType::ValueType;
using S = typename HandleType::StorageTag;
if (coords.IsType<HandleType>())
{
const vtkm::cont::StorageVirtual* storage = coords.GetStorage();
auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
f(any->GetHandle(), std::forward<Args>(args)...);
}
else
{
f(coords, std::forward<Args>(args)...);
}
}
//=============================================================================
// Specializations of serialization related classes
template <typename T>
struct TypeString<vtkm::cont::ArrayHandleVirtual<T>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "AH_Virtual<" + TypeString<T>::Get() + ">";
return name;
}
};
}
} //namespace vtkm::cont
#endif //vtk_m_cont_ArrayHandleVirtual_h

@ -0,0 +1,166 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_ArrayHandleVirtual_hxx
#define vtk_m_cont_ArrayHandleVirtual_hxx
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/StorageAny.hxx>
#include <vtkm/cont/TryExecute.h>
namespace vtkm
{
namespace cont
{
template <typename T>
template <typename ArrayHandleType>
bool ArrayHandle<T, StorageTagVirtual>::IsSameType(
std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const
{
if (!this->Storage)
{
return false;
}
using S = typename ArrayHandleType::StorageTag;
return this->Storage->template IsType<vtkm::cont::StorageAny<T, S>>();
}
template <typename T>
template <typename ArrayHandleType>
ArrayHandleType ArrayHandle<T, StorageTagVirtual>::CastToType(
std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const
{
if (!this->Storage)
{
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeName<ArrayHandleType>());
}
using S = typename ArrayHandleType::StorageTag;
const auto* any = this->Storage->template Cast<vtkm::cont::StorageAny<T, S>>();
return any->GetHandle();
}
}
} // namespace vtkm::const
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
//=============================================================================
// Specializations of serialization related classes
namespace diy
{
template <typename T>
struct Serialization<vtkm::cont::ArrayHandleVirtual<T>>
{
static VTKM_CONT void save(diy::BinaryBuffer& bb, const vtkm::cont::ArrayHandleVirtual<T>& obj)
{
vtkm::cont::internal::ArrayHandleDefaultSerialization(bb, obj);
}
static VTKM_CONT void load(BinaryBuffer& bb, vtkm::cont::ArrayHandleVirtual<T>& obj)
{
vtkm::cont::ArrayHandle<T> array;
diy::load(bb, array);
obj = std::move(vtkm::cont::ArrayHandleVirtual<T>{ array });
}
};
template <typename T>
struct IntAnySerializer
{
using CountingType = vtkm::cont::ArrayHandleCounting<T>;
using ConstantType = vtkm::cont::ArrayHandleConstant<T>;
using BasicType = vtkm::cont::ArrayHandle<T>;
static VTKM_CONT void save(diy::BinaryBuffer& bb, const vtkm::cont::ArrayHandleVirtual<T>& obj)
{
if (obj.template IsType<CountingType>())
{
diy::save(bb, vtkm::cont::TypeString<CountingType>::Get());
using S = typename CountingType::StorageTag;
const vtkm::cont::StorageVirtual* storage = obj.GetStorage();
auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
diy::save(bb, any->GetHandle());
}
else if (obj.template IsType<ConstantType>())
{
diy::save(bb, vtkm::cont::TypeString<ConstantType>::Get());
using S = typename ConstantType::StorageTag;
const vtkm::cont::StorageVirtual* storage = obj.GetStorage();
auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
diy::save(bb, any->GetHandle());
}
else
{
diy::save(bb, vtkm::cont::TypeString<BasicType>::Get());
vtkm::cont::internal::ArrayHandleDefaultSerialization(bb, obj);
}
}
static VTKM_CONT void load(BinaryBuffer& bb, vtkm::cont::ArrayHandleVirtual<T>& obj)
{
std::string typeString;
diy::load(bb, typeString);
if (typeString == vtkm::cont::TypeString<CountingType>::Get())
{
CountingType array;
diy::load(bb, array);
obj = std::move(vtkm::cont::ArrayHandleVirtual<T>{ array });
}
else if (typeString == vtkm::cont::TypeString<ConstantType>::Get())
{
ConstantType array;
diy::load(bb, array);
obj = std::move(vtkm::cont::ArrayHandleVirtual<T>{ array });
}
else
{
vtkm::cont::ArrayHandle<T> array;
diy::load(bb, array);
obj = std::move(vtkm::cont::ArrayHandleVirtual<T>{ array });
}
}
};
template <>
struct Serialization<vtkm::cont::ArrayHandleVirtual<vtkm::UInt8>>
: public IntAnySerializer<vtkm::UInt8>
{
};
template <>
struct Serialization<vtkm::cont::ArrayHandleVirtual<vtkm::Int32>>
: public IntAnySerializer<vtkm::Int32>
{
};
template <>
struct Serialization<vtkm::cont::ArrayHandleVirtual<vtkm::Int64>>
: public IntAnySerializer<vtkm::Int64>
{
};
}
#endif

@ -20,17 +20,15 @@
#ifndef vtk_m_cont_ArrayHandleVirtualCoordinates_h
#define vtk_m_cont_ArrayHandleVirtualCoordinates_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/cont/internal/DynamicTransform.h>
#include <vtkm/VecTraits.h>
#include <vtkm/VirtualObjectBase.h>
#include <memory>
#include <type_traits>
@ -40,473 +38,42 @@ namespace vtkm
namespace cont
{
namespace internal
{
//=============================================================================
class VTKM_ALWAYS_EXPORT CoordinatesPortalBase : public VirtualObjectBase
{
public:
VTKM_EXEC_CONT virtual vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id i) const = 0;
VTKM_EXEC_CONT virtual void Set(vtkm::Id i,
const vtkm::Vec<vtkm::FloatDefault, 3>& val) const = 0;
};
template <typename PortalType, typename ValueType>
class VTKM_ALWAYS_EXPORT CoordinatesPortalImpl : public CoordinatesPortalBase
{
public:
VTKM_CONT CoordinatesPortalImpl() = default;
VTKM_CONT explicit CoordinatesPortalImpl(const PortalType& portal)
: Portal(portal)
{
}
VTKM_CONT void SetPortal(const PortalType& portal) { this->Portal = portal; }
VTKM_EXEC_CONT vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id i) const override
{
auto val = this->Portal.Get(i);
return { static_cast<vtkm::FloatDefault>(val[0]),
static_cast<vtkm::FloatDefault>(val[1]),
static_cast<vtkm::FloatDefault>(val[2]) };
}
VTKM_EXEC_CONT void Set(vtkm::Id i, const vtkm::Vec<vtkm::FloatDefault, 3>& val) const override
{
using VecType = typename PortalType::ValueType;
using ComponentType = typename vtkm::VecTraits<VecType>::ComponentType;
this->Portal.Set(i,
{ static_cast<ComponentType>(val[0]),
static_cast<ComponentType>(val[1]),
static_cast<ComponentType>(val[2]) });
}
private:
PortalType Portal;
};
template <typename PortalType>
class VTKM_ALWAYS_EXPORT CoordinatesPortalImpl<PortalType, void*> : public CoordinatesPortalBase
{
public:
VTKM_CONT CoordinatesPortalImpl() = default;
VTKM_CONT explicit CoordinatesPortalImpl(const PortalType&) {}
VTKM_CONT void SetPortal(const PortalType&) {}
VTKM_EXEC_CONT vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id) const override { return {}; }
VTKM_EXEC_CONT void Set(vtkm::Id, const vtkm::Vec<vtkm::FloatDefault, 3>&) const override {}
};
template <typename PortalType>
class VTKM_ALWAYS_EXPORT CoordinatesPortal
: public CoordinatesPortalImpl<PortalType, typename PortalType::ValueType>
{
public:
VTKM_CONT CoordinatesPortal() = default;
VTKM_CONT explicit CoordinatesPortal(const PortalType& portal)
: CoordinatesPortalImpl<PortalType, typename PortalType::ValueType>(portal)
{
}
};
template <typename PortalType>
class VTKM_ALWAYS_EXPORT CoordinatesPortalConst : public CoordinatesPortalBase
{
public:
VTKM_CONT CoordinatesPortalConst() = default;
VTKM_CONT explicit CoordinatesPortalConst(const PortalType& portal)
: Portal(portal)
{
}
VTKM_CONT void SetPortal(const PortalType& portal) { this->Portal = portal; }
VTKM_EXEC_CONT vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id i) const override
{
auto val = this->Portal.Get(i);
return { static_cast<vtkm::FloatDefault>(val[0]),
static_cast<vtkm::FloatDefault>(val[1]),
static_cast<vtkm::FloatDefault>(val[2]) };
}
VTKM_EXEC_CONT void Set(vtkm::Id, const vtkm::Vec<vtkm::FloatDefault, 3>&) const override {}
private:
PortalType Portal;
};
class VTKM_ALWAYS_EXPORT ArrayPortalVirtualCoordinates
/// ArrayHandleVirtualCoordinates is a specialization of ArrayHandle.
class VTKM_ALWAYS_EXPORT ArrayHandleVirtualCoordinates final
: public vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>
{
public:
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
using StorageTag = vtkm::cont::StorageTagVirtual;
VTKM_EXEC_CONT ArrayPortalVirtualCoordinates()
: NumberOfValues(0)
, VirtualPortal(nullptr)
using NonDefaultCoord = typename std::conditional<std::is_same<vtkm::FloatDefault, float>::value,
vtkm::Vec<double, 3>,
vtkm::Vec<float, 3>>::type;
ArrayHandleVirtualCoordinates()
: vtkm::cont::ArrayHandleVirtual<ValueType>()
{
}
VTKM_EXEC_CONT ArrayPortalVirtualCoordinates(vtkm::Id numberOfValues,
const CoordinatesPortalBase* virtualPortal)
: NumberOfValues(numberOfValues)
, VirtualPortal(virtualPortal)
{
}
VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
VTKM_EXEC_CONT ValueType Get(vtkm::Id i) const { return this->VirtualPortal->Get(i); }
VTKM_EXEC_CONT void Set(vtkm::Id i, const ValueType& val) const
{
this->VirtualPortal->Set(i, val);
}
private:
vtkm::Id NumberOfValues;
const CoordinatesPortalBase* VirtualPortal;
};
//=============================================================================
class VTKM_ALWAYS_EXPORT CoordinatesArrayHandleBase
{
public:
using Portal = ArrayPortalVirtualCoordinates;
using PortalConst = ArrayPortalVirtualCoordinates;
virtual ~CoordinatesArrayHandleBase() = default;
VTKM_CONT virtual vtkm::Id GetNumberOfValues() const = 0;
VTKM_CONT virtual Portal GetPortalControl() = 0;
VTKM_CONT virtual PortalConst GetPortalConstControl() = 0;
VTKM_CONT virtual void Allocate(vtkm::Id numberOfValues) = 0;
VTKM_CONT virtual void Shrink(vtkm::Id numberOfValues) = 0;
VTKM_CONT virtual void ReleaseResources() = 0;
VTKM_CONT virtual void ReleaseResourcesExecution() = 0;
VTKM_CONT virtual PortalConst PrepareForInput(vtkm::cont::DeviceAdapterId deviceId) = 0;
VTKM_CONT virtual Portal PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId deviceId) = 0;
VTKM_CONT virtual Portal PrepareForInPlace(vtkm::cont::DeviceAdapterId deviceId) = 0;
};
template <typename ArrayHandleType>
class VTKM_ALWAYS_EXPORT CoordinatesArrayHandleArrayWrapper : public CoordinatesArrayHandleBase
{
public:
VTKM_CONT explicit CoordinatesArrayHandleArrayWrapper(const ArrayHandleType& array)
: Array(array)
{
}
VTKM_CONT const ArrayHandleType& GetArray() const { return this->Array; }
protected:
ArrayHandleType Array;
};
template <typename ArrayHandleType, typename DeviceList>
class VTKM_ALWAYS_EXPORT CoordinatesArrayHandle
: public CoordinatesArrayHandleArrayWrapper<ArrayHandleType>
{
public:
static_assert(std::is_same<DeviceList, vtkm::cont::DeviceAdapterListTagCommon>::value, "error");
using Portal = CoordinatesArrayHandleBase::Portal;
using PortalConst = CoordinatesArrayHandleBase::PortalConst;
VTKM_CONT explicit CoordinatesArrayHandle(const ArrayHandleType& array)
: CoordinatesArrayHandleArrayWrapper<ArrayHandleType>(array)
{
}
VTKM_CONT vtkm::Id GetNumberOfValues() const override { return this->Array.GetNumberOfValues(); }
VTKM_CONT Portal GetPortalControl() override
{
this->ControlPortal.SetPortal(this->Array.GetPortalControl());
return Portal(this->GetNumberOfValues(), &this->ControlPortal);
}
VTKM_CONT PortalConst GetPortalConstControl() override
{
this->ControlConstPortal.SetPortal(this->Array.GetPortalConstControl());
return PortalConst(this->GetNumberOfValues(), &this->ControlConstPortal);
}
VTKM_CONT void Allocate(vtkm::Id numberOfValues) override
{
this->Array.Allocate(numberOfValues);
}
VTKM_CONT void Shrink(vtkm::Id numberOfValues) override { this->Array.Shrink(numberOfValues); }
VTKM_CONT void ReleaseResources() override { this->Array.ReleaseResources(); }
VTKM_CONT void ReleaseResourcesExecution() override { this->Array.ReleaseResourcesExecution(); }
VTKM_CONT PortalConst PrepareForInput(vtkm::cont::DeviceAdapterId deviceId) override
{
PortalConst portal;
bool success = vtkm::cont::TryExecuteOnDevice(
deviceId, PrepareForInputFunctor(), DeviceList(), this, portal);
if (!success)
{
throwFailedRuntimeDeviceTransfer("ArrayHandleVirtualCoordinates", deviceId);
}
return portal;
}
VTKM_CONT Portal PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId deviceId) override
{
Portal portal;
bool success = vtkm::cont::TryExecuteOnDevice(
deviceId, PrepareForOutputFunctor(), DeviceList(), this, numberOfValues, portal);
if (!success)
{
throwFailedRuntimeDeviceTransfer("ArrayHandleVirtualCoordinates", deviceId);
}
return portal;
}
VTKM_CONT Portal PrepareForInPlace(vtkm::cont::DeviceAdapterId deviceId) override
{
Portal portal;
bool success = vtkm::cont::TryExecuteOnDevice(
deviceId, PrepareForInPlaceFunctor(), DeviceList(), this, portal);
if (!success)
{
throwFailedRuntimeDeviceTransfer("ArrayHandleVirtualCoordinates", deviceId);
}
return portal;
}
private:
struct PrepareForInputFunctor
{
template <typename DeviceAdapter>
VTKM_CONT bool operator()(DeviceAdapter device,
CoordinatesArrayHandle* instance,
PortalConst& ret) const
{
auto portal = instance->Array.PrepareForInput(device);
instance->DevicePortalHandle.Reset(new CoordinatesPortalConst<decltype(portal)>(portal),
true,
vtkm::ListTagBase<DeviceAdapter>());
ret = PortalConst(portal.GetNumberOfValues(),
instance->DevicePortalHandle.PrepareForExecution(device));
return true;
}
};
struct PrepareForOutputFunctor
{
template <typename DeviceAdapter>
VTKM_CONT bool operator()(DeviceAdapter device,
CoordinatesArrayHandle* instance,
vtkm::Id numberOfValues,
Portal& ret) const
{
auto portal = instance->Array.PrepareForOutput(numberOfValues, device);
instance->DevicePortalHandle.Reset(
new CoordinatesPortal<decltype(portal)>(portal), true, vtkm::ListTagBase<DeviceAdapter>());
ret = Portal(numberOfValues, instance->DevicePortalHandle.PrepareForExecution(device));
return true;
}
};
struct PrepareForInPlaceFunctor
{
template <typename DeviceAdapter>
VTKM_CONT bool operator()(DeviceAdapter device,
CoordinatesArrayHandle* instance,
Portal& ret) const
{
auto portal = instance->Array.PrepareForInPlace(device);
instance->DevicePortalHandle.Reset(
new CoordinatesPortal<decltype(portal)>(portal), true, vtkm::ListTagBase<DeviceAdapter>());
ret = Portal(instance->Array.GetNumberOfValues(),
instance->DevicePortalHandle.PrepareForExecution(device));
return true;
}
};
CoordinatesPortal<typename ArrayHandleType::PortalControl> ControlPortal;
CoordinatesPortalConst<typename ArrayHandleType::PortalConstControl> ControlConstPortal;
vtkm::cont::VirtualObjectHandle<CoordinatesPortalBase> DevicePortalHandle;
};
//=============================================================================
struct VTKM_ALWAYS_EXPORT StorageTagVirtualCoordinates
{
};
template <>
class VTKM_ALWAYS_EXPORT Storage<vtkm::Vec<vtkm::FloatDefault, 3>, StorageTagVirtualCoordinates>
{
public:
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
using PortalType = CoordinatesArrayHandleBase::Portal;
using PortalConstType = CoordinatesArrayHandleBase::PortalConst;
VTKM_CONT Storage() = default;
template <typename ArrayHandleType, typename DeviceList>
VTKM_CONT explicit Storage(const ArrayHandleType& array, DeviceList)
: Array(new CoordinatesArrayHandle<ArrayHandleType, DeviceList>(array))
{
}
VTKM_CONT PortalType GetPortal() { return this->Array->GetPortalControl(); }
VTKM_CONT PortalConstType GetPortalConst() const { return this->Array->GetPortalConstControl(); }
VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Array->GetNumberOfValues(); }
VTKM_CONT void Allocate(vtkm::Id numberOfValues) { this->Array->Allocate(numberOfValues); }
VTKM_CONT void Shrink(vtkm::Id numberOfValues) { this->Array->Shrink(numberOfValues); }
VTKM_CONT void ReleaseResources() { this->Array->ReleaseResources(); }
VTKM_CONT CoordinatesArrayHandleBase* GetVirtualArray() const { return this->Array.get(); }
private:
std::shared_ptr<CoordinatesArrayHandleBase> Array;
};
//=============================================================================
template <typename DeviceAdapter>
class VTKM_ALWAYS_EXPORT
ArrayTransfer<vtkm::Vec<vtkm::FloatDefault, 3>, StorageTagVirtualCoordinates, DeviceAdapter>
{
public:
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTagVirtualCoordinates>;
using PortalControl = typename StorageType::PortalType;
using PortalConstControl = typename StorageType::PortalConstType;
using PortalExecution = CoordinatesArrayHandleBase::Portal;
using PortalConstExecution = CoordinatesArrayHandleBase::PortalConst;
VTKM_CONT
ArrayTransfer(StorageType* storage)
: Array(storage->GetVirtualArray())
{
}
VTKM_CONT
vtkm::Id GetNumberOfValues() const { return this->Array->GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool)
{
return this->Array->PrepareForInput(DeviceAdapter());
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool)
{
return this->Array->PrepareForInPlace(DeviceAdapter());
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
{
return this->Array->PrepareForOutput(numberOfValues, DeviceAdapter());
}
VTKM_CONT
void RetrieveOutputData(StorageType*) const
{
// Implementation of this method should be unnecessary.
}
VTKM_CONT
void Shrink(vtkm::Id numberOfValues) { this->Array->Shrink(numberOfValues); }
// ArrayTransfer should only be capable of releasing resources in the execution
// environment
VTKM_CONT
void ReleaseResources() { this->Array->ReleaseResourcesExecution(); }
private:
CoordinatesArrayHandleBase* Array;
};
} // internal
//=============================================================================
class VTKM_ALWAYS_EXPORT ArrayHandleVirtualCoordinates
: public ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>, internal::StorageTagVirtualCoordinates>
{
public:
VTKM_ARRAY_HANDLE_SUBCLASS_NT(
ArrayHandleVirtualCoordinates,
(ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>, internal::StorageTagVirtualCoordinates>));
template <typename StorageTag, typename DeviceList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
explicit ArrayHandleVirtualCoordinates(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>, StorageTag>& array,
DeviceList devices = DeviceList())
: Superclass(typename Superclass::StorageType(array, devices))
const vtkm::cont::ArrayHandle<ValueType, vtkm::cont::StorageTagVirtual>& ah)
: vtkm::cont::ArrayHandleVirtual<ValueType>(ah)
{
}
template <typename StorageTag, typename DeviceList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
explicit ArrayHandleVirtualCoordinates(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>, StorageTag>& array,
DeviceList devices = DeviceList())
: Superclass(typename Superclass::StorageType(array, devices))
template <typename S>
explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle<ValueType, S>& ah)
: vtkm::cont::ArrayHandleVirtual<ValueType>(ah)
{
}
template <typename ArrayHandleType>
bool IsType() const
template <typename S>
explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle<NonDefaultCoord, S>& ah)
: vtkm::cont::ArrayHandleVirtual<ValueType>()
{
return this->GetArrayHandleWrapper<ArrayHandleType>() != nullptr;
}
template <typename ArrayHandleType>
bool IsSameType(const ArrayHandleType&) const
{
return this->GetArrayHandleWrapper<ArrayHandleType>() != nullptr;
}
template <typename ArrayHandleType>
const ArrayHandleType Cast() const
{
auto wrapper = this->GetArrayHandleWrapper<ArrayHandleType>();
if (!wrapper)
{
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
throw vtkm::cont::ErrorBadType("dynamic cast failed");
}
VTKM_LOG_CAST_SUCC(*this, wrapper->GetArray());
return ArrayHandleType(wrapper->GetArray());
}
private:
template <typename ArrayHandleType>
struct WrapperType
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
using ValueType = typename ArrayHandleType::ValueType;
using StorageTag = typename ArrayHandleType::StorageTag;
using BaseArrayHandleType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using Type = internal::CoordinatesArrayHandleArrayWrapper<BaseArrayHandleType>;
};
template <typename ArrayHandleType>
VTKM_CONT const typename WrapperType<ArrayHandleType>::Type* GetArrayHandleWrapper() const
{
auto va = this->GetStorage().GetVirtualArray();
return dynamic_cast<const typename WrapperType<ArrayHandleType>::Type*>(va);
auto castedHandle = vtkm::cont::make_ArrayHandleCast<ValueType>(ah);
using ST = typename decltype(castedHandle)::StorageTag;
this->Storage = std::make_shared<vtkm::cont::StorageAny<ValueType, ST>>(castedHandle);
}
};
@ -515,9 +82,11 @@ void CastAndCall(const vtkm::cont::ArrayHandleVirtualCoordinates& coords,
Functor&& f,
Args&&... args)
{
if (coords.IsType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
using HandleType = ArrayHandleUniformPointCoordinates;
if (coords.IsType<HandleType>())
{
f(coords.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>(), std::forward<Args>(args)...);
HandleType uniform = coords.Cast<HandleType>();
f(uniform, std::forward<Args>(args)...);
}
else
{
@ -525,100 +94,6 @@ void CastAndCall(const vtkm::cont::ArrayHandleVirtualCoordinates& coords,
}
}
template <typename Functor, typename... Args>
void CastAndCall(const typename vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& coords,
Functor&& f,
Args&&... args)
{
CastAndCall(static_cast<const vtkm::cont::ArrayHandleVirtualCoordinates&>(coords),
std::forward<Functor>(f),
std::forward<Args>(args)...);
}
}
} // vtkm::cont
#ifdef VTKM_CUDA
// Cuda seems to have a bug where it expects the template class VirtualObjectTransfer
// to be instantiated in a consistent order among all the translation units of an
// executable. Failing to do so results in random crashes and incorrect results.
// We workaroud this issue by explicitly instantiating VirtualObjectTransfer for
// all the portal types here.
#include <vtkm/cont/cuda/internal/VirtualObjectTransferCuda.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleCompositeVector.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
namespace vtkm
{
namespace cont
{
namespace internal
{
template <typename ArrayHandleType>
struct CudaPortalTypes
{
using PortalConst = typename ArrayHandleType::template ExecutionTypes<
vtkm::cont::DeviceAdapterTagCuda>::PortalConst;
using Portal =
typename ArrayHandleType::template ExecutionTypes<vtkm::cont::DeviceAdapterTagCuda>::Portal;
};
using CudaPortalsBasicF32 = CudaPortalTypes<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>>;
using CudaPortalsBasicF64 = CudaPortalTypes<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>>>;
using CudaPortalsUniformPointCoordinates =
CudaPortalTypes<vtkm::cont::ArrayHandleUniformPointCoordinates>;
using CudaPortalsRectilinearCoords = CudaPortalTypes<
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>>;
using CudaPortalsCompositeCoords = CudaPortalTypes<
vtkm::cont::ArrayHandleCompositeVector<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>>;
}
}
} // vtkm::cont::internal
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortalConst<
vtkm::cont::internal::CudaPortalsBasicF32::PortalConst>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
vtkm::cont::internal::CoordinatesPortal<vtkm::cont::internal::CudaPortalsBasicF32::Portal>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortalConst<
vtkm::cont::internal::CudaPortalsBasicF64::PortalConst>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
vtkm::cont::internal::CoordinatesPortal<vtkm::cont::internal::CudaPortalsBasicF64::Portal>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
vtkm::cont::internal::CoordinatesPortalConst<
vtkm::cont::internal::CudaPortalsUniformPointCoordinates::PortalConst>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
vtkm::cont::internal::CoordinatesPortal<
vtkm::cont::internal::CudaPortalsUniformPointCoordinates::Portal>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
vtkm::cont::internal::CoordinatesPortalConst<
vtkm::cont::internal::CudaPortalsRectilinearCoords::PortalConst>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortal<
vtkm::cont::internal::CudaPortalsRectilinearCoords::Portal>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
vtkm::cont::internal::CoordinatesPortalConst<
vtkm::cont::internal::CudaPortalsCompositeCoords::PortalConst>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortal<
vtkm::cont::internal::CudaPortalsCompositeCoords::Portal>);
#endif // VTKM_CUDA
//=============================================================================
// Specializations of serialization related classes
namespace vtkm
{
namespace cont
{
template <>
struct TypeString<vtkm::cont::ArrayHandleVirtualCoordinates>
@ -626,15 +101,11 @@ struct TypeString<vtkm::cont::ArrayHandleVirtualCoordinates>
static VTKM_CONT const std::string Get() { return "AH_VirtualCoordinates"; }
};
template <>
struct TypeString<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>,
vtkm::cont::internal::StorageTagVirtualCoordinates>>
: TypeString<vtkm::cont::ArrayHandleVirtualCoordinates>
{
};
}
} // vtkm::cont
} // namespace cont
} // namespace vtkm
//=============================================================================
// Specializations of serialization related classes
namespace diy
{
@ -654,23 +125,29 @@ private:
public:
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
{
const auto& virtArray = static_cast<const vtkm::cont::ArrayHandleVirtualCoordinates&>(obj);
if (virtArray.IsType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
const vtkm::cont::StorageVirtual* storage = obj.GetStorage();
if (obj.IsType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
{
auto array = virtArray.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>();
diy::save(bb, vtkm::cont::TypeString<vtkm::cont::ArrayHandleUniformPointCoordinates>::Get());
diy::save(bb, array);
using HandleType = vtkm::cont::ArrayHandleUniformPointCoordinates;
using T = typename HandleType::ValueType;
using S = typename HandleType::StorageTag;
auto array = storage->Cast<vtkm::cont::StorageAny<T, S>>();
diy::save(bb, vtkm::cont::TypeString<HandleType>::Get());
diy::save(bb, array->GetHandle());
}
else if (virtArray.IsType<RectilinearCoordsArrayType>())
else if (obj.IsType<RectilinearCoordsArrayType>())
{
auto array = virtArray.Cast<RectilinearCoordsArrayType>();
diy::save(bb, vtkm::cont::TypeString<RectilinearCoordsArrayType>::Get());
diy::save(bb, array);
using HandleType = RectilinearCoordsArrayType;
using T = typename HandleType::ValueType;
using S = typename HandleType::StorageTag;
auto array = storage->Cast<vtkm::cont::StorageAny<T, S>>();
diy::save(bb, vtkm::cont::TypeString<HandleType>::Get());
diy::save(bb, array->GetHandle());
}
else
{
diy::save(bb, vtkm::cont::TypeString<BasicCoordsType>::Get());
vtkm::cont::internal::ArrayHandleDefaultSerialization(bb, virtArray);
vtkm::cont::internal::ArrayHandleDefaultSerialization(bb, obj);
}
}
@ -705,13 +182,6 @@ public:
}
};
template <>
struct Serialization<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>,
vtkm::cont::internal::StorageTagVirtualCoordinates>>
: Serialization<vtkm::cont::ArrayHandleVirtualCoordinates>
{
};
} // diy
#endif // vtk_m_cont_ArrayHandleVirtualCoordinates_h

@ -22,6 +22,7 @@
#include <vtkm/Pair.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/internal/ArrayPortalHelpers.h>
namespace vtkm
{
@ -37,6 +38,9 @@ class ArrayPortalZip
{
public:
using ValueType = ValueType_;
using T = typename ValueType::FirstType;
using U = typename ValueType::SecondType;
using IteratorType = ValueType_;
using PortalTypeFirst = PortalTypeFirst_;
using PortalTypeSecond = PortalTypeSecond_;
@ -73,14 +77,20 @@ public:
VTKM_EXEC
ValueType Get(vtkm::Id index) const
{
return vtkm::make_Pair(this->PortalFirst.Get(index), this->PortalSecond.Get(index));
using call_supported_t1 = typename vtkm::internal::PortalSupportsGets<PortalTypeFirst>::type;
using call_supported_t2 = typename vtkm::internal::PortalSupportsGets<PortalTypeSecond>::type;
return vtkm::make_Pair(this->GetFirst(call_supported_t1(), index),
this->GetSecond(call_supported_t2(), index));
}
VTKM_EXEC
void Set(vtkm::Id index, const ValueType& value) const
{
this->PortalFirst.Set(index, value.first);
this->PortalSecond.Set(index, value.second);
using call_supported_t1 = typename vtkm::internal::PortalSupportsSets<PortalTypeFirst>::type;
using call_supported_t2 = typename vtkm::internal::PortalSupportsSets<PortalTypeSecond>::type;
this->SetFirst(call_supported_t1(), index, value.first);
this->SetSecond(call_supported_t2(), index, value.second);
}
VTKM_EXEC_CONT
@ -90,6 +100,28 @@ public:
const PortalTypeSecond& GetSecondPortal() const { return this->PortalSecond; }
private:
VTKM_EXEC inline T GetFirst(std::true_type, vtkm::Id index) const noexcept
{
return this->PortalFirst.Get(index);
}
VTKM_EXEC inline T GetFirst(std::false_type, vtkm::Id) const noexcept { return T{}; }
VTKM_EXEC inline U GetSecond(std::true_type, vtkm::Id index) const noexcept
{
return this->PortalSecond.Get(index);
}
VTKM_EXEC inline U GetSecond(std::false_type, vtkm::Id) const noexcept { return U{}; }
VTKM_EXEC inline void SetFirst(std::true_type, vtkm::Id index, const T& value) const noexcept
{
this->PortalFirst.Set(index, value);
}
VTKM_EXEC inline void SetFirst(std::false_type, vtkm::Id, const T&) const noexcept {}
VTKM_EXEC inline void SetSecond(std::true_type, vtkm::Id index, const U& value) const noexcept
{
this->PortalSecond.Set(index, value);
}
VTKM_EXEC inline void SetSecond(std::false_type, vtkm::Id, const U&) const noexcept {}
PortalTypeFirst PortalFirst;
PortalTypeSecond PortalSecond;
};

@ -76,10 +76,6 @@ VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::UInt8, 4, vtkm::cont::StorageTagBasic);
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Float32, 4, vtkm::cont::StorageTagBasic);
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Float64, 4, vtkm::cont::StorageTagBasic);
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::FloatDefault,
3,
vtkm::cont::ArrayHandleVirtualCoordinates::StorageTag);
#undef VTKM_ARRAY_RANGE_COMPUTE_IMPL_T
#undef VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC
@ -107,30 +103,5 @@ vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
return rangeArray;
}
// Special implementation for composite vectors.
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>,
typename vtkm::cont::ArrayHandleCompositeVector<
vtkm::cont::ArrayHandle<vtkm::Float32>,
vtkm::cont::ArrayHandle<vtkm::Float32>,
vtkm::cont::ArrayHandle<vtkm::Float32>>::StorageTag>& input,
vtkm::cont::RuntimeDeviceTracker tracker)
{
return detail::ArrayRangeComputeImpl(input, tracker);
}
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>,
typename vtkm::cont::ArrayHandleCompositeVector<
vtkm::cont::ArrayHandle<vtkm::Float64>,
vtkm::cont::ArrayHandle<vtkm::Float64>,
vtkm::cont::ArrayHandle<vtkm::Float64>>::StorageTag>& input,
vtkm::cont::RuntimeDeviceTracker tracker)
{
return detail::ArrayRangeComputeImpl(input, tracker);
}
}
} // namespace vtkm::cont

@ -94,17 +94,26 @@ VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::UInt8, 4, vtkm::cont::StorageTagBasic)
VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float32, 4, vtkm::cont::StorageTagBasic);
VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::Float64, 4, vtkm::cont::StorageTagBasic);
VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::FloatDefault,
3,
vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag);
VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::FloatDefault,
3,
vtkm::cont::ArrayHandleVirtualCoordinates::StorageTag);
#undef VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T
#undef VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC
// VTKM_CONT
// vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
// const vtkm::cont::ArrayHandleVirtualCoordinates& input,
// vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker());
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>& input,
vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker());
VTKM_CONT_EXPORT
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>,
vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag>& array,
vtkm::cont::RuntimeDeviceTracker = vtkm::cont::GetGlobalRuntimeDeviceTracker());
// Implementation of composite vectors
VTKM_CONT_EXPORT
VTKM_CONT

@ -103,6 +103,52 @@ inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeComputeImpl(
} // namespace detail
// VTKM_CONT
// inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
// const vtkm::cont::ArrayHandleVirtualCoordinates& input,
// vtkm::cont::RuntimeDeviceTracker tracker)
// {
// auto array =
// static_cast<const vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>&>(input);
// return ArrayRangeCompute(array, tracker);
// }
VTKM_CONT
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>& input,
vtkm::cont::RuntimeDeviceTracker tracker)
{
using UniformHandleType = ArrayHandleUniformPointCoordinates;
using RectilinearHandleType =
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>;
if (input.IsType<UniformHandleType>())
{
using T = typename UniformHandleType::ValueType;
using S = typename UniformHandleType::StorageTag;
const vtkm::cont::StorageVirtual* storage = input.GetStorage();
const auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
return ArrayRangeCompute(any->GetHandle(), tracker);
}
else if (input.IsType<RectilinearHandleType>())
{
using T = typename RectilinearHandleType::ValueType;
using S = typename RectilinearHandleType::StorageTag;
const vtkm::cont::StorageVirtual* storage = input.GetStorage();
const auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
return ArrayRangeCompute(any->GetHandle(), tracker);
}
else
{
return detail::ArrayRangeComputeImpl(input, tracker);
}
}
template <typename ArrayHandleType>
inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
const ArrayHandleType& input,

@ -24,8 +24,10 @@
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/BoundingIntervalHierarchyNode.h>
#include <vtkm/cont/CellLocator.h>
#include <vtkm/worklet/spatialstructure/BoundingIntervalHierarchy.h>
namespace vtkm

@ -22,13 +22,14 @@ set(headers
Algorithm.h
ArrayCopy.h
ArrayHandle.h
ArrayHandleCast.h
ArrayHandleCartesianProduct.h
ArrayHandleCast.h
ArrayHandleCompositeVector.h
ArrayHandleConcatenate.h
ArrayHandleConstant.h
ArrayHandleCounting.h
ArrayHandleExtractComponent.h
ArrayHandleDiscard.h
ArrayHandleExtractComponent.h
ArrayHandleGroupVec.h
ArrayHandleGroupVecVariable.h
ArrayHandleImplicit.h
@ -40,16 +41,16 @@ set(headers
ArrayHandleTransform.h
ArrayHandleUniformPointCoordinates.h
ArrayHandleView.h
ArrayHandleVirtual.h
ArrayHandleVirtualCoordinates.h
ArrayHandleZip.h
ArrayPortal.h
ArrayPortalToIterators.h
ArrayHandleConcatenate.h
ArrayRangeCompute.h
AssignerMultiBlock.h
AtomicArray.h
BoundingIntervalHierarchyNode.h
BoundingIntervalHierarchy.h
BoundingIntervalHierarchyNode.h
BoundsCompute.h
BoundsGlobalCompute.h
CellLocator.h
@ -58,9 +59,9 @@ set(headers
CellSet.h
CellSetExplicit.h
CellSetListTag.h
CellSetPermutation.h
CellSetSingleType.h
CellSetStructured.h
CellSetPermutation.h
ColorTable.h
ColorTableSamples.h
CoordinateSystem.h
@ -72,7 +73,6 @@ set(headers
DeviceAdapter.h
DeviceAdapterAlgorithm.h
DeviceAdapterListTag.h
DynamicArrayHandle.h
DynamicCellSet.h
EnvironmentTracker.h
Error.h
@ -80,8 +80,8 @@ set(headers
ErrorBadDevice.h
ErrorBadType.h
ErrorBadValue.h
ErrorFilterExecution.h
ErrorExecution.h
ErrorFilterExecution.h
ErrorInternal.h
ExecutionAndControlObjectBase.h
ExecutionObjectBase.h
@ -98,17 +98,21 @@ set(headers
RuntimeDeviceTracker.h
Serialization.h
Storage.h
StorageAny.h
StorageBasic.h
StorageImplicit.h
StorageListTag.h
StorageVirtual.h
Timer.h
TryExecute.h
TypeString.h
VariantArrayHandle.h
VirtualObjectHandle.h
)
set(template_sources
ArrayHandle.hxx
ArrayHandleVirtual.hxx
ArrayRangeCompute.hxx
BoundingIntervalHierarchy.hxx
CellSetExplicit.hxx
@ -117,7 +121,9 @@ set(template_sources
CoordinateSystem.hxx
FieldRangeCompute.hxx
FieldRangeGlobalCompute.hxx
StorageAny.hxx
StorageBasic.hxx
StorageVirtual.hxx
)
set(sources
@ -133,9 +139,9 @@ set(sources
DataSetBuilderExplicit.cxx
DataSetBuilderRectilinear.cxx
DataSetBuilderUniform.cxx
DynamicArrayHandle.cxx
EnvironmentTracker.cxx
ErrorBadDevice.cxx
ErrorBadType.cxx
Field.cxx
FieldRangeCompute.cxx
FieldRangeGlobalCompute.cxx
@ -143,7 +149,7 @@ set(sources
internal/ArrayManagerExecutionShareWithControl.cxx
internal/DeviceAdapterTag.cxx
internal/SimplePolymorphicContainer.cxx
internal/SimplePolymorphicContainer.cxx
internal/TransferInfo.cxx
internal/VirtualObjectTransfer.cxx
Initialize.cxx
Logging.cxx
@ -151,7 +157,9 @@ set(sources
RuntimeDeviceInformation.cxx
RuntimeDeviceTracker.cxx
StorageBasic.cxx
StorageVirtual.cxx
TryExecute.cxx
VariantArrayHandle.cxx
)
# This list of sources has code that uses devices and so might need to be
@ -169,6 +177,7 @@ vtkm_library( NAME vtkm_cont
HEADERS ${headers}
WRAP_FOR_CUDA ${device_sources}
)
add_subdirectory(internal)
add_subdirectory(arg)
add_subdirectory(serial)

@ -25,6 +25,7 @@
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ExecutionObjectBase.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/exec/CellLocator.h>
namespace vtkm

@ -26,8 +26,8 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/VariantArrayHandle.h>
namespace vtkm
{

@ -27,10 +27,6 @@ namespace vtkm
namespace cont
{
using CoordinatesTypeList = vtkm::ListTagBase<vtkm::cont::ArrayHandleVirtualCoordinates::ValueType>;
using CoordinatesStorageList =
vtkm::ListTagBase<vtkm::cont::ArrayHandleVirtualCoordinates::StorageTag>;
VTKM_CONT CoordinateSystem::CoordinateSystem()
: Superclass()
{
@ -38,7 +34,7 @@ VTKM_CONT CoordinateSystem::CoordinateSystem()
VTKM_CONT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& data)
const vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>& data)
: Superclass(name, Association::POINTS, data)
{
}
@ -64,7 +60,8 @@ vtkm::cont::ArrayHandleVirtualCoordinates CoordinateSystem::GetData() const
}
VTKM_CONT
void CoordinateSystem::SetData(const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& newdata)
void CoordinateSystem::SetData(
const vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>& newdata)
{
this->Superclass::SetData(newdata);
}
@ -76,26 +73,6 @@ void CoordinateSystem::PrintSummary(std::ostream& out) const
this->Superclass::PrintSummary(out);
}
VTKM_CONT
void CoordinateSystem::GetRange(vtkm::Range* range) const
{
this->Superclass::GetRange(range, CoordinatesTypeList(), CoordinatesStorageList());
}
VTKM_CONT
const vtkm::cont::ArrayHandle<vtkm::Range>& CoordinateSystem::GetRange() const
{
return this->Superclass::GetRange(CoordinatesTypeList(), CoordinatesStorageList());
}
VTKM_CONT
vtkm::Bounds CoordinateSystem::GetBounds() const
{
vtkm::Range ranges[3];
this->GetRange(ranges);
return vtkm::Bounds(ranges[0], ranges[1], ranges[2]);
}
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandle<vtkm::Vec<float, 3>>&);
@ -141,12 +118,12 @@ template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
vtkm::cont::ArrayHandle<vtkm::Float64, vtkm::cont::StorageTagBasic>>::StorageTag>&);
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(std::string name,
const vtkm::cont::DynamicArrayHandle&);
const vtkm::cont::VariantArrayHandle&);
template VTKM_CONT_EXPORT void CoordinateSystem::SetData(
const vtkm::cont::ArrayHandle<vtkm::Vec<float, 3>>&);
template VTKM_CONT_EXPORT void CoordinateSystem::SetData(
const vtkm::cont::ArrayHandle<vtkm::Vec<double, 3>>&);
template VTKM_CONT_EXPORT void CoordinateSystem::SetData(const vtkm::cont::DynamicArrayHandle&);
template VTKM_CONT_EXPORT void CoordinateSystem::SetData(const vtkm::cont::VariantArrayHandle&);
}
} // namespace vtkm::cont

@ -33,17 +33,20 @@ namespace cont
class VTKM_CONT_EXPORT CoordinateSystem : public vtkm::cont::Field
{
using Superclass = vtkm::cont::Field;
using CoordinatesTypeList =
vtkm::ListTagBase<vtkm::cont::ArrayHandleVirtualCoordinates::ValueType>;
public:
VTKM_CONT
CoordinateSystem();
VTKM_CONT CoordinateSystem(std::string name,
const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& data);
VTKM_CONT CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>& data);
template <typename TypeList, typename StorageList>
template <typename TypeList>
VTKM_CONT CoordinateSystem(std::string name,
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& data);
const vtkm::cont::VariantArrayHandleBase<TypeList>& data);
template <typename T, typename Storage>
VTKM_CONT CoordinateSystem(std::string name, const ArrayHandle<T, Storage>& data);
@ -60,23 +63,35 @@ public:
VTKM_CONT
vtkm::cont::ArrayHandleVirtualCoordinates GetData() const;
VTKM_CONT void SetData(const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& newdata);
VTKM_CONT void SetData(
const vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>& newdata);
template <typename T, typename StorageTag>
VTKM_CONT void SetData(const vtkm::cont::ArrayHandle<T, StorageTag>& newdata);
template <typename T, typename Storage>
VTKM_CONT void SetData(const vtkm::cont::ArrayHandle<T, Storage>& newdata);
VTKM_CONT
template <typename TypeList, typename StorageList>
void SetData(const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& newdata);
template <typename TypeList>
void SetData(const vtkm::cont::VariantArrayHandleBase<TypeList>& newdata);
VTKM_CONT
void GetRange(vtkm::Range* range) const;
void GetRange(vtkm::Range* range) const
{
this->Superclass::GetRange(range, CoordinatesTypeList());
}
VTKM_CONT
const vtkm::cont::ArrayHandle<vtkm::Range>& GetRange() const;
const vtkm::cont::ArrayHandle<vtkm::Range>& GetRange() const
{
return this->Superclass::GetRange(CoordinatesTypeList());
}
VTKM_CONT
vtkm::Bounds GetBounds() const;
vtkm::Bounds GetBounds() const
{
vtkm::Range ranges[3];
this->GetRange(ranges);
return vtkm::Bounds(ranges[0], ranges[1], ranges[2]);
}
virtual void PrintSummary(std::ostream& out) const override;

@ -48,22 +48,22 @@ struct MakeArrayHandleVirtualCoordinatesFunctor
}
};
template <typename TypeList, typename StorageList>
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandleVirtualCoordinates MakeArrayHandleVirtualCoordinates(
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& array)
const vtkm::cont::VariantArrayHandleBase<TypeList>& array)
{
vtkm::cont::ArrayHandleVirtualCoordinates output;
vtkm::cont::CastAndCall(array.ResetTypeList(vtkm::TypeListTagFieldVec3{}),
vtkm::cont::CastAndCall(array.ResetTypes(vtkm::TypeListTagFieldVec3{}),
MakeArrayHandleVirtualCoordinatesFunctor{},
output);
return output;
}
} // namespace detail
template <typename TypeList, typename StorageList>
template <typename TypeList>
VTKM_CONT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& data)
const vtkm::cont::VariantArrayHandleBase<TypeList>& data)
: Superclass(name, Association::POINTS, detail::MakeArrayHandleVirtualCoordinates(data))
{
}
@ -81,9 +81,9 @@ VTKM_CONT void CoordinateSystem::SetData(const vtkm::cont::ArrayHandle<T, Storag
this->SetData(vtkm::cont::ArrayHandleVirtualCoordinates(newdata));
}
template <typename TypeList, typename StorageList>
template <typename TypeList>
VTKM_CONT void CoordinateSystem::SetData(
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& newdata)
const vtkm::cont::VariantArrayHandleBase<TypeList>& newdata)
{
this->SetData(detail::MakeArrayHandleVirtualCoordinates(newdata));
}

@ -25,10 +25,10 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/VariantArrayHandle.h>
namespace vtkm
{
@ -193,7 +193,6 @@ namespace cont
{
template <typename FieldTypeList = VTKM_DEFAULT_TYPE_LIST_TAG,
typename FieldStorageList = VTKM_DEFAULT_STORAGE_LIST_TAG,
typename CellSetTypesList = VTKM_DEFAULT_CELL_SET_LIST_TAG>
struct SerializableDataSet
{
@ -212,12 +211,11 @@ struct SerializableDataSet
namespace diy
{
template <typename FieldTypeList, typename FieldStorageList, typename CellSetTypesList>
struct Serialization<
vtkm::cont::SerializableDataSet<FieldTypeList, FieldStorageList, CellSetTypesList>>
template <typename FieldTypeList, typename CellSetTypesList>
struct Serialization<vtkm::cont::SerializableDataSet<FieldTypeList, CellSetTypesList>>
{
private:
using Type = vtkm::cont::SerializableDataSet<FieldTypeList, FieldStorageList, CellSetTypesList>;
using Type = vtkm::cont::SerializableDataSet<FieldTypeList, CellSetTypesList>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& serializable)
@ -242,8 +240,7 @@ public:
diy::save(bb, numberOfFields);
for (vtkm::IdComponent i = 0; i < numberOfFields; ++i)
{
diy::save(
bb, vtkm::cont::SerializableField<FieldTypeList, FieldStorageList>(dataset.GetField(i)));
diy::save(bb, vtkm::cont::SerializableField<FieldTypeList>(dataset.GetField(i)));
}
}
@ -274,7 +271,7 @@ public:
diy::load(bb, numberOfFields);
for (vtkm::IdComponent i = 0; i < numberOfFields; ++i)
{
vtkm::cont::SerializableField<FieldTypeList, FieldStorageList> field;
vtkm::cont::SerializableField<FieldTypeList> field;
diy::load(bb, field);
dataset.AddField(field.Field);
}

@ -38,7 +38,7 @@ public:
VTKM_CONT
static void AddPointField(vtkm::cont::DataSet& dataSet,
const std::string& fieldName,
const vtkm::cont::DynamicArrayHandle& field)
const vtkm::cont::VariantArrayHandle& field)
{
dataSet.AddField(Field(fieldName, vtkm::cont::Field::Association::POINTS, field));
}
@ -74,7 +74,7 @@ public:
VTKM_CONT
static void AddCellField(vtkm::cont::DataSet& dataSet,
const std::string& fieldName,
const vtkm::cont::DynamicArrayHandle& field,
const vtkm::cont::VariantArrayHandle& field,
const std::string& cellSetName)
{
dataSet.AddField(
@ -119,7 +119,7 @@ public:
VTKM_CONT
static void AddCellField(vtkm::cont::DataSet& dataSet,
const std::string& fieldName,
const vtkm::cont::DynamicArrayHandle& field,
const vtkm::cont::VariantArrayHandle& field,
vtkm::Id cellSetIndex = 0)
{
std::string cellSetName = dataSet.GetCellSet(cellSetIndex).GetName();

@ -1,579 +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.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_DynamicArrayHandle_h
#define vtk_m_cont_DynamicArrayHandle_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/TypeListTag.h>
#include <vtkm/VecTraits.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/StorageListTag.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/internal/DynamicTransform.h>
namespace vtkm
{
template struct ListCrossProduct<VTKM_DEFAULT_TYPE_LIST_TAG, VTKM_DEFAULT_STORAGE_LIST_TAG>;
namespace cont
{
// Forward declaration
template <typename TypeList, typename StorageList>
class DynamicArrayHandleBase;
namespace detail
{
/// \brief Base class for PolymorphicArrayHandleContainer
///
struct VTKM_CONT_EXPORT PolymorphicArrayHandleContainerBase
{
PolymorphicArrayHandleContainerBase();
// This must exist so that subclasses are destroyed correctly.
virtual ~PolymorphicArrayHandleContainerBase();
virtual vtkm::IdComponent GetNumberOfComponents() const = 0;
virtual vtkm::Id GetNumberOfValues() const = 0;
virtual void PrintSummary(std::ostream& out) const = 0;
virtual std::shared_ptr<PolymorphicArrayHandleContainerBase> NewInstance() const = 0;
};
/// \brief ArrayHandle container that can use C++ run-time type information.
///
/// The \c PolymorphicArrayHandleContainer is similar to the
/// \c SimplePolymorphicContainer in that it can contain an object of an
/// unknown type. However, this class specifically holds ArrayHandle objects
/// (with different template parameters) so that it can polymorphically answer
/// simple questions about the object.
///
template <typename T, typename Storage>
struct VTKM_ALWAYS_EXPORT PolymorphicArrayHandleContainer
: public PolymorphicArrayHandleContainerBase
{
using ArrayHandleType = vtkm::cont::ArrayHandle<T, Storage>;
ArrayHandleType Array;
VTKM_CONT
PolymorphicArrayHandleContainer()
: Array()
{
}
VTKM_CONT
PolymorphicArrayHandleContainer(const ArrayHandleType& array)
: Array(array)
{
}
virtual vtkm::IdComponent GetNumberOfComponents() const
{
return vtkm::VecTraits<T>::NUM_COMPONENTS;
}
virtual vtkm::Id GetNumberOfValues() const { return this->Array.GetNumberOfValues(); }
virtual void PrintSummary(std::ostream& out) const
{
vtkm::cont::printSummary_ArrayHandle(this->Array, out);
}
virtual std::shared_ptr<PolymorphicArrayHandleContainerBase> NewInstance() const
{
return std::shared_ptr<PolymorphicArrayHandleContainerBase>(
new PolymorphicArrayHandleContainer<T, Storage>());
}
};
// 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 DynamicArrayHandle from another DynamicArrayHandle of any other
// type. Since you cannot partially specialize friendship, use this accessor
// class to get at the internals for the copy constructor.
struct DynamicArrayHandleCopyHelper
{
template <typename TypeList, typename StorageList>
VTKM_CONT static const std::shared_ptr<vtkm::cont::detail::PolymorphicArrayHandleContainerBase>&
GetArrayHandleContainer(const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& src)
{
return src.ArrayContainer;
}
};
// A simple function to downcast an ArrayHandle encapsulated in a
// PolymorphicArrayHandleContainerBase to the given type of ArrayHandle. If the
// conversion cannot be done, nullptr is returned.
template <typename Type, typename Storage>
VTKM_CONT vtkm::cont::ArrayHandle<Type, Storage>* DynamicArrayHandleTryCast(
vtkm::cont::detail::PolymorphicArrayHandleContainerBase* arrayContainer)
{
vtkm::cont::detail::PolymorphicArrayHandleContainer<Type, Storage>* downcastContainer = nullptr;
downcastContainer = dynamic_cast<decltype(downcastContainer)>(arrayContainer);
if (downcastContainer != nullptr)
{
return &downcastContainer->Array;
}
else
{
return nullptr;
}
}
template <typename Type, typename Storage>
VTKM_CONT vtkm::cont::ArrayHandle<Type, Storage>* DynamicArrayHandleTryCast(
const std::shared_ptr<vtkm::cont::detail::PolymorphicArrayHandleContainerBase>& arrayContainer)
{
return detail::DynamicArrayHandleTryCast<Type, Storage>(arrayContainer.get());
}
} // namespace detail
/// \brief Holds an array handle without having to specify template parameters.
///
/// \c DynamicArrayHandle holds an \c ArrayHandle object using runtime
/// polymorphism to manage different value types and storage 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.
///
/// To interface between the runtime polymorphism and the templated algorithms
/// in VTK-m, \c DynamicArrayHandle contains a method named \c CastAndCall that
/// will determine the correct type from some known list of types and storage
/// objects. This mechanism is used internally by VTK-m's worklet invocation
/// mechanism to determine the type when running algorithms.
///
/// By default, \c DynamicArrayHandle will assume that the value type in the
/// array matches one of the types specified by \c VTKM_DEFAULT_TYPE_LIST_TAG
/// and the storage matches one of the tags specified by \c
/// VTKM_DEFAULT_STORAGE_LIST_TAG. These lists can be changed by using the \c
/// ResetTypeList and \c ResetStorageList methods, respectively. It is
/// worthwhile to match these lists closely to the possible types that might be
/// used. If a type is missing you will get a runtime error. If there are more
/// types than necessary, then the template mechanism will create a lot of
/// object code that is never used, and keep in mind that the number of
/// combinations grows exponentially when using multiple \c DynamicArrayHandle
/// objects.
///
/// The actual implementation of \c DynamicArrayHandle is in a templated class
/// named \c DynamicArrayHandleBase, which is templated on the list of
/// component types and storage types. \c DynamicArrayHandle is really just a
/// typedef of \c DynamicArrayHandleBase with the default type and storage
/// lists.
///
template <typename TypeList, typename StorageList>
class VTKM_ALWAYS_EXPORT DynamicArrayHandleBase
{
public:
VTKM_CONT
DynamicArrayHandleBase() {}
template <typename Type, typename Storage>
VTKM_CONT DynamicArrayHandleBase(const vtkm::cont::ArrayHandle<Type, Storage>& array)
: ArrayContainer(new vtkm::cont::detail::PolymorphicArrayHandleContainer<Type, Storage>(array))
{
}
VTKM_CONT
DynamicArrayHandleBase(const DynamicArrayHandleBase<TypeList, StorageList>& src)
: ArrayContainer(src.ArrayContainer)
{
}
template <typename OtherTypeList, typename OtherStorageList>
VTKM_CONT explicit DynamicArrayHandleBase(
const DynamicArrayHandleBase<OtherTypeList, OtherStorageList>& src)
: ArrayContainer(detail::DynamicArrayHandleCopyHelper::GetArrayHandleContainer(src))
{
}
VTKM_CONT
~DynamicArrayHandleBase() {}
VTKM_CONT
vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& operator=(
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& src)
{
this->ArrayContainer = src.ArrayContainer;
return *this;
}
/// Returns true if this array is of the provided type and uses the provided
/// storage.
///
template <typename Type, typename Storage>
VTKM_CONT bool IsTypeAndStorage() const
{
return (detail::DynamicArrayHandleTryCast<Type, Storage>(this->ArrayContainer) != nullptr);
}
/// Returns true if this array matches the array handle type passed in.
///
template <typename ArrayHandleType>
VTKM_CONT bool IsType()
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
using ValueType = typename ArrayHandleType::ValueType;
using StorageTag = typename ArrayHandleType::StorageTag;
return this->IsTypeAndStorage<ValueType, StorageTag>();
}
/// Returns true if the array held in this object is the same (or equivalent)
/// type as the object given.
///
template <typename ArrayHandleType>
VTKM_CONT bool IsSameType(const ArrayHandleType&)
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
return this->IsType<ArrayHandleType>();
}
/// Returns this array cast to an ArrayHandle object of the given type and
/// storage. Throws \c ErrorBadType if the cast does not work. Use
/// \c IsTypeAndStorage to check if the cast can happen.
///
///
template <typename Type, typename Storage>
VTKM_CONT vtkm::cont::ArrayHandle<Type, Storage> CastToTypeStorage() const
{
vtkm::cont::ArrayHandle<Type, Storage>* downcastArray =
detail::DynamicArrayHandleTryCast<Type, Storage>(this->ArrayContainer);
if (downcastArray == nullptr)
{
VTKM_LOG_CAST_FAIL(*this, decltype(downcastArray));
throw vtkm::cont::ErrorBadType("Bad cast of dynamic array.");
}
// 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.
VTKM_LOG_CAST_SUCC(*this, *downcastArray);
return *downcastArray;
}
/// 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.
///
template <typename ArrayHandleType>
VTKM_CONT ArrayHandleType Cast() const
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
using ValueType = typename ArrayHandleType::ValueType;
using StorageTag = typename ArrayHandleType::StorageTag;
// 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.
return this->CastToTypeStorage<ValueType, StorageTag>();
}
/// Given a references to an ArrayHandle object, casts this array to the
/// ArrayHandle's type and sets the given ArrayHandle to this array. Throws
/// \c ErrorBadType if the cast does not work. Use \c
/// ArrayHandleType to check if the cast can happen.
///
/// Note that this is a shallow copy. The data are not copied and a change
/// in the data in one array will be reflected in the other.
///
template <typename ArrayHandleType>
VTKM_CONT void CopyTo(ArrayHandleType& array) const
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
array = this->Cast<ArrayHandleType>();
}
/// Changes the types to try casting to when resolving this dynamic array,
/// which is specified with a list tag like those in TypeListTag.h. Since C++
/// does not allow you to actually change the template arguments, this method
/// returns a new dynamic array object. This method is particularly useful to
/// narrow down (or expand) the types when using an array of particular
/// constraints.
///
template <typename NewTypeList>
VTKM_CONT DynamicArrayHandleBase<NewTypeList, StorageList> ResetTypeList(
NewTypeList = NewTypeList()) const
{
VTKM_IS_LIST_TAG(NewTypeList);
return DynamicArrayHandleBase<NewTypeList, StorageList>(*this);
}
/// Changes the array storage types to try casting to when resolving this
/// dynamic array, which is specified with a list tag like those in
/// StorageListTag.h. Since C++ does not allow you to actually change the
/// template arguments, this method returns a new dynamic array object. This
/// method is particularly useful to narrow down (or expand) the types when
/// using an array of particular constraints.
///
template <typename NewStorageList>
VTKM_CONT DynamicArrayHandleBase<TypeList, NewStorageList> ResetStorageList(
NewStorageList = NewStorageList()) const
{
VTKM_IS_LIST_TAG(NewStorageList);
return DynamicArrayHandleBase<TypeList, NewStorageList>(*this);
}
/// Changes the value, and array storage types to try casting to when
/// resolving this dynamic array. Since C++ does not allow you to actually
/// change the template arguments, this method returns a new dynamic array
/// object. This method is particularly useful when you have both custom
/// types and traits.
///
template <typename NewTypeList, typename NewStorageList>
VTKM_CONT DynamicArrayHandleBase<NewTypeList, NewStorageList> ResetTypeAndStorageLists(
NewTypeList = NewTypeList(),
NewStorageList = NewStorageList()) const
{
VTKM_IS_LIST_TAG(NewTypeList);
VTKM_IS_LIST_TAG(NewStorageList);
return DynamicArrayHandleBase<NewTypeList, NewStorageList>(*this);
}
/// Attempts to cast the held array to a specific value type and storage,
/// then call the given functor with the cast array. The types and storage
/// tried in the cast are those in the lists defined by the TypeList and
/// StorageList, respectively. The default \c DynamicArrayHandle sets these
/// two lists to VTKM_DEFAULT_TYPE_LIST_TAG and VTK_DEFAULT_STORAGE_LIST_TAG,
/// respectively.
///
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCall(Functor&& f, Args&&...) const;
/// \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 dynamic array handle for it. This method is convenient when
/// creating output arrays that should be the same type as some input array.
///
VTKM_CONT
DynamicArrayHandleBase<TypeList, StorageList> NewInstance() const
{
DynamicArrayHandleBase<TypeList, StorageList> newArray;
newArray.ArrayContainer = this->ArrayContainer->NewInstance();
return newArray;
}
/// \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); }
private:
std::shared_ptr<vtkm::cont::detail::PolymorphicArrayHandleContainerBase> ArrayContainer;
friend struct detail::DynamicArrayHandleCopyHelper;
};
using DynamicArrayHandle =
vtkm::cont::DynamicArrayHandleBase<VTKM_DEFAULT_TYPE_LIST_TAG, VTKM_DEFAULT_STORAGE_LIST_TAG>;
namespace detail
{
struct DynamicArrayHandleTry
{
template <typename T, typename U, typename Functor, typename... Args>
void operator()(brigand::list<T, U>,
Functor&& f,
bool& called,
const PolymorphicArrayHandleContainerBase* const container,
Args&&... args) const
{
if (!called)
{
using downcastType = const vtkm::cont::detail::PolymorphicArrayHandleContainer<T, U>* const;
downcastType downcastContainer = dynamic_cast<downcastType>(container);
if (downcastContainer)
{
VTKM_LOG_CAST_SUCC(*container, *downcastContainer);
f(downcastContainer->Array, std::forward<Args>(args)...);
called = true;
}
}
}
};
VTKM_CONT_EXPORT void ThrowCastAndCallException(PolymorphicArrayHandleContainerBase*,
const std::type_info*,
const std::type_info*);
} // namespace detail
template <typename T>
struct IsUndefinedStorage
{
};
template <typename T, typename U>
struct IsUndefinedStorage<brigand::list<T, U>> : vtkm::cont::internal::IsInValidArrayHandle<T, U>
{
};
template <typename TypeList, typename StorageList>
struct ListTagDynamicTypes : vtkm::detail::ListRoot
{
using crossProduct = typename vtkm::ListCrossProduct<TypeList, StorageList>;
// using list = typename crossProduct::list;
using list = ::brigand::remove_if<typename crossProduct::list, IsUndefinedStorage<brigand::_1>>;
};
template <typename TypeList, typename StorageList>
template <typename Functor, typename... Args>
VTKM_CONT void DynamicArrayHandleBase<TypeList, StorageList>::CastAndCall(Functor&& f,
Args&&... args) const
{
//For optimizations we should compile once the cross product for the default types
//and make it extern
using crossProduct = ListTagDynamicTypes<TypeList, StorageList>;
bool called = false;
auto* ptr = this->ArrayContainer.get();
vtkm::ListForEach(detail::DynamicArrayHandleTry{},
crossProduct{},
std::forward<Functor>(f),
called,
ptr,
std::forward<Args>(args)...);
if (!called)
{
// throw an exception
VTKM_LOG_CAST_FAIL(*this, crossProduct);
detail::ThrowCastAndCallException(ptr, &typeid(TypeList), &typeid(StorageList));
}
}
namespace internal
{
template <typename TypeList, typename StorageList>
struct DynamicTransformTraits<vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>>
{
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
};
} // namespace internal
}
} // namespace vtkm::cont
//=============================================================================
// Specializations of serialization related classes
namespace diy
{
namespace internal
{
struct DynamicArrayHandleSerializeFunctor
{
template <typename ArrayHandleType>
void operator()(const ArrayHandleType& ah, BinaryBuffer& bb) const
{
diy::save(bb, vtkm::cont::TypeString<ArrayHandleType>::Get());
diy::save(bb, ah);
}
};
template <typename TypeList, typename StorageList>
struct DynamicArrayHandleDeserializeFunctor
{
template <typename T, typename S>
void operator()(brigand::list<T, S>,
vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& dh,
const std::string& typeString,
bool& success,
BinaryBuffer& bb) const
{
using ArrayHandleType = vtkm::cont::ArrayHandle<T, S>;
if (!success && (typeString == vtkm::cont::TypeString<ArrayHandleType>::Get()))
{
ArrayHandleType ah;
diy::load(bb, ah);
dh = vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>(ah);
success = true;
}
}
};
} // internal
template <typename TypeList, typename StorageList>
struct Serialization<vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>>
{
private:
using Type = vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj)
{
obj.CastAndCall(internal::DynamicArrayHandleSerializeFunctor{}, bb);
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& obj)
{
using CrossProduct = vtkm::cont::ListTagDynamicTypes<TypeList, StorageList>;
std::string typeString;
diy::load(bb, typeString);
bool success = false;
vtkm::ListForEach(internal::DynamicArrayHandleDeserializeFunctor<TypeList, StorageList>{},
CrossProduct{},
obj,
typeString,
success,
bb);
if (!success)
{
throw vtkm::cont::ErrorBadType(
"Error deserializing DynamicArrayHandle. Message TypeString: " + typeString);
}
}
};
} // diy
#endif //vtk_m_cont_DynamicArrayHandle_h

@ -0,0 +1,37 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/ErrorBadType.h>
#include <string>
namespace vtkm
{
namespace cont
{
void throwFailedDynamicCast(const std::string& baseType, const std::string& derivedType)
{ //Should we support typeid() instead of className?
const std::string msg = "Cast failed: " + baseType + " --> " + derivedType;
throw vtkm::cont::ErrorBadType(msg);
}
}
}

@ -42,6 +42,14 @@ public:
};
VTKM_SILENCE_WEAK_VTABLE_WARNING_END
/// Throws an ErrorBadType exception with the following message:
/// Cast failed: \c baseType --> \c derivedType".
/// This is generally caused by asking for a casting of a VariantArrayHandle
/// with an insufficient type list.
//
VTKM_CONT_EXPORT void throwFailedDynamicCast(const std::string& baseType,
const std::string& derivedType);
}
} // namespace vtkm::cont

@ -18,7 +18,7 @@
// this software.
//============================================================================
#include <vtkm/cont/Field.h>
#include "Field.h"
namespace vtkm
{
@ -27,7 +27,7 @@ namespace cont
/// constructors for points / whole mesh
VTKM_CONT
Field::Field(std::string name, Association association, const vtkm::cont::DynamicArrayHandle& data)
Field::Field(std::string name, Association association, const vtkm::cont::VariantArrayHandle& data)
: Name(name)
, FieldAssociation(association)
, AssocCellSetName()
@ -45,7 +45,7 @@ VTKM_CONT
Field::Field(std::string name,
Association association,
const std::string& cellSetName,
const vtkm::cont::DynamicArrayHandle& data)
const vtkm::cont::VariantArrayHandle& data)
: Name(name)
, FieldAssociation(association)
, AssocCellSetName(cellSetName)
@ -62,7 +62,7 @@ VTKM_CONT
Field::Field(std::string name,
Association association,
vtkm::IdComponent logicalDim,
const vtkm::cont::DynamicArrayHandle& data)
const vtkm::cont::VariantArrayHandle& data)
: Name(name)
, FieldAssociation(association)
, AssocCellSetName()
@ -155,36 +155,18 @@ Field::~Field()
{
}
VTKM_CONT
const vtkm::cont::ArrayHandle<vtkm::Range>& Field::GetRange() const
{
return this->GetRange(VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG());
}
VTKM_CONT
void Field::GetRange(vtkm::Range* range) const
{
this->GetRange(range, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG());
}
VTKM_CONT
const vtkm::cont::DynamicArrayHandle& Field::GetData() const
const vtkm::cont::VariantArrayHandle& Field::GetData() const
{
return this->Data;
}
VTKM_CONT
vtkm::cont::DynamicArrayHandle& Field::GetData()
vtkm::cont::VariantArrayHandle& Field::GetData()
{
this->ModifiedFlag = true;
return this->Data;
}
VTKM_CONT
const vtkm::cont::ArrayHandle<vtkm::Range>& Field::GetRange(VTKM_DEFAULT_TYPE_LIST_TAG,
VTKM_DEFAULT_STORAGE_LIST_TAG) const
{
return this->GetRangeImpl(VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG());
}
}
} // namespace vtkm::cont

@ -28,7 +28,8 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/cont/ArrayRangeCompute.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/ArrayRangeCompute.hxx>
#include <vtkm/cont/VariantArrayHandle.h>
namespace vtkm
{
@ -38,26 +39,18 @@ namespace cont
namespace internal
{
class ComputeRange
struct ComputeRange
{
public:
ComputeRange(ArrayHandle<vtkm::Range>& range)
: Range(&range)
{
}
template <typename ArrayHandleType>
void operator()(const ArrayHandleType& input) const
void operator()(const ArrayHandleType& input, vtkm::cont::ArrayHandle<vtkm::Range>& range) const
{
*this->Range = vtkm::cont::ArrayRangeCompute(input);
range = vtkm::cont::ArrayRangeCompute(input);
}
private:
vtkm::cont::ArrayHandle<vtkm::Range>* Range;
};
} // namespace internal
/// A \c Field encapsulates an array on some piece of the mesh, such as
/// the points, a cell set, a point logical dimension, or the whole mesh.
///
@ -78,11 +71,13 @@ public:
/// constructors for points / whole mesh
VTKM_CONT
Field(std::string name, Association association, const vtkm::cont::DynamicArrayHandle& data);
Field(std::string name, Association association, const vtkm::cont::VariantArrayHandle& data);
template <typename T, typename Storage>
VTKM_CONT Field(std::string name, Association association, const ArrayHandle<T, Storage>& data)
: Field(name, association, vtkm::cont::DynamicArrayHandle{ data })
VTKM_CONT Field(std::string name,
Association association,
const vtkm::cont::ArrayHandle<T, Storage>& data)
: Field(name, association, vtkm::cont::VariantArrayHandle{ data })
{
}
@ -91,14 +86,14 @@ public:
Field(std::string name,
Association association,
const std::string& cellSetName,
const vtkm::cont::DynamicArrayHandle& data);
const vtkm::cont::VariantArrayHandle& data);
template <typename T, typename Storage>
VTKM_CONT Field(std::string name,
Association association,
const std::string& cellSetName,
const vtkm::cont::ArrayHandle<T, Storage>& data)
: Field(name, association, cellSetName, vtkm::cont::DynamicArrayHandle{ data })
: Field(name, association, cellSetName, vtkm::cont::VariantArrayHandle{ data })
{
}
@ -107,14 +102,14 @@ public:
Field(std::string name,
Association association,
vtkm::IdComponent logicalDim,
const vtkm::cont::DynamicArrayHandle& data);
const vtkm::cont::VariantArrayHandle& data);
template <typename T, typename Storage>
VTKM_CONT Field(std::string name,
Association association,
vtkm::IdComponent logicalDim,
const vtkm::cont::ArrayHandle<T, Storage>& data)
: Field(name, association, logicalDim, vtkm::cont::DynamicArrayHandle{ data })
: Field(name, association, logicalDim, vtkm::cont::VariantArrayHandle{ data })
{
}
@ -126,40 +121,19 @@ public:
VTKM_CONT Field& operator=(const vtkm::cont::Field& src);
VTKM_CONT Field& operator=(vtkm::cont::Field&& src) noexcept;
VTKM_CONT
const std::string& GetName() const { return this->Name; }
VTKM_CONT const std::string& GetName() const { return this->Name; }
VTKM_CONT Association GetAssociation() const { return this->FieldAssociation; }
VTKM_CONT std::string GetAssocCellSet() const { return this->AssocCellSetName; }
VTKM_CONT vtkm::IdComponent GetAssocLogicalDim() const { return this->AssocLogicalDim; }
const vtkm::cont::VariantArrayHandle& GetData() const;
vtkm::cont::VariantArrayHandle& GetData();
VTKM_CONT
Association GetAssociation() const { return this->FieldAssociation; }
VTKM_CONT
std::string GetAssocCellSet() const { return this->AssocCellSetName; }
VTKM_CONT
vtkm::IdComponent GetAssocLogicalDim() const { return this->AssocLogicalDim; }
template <typename TypeList, typename StorageList>
VTKM_CONT const vtkm::cont::ArrayHandle<vtkm::Range>& GetRange(TypeList, StorageList) const
template <typename TypeList>
VTKM_CONT void GetRange(vtkm::Range* range, TypeList) const
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
return this->GetRangeImpl(TypeList(), StorageList());
}
VTKM_CONT
const vtkm::cont::ArrayHandle<vtkm::Range>& GetRange(VTKM_DEFAULT_TYPE_LIST_TAG,
VTKM_DEFAULT_STORAGE_LIST_TAG) const;
template <typename TypeList, typename StorageList>
VTKM_CONT void GetRange(vtkm::Range* range, TypeList, StorageList) const
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
this->GetRange(TypeList(), StorageList());
vtkm::Id length = this->Range.GetNumberOfValues();
this->GetRangeImpl(TypeList());
const vtkm::Id length = this->Range.GetNumberOfValues();
for (vtkm::Id i = 0; i < length; ++i)
{
range[i] = this->Range.GetPortalConstControl().Get(i);
@ -169,28 +143,19 @@ public:
template <typename TypeList>
VTKM_CONT const vtkm::cont::ArrayHandle<vtkm::Range>& GetRange(TypeList) const
{
VTKM_IS_LIST_TAG(TypeList);
return this->GetRange(TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG());
return this->GetRangeImpl(TypeList());
}
template <typename TypeList>
VTKM_CONT void GetRange(vtkm::Range* range, TypeList) const
VTKM_CONT
const vtkm::cont::ArrayHandle<vtkm::Range>& GetRange() const
{
VTKM_IS_LIST_TAG(TypeList);
return this->GetRangeImpl(VTKM_DEFAULT_TYPE_LIST_TAG());
};
this->GetRange(range, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG());
}
VTKM_CONT
const vtkm::cont::ArrayHandle<vtkm::Range>& GetRange() const;
VTKM_CONT
void GetRange(vtkm::Range* range) const;
const vtkm::cont::DynamicArrayHandle& GetData() const;
vtkm::cont::DynamicArrayHandle& GetData();
VTKM_CONT void GetRange(vtkm::Range* range) const
{
return this->GetRange(range, VTKM_DEFAULT_TYPE_LIST_TAG());
};
template <typename T, typename StorageTag>
VTKM_CONT void SetData(const vtkm::cont::ArrayHandle<T, StorageTag>& newdata)
@ -200,27 +165,19 @@ public:
}
VTKM_CONT
void SetData(const vtkm::cont::DynamicArrayHandle& newdata)
void SetData(const vtkm::cont::VariantArrayHandle& newdata)
{
this->Data = newdata;
this->ModifiedFlag = true;
}
template <typename T>
VTKM_CONT void CopyData(const T* ptr, vtkm::Id nvals)
{
this->Data = vtkm::cont::make_ArrayHandle(ptr, nvals, true);
this->ModifiedFlag = true;
}
VTKM_CONT
virtual void PrintSummary(std::ostream& out) const;
VTKM_CONT
virtual void ReleaseResourcesExecution()
{
// TODO: Call ReleaseResourcesExecution on the data when
// the DynamicArrayHandle class is able to do so.
this->Data.ReleaseResourcesExecution();
this->Range.ReleaseResourcesExecution();
}
@ -231,20 +188,19 @@ private:
std::string AssocCellSetName; ///< only populate if assoc is cells
vtkm::IdComponent AssocLogicalDim; ///< only populate if assoc is logical dim
vtkm::cont::DynamicArrayHandle Data;
vtkm::cont::VariantArrayHandle Data;
mutable vtkm::cont::ArrayHandle<vtkm::Range> Range;
mutable bool ModifiedFlag = true;
template <typename TypeList, typename StorageList>
VTKM_CONT const vtkm::cont::ArrayHandle<vtkm::Range>& GetRangeImpl(TypeList, StorageList) const
template <typename TypeList>
VTKM_CONT const vtkm::cont::ArrayHandle<vtkm::Range>& GetRangeImpl(TypeList) const
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
if (this->ModifiedFlag)
{
internal::ComputeRange computeRange(this->Range);
this->Data.ResetTypeAndStorageLists(TypeList(), StorageList()).CastAndCall(computeRange);
vtkm::cont::CastAndCall(
this->Data.ResetTypes(TypeList()), internal::ComputeRange{}, this->Range);
this->ModifiedFlag = false;
}
@ -255,7 +211,7 @@ private:
template <typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::Field& field, Functor&& f, Args&&... args)
{
field.GetData().CastAndCall(std::forward<Functor>(f), std::forward<Args>(args)...);
vtkm::cont::CastAndCall(field.GetData(), std::forward<Functor>(f), std::forward<Args>(args)...);
}
//@{
@ -325,15 +281,21 @@ vtkm::cont::Field make_Field(std::string name,
}
//@}
} // namespace cont
} // namespace vtkm
namespace vtkm
{
namespace cont
{
namespace internal
{
template <>
struct DynamicTransformTraits<vtkm::cont::Field>
{
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
};
} // namespace internal
} // namespace cont
} // namespace vtkm
@ -344,9 +306,7 @@ namespace vtkm
{
namespace cont
{
template <typename TypeList = VTKM_DEFAULT_TYPE_LIST_TAG,
typename StorageList = VTKM_DEFAULT_STORAGE_LIST_TAG>
template <typename TypeList = VTKM_DEFAULT_TYPE_LIST_TAG>
struct SerializableField
{
SerializableField() = default;
@ -358,17 +318,17 @@ struct SerializableField
vtkm::cont::Field Field;
};
}
} // vtkm::cont
} // namespace cont
} // namespace vtkm
namespace diy
{
template <typename TypeList, typename StorageList>
struct Serialization<vtkm::cont::SerializableField<TypeList, StorageList>>
template <typename TypeList>
struct Serialization<vtkm::cont::SerializableField<TypeList>>
{
private:
using Type = vtkm::cont::SerializableField<TypeList, StorageList>;
using Type = vtkm::cont::SerializableField<TypeList>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& serializable)
@ -385,7 +345,7 @@ public:
{
diy::save(bb, field.GetAssocLogicalDim());
}
diy::save(bb, field.GetData().ResetTypeAndStorageLists(TypeList{}, StorageList{}));
diy::save(bb, field.GetData().ResetTypes(TypeList{}));
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& serializable)
@ -398,26 +358,26 @@ public:
diy::load(bb, assocVal);
auto assoc = static_cast<vtkm::cont::Field::Association>(assocVal);
vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList> data;
vtkm::cont::VariantArrayHandleBase<TypeList> data;
if (assoc == vtkm::cont::Field::Association::CELL_SET)
{
std::string assocCellSetName;
diy::load(bb, assocCellSetName);
diy::load(bb, data);
field =
vtkm::cont::Field(name, assoc, assocCellSetName, vtkm::cont::DynamicArrayHandle(data));
vtkm::cont::Field(name, assoc, assocCellSetName, vtkm::cont::VariantArrayHandle(data));
}
else if (assoc == vtkm::cont::Field::Association::LOGICAL_DIM)
{
vtkm::IdComponent assocLogicalDim;
diy::load(bb, assocLogicalDim);
diy::load(bb, data);
field = vtkm::cont::Field(name, assoc, assocLogicalDim, vtkm::cont::DynamicArrayHandle(data));
field = vtkm::cont::Field(name, assoc, assocLogicalDim, vtkm::cont::VariantArrayHandle(data));
}
else
{
diy::load(bb, data);
field = vtkm::cont::Field(name, assoc, vtkm::cont::DynamicArrayHandle(data));
field = vtkm::cont::Field(name, assoc, vtkm::cont::VariantArrayHandle(data));
}
}
};

@ -34,7 +34,7 @@ vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(const vtkm::cont::DataSet
vtkm::cont::Field::Association assoc)
{
return vtkm::cont::detail::FieldRangeComputeImpl(
dataset, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG());
dataset, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG());
}
//-----------------------------------------------------------------------------
@ -44,7 +44,7 @@ vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(const vtkm::cont::MultiBl
vtkm::cont::Field::Association assoc)
{
return vtkm::cont::detail::FieldRangeComputeImpl(
multiblock, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG());
multiblock, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG());
}
}
} // namespace vtkm::cont

@ -47,20 +47,6 @@ vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(
const std::string& name,
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY);
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(
const vtkm::cont::DataSet& dataset,
const std::string& name,
vtkm::cont::Field::Association assoc,
TypeList,
StorageList)
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
return vtkm::cont::detail::FieldRangeComputeImpl(dataset, name, assoc, TypeList(), StorageList());
}
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(
const vtkm::cont::DataSet& dataset,
@ -69,9 +55,9 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(
TypeList)
{
VTKM_IS_LIST_TAG(TypeList);
return vtkm::cont::detail::FieldRangeComputeImpl(
dataset, name, assoc, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG());
return vtkm::cont::detail::FieldRangeComputeImpl(dataset, name, assoc, TypeList());
}
//@}
//{@
@ -88,21 +74,6 @@ vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(
const std::string& name,
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY);
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(
const vtkm::cont::MultiBlock& multiblock,
const std::string& name,
vtkm::cont::Field::Association assoc,
TypeList,
StorageList)
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
return vtkm::cont::detail::FieldRangeComputeImpl(
multiblock, name, assoc, TypeList(), StorageList());
}
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(
const vtkm::cont::MultiBlock& multiblock,
@ -111,9 +82,9 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeCompute(
TypeList)
{
VTKM_IS_LIST_TAG(TypeList);
return vtkm::cont::detail::FieldRangeComputeImpl(
multiblock, name, assoc, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG());
return vtkm::cont::detail::FieldRangeComputeImpl(multiblock, name, assoc, TypeList());
}
//@}
}
} // namespace vtkm::cont

@ -29,13 +29,12 @@ namespace cont
namespace detail
{
template <typename TypeList, typename StorageList>
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeComputeImpl(
const vtkm::cont::DataSet& dataset,
const std::string& name,
vtkm::cont::Field::Association assoc,
TypeList,
StorageList)
TypeList)
{
vtkm::cont::Field field;
try
@ -48,16 +47,15 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeComputeImpl(
return vtkm::cont::ArrayHandle<vtkm::Range>();
}
return field.GetRange(TypeList(), StorageList());
return field.GetRange(TypeList());
}
template <typename TypeList, typename StorageList>
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeComputeImpl(
const vtkm::cont::MultiBlock& multiblock,
const std::string& name,
vtkm::cont::Field::Association assoc,
TypeList,
StorageList)
TypeList)
{
std::vector<vtkm::Range> result_vector = std::accumulate(
multiblock.begin(),
@ -65,7 +63,7 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeComputeImpl(
std::vector<vtkm::Range>(),
[&](const std::vector<vtkm::Range>& accumulated_value, const vtkm::cont::DataSet& dataset) {
vtkm::cont::ArrayHandle<vtkm::Range> block_range =
vtkm::cont::detail::FieldRangeComputeImpl(dataset, name, assoc, TypeList(), StorageList());
vtkm::cont::detail::FieldRangeComputeImpl(dataset, name, assoc, TypeList());
std::vector<vtkm::Range> result = accumulated_value;

@ -45,8 +45,7 @@ vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(const vtkm::cont::D
const std::string& name,
vtkm::cont::Field::Association assoc)
{
return detail::FieldRangeGlobalComputeImpl(
dataset, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG());
return detail::FieldRangeGlobalComputeImpl(dataset, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG());
}
//-----------------------------------------------------------------------------
@ -56,8 +55,7 @@ vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
const std::string& name,
vtkm::cont::Field::Association assoc)
{
return detail::FieldRangeGlobalComputeImpl(
multiblock, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG());
return detail::FieldRangeGlobalComputeImpl(multiblock, name, assoc, VTKM_DEFAULT_TYPE_LIST_TAG());
}
//-----------------------------------------------------------------------------

@ -45,20 +45,6 @@ vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
const std::string& name,
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY);
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
const vtkm::cont::DataSet& dataset,
const std::string& name,
vtkm::cont::Field::Association assoc,
TypeList,
StorageList)
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
return detail::FieldRangeGlobalComputeImpl(dataset, name, assoc, TypeList(), StorageList());
}
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
const vtkm::cont::DataSet& dataset,
@ -67,9 +53,9 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
TypeList)
{
VTKM_IS_LIST_TAG(TypeList);
return detail::FieldRangeGlobalComputeImpl(
dataset, name, assoc, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG());
return detail::FieldRangeGlobalComputeImpl(dataset, name, assoc, TypeList());
}
//@}
//{@
@ -86,20 +72,6 @@ vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
const std::string& name,
vtkm::cont::Field::Association assoc = vtkm::cont::Field::Association::ANY);
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
const vtkm::cont::MultiBlock& multiblock,
const std::string& name,
vtkm::cont::Field::Association assoc,
TypeList,
StorageList)
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
return detail::FieldRangeGlobalComputeImpl(multiblock, name, assoc, TypeList(), StorageList());
}
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
const vtkm::cont::MultiBlock& multiblock,
@ -108,8 +80,7 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalCompute(
TypeList)
{
VTKM_IS_LIST_TAG(TypeList);
return detail::FieldRangeGlobalComputeImpl(
multiblock, name, assoc, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG());
return detail::FieldRangeGlobalComputeImpl(multiblock, name, assoc, TypeList());
}
//@}
}

@ -32,27 +32,25 @@ VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Range> MergeRangesGlobal(
const vtkm::cont::ArrayHandle<vtkm::Range>& range);
template <typename TypeList, typename StorageList>
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalComputeImpl(
const vtkm::cont::DataSet& dataset,
const std::string& name,
vtkm::cont::Field::Association assoc,
TypeList,
StorageList)
TypeList)
{
auto lrange = vtkm::cont::FieldRangeCompute(dataset, name, assoc, TypeList(), StorageList());
auto lrange = vtkm::cont::FieldRangeCompute(dataset, name, assoc, TypeList());
return vtkm::cont::detail::MergeRangesGlobal(lrange);
}
template <typename TypeList, typename StorageList>
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> FieldRangeGlobalComputeImpl(
const vtkm::cont::MultiBlock& multiblock,
const std::string& name,
vtkm::cont::Field::Association assoc,
TypeList,
StorageList)
TypeList)
{
auto lrange = vtkm::cont::FieldRangeCompute(multiblock, name, assoc, TypeList(), StorageList());
auto lrange = vtkm::cont::FieldRangeCompute(multiblock, name, assoc, TypeList());
return vtkm::cont::detail::MergeRangesGlobal(lrange);
}
}

@ -23,7 +23,6 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/EnvironmentTracker.h>
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/Field.h>

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

@ -22,6 +22,7 @@
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/ExecutionObjectBase.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/exec/PointLocator.h>
namespace vtkm

74
vtkm/cont/StorageAny.h Normal file

@ -0,0 +1,74 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_StorageAny_h
#define vtk_m_cont_StorageAny_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/StorageVirtual.h>
namespace vtkm
{
namespace cont
{
template <typename T, typename S>
class VTKM_ALWAYS_EXPORT StorageAny final : public vtkm::cont::StorageVirtual
{
public:
VTKM_CONT
explicit StorageAny(const vtkm::cont::ArrayHandle<T, S>& ah);
explicit StorageAny(vtkm::cont::ArrayHandle<T, S>&& ah) noexcept;
VTKM_CONT
~StorageAny() = default;
const vtkm::cont::ArrayHandle<T, S>& GetHandle() const { return this->Handle; }
vtkm::Id GetNumberOfValues() const { return this->Handle.GetNumberOfValues(); }
void ReleaseResourcesExecution();
void ReleaseResources();
private:
std::unique_ptr<StorageVirtual> MakeNewInstance() const
{
return std::unique_ptr<StorageVirtual>(new StorageAny<T, S>{ vtkm::cont::ArrayHandle<T, S>{} });
}
void ControlPortalForInput(vtkm::cont::internal::TransferInfoArray& payload) const;
void ControlPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload);
void TransferPortalForInput(vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::DeviceAdapterId devId) const;
void TransferPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload,
OutputMode mode,
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId);
vtkm::cont::ArrayHandle<T, S> Handle;
};
}
}
#endif //vtk_m_cont_StorageAny_h

162
vtkm/cont/StorageAny.hxx Normal file

@ -0,0 +1,162 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_StorageAny_hxx
#define vtk_m_cont_StorageAny_hxx
#include <vtkm/cont/StorageAny.h>
#include <vtkm/cont/StorageVirtual.hxx>
namespace vtkm
{
namespace cont
{
VTKM_CONT
template <typename T, typename S>
StorageAny<T, S>::StorageAny(const vtkm::cont::ArrayHandle<T, S>& ah)
: vtkm::cont::StorageVirtual()
, Handle(ah)
{
}
VTKM_CONT
template <typename T, typename S>
StorageAny<T, S>::StorageAny(vtkm::cont::ArrayHandle<T, S>&& ah) noexcept
: vtkm::cont::StorageVirtual(),
Handle(std::move(ah))
{
}
/// release execution side resources
template <typename T, typename S>
void StorageAny<T, S>::ReleaseResourcesExecution()
{
vtkm::cont::StorageVirtual::ReleaseResourcesExecution();
this->Handle.ReleaseResourcesExecution();
}
/// release control side resources
template <typename T, typename S>
void StorageAny<T, S>::ReleaseResources()
{
vtkm::cont::StorageVirtual::ReleaseResources();
this->Handle.ReleaseResources();
}
namespace detail
{
struct PortalWrapperToDevice
{
template <typename DeviceAdapterTag, typename Handle>
bool operator()(DeviceAdapterTag device,
Handle&& handle,
vtkm::cont::internal::TransferInfoArray& payload) const
{
auto portal = handle.PrepareForInput(device);
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::detail::TransferToDevice<DerivedPortal> transfer;
return transfer(device, payload, portal);
}
template <typename DeviceAdapterTag, typename Handle>
bool operator()(DeviceAdapterTag device,
Handle&& handle,
vtkm::Id numberOfValues,
vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::StorageVirtual::OutputMode mode) const
{
using ACCESS_MODE = vtkm::cont::StorageVirtual::OutputMode;
if (mode == ACCESS_MODE::WRITE)
{
auto portal = handle.PrepareForOutput(numberOfValues, device);
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::detail::TransferToDevice<DerivedPortal> transfer;
return transfer(device, payload, portal);
}
else
{
auto portal = handle.PrepareForInPlace(device);
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::detail::TransferToDevice<DerivedPortal> transfer;
return transfer(device, payload, portal);
}
}
};
}
template <typename T, typename S>
void StorageAny<T, S>::ControlPortalForInput(vtkm::cont::internal::TransferInfoArray& payload) const
{
auto portal = this->Handle.GetPortalConstControl();
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::make_hostPortal<DerivedPortal>(payload, portal);
}
namespace detail
{
template <typename HandleType>
void make_writableHostPortal(std::true_type,
vtkm::cont::internal::TransferInfoArray& payload,
HandleType& handle)
{
auto portal = handle.GetPortalControl();
using DerivedPortal = vtkm::ArrayPortalWrapper<decltype(portal)>;
vtkm::cont::make_hostPortal<DerivedPortal>(payload, portal);
}
template <typename HandleType>
void make_writableHostPortal(std::false_type,
vtkm::cont::internal::TransferInfoArray& payload,
HandleType&)
{
payload.updateHost(nullptr);
throw vtkm::cont::ErrorBadValue(
"ArrayHandleAny was bound to an ArrayHandle that doesn't support output.");
}
}
template <typename T, typename S>
void StorageAny<T, S>::ControlPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload)
{
using HT = vtkm::cont::ArrayHandle<T, S>;
constexpr auto isWriteable = typename vtkm::cont::internal::IsWriteableArrayHandle<HT>::type{};
detail::make_writableHostPortal(isWriteable, payload, this->Handle);
}
template <typename T, typename S>
void StorageAny<T, S>::TransferPortalForInput(vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::DeviceAdapterId devId) const
{
vtkm::cont::TryExecuteOnDevice(devId, detail::PortalWrapperToDevice(), this->Handle, payload);
}
template <typename T, typename S>
void StorageAny<T, S>::TransferPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::StorageVirtual::OutputMode mode,
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId)
{
vtkm::cont::TryExecuteOnDevice(
devId, detail::PortalWrapperToDevice(), this->Handle, numberOfValues, payload, mode);
}
}
} // namespace vtkm::cont
#endif //vtk_m_cont_StorageAny_hxx

@ -53,7 +53,8 @@ namespace internal
{
template <class ArrayPortalType>
class Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>
class VTKM_ALWAYS_EXPORT
Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>
{
using ClassType =
Storage<typename ArrayPortalType::ValueType, StorageTagImplicit<ArrayPortalType>>;

@ -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.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include "StorageVirtual.h"
#include <vtkm/cont/internal/DeviceAdapterError.h>
namespace vtkm
{
namespace cont
{
namespace internal
{
//--------------------------------------------------------------------
Storage<void, ::vtkm::cont::StorageTagVirtual>::Storage(
const Storage<void, vtkm::cont::StorageTagVirtual>& src)
: HostUpToDate(src.HostUpToDate)
, DeviceUpToDate(src.DeviceUpToDate)
, DeviceTransferState(src.DeviceTransferState)
{
}
//--------------------------------------------------------------------
Storage<void, ::vtkm::cont::StorageTagVirtual>::Storage(
Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept
: HostUpToDate(src.HostUpToDate),
DeviceUpToDate(src.DeviceUpToDate),
DeviceTransferState(std::move(src.DeviceTransferState))
{
}
//--------------------------------------------------------------------
Storage<void, vtkm::cont::StorageTagVirtual>& Storage<void, ::vtkm::cont::StorageTagVirtual>::
operator=(const Storage<void, vtkm::cont::StorageTagVirtual>& src)
{
this->HostUpToDate = src.HostUpToDate;
this->DeviceUpToDate = src.DeviceUpToDate;
this->DeviceTransferState = src.DeviceTransferState;
return *this;
}
//--------------------------------------------------------------------
Storage<void, vtkm::cont::StorageTagVirtual>& Storage<void, ::vtkm::cont::StorageTagVirtual>::
operator=(Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept
{
this->HostUpToDate = src.HostUpToDate;
this->DeviceUpToDate = src.DeviceUpToDate;
this->DeviceTransferState = std::move(src.DeviceTransferState);
return *this;
}
//--------------------------------------------------------------------
Storage<void, ::vtkm::cont::StorageTagVirtual>::~Storage()
{
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::ReleaseResourcesExecution()
{
this->DeviceTransferState->releaseDevice();
this->DeviceUpToDate = false;
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::ReleaseResources()
{
this->DeviceTransferState->releaseAll();
this->HostUpToDate = false;
this->DeviceUpToDate = false;
}
//--------------------------------------------------------------------
std::unique_ptr<Storage<void, ::vtkm::cont::StorageTagVirtual>>
Storage<void, ::vtkm::cont::StorageTagVirtual>::NewInstance() const
{
return this->MakeNewInstance();
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForInput(
vtkm::cont::DeviceAdapterId devId) const
{
if (devId == vtkm::cont::DeviceAdapterTagUndefined())
{
throw vtkm::cont::ErrorBadValue("device should not be VTKM_DEVICE_ADAPTER_UNDEFINED");
}
if (devId == vtkm::cont::DeviceAdapterTagError())
{
throw vtkm::cont::ErrorBadValue("device should not be VTKM_DEVICE_ADAPTER_ERROR");
}
const bool needsUpload = !(this->DeviceTransferState->valid(devId) && this->DeviceUpToDate);
if (needsUpload)
{ //Either transfer state is pointing to another device, or has
//had the execution resources released. Either way we
//need to re-transfer the execution information
auto* payload = this->DeviceTransferState.get();
this->TransferPortalForInput(*payload, devId);
this->DeviceUpToDate = true;
}
return this->DeviceTransferState->devicePtr();
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId)
{
if (devId == vtkm::cont::DeviceAdapterTagUndefined())
{
throw vtkm::cont::ErrorBadValue("device should not be VTKM_DEVICE_ADAPTER_UNDEFINED");
}
if (devId == vtkm::cont::DeviceAdapterTagError())
{
throw vtkm::cont::ErrorBadValue("device should not be VTKM_DEVICE_ADAPTER_ERROR");
}
const bool needsUpload = !(this->DeviceTransferState->valid(devId) && this->DeviceUpToDate);
if (needsUpload)
{
this->TransferPortalForOutput(
*(this->DeviceTransferState), OutputMode::WRITE, numberOfValues, devId);
this->HostUpToDate = false;
this->DeviceUpToDate = true;
}
return this->DeviceTransferState->devicePtr();
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForInPlace(vtkm::cont::DeviceAdapterId devId)
{
if (devId == vtkm::cont::DeviceAdapterTagUndefined())
{
throw vtkm::cont::ErrorBadValue("device should not be VTKM_DEVICE_ADAPTER_UNDEFINED");
}
if (devId == vtkm::cont::DeviceAdapterTagError())
{
throw vtkm::cont::ErrorBadValue("device should not be VTKM_DEVICE_ADAPTER_ERROR");
}
const bool needsUpload = !(this->DeviceTransferState->valid(devId) && this->DeviceUpToDate);
if (needsUpload)
{
vtkm::Id numberOfValues = this->GetNumberOfValues();
this->TransferPortalForOutput(
*(this->DeviceTransferState), OutputMode::READ_WRITE, numberOfValues, devId);
this->HostUpToDate = false;
this->DeviceUpToDate = true;
}
return this->DeviceTransferState->devicePtr();
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::GetPortalControl()
{
if (!this->HostUpToDate)
{
//we need to prepare for input and grab the host ptr
auto* payload = this->DeviceTransferState.get();
this->ControlPortalForOutput(*payload);
}
this->DeviceUpToDate = false;
this->HostUpToDate = true;
return this->DeviceTransferState->hostPtr();
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::GetPortalConstControl() const
{
if (!this->HostUpToDate)
{
//we need to prepare for input and grab the host ptr
vtkm::cont::internal::TransferInfoArray* payload = this->DeviceTransferState.get();
this->ControlPortalForInput(*payload);
}
this->HostUpToDate = true;
return this->DeviceTransferState->hostPtr();
}
//--------------------------------------------------------------------
DeviceAdapterId Storage<void, ::vtkm::cont::StorageTagVirtual>::GetDeviceAdapterId() const noexcept
{
return this->DeviceTransferState->deviceId();
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::ControlPortalForOutput(
vtkm::cont::internal::TransferInfoArray&)
{
throw vtkm::cont::ErrorBadValue(
"StorageTagVirtual by default doesn't support control side writes.");
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::TransferPortalForOutput(
vtkm::cont::internal::TransferInfoArray&,
OutputMode,
vtkm::Id,
vtkm::cont::DeviceAdapterId)
{
throw vtkm::cont::ErrorBadValue("StorageTagVirtual by default doesn't support exec side writes.");
}
}
}
}

190
vtkm/cont/StorageVirtual.h Normal file

@ -0,0 +1,190 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_StorageVirtual_h
#define vtk_m_cont_StorageVirtual_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/Storage.h>
#include <vtkm/cont/internal/TransferInfo.h>
#include <vtkm/internal/ArrayPortalVirtual.h>
#include <typeinfo>
namespace vtkm
{
namespace cont
{
struct VTKM_ALWAYS_EXPORT StorageTagVirtual
{
};
namespace internal
{
template <>
class VTKM_CONT_EXPORT Storage<void, vtkm::cont::StorageTagVirtual>
{
public:
/// \brief construct storage that VTK-m is responsible for
Storage() = default;
Storage(const Storage<void, vtkm::cont::StorageTagVirtual>& src);
Storage(Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept;
Storage& operator=(const Storage<void, vtkm::cont::StorageTagVirtual>& src);
Storage& operator=(Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept;
virtual ~Storage();
/// Releases any resources being used in the execution environment (that are
/// not being shared by the control environment).
///
/// Only needs to overridden by subclasses such as Zip that have member
/// variables that themselves have execution memory
virtual void ReleaseResourcesExecution();
/// Releases all resources in both the control and execution environments.
///
/// Only needs to overridden by subclasses such as Zip that have member
/// variables that themselves have execution memory
virtual void ReleaseResources();
/// Returns the number of entries in the array.
///
virtual vtkm::Id GetNumberOfValues() const = 0;
/// \brief Allocates an array large enough to hold the given number of values.
///
/// The allocation may be done on an already existing array, but can wipe out
/// any data already in the array. This method can throw
/// ErrorBadAllocation if the array cannot be allocated or
/// ErrorBadValue if the allocation is not feasible (for example, the
/// array storage is read-only).
///
void Allocate(vtkm::Id numberOfValues)
{
std::cout << "StorageVirtual::Allocate(" << numberOfValues << ") Not Implemented!" << std::endl;
} //return this->DoAllocate(numberOfValues); }
/// \brief Reduces the size of the array without changing its values.
///
/// This method allows you to resize the array without reallocating it. The
/// number of entries in the array is changed to \c numberOfValues. The data
/// in the array (from indices 0 to \c numberOfValues - 1) are the same, but
/// \c numberOfValues must be equal or less than the preexisting size
/// (returned from GetNumberOfValues). That is, this method can only be used
/// to shorten the array, not lengthen.
void Shrink(vtkm::Id numberOfValues)
{
std::cout << "StorageVirtual::Shrink(" << numberOfValues << ") Not Implemented!." << std::endl;
} //return this->DoShrink(numberOfValues); }
/// Determines if storage types matches the type passed in.
///
template <typename DerivedStorage>
bool IsType() const
{ //needs optimizations based on platform. !OSX can use typeid
return nullptr != dynamic_cast<const DerivedStorage*>(this);
}
/// \brief Create a new storage of the same type as this storage.
///
/// This method creates a new storage that is the same type as this one and
/// returns a unique_ptr for it. This method is convenient when
/// creating output arrays that should be the same type as some input array.
///
std::unique_ptr<Storage<void, ::vtkm::cont::StorageTagVirtual>> NewInstance() const;
template <typename DerivedStorage>
const DerivedStorage* Cast() const
{
const DerivedStorage* derived = dynamic_cast<const DerivedStorage*>(this);
if (!derived)
{
VTKM_LOG_CAST_FAIL(*this, DerivedStorage);
throwFailedDynamicCast("StorageVirtual", vtkm::cont::TypeName<DerivedStorage>());
}
VTKM_LOG_CAST_SUCC(*this, derived);
return derived;
}
const vtkm::internal::PortalVirtualBase* PrepareForInput(vtkm::cont::DeviceAdapterId devId) const;
const vtkm::internal::PortalVirtualBase* PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId);
const vtkm::internal::PortalVirtualBase* PrepareForInPlace(vtkm::cont::DeviceAdapterId devId);
//This needs to cause a host side sync!
//This needs to work before we execute on a device
const vtkm::internal::PortalVirtualBase* GetPortalControl();
//This needs to cause a host side sync!
//This needs to work before we execute on a device
const vtkm::internal::PortalVirtualBase* GetPortalConstControl() const;
/// Returns the DeviceAdapterId for the current device. If there is no device
/// with an up-to-date copy of the data, VTKM_DEVICE_ADAPTER_UNDEFINED is
/// returned.
DeviceAdapterId GetDeviceAdapterId() const noexcept;
enum struct OutputMode
{
WRITE,
READ_WRITE
};
private:
//Memory management routines
// virtual void DoAllocate(vtkm::Id numberOfValues) = 0;
// virtual void DoShrink(vtkm::Id numberOfValues) = 0;
//RTTI routines
virtual std::unique_ptr<Storage<void, ::vtkm::cont::StorageTagVirtual>> MakeNewInstance()
const = 0;
//Portal routines
virtual void ControlPortalForInput(vtkm::cont::internal::TransferInfoArray& payload) const = 0;
virtual void ControlPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload);
virtual void TransferPortalForInput(vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::DeviceAdapterId devId) const = 0;
virtual void TransferPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload,
OutputMode mode,
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId);
//These might need to exist in TransferInfoArray
mutable bool HostUpToDate = false;
mutable bool DeviceUpToDate = false;
std::shared_ptr<vtkm::cont::internal::TransferInfoArray> DeviceTransferState =
std::make_shared<vtkm::cont::internal::TransferInfoArray>();
};
} // namespace internal
using StorageVirtual = internal::Storage<void, vtkm::cont::StorageTagVirtual>;
}
} // namespace vtkm::cont
#endif

@ -0,0 +1,71 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_StorageVirtual_hxx
#define vtk_m_cont_StorageVirtual_hxx
#include <vtkm/cont/StorageAny.hxx>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/internal/TransferInfo.h>
namespace vtkm
{
namespace cont
{
namespace detail
{
template <typename DerivedPortal>
struct TransferToDevice
{
template <typename DeviceAdapterTag, typename Payload, typename... Args>
bool operator()(DeviceAdapterTag devId, Payload&& payload, Args&&... args) const
{
using TransferType = cont::internal::VirtualObjectTransfer<DerivedPortal, DeviceAdapterTag>;
//construct all new transfer payload
auto host = std::unique_ptr<DerivedPortal>(new DerivedPortal(std::forward<Args>(args)...));
auto transfer = std::make_shared<TransferType>(host.get());
auto device = transfer->PrepareForExecution(true);
payload.updateDevice(devId, std::move(host), device, std::static_pointer_cast<void>(transfer));
return true;
}
};
}
template <typename DerivedPortal, typename... Args>
inline void make_transferToDevice(vtkm::cont::DeviceAdapterId devId, Args&&... args)
{
vtkm::cont::TryExecuteOnDevice(
devId, detail::TransferToDevice<DerivedPortal>{}, std::forward<Args>(args)...);
}
template <typename DerivedPortal, typename Payload, typename... Args>
inline void make_hostPortal(Payload&& payload, Args&&... args)
{
auto host = std::unique_ptr<DerivedPortal>(new DerivedPortal(std::forward<Args>(args)...));
payload.updateHost(std::move(host));
}
}
} // namespace vtkm::cont::
#endif

@ -20,32 +20,36 @@
#include <sstream>
#include <typeindex>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/VariantArrayHandle.h>
namespace vtkm
{
namespace cont
{
namespace internal
{
VariantArrayHandleContainerBase::VariantArrayHandleContainerBase()
{
}
VariantArrayHandleContainerBase::~VariantArrayHandleContainerBase()
{
}
}
namespace detail
{
PolymorphicArrayHandleContainerBase::PolymorphicArrayHandleContainerBase()
{
}
PolymorphicArrayHandleContainerBase::~PolymorphicArrayHandleContainerBase()
{
}
void ThrowCastAndCallException(PolymorphicArrayHandleContainerBase* ptr,
const std::type_info* type,
const std::type_info* storage)
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 CastAndCall1.\n"
"Array: ";
ptr->PrintSummary(out);
out << "TypeList: " << type->name() << "\nStorageList: " << storage->name() << "\n";
ref.PrintSummary(out);
out << "TypeList: " << type.name() << "\n";
throw vtkm::cont::ErrorBadValue(out.str());
}
}

@ -0,0 +1,389 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_VariantArrayHandle_h
#define vtk_m_cont_VariantArrayHandle_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/TypeListTag.h>
#include <vtkm/VecTraits.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/internal/DynamicTransform.h>
#include <vtkm/cont/internal/VariantArrayHandleContainer.h>
namespace vtkm
{
namespace cont
{
/// \brief Holds an array handle without having to specify template parameters.
///
/// \c VariantArrayHandle holds an \c ArrayHandle or \c ArrayHandleVirtual
/// object using runtime polymorphism to manage different value types and
/// storage 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.
///
/// To interface between the runtime polymorphism and the templated algorithms
/// in VTK-m, \c VariantArrayHandle contains a method named \c CastAndCall that
/// will determine the correct type from some known list of types. It returns
/// an ArrayHandleVirtual which type erases the storage type by using polymorphism.
/// This mechanism is used internally by VTK-m's worklet invocation
/// mechanism to determine the type when running algorithms.
///
/// By default, \c VariantArrayHandle will assume that the value type in the
/// array matches one of the types specified by \c VTKM_DEFAULT_TYPE_LIST_TAG
/// This list can be changed by using the \c ResetTypes. It is
/// worthwhile to match these lists closely to the possible types that might be
/// used. If a type is missing you will get a runtime error. If there are more
/// types than necessary, then the template mechanism will create a lot of
/// object code that is never used, and keep in mind that the number of
/// combinations grows exponentially when using multiple \c VariantArrayHandle
/// objects.
///
/// The actual implementation of \c VariantArrayHandle is in a templated class
/// named \c VariantArrayHandleBase, which is templated on the list of
/// component types.
///
template <typename TypeList>
class VTKM_ALWAYS_EXPORT VariantArrayHandleBase
{
public:
VTKM_CONT
VariantArrayHandleBase() = default;
template <typename T, typename Storage>
VTKM_CONT VariantArrayHandleBase(const vtkm::cont::ArrayHandle<T, Storage>& array)
: ArrayContainer(std::make_shared<internal::VariantArrayHandleContainer<T>>(
vtkm::cont::ArrayHandleVirtual<T>{ array }))
{
}
template <typename T>
explicit VTKM_CONT VariantArrayHandleBase(
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>& array)
: ArrayContainer(std::make_shared<internal::VariantArrayHandleContainer<T>>(array))
{
}
template <typename OtherTypeList>
VTKM_CONT explicit VariantArrayHandleBase(const VariantArrayHandleBase<OtherTypeList>& src)
: ArrayContainer(internal::variant::GetContainer::Extract(src))
{
}
VTKM_CONT VariantArrayHandleBase(const VariantArrayHandleBase& src) = default;
VTKM_CONT VariantArrayHandleBase(VariantArrayHandleBase&& src) noexcept = default;
VTKM_CONT
~VariantArrayHandleBase() {}
VTKM_CONT
VariantArrayHandleBase<TypeList>& operator=(const VariantArrayHandleBase<TypeList>& src) =
default;
VTKM_CONT
VariantArrayHandleBase<TypeList>& operator=(VariantArrayHandleBase<TypeList>&& src) noexcept =
default;
/// 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());
}
/// 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.
///
template <typename ArrayHandleType>
VTKM_CONT ArrayHandleType Cast() const
{
return internal::variant::Cast<ArrayHandleType>(this->ArrayContainer.get());
}
/// Returns this array cast to a \c ArrayHandleVirtual of the given type. Throws \c
/// ErrorBadType if the cast does not work.
///
template <typename T>
VTKM_CONT vtkm::cont::ArrayHandleVirtual<T> AsVirtual() const
{
return internal::variant::Cast<vtkm::cont::ArrayHandleVirtual<T>>(this->ArrayContainer.get());
}
/// Given a references to an ArrayHandle object, casts this array to the
/// ArrayHandle's type and sets the given ArrayHandle to this array. Throws
/// \c ErrorBadType if the cast does not work. Use \c
/// ArrayHandleType to check if the cast can happen.
///
/// Note that this is a shallow copy. The data are not copied and a change
/// in the data in one array will be reflected in the other.
///
template <typename ArrayHandleType>
VTKM_CONT void CopyTo(ArrayHandleType& array) const
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
array = this->Cast<ArrayHandleType>();
}
/// Changes the types to try casting to when resolving this variant array,
/// which is specified with a list tag like those in TypeListTag.h. Since C++
/// does not allow you to actually change the template arguments, this method
/// returns a new variant array object. This method is particularly useful to
/// narrow down (or expand) the types when using an array of particular
/// constraints.
///
template <typename NewTypeList>
VTKM_CONT VariantArrayHandleBase<NewTypeList> ResetTypes(NewTypeList = NewTypeList()) const
{
VTKM_IS_LIST_TAG(NewTypeList);
return VariantArrayHandleBase<NewTypeList>(*this);
}
/// Attempts to cast the held array to a specific value type,
/// then call the given functor with the cast array. The types
/// tried in the cast are those in the lists defined by the TypeList.
/// By default \c VariantArrayHandle set this to VTKM_DEFAULT_TYPE_LIST_TAG.
///
template <typename Functor, typename... Args>
VTKM_CONT void CastAndCall(Functor&& f, Args&&...) const;
/// \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 variant array handle for it. This method is convenient when
/// creating output arrays that should be the same type as some input array.
///
VTKM_CONT
VariantArrayHandleBase<TypeList> NewInstance() const
{
VariantArrayHandleBase<TypeList> instance;
instance.ArrayContainer = this->ArrayContainer->NewInstance();
return instance;
}
/// 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); }
private:
friend struct internal::variant::GetContainer;
std::shared_ptr<vtkm::cont::internal::VariantArrayHandleContainerBase> ArrayContainer;
};
using VariantArrayHandle = vtkm::cont::VariantArrayHandleBase<VTKM_DEFAULT_TYPE_LIST_TAG>;
//=============================================================================
// Free function casting helpers
template <typename ArrayHandleType, typename Ts>
VTKM_CONT inline bool IsType(const vtkm::cont::VariantArrayHandleBase<Ts>& variant)
{
return variant.template IsType<ArrayHandleType>();
}
template <typename ArrayHandleType, typename Ts>
VTKM_CONT inline ArrayHandleType Cast(const vtkm::cont::VariantArrayHandleBase<Ts>& variant)
{
return variant.template Cast<ArrayHandleType>();
}
namespace detail
{
struct VariantArrayHandleTry
{
template <typename T, typename Functor, typename... Args>
void operator()(T,
Functor&& f,
bool& called,
const vtkm::cont::internal::VariantArrayHandleContainerBase& container,
Args&&... args) const
{
if (!called && vtkm::cont::internal::variant::IsValueType<T>(&container))
{
called = true;
const auto* derived =
static_cast<const vtkm::cont::internal::VariantArrayHandleContainer<T>*>(&container);
VTKM_LOG_CAST_SUCC(container, derived);
f(derived->Array, std::forward<Args>(args)...);
}
}
};
VTKM_CONT_EXPORT void ThrowCastAndCallException(
const vtkm::cont::internal::VariantArrayHandleContainerBase&,
const std::type_info&);
} // namespace detail
template <typename TypeList>
template <typename Functor, typename... Args>
VTKM_CONT void VariantArrayHandleBase<TypeList>::CastAndCall(Functor&& f, Args&&... args) const
{
bool called = false;
const auto& ref = *this->ArrayContainer;
vtkm::ListForEach(detail::VariantArrayHandleTry{},
TypeList{},
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 internal
{
template <typename TypeList>
struct DynamicTransformTraits<vtkm::cont::VariantArrayHandleBase<TypeList>>
{
using DynamicTag = vtkm::cont::internal::DynamicTransformTagCastAndCall;
};
} // namespace internal
} // namespace cont
} // namespace vtkm
//=============================================================================
// Specializations of serialization related classes
namespace diy
{
namespace internal
{
struct VariantArrayHandleSerializeFunctor
{
template <typename ArrayHandleType>
void operator()(const ArrayHandleType& ah, BinaryBuffer& bb) const
{
diy::save(bb, vtkm::cont::TypeString<ArrayHandleType>::Get());
diy::save(bb, ah);
}
};
struct VariantArrayHandleDeserializeFunctor
{
template <typename T, typename TypeList>
void operator()(T,
vtkm::cont::VariantArrayHandleBase<TypeList>& dh,
const std::string& typeString,
bool& success,
BinaryBuffer& bb) const
{
using ArrayHandleType = vtkm::cont::ArrayHandleVirtual<T>;
if (!success && (typeString == vtkm::cont::TypeString<ArrayHandleType>::Get()))
{
ArrayHandleType ah;
diy::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>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const Type& obj)
{
vtkm::cont::CastAndCall(obj, internal::VariantArrayHandleSerializeFunctor{}, bb);
}
static VTKM_CONT void load(BinaryBuffer& bb, Type& obj)
{
std::string typeString;
diy::load(bb, typeString);
bool success = false;
vtkm::ListForEach(
internal::VariantArrayHandleDeserializeFunctor{}, TypeList{}, obj, typeString, success, bb);
if (!success)
{
throw vtkm::cont::ErrorBadType(
"Error deserializing VariantArrayHandle. Message TypeString: " + typeString);
}
}
};
} // diy
#endif //vtk_m_virts_VariantArrayHandle_h

@ -23,7 +23,10 @@
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/StorageBasic.h>
#include <vtkm/cont/StorageVirtual.h>
#include <vtkm/cont/arg/Transport.h>
@ -70,6 +73,42 @@ struct Transport<vtkm::cont::arg::TransportTagAtomicArray,
return obj.PrepareForExecution(Device());
}
};
template <typename T, typename Device>
struct Transport<vtkm::cont::arg::TransportTagAtomicArray,
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>,
Device>
{
using ExecObjectType = vtkm::exec::AtomicArrayExecutionObject<T, Device>;
using ExecType = vtkm::cont::AtomicArray<T>;
template <typename InputDomainType>
VTKM_CONT ExecObjectType
operator()(vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>& array,
const InputDomainType&,
vtkm::Id,
vtkm::Id) const
{
using ArrayHandleType = vtkm::cont::ArrayHandle<T>;
const bool is_type = vtkm::cont::IsType<ArrayHandleType>(array);
if (!is_type)
{
#if defined(VTKM_ENABLE_LOGGING)
VTKM_LOG_CAST_FAIL(array, ArrayHandleType);
#endif
throw vtkm::cont::ErrorBadValue("Arrays being used as atomic's must always have storage that "
"is of the type StorageTagBasic.");
}
ArrayHandleType handle = vtkm::cont::Cast<ArrayHandleType>(array);
// Note: we ignore the size of the domain because the randomly accessed
// array might not have the same size depending on how the user is using
// the array.
ExecType obj(handle);
return obj.PrepareForExecution(Device());
}
};
}
}
} // namespace vtkm::cont::arg

@ -26,6 +26,7 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/StorageBasic.h>
#include <vtkm/cont/StorageVirtual.h>
#include <vtkm/cont/AtomicArray.h>
@ -59,6 +60,14 @@ struct TypeCheck<TypeCheckTagAtomicArray<TypeList>,
static constexpr bool value = (vtkm::ListContains<TypeList, T>::value &&
vtkm::ListContains<vtkm::cont::AtomicArrayTypeListTag, T>::value);
};
template <typename T, typename TypeList>
struct TypeCheck<TypeCheckTagAtomicArray<TypeList>,
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>>
{
static constexpr bool value = (vtkm::ListContains<TypeList, T>::value &&
vtkm::ListContains<vtkm::cont::AtomicArrayTypeListTag, T>::value);
};
}
}
} // namespace vtkm::cont::arg

@ -23,6 +23,7 @@ set(headers
ArrayHandleBasicImpl.h
ArrayHandleBasicImpl.hxx
ArrayHandleExecutionManager.h
VariantArrayHandleContainer.h
ArrayManagerExecution.h
ArrayManagerExecutionShareWithControl.h
ArrayPortalFromIterators.h
@ -45,6 +46,7 @@ set(headers
ReverseConnectivityBuilder.h
SimplePolymorphicContainer.h
StorageError.h
TransferInfo.h
VirtualObjectTransfer.h
VirtualObjectTransferShareWithControl.h
)

@ -0,0 +1,68 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/internal/TransferInfo.h>
#include <vtkm/internal/ArrayPortalVirtual.h>
namespace vtkm
{
namespace cont
{
namespace internal
{
bool TransferInfoArray::valid(vtkm::cont::DeviceAdapterId devId) const noexcept
{
return this->DeviceId == devId;
}
void TransferInfoArray::updateHost(
std::unique_ptr<vtkm::internal::PortalVirtualBase>&& host) noexcept
{
this->Host = std::move(host);
}
void TransferInfoArray::updateDevice(vtkm::cont::DeviceAdapterId devId,
std::unique_ptr<vtkm::internal::PortalVirtualBase>&& hostCopy,
const vtkm::internal::PortalVirtualBase* device,
const std::shared_ptr<void>& deviceState) noexcept
{
this->HostCopyOfDevice = std::move(hostCopy);
this->DeviceId = devId;
this->Device = device;
this->DeviceTransferState = deviceState;
}
void TransferInfoArray::releaseDevice()
{
this->DeviceId = vtkm::cont::DeviceAdapterTagUndefined{};
this->Device = nullptr; //The device transfer state own this pointer
this->DeviceTransferState = nullptr; //release the device transfer state
this->HostCopyOfDevice.release(); //we own this pointer so release it
}
void TransferInfoArray::releaseAll()
{
this->Host.release(); //we own this pointer so release it
this->releaseDevice();
}
}
}
}

@ -0,0 +1,74 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_internal_TransferInfo_h
#define vtk_m_cont_internal_TransferInfo_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/Types.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/internal/ArrayPortalVirtual.h>
#include <memory>
namespace vtkm
{
namespace internal
{
class PortalVirtualBase;
}
namespace cont
{
namespace internal
{
struct VTKM_CONT_EXPORT TransferInfoArray
{
bool valid(vtkm::cont::DeviceAdapterId tagValue) const noexcept;
void updateHost(std::unique_ptr<vtkm::internal::PortalVirtualBase>&& host) noexcept;
void updateDevice(
vtkm::cont::DeviceAdapterId id,
std::unique_ptr<vtkm::internal::PortalVirtualBase>&& host_copy, //NOT the same as host version
const vtkm::internal::PortalVirtualBase* device,
const std::shared_ptr<void>& state) noexcept;
void releaseDevice();
void releaseAll();
const vtkm::internal::PortalVirtualBase* hostPtr() const noexcept { return this->Host.get(); }
const vtkm::internal::PortalVirtualBase* devicePtr() const noexcept { return this->Device; }
vtkm::cont::DeviceAdapterId deviceId() const noexcept { return this->DeviceId; }
std::shared_ptr<void>& state() noexcept { return this->DeviceTransferState; }
private:
vtkm::cont::DeviceAdapterId DeviceId = vtkm::cont::DeviceAdapterTagUndefined{};
std::unique_ptr<vtkm::internal::PortalVirtualBase> Host = nullptr;
std::unique_ptr<vtkm::internal::PortalVirtualBase> HostCopyOfDevice = nullptr;
const vtkm::internal::PortalVirtualBase* Device = nullptr;
std::shared_ptr<void> DeviceTransferState = nullptr;
};
}
}
}
#endif

@ -0,0 +1,217 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_VariantArrayHandleContainer_h
#define vtk_m_cont_VariantArrayHandleContainer_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/ArrayHandleVirtual.hxx>
#include <memory>
#include <vtkm/Types.h>
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
{
VariantArrayHandleContainerBase();
// 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;
virtual const vtkm::cont::StorageVirtual* GetStorage() const = 0;
};
/// \brief ArrayHandle container that can use C++ run-time type information.
///
/// The \c VariantArrayHandleContainer is similar to the
/// \c SimplePolymorphicContainer in that it can contain an object of an
/// unknown type. However, this class specifically 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;
VariantArrayHandleContainer()
: Array()
{
}
VariantArrayHandleContainer(const vtkm::cont::ArrayHandleVirtual<T>& array)
: Array(array)
{
}
~VariantArrayHandleContainer<T>() = default;
vtkm::Id GetNumberOfValues() const { return this->Array.GetNumberOfValues(); }
vtkm::IdComponent GetNumberOfComponents() const { return vtkm::VecTraits<T>::NUM_COMPONENTS; }
void ReleaseResourcesExecution() { this->Array.ReleaseResourcesExecution(); }
void ReleaseResources() { this->Array.ReleaseResources(); }
void PrintSummary(std::ostream& out) const
{
vtkm::cont::printSummary_ArrayHandle(this->Array, out);
}
std::shared_ptr<VariantArrayHandleContainerBase> NewInstance() const
{
return std::make_shared<VariantArrayHandleContainer<T>>(this->Array.NewInstance());
}
const vtkm::cont::StorageVirtual* GetStorage() const { return this->Array.GetStorage(); }
};
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 ArrayHandleType>
VTKM_CONT bool IsType(const VariantArrayHandleContainerBase* container)
{ //container could be nullptr
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
if (!container)
{
return false;
}
using VT = typename ArrayHandleType::ValueType;
using ST = typename ArrayHandleType::StorageTag;
const vtkm::cont::StorageVirtual* storage = container->GetStorage();
return storage->IsType<vtkm::cont::StorageAny<VT, ST>>();
}
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 (nullptr != dynamic_cast<const VariantArrayHandleContainer<T>*>(container));
}
template <typename T, typename S>
struct VTKM_ALWAYS_EXPORT Caster
{
vtkm::cont::ArrayHandle<T, S> operator()(const VariantArrayHandleContainerBase* container) const
{
using ArrayHandleType = vtkm::cont::ArrayHandle<T, S>;
if (!IsType<ArrayHandleType>(container))
{
VTKM_LOG_CAST_FAIL(container, ArrayHandleType);
throwFailedDynamicCast(vtkm::cont::TypeName(container),
vtkm::cont::TypeName<ArrayHandleType>());
}
//we know the storage isn't a virtual but another storage type
//that means that the container holds a vtkm::cont::StorageAny<T>
const auto* any = static_cast<const vtkm::cont::StorageAny<T, S>*>(container->GetStorage());
VTKM_LOG_CAST_SUCC(container, *any);
return any->GetHandle();
}
};
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::TypeName(container),
vtkm::cont::TypeName<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;
}
};
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));
}
}
}
}
} //namespace vtkm::cont::internal::variant
#endif

@ -21,8 +21,8 @@
#include "vtkm/cont/internal/DynamicTransform.h"
#include "vtkm/cont/ArrayHandle.h"
#include "vtkm/cont/DynamicArrayHandle.h"
#include "vtkm/cont/DynamicCellSet.h"
#include "vtkm/cont/VariantArrayHandle.h"
#include "vtkm/internal/FunctionInterface.h"
@ -31,7 +31,7 @@
namespace vtkm
{
// DynamicArrayHandle requires its value type to have a defined VecTraits
// VariantArrayHandle requires its value type to have a defined VecTraits
// class. One of the tests is to use an "unusual" array of std::string
// (which is pretty pointless but might tease out some assumptions).
// Make an implementation here. Because I am lazy, this is only a partial
@ -71,10 +71,15 @@ struct ScalarFunctor
struct ArrayHandleScalarFunctor
{
template <typename T>
void operator()(const vtkm::cont::ArrayHandle<T>&) const
void operator()(const vtkm::cont::ArrayHandleVirtual<T>&) const
{
VTKM_TEST_FAIL("Called wrong form of functor operator.");
}
void operator()(const vtkm::cont::ArrayHandleVirtual<vtkm::FloatDefault>&) const
{
std::cout << " In ArrayHandleVirtual<Scalar> functor." << std::endl;
g_FunctionCalls++;
}
void operator()(const vtkm::cont::ArrayHandle<vtkm::FloatDefault>&) const
{
std::cout << " In ArrayHandle<Scalar> functor." << std::endl;
@ -84,9 +89,9 @@ struct ArrayHandleScalarFunctor
struct ArrayHandleStringFunctor
{
void operator()(const vtkm::cont::ArrayHandle<std::string>&) const
void operator()(const vtkm::cont::ArrayHandleVirtual<std::string>&) const
{
std::cout << " In ArrayHandle<string> functor." << std::endl;
std::cout << " In ArrayHandleVirtual<string> functor." << std::endl;
g_FunctionCalls++;
}
};
@ -121,6 +126,16 @@ struct FunctionInterfaceFunctor
std::cout << " In FunctionInterface<...> functor." << std::endl;
g_FunctionCalls++;
}
void operator()(
const vtkm::internal::FunctionInterface<void(vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandleVirtual<vtkm::FloatDefault>,
vtkm::cont::ArrayHandleVirtual<std::string>,
vtkm::cont::CellSetStructured<3>)>&) const
{
std::cout << " In FunctionInterface<...> functor." << std::endl;
g_FunctionCalls++;
}
};
void TestBasicTransform()
@ -138,13 +153,13 @@ void TestBasicTransform()
TRY_TRANSFORM(transform(concreteArray, ArrayHandleScalarFunctor(), indexTag));
std::cout << " Trying scalar dynamic array." << std::endl;
vtkm::cont::DynamicArrayHandle dynamicArray = concreteArray;
vtkm::cont::VariantArrayHandle dynamicArray = concreteArray;
TRY_TRANSFORM(transform(dynamicArray, ArrayHandleScalarFunctor(), indexTag));
std::cout << " Trying with unusual (string) dynamic array." << std::endl;
dynamicArray = vtkm::cont::ArrayHandle<std::string>();
TRY_TRANSFORM(transform(
dynamicArray.ResetTypeList(TypeListTagString()), ArrayHandleStringFunctor(), indexTag));
TRY_TRANSFORM(
transform(dynamicArray.ResetTypes(TypeListTagString()), ArrayHandleStringFunctor(), indexTag));
std::cout << " Trying with structured cell set." << std::endl;
vtkm::cont::CellSetStructured<3> concreteCellSet;
@ -171,8 +186,8 @@ void TestFunctionTransform()
TRY_TRANSFORM(
vtkm::internal::make_FunctionInterface<void>(
scalarArray,
vtkm::cont::DynamicArrayHandle(scalarArray),
vtkm::cont::DynamicArrayHandle(stringArray).ResetTypeList(TypeListTagString()),
vtkm::cont::VariantArrayHandle(scalarArray),
vtkm::cont::VariantArrayHandle(stringArray).ResetTypes(TypeListTagString()),
vtkm::cont::DynamicCellSet(structuredCellSet))
.DynamicTransformCont(vtkm::cont::internal::DynamicTransform(), FunctionInterfaceFunctor()));
}

@ -55,6 +55,8 @@ set(unit_tests
UnitTestArrayHandleTransform.cxx
UnitTestArrayHandleUniformPointCoordinates.cxx
UnitTestArrayHandleConcatenate.cxx
UnitTestArrayHandleVirtual.cxx
UnitTestVariantArrayHandle.cxx
UnitTestArrayPortalToIterators.cxx
UnitTestCellLocator.cxx
UnitTestCellSetExplicit.cxx
@ -68,7 +70,6 @@ set(unit_tests
UnitTestDataSetUniform.cxx
UnitTestDeviceAdapterAlgorithmDependency.cxx
UnitTestDeviceAdapterAlgorithmGeneral.cxx
UnitTestDynamicArrayHandle.cxx
UnitTestDynamicCellSet.cxx
UnitTestFieldRangeCompute.cxx
UnitTestLogging.cxx

@ -30,8 +30,8 @@
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/VariantArrayHandle.h>
// clang-format off
@ -216,28 +216,28 @@ struct TestEqualArrayHandle
}
}
template <typename T, typename StorageTag, typename TypeList, typename StorageList>
template <typename T, typename StorageTag, typename TypeList>
VTKM_CONT void operator()(
const vtkm::cont::ArrayHandle<T, StorageTag>& array1,
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& array2,
const vtkm::cont::VariantArrayHandleBase<TypeList>& array2,
TestEqualResult& result) const
{
array2.CastAndCall(*this, array1, result);
}
template <typename T, typename StorageTag, typename TypeList, typename StorageList>
template <typename T, typename StorageTag, typename TypeList>
VTKM_CONT void operator()(
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& array1,
const vtkm::cont::VariantArrayHandleBase<TypeList>& array1,
const vtkm::cont::ArrayHandle<T, StorageTag>& array2,
TestEqualResult& result) const
{
array1.CastAndCall(*this, array2, result);
}
template <typename TypeList1, typename StorageList1, typename TypeList2, typename StorageList2>
template <typename TypeList1, typename TypeList2>
VTKM_CONT void operator()(
const vtkm::cont::DynamicArrayHandleBase<TypeList1, StorageList1>& array1,
const vtkm::cont::DynamicArrayHandleBase<TypeList2, StorageList2>& array2,
const vtkm::cont::VariantArrayHandleBase<TypeList1>& array1,
const vtkm::cont::VariantArrayHandleBase<TypeList2>& array2,
TestEqualResult& result) const
{
array2.CastAndCall(*this, array1, result);
@ -359,12 +359,10 @@ inline VTKM_CONT TestEqualResult test_equal_CellSets(const CellSet1& cellset1,
return result;
}
template <typename FieldTypeList = VTKM_DEFAULT_TYPE_LIST_TAG,
typename FieldStorageList = VTKM_DEFAULT_STORAGE_LIST_TAG>
template <typename FieldTypeList = VTKM_DEFAULT_TYPE_LIST_TAG>
inline VTKM_CONT TestEqualResult test_equal_Fields(const vtkm::cont::Field& f1,
const vtkm::cont::Field& f2,
FieldTypeList fTtypes = FieldTypeList(),
FieldStorageList fStypes = FieldStorageList())
FieldTypeList fTtypes = FieldTypeList())
{
TestEqualResult result;
@ -397,8 +395,8 @@ inline VTKM_CONT TestEqualResult test_equal_Fields(const vtkm::cont::Field& f1,
}
}
result = test_equal_ArrayHandles(f1.GetData().ResetTypeAndStorageLists(fTtypes, fStypes),
f2.GetData().ResetTypeAndStorageLists(fTtypes, fStypes));
result = test_equal_ArrayHandles(f1.GetData().ResetTypes(fTtypes),
f2.GetData().ResetTypes(fTtypes));
if (!result)
{
result.PushMessage("data doesn't match");
@ -408,13 +406,11 @@ inline VTKM_CONT TestEqualResult test_equal_Fields(const vtkm::cont::Field& f1,
}
template <typename CellSetTypes = VTKM_DEFAULT_CELL_SET_LIST_TAG,
typename FieldTypeList = VTKM_DEFAULT_TYPE_LIST_TAG,
typename FieldStorageList = VTKM_DEFAULT_STORAGE_LIST_TAG>
typename FieldTypeList = VTKM_DEFAULT_TYPE_LIST_TAG>
inline VTKM_CONT TestEqualResult test_equal_DataSets(const vtkm::cont::DataSet& ds1,
const vtkm::cont::DataSet& ds2,
CellSetTypes ctypes = CellSetTypes(),
FieldTypeList fTtypes = FieldTypeList(),
FieldStorageList fStypes = FieldStorageList())
FieldTypeList fTtypes = FieldTypeList())
{
TestEqualResult result;
if (ds1.GetNumberOfCoordinateSystems() != ds2.GetNumberOfCoordinateSystems())
@ -458,7 +454,7 @@ inline VTKM_CONT TestEqualResult test_equal_DataSets(const vtkm::cont::DataSet&
}
for (vtkm::IdComponent i = 0; i < ds1.GetNumberOfFields(); ++i)
{
result = test_equal_Fields(ds1.GetField(i), ds2.GetField(i), fTtypes, fStypes);
result = test_equal_Fields(ds1.GetField(i), ds2.GetField(i), fTtypes);
if (!result)
{
result.PushMessage(

@ -26,7 +26,7 @@
#include <vtkm/cont/RuntimeDeviceTracker.h>
#include <vtkm/cont/testing/Testing.h>
// Required for implementation of ArrayRangeCompute for "odd" arrays
// Required for implementation of ArrayRangeCompute for virtual arrays
#include <vtkm/cont/ArrayRangeCompute.hxx>
#include <algorithm>
@ -94,7 +94,7 @@ private:
vtkm::cont::make_Field("TestField", vtkm::cont::Field::Association::POINTS, fieldData, nvals);
vtkm::Range result[NumberOfComponents];
field.GetRange(result, CustomTypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG());
field.GetRange(result, CustomTypeList());
for (vtkm::IdComponent i = 0; i < NumberOfComponents; ++i)
{

@ -21,7 +21,7 @@
#define vtk_m_cont_testing_TestingSerialization_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/VariantArrayHandle.h>
#include <vtkm/cont/testing/Testing.h>
// clang-format off

@ -0,0 +1,208 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/serial/internal/ArrayManagerExecutionSerial.h>
#include <vtkm/cont/serial/internal/DeviceAdapterAlgorithmSerial.h>
#include <vtkm/cont/serial/internal/DeviceAdapterTagSerial.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/BinaryOperators.h>
#include <algorithm>
namespace UnitTestArrayHandleVirtualDetail
{
template <typename ValueType>
struct Test
{
static constexpr vtkm::Id ARRAY_SIZE = 100;
static constexpr vtkm::Id NUM_KEYS = 3;
using ArrayHandle = vtkm::cont::ArrayHandle<ValueType>;
using VirtHandle = vtkm::cont::ArrayHandleVirtual<ValueType>;
using DeviceTag = vtkm::cont::DeviceAdapterTagSerial;
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceTag>;
void TestConstructors()
{
VirtHandle nullStorage;
VTKM_TEST_ASSERT(nullStorage.GetStorage() == nullptr,
"storage should be empty when using ArrayHandleVirtual().");
VirtHandle fromArrayHandle{ ArrayHandle{} };
VTKM_TEST_ASSERT(fromArrayHandle.GetStorage() != nullptr,
"storage should be empty when using ArrayHandleVirtual().");
VTKM_TEST_ASSERT(vtkm::cont::IsType<ArrayHandle>(fromArrayHandle),
"ArrayHandleVirtual should contain a ArrayHandle<ValueType>.");
VirtHandle fromVirtHandle(fromArrayHandle);
VTKM_TEST_ASSERT(fromVirtHandle.GetStorage() != nullptr,
"storage should be empty when using ArrayHandleVirtual().");
VTKM_TEST_ASSERT(vtkm::cont::IsType<ArrayHandle>(fromVirtHandle),
"ArrayHandleVirtual should contain a ArrayHandle<ValueType>.");
VirtHandle fromNullPtrHandle(nullStorage);
VTKM_TEST_ASSERT(fromNullPtrHandle.GetStorage() == nullptr,
"storage should be empty when constructing from a ArrayHandleVirtual that has "
"nullptr storage.");
VTKM_TEST_ASSERT((vtkm::cont::IsType<ArrayHandle>(fromNullPtrHandle) == false),
"ArrayHandleVirtual shouldn't match any type with nullptr storage.");
}
void TestMoveConstructors()
{
//test shared_ptr move constructor
{
vtkm::cont::ArrayHandleCounting<ValueType> countingHandle;
using ST = typename decltype(countingHandle)::StorageTag;
auto sharedPtr = std::make_shared<vtkm::cont::StorageAny<ValueType, ST>>(countingHandle);
VirtHandle virt(std::move(sharedPtr));
VTKM_TEST_ASSERT(
vtkm::cont::IsType<decltype(countingHandle)>(virt),
"ArrayHandleVirtual should be valid after move constructor shared_ptr<Storage>.");
}
//test unique_ptr move constructor
{
vtkm::cont::ArrayHandleCounting<ValueType> countingHandle;
using ST = typename decltype(countingHandle)::StorageTag;
auto uniquePtr = std::unique_ptr<vtkm::cont::StorageAny<ValueType, ST>>(
new vtkm::cont::StorageAny<ValueType, ST>(countingHandle));
VirtHandle virt(std::move(uniquePtr));
VTKM_TEST_ASSERT(
vtkm::cont::IsType<decltype(countingHandle)>(virt),
"ArrayHandleVirtual should be valid after move constructor unique_ptr<Storage>.");
}
//test ArrayHandle move constructor
{
ArrayHandle handle;
VirtHandle virt(std::move(handle));
VTKM_TEST_ASSERT(
vtkm::cont::IsType<ArrayHandle>(virt),
"ArrayHandleVirtual should be valid after move constructor ArrayHandle<ValueType>.");
}
//test ArrayHandleVirtual move constructor
{
ArrayHandle handle;
VirtHandle virt(std::move(handle));
VirtHandle virt2(std::move(virt));
VTKM_TEST_ASSERT(
vtkm::cont::IsType<ArrayHandle>(virt2),
"ArrayHandleVirtual should be valid after move constructor ArrayHandleVirtual<ValueType>.");
}
}
void TestAssignmentOps()
{
//test assignment operator from ArrayHandleVirtual
{
VirtHandle virt;
virt = VirtHandle{ ArrayHandle{} };
VTKM_TEST_ASSERT(vtkm::cont::IsType<ArrayHandle>(virt),
"ArrayHandleVirtual should be valid after assignment op from AHV.");
}
//test assignment operator from ArrayHandle
{
VirtHandle virt = vtkm::cont::ArrayHandleCounting<ValueType>{};
virt = ArrayHandle{};
VTKM_TEST_ASSERT(vtkm::cont::IsType<ArrayHandle>(virt),
"ArrayHandleVirtual should be valid after assignment op from AH.");
}
//test move assignment operator from ArrayHandleVirtual
{
VirtHandle temp{ ArrayHandle{} };
VirtHandle virt;
virt = std::move(temp);
VTKM_TEST_ASSERT(vtkm::cont::IsType<ArrayHandle>(virt),
"ArrayHandleVirtual should be valid after move assignment op from AHV.");
}
//test move assignment operator from ArrayHandle
{
vtkm::cont::ArrayHandleCounting<ValueType> temp;
VirtHandle virt;
virt = std::move(temp);
VTKM_TEST_ASSERT(vtkm::cont::IsType<decltype(temp)>(virt),
"ArrayHandleVirtual should be valid after move assignment op from AH.");
}
}
void TestPrepareForExecution()
{
vtkm::cont::ArrayHandle<ValueType> handle;
handle.Allocate(50);
VirtHandle virt(std::move(handle));
try
{
virt.PrepareForInput(DeviceTag());
virt.PrepareForInPlace(DeviceTag());
virt.PrepareForOutput(ARRAY_SIZE, DeviceTag());
}
catch (vtkm::cont::ErrorBadValue&)
{
// un-expected failure.
VTKM_TEST_FAIL(
"Unexpected error when using Prepare* on an ArrayHandleVirtual with StorageAny.");
}
}
void operator()()
{
TestConstructors();
TestMoveConstructors();
TestAssignmentOps();
TestPrepareForExecution();
}
};
void TestArrayHandleVirtual()
{
Test<vtkm::UInt8>()();
Test<vtkm::Int16>()();
Test<vtkm::Int32>()();
Test<vtkm::Int64>()();
Test<vtkm::Float32>()();
Test<vtkm::Float64>()();
}
} // end namespace UnitTestArrayHandleVirtualDetail
int UnitTestArrayHandleVirtual(int, char* [])
{
using namespace UnitTestArrayHandleVirtualDetail;
return vtkm::cont::testing::Testing::Run(TestArrayHandleVirtual);
}

@ -33,7 +33,6 @@
namespace
{
// clang-format off
template<typename T>
void is_noexcept_movable()
@ -77,10 +76,26 @@ struct IsNoExceptHandle
template <typename T>
void operator()(T) const
{
is_noexcept_movable< vtkm::cont::ArrayHandle<T> >();
using HandleType = vtkm::cont::ArrayHandle<T>;
using VirtualType = vtkm::cont::ArrayHandleVirtual<T>;
//verify the handle type
is_noexcept_movable<HandleType>();
is_noexcept_movable<VirtualType>();
//verify the input portals of the handle
is_noexcept_movable<decltype(
std::declval<HandleType>().PrepareForInput(vtkm::cont::DeviceAdapterTagSerial{}))>();
is_noexcept_movable<decltype(
std::declval<VirtualType>().PrepareForInput(vtkm::cont::DeviceAdapterTagSerial{}))>();
//verify the output portals of the handle
is_noexcept_movable<decltype(
std::declval<HandleType>().PrepareForOutput(2, vtkm::cont::DeviceAdapterTagSerial{}))>();
is_noexcept_movable<decltype(
std::declval<VirtualType>().PrepareForOutput(2, vtkm::cont::DeviceAdapterTagSerial{}))>();
}
};
}
//-----------------------------------------------------------------------------
@ -91,23 +106,22 @@ void TestContDataTypesHaveMoveSemantics()
is_triv_noexcept_movable<vtkm::Vec<vtkm::Vec<float,3>,3>>();
//verify that ArrayHandles are noexcept movable
//verify that ArrayHandles and related portals are noexcept movable
//allowing for efficient storage in containers such as std::vector
vtkm::testing::Testing::TryTypes( IsNoExceptHandle{}, vtkm::TypeListTagAll{} );
//verify the DataSet, Field, and CoordinateSystem,
//verify the DataSet, Field, CoordinateSystem, and ArrayHandleVirtualCoordinates
//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>();
is_noexcept_movable<vtkm::cont::ArrayHandleVirtualCoordinates>();
//verify the CellSetStructured, and CellSetExplicit
//have efficient storage in containers such as std::vector
is_noexcept_movable<vtkm::cont::CellSetStructured<2>>();
is_noexcept_movable<vtkm::cont::CellSetStructured<3>>();
is_noexcept_movable<vtkm::cont::CellSetExplicit<>>();
}

@ -27,8 +27,6 @@
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DataSetFieldAdd.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/FieldRangeCompute.h>
#include <vtkm/cont/MultiBlock.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>

@ -36,7 +36,8 @@
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
#include <vtkm/cont/ArrayHandleZip.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/VariantArrayHandle.h>
#include <vtkm/cont/testing/TestingSerialization.h>
@ -75,12 +76,10 @@ constexpr vtkm::Id ArraySize = 10;
using TestTypesList =
vtkm::ListTagBase<vtkm::Int8, vtkm::Id, vtkm::FloatDefault, vtkm::Vec<vtkm::FloatDefault, 3>>;
using TestStorageList = vtkm::ListTagBase<vtkm::cont::StorageTagBasic>;
template <typename T, typename S>
inline vtkm::cont::DynamicArrayHandleBase<vtkm::ListTagAppendUnique<TestTypesList, T>,
vtkm::ListTagAppendUnique<TestStorageList, S>>
MakeTestDynamicArrayHandle(const vtkm::cont::ArrayHandle<T, S>& array)
inline vtkm::cont::VariantArrayHandleBase<vtkm::ListTagAppendUnique<TestTypesList, T>>
MakeTestVariantArrayHandle(const vtkm::cont::ArrayHandle<T, S>& array)
{
return array;
}
@ -92,7 +91,7 @@ struct TestArrayHandleBasic
{
auto array = RandomArrayHandle<T>::Make(ArraySize);
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -106,7 +105,7 @@ struct TestArrayHandleCartesianProduct
RandomArrayHandle<T>::Make(ArraySize),
RandomArrayHandle<T>::Make(ArraySize));
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -116,9 +115,9 @@ struct TestArrayHandleCast
void operator()(T) const
{
auto array =
vtkm::cont::make_ArrayHandleCast(RandomArrayHandle<vtkm::Int8>::Make(ArraySize), T{});
vtkm::cont::make_ArrayHandleCast<T>(RandomArrayHandle<vtkm::Int8>::Make(ArraySize));
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -130,7 +129,7 @@ struct TestArrayHandleCompositeVector
auto array = vtkm::cont::make_ArrayHandleCompositeVector(RandomArrayHandle<T>::Make(ArraySize),
RandomArrayHandle<T>::Make(ArraySize));
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -142,7 +141,7 @@ struct TestArrayHandleConcatenate
auto array = vtkm::cont::make_ArrayHandleConcatenate(RandomArrayHandle<T>::Make(ArraySize),
RandomArrayHandle<T>::Make(ArraySize));
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -154,7 +153,7 @@ struct TestArrayHandleConstant
T cval = RandomValue<T>::Make();
auto array = vtkm::cont::make_ArrayHandleConstant(cval, ArraySize);
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -167,7 +166,7 @@ struct TestArrayHandleCounting
T step = RandomValue<T>::Make(0, 5);
auto array = vtkm::cont::make_ArrayHandleCounting(start, step, ArraySize);
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -180,7 +179,7 @@ struct TestArrayHandleExtractComponent
auto array = vtkm::cont::make_ArrayHandleExtractComponent(
RandomArrayHandle<T>::Make(ArraySize), RandomValue<vtkm::IdComponent>::Make(0, numComps - 1));
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -197,21 +196,21 @@ struct TestArrayHandleGroupVec
{
auto array = vtkm::cont::make_ArrayHandleGroupVec<3>(flat);
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
break;
}
case 4:
{
auto array = vtkm::cont::make_ArrayHandleGroupVec<4>(flat);
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
break;
}
default:
{
auto array = vtkm::cont::make_ArrayHandleGroupVec<2>(flat);
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
break;
}
}
@ -237,9 +236,9 @@ struct TestArrayHandleGroupVecVariable
vtkm::cont::make_ArrayHandle(comps));
RunTest(array);
// cannot make a DynamicArrayHandle containing ArrayHandleGroupVecVariable
// cannot make a VariantArrayHandle containing ArrayHandleGroupVecVariable
// because of the variable number of components of its values.
// RunTest(MakeTestDynamicArrayHandle(array));
// RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -270,7 +269,7 @@ struct TestArrayHandleImplicit
ImplicitFunctor<T> functor(RandomValue<T>::Make(2, 9));
auto array = vtkm::cont::make_ArrayHandleImplicit(functor, ArraySize);
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -279,7 +278,7 @@ void TestArrayHandleIndex()
auto size = RandomValue<vtkm::Id>::Make(2, 10);
auto array = vtkm::cont::ArrayHandleIndex(size);
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
struct TestArrayHandlePermutation
@ -296,7 +295,7 @@ struct TestArrayHandlePermutation
RandomArrayHandle<vtkm::Id>::Make(ArraySize, 0, ArraySize - 1),
RandomArrayHandle<T>::Make(ArraySize));
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -307,7 +306,7 @@ struct TestArrayHandleReverse
{
auto array = vtkm::cont::make_ArrayHandleReverse(RandomArrayHandle<T>::Make(ArraySize));
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
@ -330,7 +329,7 @@ struct TestArrayHandleSwizzle
auto array = make_ArrayHandleSwizzle(RandomArrayHandle<vtkm::Vec<T, 3>>::Make(ArraySize),
map2s[RandomValue<int>::Make(0, 5)]);
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
break;
}
case 3:
@ -339,13 +338,14 @@ struct TestArrayHandleSwizzle
auto array = make_ArrayHandleSwizzle(RandomArrayHandle<vtkm::Vec<T, 3>>::Make(ArraySize),
map3s[RandomValue<int>::Make(0, 5)]);
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
break;
}
}
}
};
struct TestArrayHandleTransform
{
struct TransformFunctor
@ -362,7 +362,7 @@ struct TestArrayHandleTransform
template <typename T>
VTKM_EXEC_CONT T operator()(const T& in) const
{
return in / T{ 2 };
return static_cast<T>(in / T{ 2 });
}
};
@ -372,7 +372,7 @@ struct TestArrayHandleTransform
auto array = vtkm::cont::make_ArrayHandleTransform(RandomArrayHandle<T>::Make(ArraySize),
TransformFunctor{});
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
template <typename T>
@ -381,7 +381,7 @@ struct TestArrayHandleTransform
auto array = vtkm::cont::make_ArrayHandleTransform(
RandomArrayHandle<T>::Make(ArraySize), TransformFunctor{}, InverseTransformFunctor{});
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
template <typename T>
@ -404,7 +404,7 @@ void TestArrayHandleUniformPointCoordinates()
{
auto array = MakeRandomArrayHandleUniformPointCoordinates();
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
void TestArrayHandleVirtualCoordinates()
@ -432,7 +432,7 @@ void TestArrayHandleVirtualCoordinates()
}
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
struct TestArrayHandleZip
@ -443,10 +443,11 @@ struct TestArrayHandleZip
auto array = vtkm::cont::make_ArrayHandleZip(RandomArrayHandle<T>::Make(ArraySize),
vtkm::cont::ArrayHandleIndex(ArraySize));
RunTest(array);
RunTest(MakeTestDynamicArrayHandle(array));
RunTest(MakeTestVariantArrayHandle(array));
}
};
//-----------------------------------------------------------------------------
void TestArrayHandleSerialization()
{

@ -26,20 +26,18 @@ namespace
{
using FieldTypeList = vtkm::ListTagBase<vtkm::Float32>;
using FieldStorageList = VTKM_DEFAULT_STORAGE_LIST_TAG;
using CellSetTypes = vtkm::ListTagBase<vtkm::cont::CellSetExplicit<>,
vtkm::cont::CellSetSingleType<>,
vtkm::cont::CellSetStructured<1>,
vtkm::cont::CellSetStructured<2>,
vtkm::cont::CellSetStructured<3>>;
using DataSetWrapper =
vtkm::cont::SerializableDataSet<FieldTypeList, FieldStorageList, CellSetTypes>;
using DataSetWrapper = vtkm::cont::SerializableDataSet<FieldTypeList, CellSetTypes>;
VTKM_CONT void TestEqualDataSet(const DataSetWrapper& ds1, const DataSetWrapper& ds2)
{
auto result = vtkm::cont::testing::test_equal_DataSets(
ds1.DataSet, ds2.DataSet, CellSetTypes{}, FieldTypeList{}, FieldStorageList{});
ds1.DataSet, ds2.DataSet, CellSetTypes{}, FieldTypeList{});
VTKM_TEST_ASSERT(result, result.GetMergedMessage());
}

@ -18,7 +18,7 @@
// this software.
//============================================================================
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/VariantArrayHandle.h>
#include <vtkm/TypeTraits.h>
@ -32,6 +32,7 @@
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/ArrayHandleZip.h>
#include <vtkm/cont/internal/IteratorFromArrayPortal.h>
@ -45,7 +46,7 @@
namespace vtkm
{
// DynamicArrayHandle requires its value type to have a defined VecTraits
// VariantArrayHandle requires its value type to have a defined VecTraits
// class. One of the tests is to use an "unusual" array of std::string
// (which is pretty pointless but might tease out some assumptions).
// Make an implementation here. Because I am lazy, this is only a partial
@ -108,22 +109,21 @@ struct TestValueFunctor
struct CheckFunctor
{
template <typename T, typename Storage>
void operator()(vtkm::cont::ArrayHandle<T, Storage> array, bool& called) const
template <typename T>
void operator()(const vtkm::cont::ArrayHandleVirtual<T>& array, bool& called) const
{
called = true;
std::cout << " Checking for type: " << typeid(T).name() << std::endl;
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE, "Unexpected array size.");
typename vtkm::cont::ArrayHandle<T, Storage>::PortalConstControl portal =
array.GetPortalConstControl();
auto portal = array.GetPortalConstControl();
CheckPortal(portal);
}
};
template <typename TypeList, typename StorageList>
void BasicDynamicArrayChecks(const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& array,
template <typename TypeList>
void BasicArrayVariantChecks(const vtkm::cont::VariantArrayHandleBase<TypeList>& array,
vtkm::IdComponent numComponents)
{
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE,
@ -132,9 +132,9 @@ void BasicDynamicArrayChecks(const vtkm::cont::DynamicArrayHandleBase<TypeList,
"Dynamic array reports unexpected number of components.");
}
void CheckDynamicArray(vtkm::cont::DynamicArrayHandle array, vtkm::IdComponent numComponents)
void CheckArrayVariant(vtkm::cont::VariantArrayHandle array, vtkm::IdComponent numComponents)
{
BasicDynamicArrayChecks(array, numComponents);
BasicArrayVariantChecks(array, numComponents);
bool called = false;
array.CastAndCall(CheckFunctor(), called);
@ -143,11 +143,11 @@ void CheckDynamicArray(vtkm::cont::DynamicArrayHandle array, vtkm::IdComponent n
called, "The functor was never called (and apparently a bad value exception not thrown).");
}
template <typename TypeList, typename StorageList>
void CheckDynamicArray(vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList> array,
template <typename TypeList>
void CheckArrayVariant(const vtkm::cont::VariantArrayHandleBase<TypeList>& array,
vtkm::IdComponent numComponents)
{
BasicDynamicArrayChecks(array, numComponents);
BasicArrayVariantChecks(array, numComponents);
bool called = false;
CastAndCall(array, CheckFunctor(), called);
@ -157,7 +157,7 @@ void CheckDynamicArray(vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>
}
template <typename T>
vtkm::cont::DynamicArrayHandle CreateDynamicArray(T)
vtkm::cont::VariantArrayHandle CreateArrayVariant(T)
{
// Declared static to prevent going out of scope.
static T buffer[ARRAY_SIZE];
@ -166,7 +166,7 @@ vtkm::cont::DynamicArrayHandle CreateDynamicArray(T)
buffer[index] = TestValue(index, T());
}
return vtkm::cont::DynamicArrayHandle(vtkm::cont::make_ArrayHandle(buffer, ARRAY_SIZE));
return vtkm::cont::VariantArrayHandle(vtkm::cont::make_ArrayHandle(buffer, ARRAY_SIZE));
}
template <typename ArrayHandleType>
@ -174,29 +174,32 @@ void CheckCastToArrayHandle(const ArrayHandleType& array)
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
vtkm::cont::DynamicArrayHandle dynamicArray = array;
VTKM_TEST_ASSERT(!dynamicArray.IsType<vtkm::cont::ArrayHandle<std::string>>(),
vtkm::cont::VariantArrayHandle arrayVariant = array;
VTKM_TEST_ASSERT(!arrayVariant.IsType<vtkm::cont::ArrayHandle<std::string>>(),
"Dynamic array reporting is wrong type.");
ArrayHandleType castArray1;
dynamicArray.CopyTo(castArray1);
VTKM_TEST_ASSERT(dynamicArray.IsSameType(castArray1), "Did not query handle correctly.");
arrayVariant.CopyTo(castArray1);
VTKM_TEST_ASSERT(arrayVariant.IsType<ArrayHandleType>(), "Did not query handle correctly.");
VTKM_TEST_ASSERT(array == castArray1, "Did not get back same array.");
ArrayHandleType castArray2 =
dynamicArray.CastToTypeStorage<typename ArrayHandleType::ValueType,
typename ArrayHandleType::StorageTag>();
ArrayHandleType castArray2 = arrayVariant.Cast<ArrayHandleType>();
VTKM_TEST_ASSERT(array == castArray2, "Did not get back same array.");
using T = typename ArrayHandleType::ValueType;
vtkm::cont::ArrayHandleVirtual<T> castArray3 = arrayVariant.AsVirtual<T>();
VTKM_TEST_ASSERT(castArray3.GetNumberOfValues() == castArray2.GetNumberOfValues(),
"Did not get back virtual array handle representation.");
}
template <typename T, typename DynamicArrayType>
void TryNewInstance(T, DynamicArrayType originalArray)
template <typename T, typename ArrayVariantType>
void TryNewInstance(T, ArrayVariantType originalArray)
{
// This check should already have been performed by caller, but just in case.
CheckDynamicArray(originalArray, vtkm::VecTraits<T>::NUM_COMPONENTS);
CheckArrayVariant(originalArray, vtkm::VecTraits<T>::NUM_COMPONENTS);
std::cout << "Create new instance of array." << std::endl;
DynamicArrayType newArray = originalArray.NewInstance();
ArrayVariantType newArray = originalArray.NewInstance();
std::cout << "Get a static instance of the new array (which checks the type)." << std::endl;
vtkm::cont::ArrayHandle<T> staticArray;
@ -209,7 +212,7 @@ void TryNewInstance(T, DynamicArrayType originalArray)
{
staticArray.GetPortalControl().Set(index, TestValue(index + 100, T()));
}
CheckDynamicArray(originalArray, vtkm::VecTraits<T>::NUM_COMPONENTS);
CheckArrayVariant(originalArray, vtkm::VecTraits<T>::NUM_COMPONENTS);
std::cout << "Set the new static array to expected values and make sure the new" << std::endl
<< "dynamic array points to the same new values." << std::endl;
@ -217,15 +220,15 @@ void TryNewInstance(T, DynamicArrayType originalArray)
{
staticArray.GetPortalControl().Set(index, TestValue(index, T()));
}
CheckDynamicArray(newArray, vtkm::VecTraits<T>::NUM_COMPONENTS);
CheckArrayVariant(newArray, vtkm::VecTraits<T>::NUM_COMPONENTS);
}
template <typename T>
void TryDefaultType(T)
{
vtkm::cont::DynamicArrayHandle array = CreateDynamicArray(T());
vtkm::cont::VariantArrayHandle array = CreateArrayVariant(T());
CheckDynamicArray(array, vtkm::VecTraits<T>::NUM_COMPONENTS);
CheckArrayVariant(array, vtkm::VecTraits<T>::NUM_COMPONENTS);
TryNewInstance(T(), array);
}
@ -235,23 +238,22 @@ struct TryBasicVTKmType
template <typename T>
void operator()(T) const
{
vtkm::cont::DynamicArrayHandle array = CreateDynamicArray(T());
vtkm::cont::VariantArrayHandle array = CreateArrayVariant(T());
CheckDynamicArray(array.ResetTypeList(vtkm::TypeListTagAll()),
vtkm::VecTraits<T>::NUM_COMPONENTS);
CheckArrayVariant(array.ResetTypes(vtkm::TypeListTagAll()), vtkm::VecTraits<T>::NUM_COMPONENTS);
TryNewInstance(T(), array.ResetTypeList(vtkm::TypeListTagAll()));
TryNewInstance(T(), array.ResetTypes(vtkm::TypeListTagAll()));
}
};
void TryUnusualType()
{
// A string is an unlikely type to be declared elsewhere in VTK-m.
vtkm::cont::DynamicArrayHandle array = CreateDynamicArray(std::string());
vtkm::cont::VariantArrayHandle array = CreateArrayVariant(std::string());
try
{
CheckDynamicArray(array, 1);
CheckArrayVariant(array, 1);
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized type.");
}
catch (vtkm::cont::ErrorBadValue&)
@ -259,35 +261,31 @@ void TryUnusualType()
std::cout << " Caught exception for unrecognized type." << std::endl;
}
CheckDynamicArray(array.ResetTypeList(TypeListTagString()), 1);
CheckArrayVariant(array.ResetTypes(TypeListTagString()), 1);
std::cout << " Found type when type list was reset." << std::endl;
}
void TryUnusualStorage()
{
vtkm::cont::DynamicArrayHandle array = ArrayHandleWithUnusualStorage<vtkm::Id>();
vtkm::cont::VariantArrayHandle array = ArrayHandleWithUnusualStorage<vtkm::Id>();
try
{
CheckDynamicArray(array, 1);
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized storage.");
CheckArrayVariant(array, 1);
}
catch (vtkm::cont::ErrorBadValue&)
catch (...)
{
std::cout << " Caught exception for unrecognized storage." << std::endl;
VTKM_TEST_FAIL("CastAndCall with Variant failed to handle unusual storage.");
}
CheckDynamicArray(array.ResetStorageList(StorageListTagUnusual()), 1);
std::cout << " Found instance when storage list was reset." << std::endl;
}
void TryUnusualTypeAndStorage()
{
vtkm::cont::DynamicArrayHandle array = ArrayHandleWithUnusualStorage<std::string>();
vtkm::cont::VariantArrayHandle array = ArrayHandleWithUnusualStorage<std::string>();
try
{
CheckDynamicArray(array, 1);
CheckArrayVariant(array, 1);
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized type/storage.");
}
catch (vtkm::cont::ErrorBadValue&)
@ -297,46 +295,12 @@ void TryUnusualTypeAndStorage()
try
{
CheckDynamicArray(array.ResetTypeList(TypeListTagString()), 1);
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized storage.");
CheckArrayVariant(array.ResetTypes(TypeListTagString()), 1);
}
catch (vtkm::cont::ErrorBadValue&)
catch (...)
{
std::cout << " Caught exception for unrecognized storage." << std::endl;
VTKM_TEST_FAIL("CastAndCall with Variant failed to handle unusual storage.");
}
try
{
CheckDynamicArray(array.ResetStorageList(StorageListTagUnusual()), 1);
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized type.");
}
catch (vtkm::cont::ErrorBadValue&)
{
std::cout << " Caught exception for unrecognized type." << std::endl;
}
try
{
//resetting the string and tag should result in a valid array handle
CheckDynamicArray(array.ResetTypeAndStorageLists(TypeListTagString(), StorageListTagUnusual()),
1);
}
catch (vtkm::cont::ErrorBadValue&)
{
VTKM_TEST_FAIL("ResetTypeAndStorageLists should have handled the custom type/storage.");
}
CheckDynamicArray(
array.ResetTypeList(TypeListTagString()).ResetStorageList(StorageListTagUnusual()), 1);
std::cout << " Found instance when type and storage lists were reset." << std::endl;
CheckDynamicArray(
array.ResetStorageList(StorageListTagUnusual()).ResetTypeList(TypeListTagString()), 1);
std::cout << " Found instance when storage and type lists were reset." << std::endl;
CheckDynamicArray(array.ResetTypeAndStorageLists(TypeListTagString(), StorageListTagUnusual()),
1);
std::cout << " Found instance when storage and type lists were reset." << std::endl;
}
void TryCastToArrayHandle()
@ -384,11 +348,11 @@ void TryCastToArrayHandle()
std::cout << " Uniform point coordinates array handle." << std::endl;
CheckCastToArrayHandle(vtkm::cont::ArrayHandleUniformPointCoordinates(vtkm::Id3(ARRAY_SIZE)));
std::cout << " Zip array handle." << std::endl;
CheckCastToArrayHandle(vtkm::cont::make_ArrayHandleZip(countingArray, array));
// std::cout << " Zip array handle." << std::endl;
// CheckCastToArrayHandle(vtkm::cont::make_ArrayHandleZip(countingArray, array));
}
void TestDynamicArrayHandle()
void TestVariantArrayHandle()
{
std::cout << "Try common types with default type lists." << std::endl;
std::cout << "*** vtkm::Id **********************" << std::endl;
@ -422,7 +386,7 @@ void TestDynamicArrayHandle()
} // anonymous namespace
int UnitTestDynamicArrayHandle(int, char* [])
int UnitTestVariantArrayHandle(int, char* [])
{
return vtkm::cont::testing::Testing::Run(TestDynamicArrayHandle);
return vtkm::cont::testing::Testing::Run(TestVariantArrayHandle);
}

@ -40,23 +40,43 @@ struct FetchTagArrayDirectIn
{
};
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T, typename U>
inline VTKM_EXEC T load(const U& u, vtkm::Id v)
{
return u.Get(v);
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T, typename U>
inline VTKM_EXEC T load(const U* u, vtkm::Id v)
{
return u->Get(v);
}
template <typename ThreadIndicesType, typename ExecObjectType>
struct Fetch<vtkm::exec::arg::FetchTagArrayDirectIn,
vtkm::exec::arg::AspectTagDefault,
ThreadIndicesType,
ExecObjectType>
{
using ValueType = typename ExecObjectType::ValueType;
//need to remove pointer type from ThreadIdicesType
using ET = typename std::remove_const<typename std::remove_pointer<ExecObjectType>::type>::type;
using PortalType =
typename std::conditional<std::is_pointer<ExecObjectType>::value, const ET*, const ET&>::type;
using ValueType = typename ET::ValueType;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
ValueType Load(const ThreadIndicesType& indices, const ExecObjectType& arrayPortal) const
ValueType Load(const ThreadIndicesType& indices, PortalType arrayPortal) const
{
return arrayPortal.Get(indices.GetInputIndex());
return load<ValueType>(arrayPortal, indices.GetInputIndex());
}
VTKM_EXEC
void Store(const ThreadIndicesType&, const ExecObjectType&, const ValueType&) const
void Store(const ThreadIndicesType&, PortalType, const ValueType&) const
{
// Store is a no-op for this fetch.
}

@ -85,6 +85,17 @@ struct FetchArrayTopologyMapInImplementation
// least as far as the returned VecFromPortalPermute is used.
return ValueType(indices.GetIndicesFromPointer(), field);
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
static ValueType Load(const ThreadIndicesType& indices, const FieldExecObjectType* const field)
{
// It is important that we give the VecFromPortalPermute (ValueType) a
// pointer that will stay around during the time the Vec is valid. Thus, we
// should make sure that indices is a reference that goes up the stack at
// least as far as the returned VecFromPortalPermute is used.
return ValueType(indices.GetIndicesFromPointer(), field);
}
};
static inline VTKM_EXEC vtkm::VecAxisAlignedPointCoordinates<1> make_VecAxisAlignedPointCoordinates(

@ -21,7 +21,6 @@
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ErrorFilterExecution.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
@ -31,29 +30,6 @@ namespace vtkm
namespace filter
{
namespace clipwithfield
{
struct PointMapHelper
{
PointMapHelper(const vtkm::worklet::Clip& worklet, vtkm::cont::DynamicArrayHandle& output)
: Worklet(worklet)
, Output(output)
{
}
template <typename ArrayType>
void operator()(const ArrayType& array) const
{
this->Output = this->Worklet.ProcessPointField(array);
}
const vtkm::worklet::Clip& Worklet;
vtkm::cont::DynamicArrayHandle& Output;
};
} // end namespace clipwithfield
//-----------------------------------------------------------------------------
inline VTKM_CONT ClipWithField::ClipWithField()
: vtkm::filter::FilterDataSetWithField<ClipWithField>()
@ -71,8 +47,6 @@ inline VTKM_CONT vtkm::cont::DataSet ClipWithField::DoExecute(
const vtkm::filter::FieldMetadata& fieldMeta,
vtkm::filter::PolicyBase<DerivedPolicy> policy)
{
using namespace clipwithfield;
if (fieldMeta.IsPointField() == false)
{
throw vtkm::cont::ErrorFilterExecution("Point field expected.");

@ -28,30 +28,6 @@ namespace vtkm
{
namespace filter
{
namespace clipwithimplicitfunction
{
struct PointMapHelper
{
PointMapHelper(const vtkm::worklet::Clip& worklet, vtkm::cont::DynamicArrayHandle& output)
: Worklet(worklet)
, Output(output)
{
}
template <typename ArrayType>
void operator()(const ArrayType& array) const
{
this->Output = this->Worklet.ProcessPointField(array);
}
const vtkm::worklet::Clip& Worklet;
vtkm::cont::DynamicArrayHandle& Output;
};
} // end namespace clipwithimplicitfunction
//-----------------------------------------------------------------------------
ClipWithImplicitFunction::ClipWithImplicitFunction()
@ -64,8 +40,6 @@ inline vtkm::cont::DataSet ClipWithImplicitFunction::DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy)
{
using namespace clipwithimplicitfunction;
//get the cells and coordinates of the dataset
const vtkm::cont::DynamicCellSet& cells = input.GetCellSet(this->GetActiveCellSetIndex());

@ -82,7 +82,7 @@ inline VTKM_CONT vtkm::cont::DataSet CrossProduct::DoExecute(
inDataSet.GetField(this->SecondaryFieldName, this->SecondaryFieldAssociation),
policy,
Traits())
.ResetTypeList(TypeList())
.ResetTypes(TypeList())
.CastAndCall(functor, field);
}
}

@ -83,7 +83,7 @@ inline VTKM_CONT vtkm::cont::DataSet DotProduct::DoExecute(
inDataSet.GetField(this->SecondaryFieldName, this->SecondaryFieldAssociation),
policy,
Traits())
.ResetTypeList(TypeList())
.ResetTypes(TypeList())
.CastAndCall(functor, field);
}
}

@ -119,7 +119,7 @@ inline VTKM_CONT bool ExtractGeometry::DoMapField(
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
vtkm::cont::DynamicArrayHandle output;
vtkm::cont::VariantArrayHandle output;
if (fieldMeta.IsPointField())
{

@ -74,29 +74,26 @@ public:
template <typename T, typename StorageTag>
VTKM_CONT vtkm::cont::Field AsField(const vtkm::cont::ArrayHandle<T, StorageTag>& handle) const
{
//Field only handles arrayHandles with default storage tag, so use
//dynamic array handles
vtkm::cont::DynamicArrayHandle dhandle(handle);
if (this->IsCellField())
{
return vtkm::cont::Field(this->Name, this->Association, this->CellSetName, dhandle);
return vtkm::cont::Field(this->Name, this->Association, this->CellSetName, handle);
}
else
{
return vtkm::cont::Field(this->Name, this->Association, dhandle);
return vtkm::cont::Field(this->Name, this->Association, handle);
}
}
VTKM_CONT
vtkm::cont::Field AsField(const vtkm::cont::DynamicArrayHandle& dhandle) const
vtkm::cont::Field AsField(const vtkm::cont::VariantArrayHandle& handle) const
{
if (this->IsCellField())
{
return vtkm::cont::Field(this->Name, this->Association, this->CellSetName, dhandle);
return vtkm::cont::Field(this->Name, this->Association, this->CellSetName, handle);
}
else
{
return vtkm::cont::Field(this->Name, this->Association, dhandle);
return vtkm::cont::Field(this->Name, this->Association, handle);
}
}

@ -231,18 +231,14 @@ inline VTKM_CONT void Histogram::PreExecute(const vtkm::cont::MultiBlock& input,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
using TypeList = typename DerivedPolicy::FieldTypeList;
using StorageList = typename DerivedPolicy::FieldStorageList;
if (this->Range.IsNonEmpty())
{
this->ComputedRange = this->Range;
}
else
{
auto handle = vtkm::cont::FieldRangeGlobalCompute(input,
this->GetActiveFieldName(),
this->GetActiveFieldAssociation(),
TypeList(),
StorageList());
auto handle = vtkm::cont::FieldRangeGlobalCompute(
input, this->GetActiveFieldName(), this->GetActiveFieldAssociation(), TypeList());
if (handle.GetNumberOfValues() != 1)
{
throw vtkm::cont::ErrorFilterExecution("expecting scalar field.");

@ -21,7 +21,6 @@
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ErrorFilterExecution.h>

@ -42,7 +42,6 @@ template <typename Derived>
struct PolicyBase
{
using FieldTypeList = VTKM_DEFAULT_TYPE_LIST_TAG;
using FieldStorageList = VTKM_DEFAULT_STORAGE_LIST_TAG;
using StructuredCellSetList = vtkm::cont::CellSetListTagStructured;
using UnstructuredCellSetList = vtkm::cont::CellSetListTagUnstructured;
@ -51,29 +50,25 @@ struct PolicyBase
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::DynamicArrayHandleBase<typename DerivedPolicy::FieldTypeList,
typename DerivedPolicy::FieldStorageList>
ApplyPolicy(const vtkm::cont::Field& field, const vtkm::filter::PolicyBase<DerivedPolicy>&)
VTKM_CONT vtkm::cont::VariantArrayHandleBase<typename DerivedPolicy::FieldTypeList> ApplyPolicy(
const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
using TypeList = typename DerivedPolicy::FieldTypeList;
using StorageList = typename DerivedPolicy::FieldStorageList;
return field.GetData().ResetTypeAndStorageLists(TypeList(), StorageList());
return field.GetData().ResetTypes(TypeList());
}
//-----------------------------------------------------------------------------
template <typename DerivedPolicy, typename FilterType, typename FieldTag>
VTKM_CONT vtkm::cont::DynamicArrayHandleBase<
typename vtkm::filter::DeduceFilterFieldTypes<DerivedPolicy, FilterType, FieldTag>::TypeList,
typename DerivedPolicy::FieldStorageList>
VTKM_CONT vtkm::cont::VariantArrayHandleBase<
typename vtkm::filter::DeduceFilterFieldTypes<DerivedPolicy, FilterType, FieldTag>::TypeList>
ApplyPolicy(const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const vtkm::filter::FilterTraits<FilterType, FieldTag>&)
{
using TypeList =
typename vtkm::filter::DeduceFilterFieldTypes<DerivedPolicy, FilterType, FieldTag>::TypeList;
using StorageList = typename DerivedPolicy::FieldStorageList;
return field.GetData().ResetTypeAndStorageLists(TypeList(), StorageList());
return field.GetData().ResetTypes(TypeList());
}
//-----------------------------------------------------------------------------
@ -108,26 +103,22 @@ ApplyPolicyUnstructured(const vtkm::cont::DynamicCellSet& cellset,
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::SerializableField<typename DerivedPolicy::FieldTypeList,
typename DerivedPolicy::FieldStorageList>
VTKM_CONT vtkm::cont::SerializableField<typename DerivedPolicy::FieldTypeList>
MakeSerializableField(const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
return {};
}
template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::SerializableField<typename DerivedPolicy::FieldTypeList,
typename DerivedPolicy::FieldStorageList>
VTKM_CONT vtkm::cont::SerializableField<typename DerivedPolicy::FieldTypeList>
MakeSerializableField(const vtkm::cont::Field& field,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
return vtkm::cont::SerializableField<typename DerivedPolicy::FieldTypeList,
typename DerivedPolicy::FieldStorageList>{ field };
return vtkm::cont::SerializableField<typename DerivedPolicy::FieldTypeList>{ field };
}
template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::SerializableDataSet<typename DerivedPolicy::FieldTypeList,
typename DerivedPolicy::FieldStorageList,
typename DerivedPolicy::AllCellSetList>
MakeSerializableDataSet(const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
@ -136,13 +127,11 @@ MakeSerializableDataSet(const vtkm::filter::PolicyBase<DerivedPolicy>&)
template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::SerializableDataSet<typename DerivedPolicy::FieldTypeList,
typename DerivedPolicy::FieldStorageList,
typename DerivedPolicy::AllCellSetList>
MakeSerializableDataSet(const vtkm::cont::DataSet& dataset,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
return vtkm::cont::SerializableDataSet<typename DerivedPolicy::FieldTypeList,
typename DerivedPolicy::FieldStorageList,
typename DerivedPolicy::AllCellSetList>{ dataset };
}
}

@ -21,7 +21,6 @@
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ErrorFilterExecution.h>

@ -21,7 +21,6 @@
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ErrorFilterExecution.h>

@ -21,7 +21,6 @@
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ErrorFilterExecution.h>

@ -21,7 +21,6 @@
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ErrorFilterExecution.h>

@ -21,7 +21,6 @@
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ErrorFilterExecution.h>

@ -21,7 +21,6 @@
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/CellSetSingleType.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/ErrorFilterExecution.h>

@ -108,7 +108,7 @@ inline VTKM_CONT vtkm::cont::DataSet CreateResult(
return clone;
}
/// Use this function if you have a DynamicArrayHandle that holds the data
/// Use this function if you have a VariantArrayHandle that holds the data
/// for the field. You also need to specify a name and an association for the
/// field. If the field is associated with a particular element set (for
/// example, a cell association is associated with a cell set), the name of
@ -116,7 +116,7 @@ inline VTKM_CONT vtkm::cont::DataSet CreateResult(
/// for \c Association::WHOLE_MESH and \c Association::POINTS associations.
///
inline VTKM_CONT vtkm::cont::DataSet CreateResult(const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::DynamicArrayHandle& fieldArray,
const vtkm::cont::VariantArrayHandle& fieldArray,
const std::string& fieldName,
vtkm::cont::Field::Association fieldAssociation,
const std::string& elementSetName = "")

@ -20,7 +20,6 @@
#include "vtkm/filter/CellMeasures.h"
#include "vtkm/cont/DynamicArrayHandle.h"
#include "vtkm/cont/testing/MakeTestDataSet.h"
#include "vtkm/cont/testing/Testing.h"
@ -51,7 +50,7 @@ void TestCellMeasuresFilter(vtkm::cont::DataSet& dataset,
// Check that the empty measure name above produced a field with the expected name.
vols.SetCellMeasureName("measure");
vtkm::cont::DynamicArrayHandle temp = outputData.GetField(vols.GetCellMeasureName()).GetData();
auto temp = outputData.GetField(vols.GetCellMeasureName()).GetData();
VTKM_TEST_ASSERT(temp.GetNumberOfValues() == static_cast<vtkm::Id>(expected.size()),
"Output field could not be found or was improper.");

@ -20,7 +20,6 @@
#include <vtkm/filter/ClipWithField.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
@ -80,7 +79,7 @@ void TestClipExplicit()
VTKM_TEST_ASSERT(outputData.GetNumberOfFields() == 1,
"Wrong number of fields in the output dataset");
vtkm::cont::DynamicArrayHandle temp = outputData.GetField("scalars").GetData();
auto temp = outputData.GetField("scalars").GetData();
vtkm::cont::ArrayHandle<vtkm::Float32> resultArrayHandle;
temp.CopyTo(resultArrayHandle);

@ -20,7 +20,6 @@
#include <vtkm/filter/ClipWithImplicitFunction.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
@ -76,7 +75,7 @@ void TestClipStructured()
VTKM_TEST_ASSERT(outputData.GetCellSet().GetNumberOfCells() == 8,
"Wrong number of cells in the output dataset");
vtkm::cont::DynamicArrayHandle temp = outputData.GetField("scalars").GetData();
vtkm::cont::VariantArrayHandle temp = outputData.GetField("scalars").GetData();
vtkm::cont::ArrayHandle<vtkm::Float32> resultArrayHandle;
temp.CopyTo(resultArrayHandle);
@ -116,7 +115,7 @@ void TestClipStructuredInverted()
VTKM_TEST_ASSERT(outputData.GetCellSet().GetNumberOfCells() == 4,
"Wrong number of cells in the output dataset");
vtkm::cont::DynamicArrayHandle temp = outputData.GetField("scalars").GetData();
vtkm::cont::VariantArrayHandle temp = outputData.GetField("scalars").GetData();
vtkm::cont::ArrayHandle<vtkm::Float32> resultArrayHandle;
temp.CopyTo(resultArrayHandle);

@ -24,7 +24,6 @@
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/cont/DataSetFieldAdd.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/filter/CleanGrid.h>
@ -229,22 +228,7 @@ public:
class PolicyRadiantDataSet : public vtkm::filter::PolicyBase<PolicyRadiantDataSet>
{
using DataHandleType = MakeRadiantDataSet::DataArrayHandle;
using CountingHandleType = MakeRadiantDataSet::ConnectivityArrayHandle;
using TransformHandleType =
vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandleCounting<vtkm::Id>,
CubeGridConnectivity>;
public:
struct TypeListTagRadiantTypes : vtkm::ListTagBase<DataHandleType::StorageTag,
CountingHandleType::StorageTag,
TransformHandleType::StorageTag>
{
};
using FieldStorageList = TypeListTagRadiantTypes;
struct TypeListTagRadiantCellSetTypes : vtkm::ListTagBase<MakeRadiantDataSet::CellSet>
{
};
@ -281,12 +265,10 @@ inline vtkm::cont::DataSet MakeRadiantDataSet::Make3DRadiantDataSet(vtkm::IdComp
dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates));
//Set point scalar
dataSet.AddField(vtkm::cont::Field("distanceToOrigin",
vtkm::cont::Field::Association::POINTS,
vtkm::cont::DynamicArrayHandle(distanceToOrigin)));
dataSet.AddField(vtkm::cont::Field("distanceToOther",
vtkm::cont::Field::Association::POINTS,
vtkm::cont::DynamicArrayHandle(distanceToOther)));
dataSet.AddField(vtkm::cont::Field(
"distanceToOrigin", vtkm::cont::Field::Association::POINTS, distanceToOrigin));
dataSet.AddField(
vtkm::cont::Field("distanceToOther", vtkm::cont::Field::Association::POINTS, distanceToOther));
CellSet cellSet("cells");
cellSet.Fill(coordinates.GetNumberOfValues(), HexTag::Id, HexTraits::NUM_POINTS, connectivity);
@ -384,7 +366,7 @@ void TestMarchingCubesCustomPolicy()
//custom field type
mc.SetActiveField("distanceToOrigin");
mc.SetFieldsToPass({ "distanceToOrigin", "distanceToOther" });
vtkm::cont::DataSet outputData = mc.Execute(dataSet, PolicyRadiantDataSet());
vtkm::cont::DataSet outputData = mc.Execute(dataSet, PolicyRadiantDataSet{});
VTKM_TEST_ASSERT(outputData.GetNumberOfCellSets() == 1,
"Wrong number of cellsets in the output dataset");

@ -24,7 +24,6 @@
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DataSetFieldAdd.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/MultiBlock.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>

@ -64,19 +64,6 @@ vtkm::cont::DataSet MakeWarpScalarTestDataSet()
return dataSet;
}
class PolicyWarpScalar : public vtkm::filter::PolicyBase<PolicyWarpScalar>
{
public:
using vecType = vtkm::Vec<vtkm::FloatDefault, 3>;
struct TypeListTagWarpScalarTags
: vtkm::ListTagBase<vtkm::cont::ArrayHandleConstant<vecType>::StorageTag,
vtkm::cont::ArrayHandle<vecType>::StorageTag,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>::StorageTag>
{
};
using FieldStorageList = TypeListTagWarpScalarTags;
};
void CheckResult(const vtkm::filter::WarpScalar& filter, const vtkm::cont::DataSet& result)
{
VTKM_TEST_ASSERT(result.HasField("warpscalar", vtkm::cont::Field::Association::POINTS),
@ -124,7 +111,7 @@ void TestWarpScalarFilter()
filter.SetUseCoordinateSystemAsPrimaryField(true);
filter.SetNormalField("normal");
filter.SetScalarFactorField("scalarfactor");
vtkm::cont::DataSet result = filter.Execute(ds, PolicyWarpScalar());
vtkm::cont::DataSet result = filter.Execute(ds);
CheckResult(filter, result);
}
@ -134,7 +121,7 @@ void TestWarpScalarFilter()
filter.SetPrimaryField("vec1");
filter.SetNormalField("normal");
filter.SetScalarFactorField("scalarfactor");
vtkm::cont::DataSet result = filter.Execute(ds, PolicyWarpScalar());
vtkm::cont::DataSet result = filter.Execute(ds);
CheckResult(filter, result);
}
}

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