Merge branch 'master' of https://gitlab.kitware.com/vtk/vtk-m into gridEval

This commit is contained in:
Dave Pugmire 2019-03-04 14:34:11 -05:00
commit 2eca1d7a1d
137 changed files with 4900 additions and 2655 deletions

@ -119,8 +119,12 @@ elseif(VTKM_COMPILER_IS_ICC)
target_compile_options(vtkm_developer_flags INTERFACE $<$<COMPILE_LANGUAGE:CXX>:-wd1478 -wd13379>)
elseif(VTKM_COMPILER_IS_GNU OR VTKM_COMPILER_IS_CLANG)
set(cxx_flags -Wall -Wcast-align -Wconversion -Wchar-subscripts -Wextra -Wpointer-arith -Wformat -Wformat-security -Wshadow -Wunused-parameter -fno-common)
set(cxx_flags -Wall -Wcast-align -Wchar-subscripts -Wextra -Wpointer-arith -Wformat -Wformat-security -Wshadow -Wunused-parameter -fno-common)
if (VTKM_COMPILER_IS_GNU AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.99)
list(APPEND cxx_flags -Wfloat-conversion)
elseif (VTKM_COMPILER_IS_CLANG)
list(APPEND cxx_flags -Wconversion)
endif()
set(cuda_flags -Xcompiler=-Wall,-Wno-unknown-pragmas,-Wno-unused-local-typedefs,-Wno-unused-local-typedefs,-Wno-unused-function,-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.

@ -45,6 +45,7 @@
# VTKm_ENABLE_CUDA Will be enabled if VTK-m was built with CUDA support
# VTKm_ENABLE_TBB Will be enabled if VTK-m was built with TBB support
# VTKm_ENABLE_OPENMP Will be enabled if VTK-m was built with OpenMP support
# VTKm_ENABLE_LOGGING Will be enabled if VTK-m was built with logging support
# VTKm_ENABLE_MPI Will be enabled if VTK-m was built with MPI support
# VTKm_ENABLE_RENDERING Will be enabled if VTK-m was built with rendering support
# VTKm_ENABLE_GL_CONTEXT Will be enabled if VTK-m rendering was built with a GL context
@ -74,6 +75,7 @@ set(VTKm_BUILD_SHARED_LIBS "@VTKm_BUILD_SHARED_LIBS@")
set(VTKm_ENABLE_CUDA "@VTKm_ENABLE_CUDA@")
set(VTKm_ENABLE_TBB "@VTKm_ENABLE_TBB@")
set(VTKm_ENABLE_OPENMP "@VTKm_ENABLE_OPENMP@")
set(VTKm_ENABLE_LOGGING "@VTKm_ENABLE_LOGGING@")
set(VTKm_ENABLE_RENDERING "@VTKm_ENABLE_RENDERING@")
set(VTKm_ENABLE_GL_CONTEXT "@VTKm_ENABLE_GL_CONTEXT@")
set(VTKm_ENABLE_OSMESA_CONTEXT "@VTKm_ENABLE_OSMESA_CONTEXT@")

@ -294,3 +294,8 @@ if(VTKm_ENABLE_CUDA AND NOT TARGET vtkm::cuda)
set_target_properties(vtkm::cuda PROPERTIES VTKm_CUDA_Architecture_Flags "${arch_flags}")
endif()
if(NOT TARGET Threads::Threads)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif()

@ -22,7 +22,9 @@
#include <vtkm/TypeTraits.h>
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/Timer.h>
@ -40,10 +42,9 @@ namespace vtkm
namespace benchmarking
{
template <typename DeviceAdapter>
struct BenchmarkArrayTransfer
{
using Algo = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
using Algo = vtkm::cont::Algorithm;
using StorageTag = vtkm::cont::StorageTagBasic;
using Timer = vtkm::cont::Timer;
@ -139,11 +140,10 @@ struct BenchmarkArrayTransfer
// Copies NumValues from control environment to execution environment and
// accesses them as read-only.
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchContToExecRead
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using PortalType = typename ArrayType::template ExecutionTypes<DeviceAdapter>::PortalConst;
using ValueTypeTraits = vtkm::TypeTraits<ValueType>;
vtkm::Id NumValues;
@ -164,7 +164,7 @@ struct BenchmarkArrayTransfer
}
VTKM_CONT
vtkm::Float64 operator()()
vtkm::Float64 operator()() const
{
std::vector<ValueType> vec(static_cast<std::size_t>(this->NumValues),
ValueTypeTraits::ZeroInitialization());
@ -173,8 +173,8 @@ struct BenchmarkArrayTransfer
// Time the copy:
Timer timer{ DeviceAdapter() };
timer.Start();
ReadValues<PortalType> functor(array.PrepareForInput(DeviceAdapter()),
ValueTypeTraits::ZeroInitialization());
auto portal = array.PrepareForInput(DeviceAdapter());
ReadValues<decltype(portal)> functor(portal, ValueTypeTraits::ZeroInitialization());
Algo::Schedule(functor, this->NumValues);
return timer.GetElapsedTime();
}
@ -183,11 +183,10 @@ struct BenchmarkArrayTransfer
// Writes values to ArrayHandle in execution environment. There is no actual
// copy between control/execution in this case.
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchContToExecWrite
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using PortalType = typename ArrayType::template ExecutionTypes<DeviceAdapter>::Portal;
using ValueTypeTraits = vtkm::TypeTraits<ValueType>;
vtkm::Id NumValues;
@ -208,14 +207,15 @@ struct BenchmarkArrayTransfer
}
VTKM_CONT
vtkm::Float64 operator()()
vtkm::Float64 operator()() const
{
ArrayType array;
// Time the write:
Timer timer{ DeviceAdapter() };
timer.Start();
WriteValues<PortalType> functor(array.PrepareForOutput(this->NumValues, DeviceAdapter()));
auto portal = array.PrepareForOutput(this->NumValues, DeviceAdapter());
WriteValues<decltype(portal)> functor(portal);
Algo::Schedule(functor, this->NumValues);
return timer.GetElapsedTime();
@ -225,11 +225,10 @@ struct BenchmarkArrayTransfer
// Copies NumValues from control environment to execution environment and
// both reads and writes them.
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchContToExecReadWrite
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using PortalType = typename ArrayType::template ExecutionTypes<DeviceAdapter>::Portal;
using ValueTypeTraits = vtkm::TypeTraits<ValueType>;
vtkm::Id NumValues;
@ -250,7 +249,7 @@ struct BenchmarkArrayTransfer
}
VTKM_CONT
vtkm::Float64 operator()()
vtkm::Float64 operator()() const
{
std::vector<ValueType> vec(static_cast<std::size_t>(this->NumValues),
ValueTypeTraits::ZeroInitialization());
@ -259,7 +258,8 @@ struct BenchmarkArrayTransfer
// Time the copy:
Timer timer{ DeviceAdapter() };
timer.Start();
ReadWriteValues<PortalType> functor(array.PrepareForInPlace(DeviceAdapter()));
auto portal = array.PrepareForInPlace(DeviceAdapter());
ReadWriteValues<decltype(portal)> functor(portal);
Algo::Schedule(functor, this->NumValues);
return timer.GetElapsedTime();
}
@ -268,7 +268,7 @@ struct BenchmarkArrayTransfer
// Copies NumValues from control environment to execution environment and
// back, then accesses them as read-only.
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchRoundTripRead
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
@ -295,7 +295,7 @@ struct BenchmarkArrayTransfer
}
VTKM_CONT
vtkm::Float64 operator()()
vtkm::Float64 operator()() const
{
std::vector<ValueType> vec(static_cast<std::size_t>(this->NumValues),
ValueTypeTraits::ZeroInitialization());
@ -309,8 +309,8 @@ struct BenchmarkArrayTransfer
timer.Start();
// Copy to device:
ReadValues<PortalExecType> functor(array.PrepareForInput(DeviceAdapter()),
ValueTypeTraits::ZeroInitialization());
auto portal = array.PrepareForInput(DeviceAdapter());
ReadValues<PortalExecType> functor(portal, ValueTypeTraits::ZeroInitialization());
Algo::Schedule(functor, this->NumValues);
// Copy back to host and read:
@ -328,7 +328,7 @@ struct BenchmarkArrayTransfer
// Copies NumValues from control environment to execution environment and
// back, then reads and writes them in-place.
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchRoundTripReadWrite
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
@ -355,7 +355,7 @@ struct BenchmarkArrayTransfer
}
VTKM_CONT
vtkm::Float64 operator()()
vtkm::Float64 operator()() const
{
std::vector<ValueType> vec(static_cast<std::size_t>(this->NumValues),
ValueTypeTraits::ZeroInitialization());
@ -369,7 +369,8 @@ struct BenchmarkArrayTransfer
timer.Start();
// Do work on device:
ReadWriteValues<PortalExecType> functor(array.PrepareForInPlace(DeviceAdapter()));
auto portal = array.PrepareForInPlace(DeviceAdapter());
ReadWriteValues<PortalExecType> functor(portal);
Algo::Schedule(functor, this->NumValues);
ReadWriteValues<PortalContType> cFunctor(array.GetPortalControl());
@ -385,7 +386,7 @@ struct BenchmarkArrayTransfer
// Write NumValues to device allocated memory and copies them back to control
// for reading.
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchExecToContRead
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
@ -412,7 +413,7 @@ struct BenchmarkArrayTransfer
}
VTKM_CONT
vtkm::Float64 operator()()
vtkm::Float64 operator()() const
{
ArrayType array;
@ -421,7 +422,8 @@ struct BenchmarkArrayTransfer
timer.Start();
// Allocate/write data on device
WriteValues<PortalExecType> functor(array.PrepareForOutput(this->NumValues, DeviceAdapter()));
auto portal = array.PrepareForOutput(this->NumValues, DeviceAdapter());
WriteValues<PortalExecType> functor(portal);
Algo::Schedule(functor, this->NumValues);
// Read back on host:
@ -439,7 +441,7 @@ struct BenchmarkArrayTransfer
// Write NumValues to device allocated memory and copies them back to control
// and overwrites them.
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchExecToContWrite
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
@ -475,7 +477,8 @@ struct BenchmarkArrayTransfer
timer.Start();
// Allocate/write data on device
WriteValues<PortalExecType> functor(array.PrepareForOutput(this->NumValues, DeviceAdapter()));
auto portal = array.PrepareForOutput(this->NumValues, DeviceAdapter());
WriteValues<PortalExecType> functor(portal);
Algo::Schedule(functor, this->NumValues);
// Read back on host:
@ -492,7 +495,7 @@ struct BenchmarkArrayTransfer
// Write NumValues to device allocated memory and copies them back to control
// for reading and writing.
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchExecToContReadWrite
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
@ -528,7 +531,8 @@ struct BenchmarkArrayTransfer
timer.Start();
// Allocate/write data on device
WriteValues<PortalExecType> functor(array.PrepareForOutput(this->NumValues, DeviceAdapter()));
auto portal = array.PrepareForOutput(this->NumValues, DeviceAdapter());
WriteValues<PortalExecType> functor(portal);
Algo::Schedule(functor, this->NumValues);
// Read back on host:
@ -547,17 +551,16 @@ struct BenchmarkArrayTransfer
using TestTypes = vtkm::ListTagBase<vtkm::Float32>;
static VTKM_CONT bool Run()
static VTKM_CONT bool Run(vtkm::cont::DeviceAdapterId id)
{
VTKM_RUN_BENCHMARK(ContToExecRead, TestTypes());
VTKM_RUN_BENCHMARK(ContToExecWrite, TestTypes());
VTKM_RUN_BENCHMARK(ContToExecReadWrite, TestTypes());
VTKM_RUN_BENCHMARK(RoundTripRead, TestTypes());
VTKM_RUN_BENCHMARK(RoundTripReadWrite, TestTypes());
VTKM_RUN_BENCHMARK(ExecToContRead, TestTypes());
VTKM_RUN_BENCHMARK(ExecToContWrite, TestTypes());
VTKM_RUN_BENCHMARK(ExecToContReadWrite, TestTypes());
VTKM_RUN_BENCHMARK(ContToExecRead, TestTypes(), id);
VTKM_RUN_BENCHMARK(ContToExecWrite, TestTypes(), id);
VTKM_RUN_BENCHMARK(ContToExecReadWrite, TestTypes(), id);
VTKM_RUN_BENCHMARK(RoundTripRead, TestTypes(), id);
VTKM_RUN_BENCHMARK(RoundTripReadWrite, TestTypes(), id);
VTKM_RUN_BENCHMARK(ExecToContRead, TestTypes(), id);
VTKM_RUN_BENCHMARK(ExecToContWrite, TestTypes(), id);
VTKM_RUN_BENCHMARK(ExecToContReadWrite, TestTypes(), id);
return true;
}
};
@ -566,14 +569,11 @@ struct BenchmarkArrayTransfer
int main(int argc, char* argv[])
{
vtkm::cont::InitLogging(argc, argv);
auto opts = vtkm::cont::InitializeOptions::RequireDevice;
auto config = vtkm::cont::Initialize(argc, argv, opts);
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
using Benchmarks = vtkm::benchmarking::BenchmarkArrayTransfer<DeviceAdapter>;
using Benchmarks = vtkm::benchmarking::BenchmarkArrayTransfer;
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
tracker.ForceDevice(DeviceAdapter{});
bool result = Benchmarks::Run();
bool result = Benchmarks::Run(config.Device);
return result ? EXIT_SUCCESS : EXIT_FAILURE;
}

@ -24,6 +24,7 @@
#include <vtkm/cont/AtomicArray.h>
#include <vtkm/cont/RuntimeDeviceTracker.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/exec/FunctorBase.h>
@ -48,25 +49,24 @@ static constexpr vtkm::Id NumWrites = 33554432; // 2^25
VTKM_MAKE_BENCHMARK(Name##32768, Class, 32768); \
VTKM_MAKE_BENCHMARK(Name##1048576, Class, 1048576)
#define RUN_ATOMIC_BENCHMARKS(Name) \
VTKM_RUN_BENCHMARK(Name##1, vtkm::cont::AtomicArrayTypeListTag{}); \
VTKM_RUN_BENCHMARK(Name##8, vtkm::cont::AtomicArrayTypeListTag{}); \
VTKM_RUN_BENCHMARK(Name##32, vtkm::cont::AtomicArrayTypeListTag{}); \
VTKM_RUN_BENCHMARK(Name##512, vtkm::cont::AtomicArrayTypeListTag{}); \
VTKM_RUN_BENCHMARK(Name##2048, vtkm::cont::AtomicArrayTypeListTag{}); \
VTKM_RUN_BENCHMARK(Name##32768, vtkm::cont::AtomicArrayTypeListTag{}); \
VTKM_RUN_BENCHMARK(Name##1048576, vtkm::cont::AtomicArrayTypeListTag{})
#define RUN_ATOMIC_BENCHMARKS(Name, id) \
VTKM_RUN_BENCHMARK(Name##1, vtkm::cont::AtomicArrayTypeListTag{}, id); \
VTKM_RUN_BENCHMARK(Name##8, vtkm::cont::AtomicArrayTypeListTag{}, id); \
VTKM_RUN_BENCHMARK(Name##32, vtkm::cont::AtomicArrayTypeListTag{}, id); \
VTKM_RUN_BENCHMARK(Name##512, vtkm::cont::AtomicArrayTypeListTag{}, id); \
VTKM_RUN_BENCHMARK(Name##2048, vtkm::cont::AtomicArrayTypeListTag{}, id); \
VTKM_RUN_BENCHMARK(Name##32768, vtkm::cont::AtomicArrayTypeListTag{}, id); \
VTKM_RUN_BENCHMARK(Name##1048576, vtkm::cont::AtomicArrayTypeListTag{}, id)
template <class Device>
class BenchmarkAtomicArray
{
public:
using Algo = vtkm::cont::DeviceAdapterAlgorithm<Device>;
using Algo = vtkm::cont::Algorithm;
using Timer = vtkm::cont::Timer;
// Benchmarks AtomicArray::Add such that each work index writes to adjacent
// indices.
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchAddSeq
{
vtkm::Id ArraySize;
@ -92,17 +92,17 @@ public:
BenchAddSeq(vtkm::Id arraySize)
: ArraySize(arraySize)
{
this->Data.PrepareForOutput(this->ArraySize, Device{});
this->Data.PrepareForOutput(this->ArraySize, DeviceAdapter());
}
VTKM_CONT
vtkm::Float64 operator()()
{
vtkm::cont::AtomicArray<ValueType> array(this->Data);
auto portal = array.PrepareForExecution(Device{});
auto portal = array.PrepareForExecution(DeviceAdapter());
Worker<decltype(portal)> worker{ this->ArraySize, portal };
Timer timer{ Device() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algo::Schedule(worker, NumWrites);
@ -120,7 +120,7 @@ public:
MAKE_ATOMIC_BENCHMARKS(AddSeq, BenchAddSeq);
// Provides a non-atomic baseline for BenchAddSeq
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchAddSeqBaseline
{
vtkm::Id ArraySize;
@ -155,10 +155,10 @@ public:
VTKM_CONT
vtkm::Float64 operator()()
{
auto portal = this->Data.PrepareForOutput(this->ArraySize, Device{});
auto portal = this->Data.PrepareForOutput(this->ArraySize, DeviceAdapter());
Worker<decltype(portal)> worker{ this->ArraySize, portal };
Timer timer{ Device() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algo::Schedule(worker, NumWrites);
@ -177,7 +177,7 @@ public:
// Benchmarks AtomicArray::Add such that each work index writes to a strided
// index ( floor(i / stride) + stride * (i % stride)
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchAddStride
{
vtkm::Id ArraySize;
@ -211,17 +211,17 @@ public:
: ArraySize(arraySize)
, Stride(stride)
{
this->Data.PrepareForOutput(this->ArraySize, Device{});
this->Data.PrepareForOutput(this->ArraySize, DeviceAdapter());
}
VTKM_CONT
vtkm::Float64 operator()()
{
vtkm::cont::AtomicArray<ValueType> array(this->Data);
auto portal = array.PrepareForExecution(Device{});
auto portal = array.PrepareForExecution(DeviceAdapter());
Worker<decltype(portal)> worker{ this->ArraySize, this->Stride, portal };
Timer timer{ Device() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algo::Schedule(worker, NumWrites);
@ -240,7 +240,7 @@ public:
MAKE_ATOMIC_BENCHMARKS(AddStride, BenchAddStride);
// Non-atomic baseline for AddStride
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchAddStrideBaseline
{
vtkm::Id ArraySize;
@ -279,10 +279,10 @@ public:
VTKM_CONT
vtkm::Float64 operator()()
{
auto portal = this->Data.PrepareForOutput(this->ArraySize, Device{});
auto portal = this->Data.PrepareForOutput(this->ArraySize, DeviceAdapter());
Worker<decltype(portal)> worker{ this->ArraySize, this->Stride, portal };
Timer timer{ Device() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algo::Schedule(worker, NumWrites);
@ -302,7 +302,7 @@ public:
// Benchmarks AtomicArray::CompareAndSwap such that each work index writes to adjacent
// indices.
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchCASSeq
{
vtkm::Id ArraySize;
@ -340,17 +340,17 @@ public:
BenchCASSeq(vtkm::Id arraySize)
: ArraySize(arraySize)
{
this->Data.PrepareForOutput(this->ArraySize, Device{});
this->Data.PrepareForOutput(this->ArraySize, DeviceAdapter());
}
VTKM_CONT
vtkm::Float64 operator()()
{
vtkm::cont::AtomicArray<ValueType> array(this->Data);
auto portal = array.PrepareForExecution(Device{});
auto portal = array.PrepareForExecution(DeviceAdapter());
Worker<decltype(portal)> worker{ this->ArraySize, portal };
Timer timer{ Device() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algo::Schedule(worker, NumWrites);
@ -368,7 +368,7 @@ public:
MAKE_ATOMIC_BENCHMARKS(CASSeq, BenchCASSeq);
// Provides a non-atomic baseline for BenchCASSeq
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchCASSeqBaseline
{
vtkm::Id ArraySize;
@ -405,10 +405,10 @@ public:
VTKM_CONT
vtkm::Float64 operator()()
{
auto portal = this->Data.PrepareForOutput(this->ArraySize, Device{});
auto portal = this->Data.PrepareForOutput(this->ArraySize, DeviceAdapter());
Worker<decltype(portal)> worker{ this->ArraySize, portal };
Timer timer{ Device() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algo::Schedule(worker, NumWrites);
return timer.GetElapsedTime();
@ -427,7 +427,7 @@ public:
// Benchmarks AtomicArray::CompareAndSwap such that each work index writes to
// a strided index:
// ( floor(i / stride) + stride * (i % stride)
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchCASStride
{
vtkm::Id ArraySize;
@ -469,17 +469,17 @@ public:
: ArraySize(arraySize)
, Stride(stride)
{
this->Data.PrepareForOutput(this->ArraySize, Device{});
this->Data.PrepareForOutput(this->ArraySize, DeviceAdapter());
}
VTKM_CONT
vtkm::Float64 operator()()
{
vtkm::cont::AtomicArray<ValueType> array(this->Data);
auto portal = array.PrepareForExecution(Device{});
auto portal = array.PrepareForExecution(DeviceAdapter());
Worker<decltype(portal)> worker{ this->ArraySize, this->Stride, portal };
Timer timer{ Device() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algo::Schedule(worker, NumWrites);
@ -498,7 +498,7 @@ public:
MAKE_ATOMIC_BENCHMARKS(CASStride, BenchCASStride);
// Non-atomic baseline for CASStride
template <typename ValueType>
template <typename ValueType, typename DeviceAdapter>
struct BenchCASStrideBaseline
{
vtkm::Id ArraySize;
@ -539,10 +539,10 @@ public:
VTKM_CONT
vtkm::Float64 operator()()
{
auto portal = this->Data.PrepareForOutput(this->ArraySize, Device{});
auto portal = this->Data.PrepareForOutput(this->ArraySize, DeviceAdapter());
Worker<decltype(portal)> worker{ this->ArraySize, this->Stride, portal };
Timer timer{ Device() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algo::Schedule(worker, NumWrites);
@ -560,17 +560,17 @@ public:
};
MAKE_ATOMIC_BENCHMARKS(CASStrideBase, BenchCASStrideBaseline);
static void Run()
static void Run(vtkm::cont::DeviceAdapterId id)
{
RUN_ATOMIC_BENCHMARKS(AddSeq);
RUN_ATOMIC_BENCHMARKS(AddSeqBase);
RUN_ATOMIC_BENCHMARKS(AddStride);
RUN_ATOMIC_BENCHMARKS(AddStrideBase);
RUN_ATOMIC_BENCHMARKS(AddSeq, id);
RUN_ATOMIC_BENCHMARKS(AddSeqBase, id);
RUN_ATOMIC_BENCHMARKS(AddStride, id);
RUN_ATOMIC_BENCHMARKS(AddStrideBase, id);
RUN_ATOMIC_BENCHMARKS(CASSeq);
RUN_ATOMIC_BENCHMARKS(CASSeqBase);
RUN_ATOMIC_BENCHMARKS(CASStride);
RUN_ATOMIC_BENCHMARKS(CASStrideBase);
RUN_ATOMIC_BENCHMARKS(CASSeq, id);
RUN_ATOMIC_BENCHMARKS(CASSeqBase, id);
RUN_ATOMIC_BENCHMARKS(CASStride, id);
RUN_ATOMIC_BENCHMARKS(CASStrideBase, id);
}
};
}
@ -578,15 +578,12 @@ public:
int main(int argc, char* argv[])
{
vtkm::cont::InitLogging(argc, argv);
using Device = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
tracker.ForceDevice(Device{});
auto opts = vtkm::cont::InitializeOptions::RequireDevice;
auto config = vtkm::cont::Initialize(argc, argv, opts);
try
{
vtkm::benchmarking::BenchmarkAtomicArray<Device>::Run();
vtkm::benchmarking::BenchmarkAtomicArray::Run(config.Device);
}
catch (std::exception& e)
{

@ -37,7 +37,7 @@
#include <iostream>
#include <sstream>
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
#ifdef VTKM_ENABLE_TBB
#include <tbb/task_scheduler_init.h>
#endif // TBB
@ -58,7 +58,7 @@ const size_t COL_WIDTH = 32;
template <typename ValueType, typename DeviceAdapter>
struct MeasureCopySpeed
{
using Algo = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
using Algo = vtkm::cont::Algorithm;
vtkm::cont::ArrayHandle<ValueType> Source;
vtkm::cont::ArrayHandle<ValueType> Destination;
@ -106,19 +106,17 @@ void PrintDivider(std::ostream& out)
out << "|-" << fillStr << "-|-" << fillStr << "-|" << std::endl;
}
template <typename ValueType>
void BenchmarkValueType()
template <typename ValueType, typename DeviceAdapter>
void BenchmarkValueType(vtkm::cont::DeviceAdapterId id)
{
PrintRow(std::cout,
vtkm::testing::TypeName<ValueType>::Name(),
vtkm::cont::DeviceAdapterTraits<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::GetName());
PrintRow(std::cout, vtkm::testing::TypeName<ValueType>::Name(), id.GetName());
PrintDivider(std::cout);
Benchmarker bench(15, 100);
for (vtkm::UInt64 size = COPY_SIZE_MIN; size <= COPY_SIZE_MAX; size <<= COPY_SIZE_INC)
{
MeasureCopySpeed<ValueType, VTKM_DEFAULT_DEVICE_ADAPTER_TAG> functor(size);
MeasureCopySpeed<ValueType, DeviceAdapter> functor(size);
bench.Reset();
std::string speedStr;
@ -142,22 +140,58 @@ void BenchmarkValueType()
}
} // end namespace vtkm::benchmarking
namespace
{
using namespace vtkm::benchmarking;
struct BenchmarkValueTypeFunctor
{
template <typename DeviceAdapter>
bool operator()(DeviceAdapter id)
{
BenchmarkValueType<vtkm::UInt8, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 2>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 3>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 4>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::UInt32, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::UInt32, 2>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::UInt64, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::UInt64, 2>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Float32, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::Float32, 2>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Float64, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Vec<vtkm::Float64, 2>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Pair<vtkm::UInt32, vtkm::Float32>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Pair<vtkm::UInt32, vtkm::Float64>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Pair<vtkm::UInt64, vtkm::Float32>, DeviceAdapter>(id);
BenchmarkValueType<vtkm::Pair<vtkm::UInt64, vtkm::Float64>, DeviceAdapter>(id);
return true;
}
};
}
int main(int argc, char* argv[])
{
vtkm::cont::InitLogging(argc, argv);
auto opts = vtkm::cont::InitializeOptions::RequireDevice;
auto config = vtkm::cont::Initialize(argc, argv, opts);
using namespace vtkm::benchmarking;
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
#ifdef VTKM_ENABLE_TBB
int numThreads = tbb::task_scheduler_init::automatic;
#endif // TBB
if (argc == 3)
if (config.Arguments.size() == 2)
{
if (std::string(argv[1]) == "NumThreads")
if (std::string(config.Arguments[0]) == "NumThreads")
{
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
std::istringstream parse(argv[2]);
#ifdef VTKM_ENABLE_TBB
std::istringstream parse(config.Arguments[1]);
parse >> numThreads;
std::cout << "Selected " << numThreads << " TBB threads." << std::endl;
#else
@ -166,35 +200,11 @@ int main(int argc, char* argv[])
}
}
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
#ifdef VTKM_ENABLE_TBB
// Must not be destroyed as long as benchmarks are running:
tbb::task_scheduler_init init(numThreads);
#endif // TBB
using Device = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
tracker.ForceDevice(Device{});
BenchmarkValueType<vtkm::UInt8>();
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 2>>();
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 3>>();
BenchmarkValueType<vtkm::Vec<vtkm::UInt8, 4>>();
BenchmarkValueType<vtkm::UInt32>();
BenchmarkValueType<vtkm::Vec<vtkm::UInt32, 2>>();
BenchmarkValueType<vtkm::UInt64>();
BenchmarkValueType<vtkm::Vec<vtkm::UInt64, 2>>();
BenchmarkValueType<vtkm::Float32>();
BenchmarkValueType<vtkm::Vec<vtkm::Float32, 2>>();
BenchmarkValueType<vtkm::Float64>();
BenchmarkValueType<vtkm::Vec<vtkm::Float64, 2>>();
BenchmarkValueType<vtkm::Pair<vtkm::UInt32, vtkm::Float32>>();
BenchmarkValueType<vtkm::Pair<vtkm::UInt32, vtkm::Float64>>();
BenchmarkValueType<vtkm::Pair<vtkm::UInt64, vtkm::Float32>>();
BenchmarkValueType<vtkm::Pair<vtkm::UInt64, vtkm::Float64>>();
BenchmarkValueTypeFunctor functor;
vtkm::cont::TryExecuteOnDevice(config.Device, functor);
}

@ -44,9 +44,10 @@
#include <vtkm/internal/Windows.h>
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
#ifdef VTKM_ENABLE_TBB
#include <tbb/task_scheduler_init.h>
#elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_OPENMP
#endif
#ifdef VTKM_ENABLE_OPENMP
#include <omp.h>
#endif
@ -168,25 +169,23 @@ static const std::string DIVIDER(40, '-');
/// This class runs a series of micro-benchmarks to measure
/// performance of the parallel primitives provided by each
/// device adapter
template <class DeviceAdapterTag>
class BenchmarkDeviceAdapter
{
using StorageTag = vtkm::cont::StorageTagBasic;
using IdArrayHandle = vtkm::cont::ArrayHandle<vtkm::Id, StorageTag>;
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>;
using Algorithm = vtkm::cont::Algorithm;
using Timer = vtkm::cont::Timer;
public:
// Various kernels used by the different benchmarks to accelerate
// initialization of data
template <typename Value>
template <typename Value, typename PortalType>
struct FillTestValueKernel : vtkm::exec::FunctorBase
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
using PortalType = typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>::Portal;
PortalType Output;
@ -199,11 +198,10 @@ public:
VTKM_EXEC void operator()(vtkm::Id i) const { Output.Set(i, TestValue(i, Value())); }
};
template <typename Value>
template <typename Value, typename PortalType>
struct FillScaledTestValueKernel : vtkm::exec::FunctorBase
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
using PortalType = typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>::Portal;
PortalType Output;
const vtkm::Id IdScale;
@ -218,11 +216,10 @@ public:
VTKM_EXEC void operator()(vtkm::Id i) const { Output.Set(i, TestValue(i * IdScale, Value())); }
};
template <typename Value>
template <typename Value, typename PortalType>
struct FillModuloTestValueKernel : vtkm::exec::FunctorBase
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
using PortalType = typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>::Portal;
PortalType Output;
const vtkm::Id Modulus;
@ -237,11 +234,10 @@ public:
VTKM_EXEC void operator()(vtkm::Id i) const { Output.Set(i, TestValue(i % Modulus, Value())); }
};
template <typename Value>
template <typename Value, typename PortalType>
struct FillBinaryTestValueKernel : vtkm::exec::FunctorBase
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
using PortalType = typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>::Portal;
PortalType Output;
const vtkm::Id Modulus;
@ -260,7 +256,7 @@ public:
};
private:
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchCopy
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -284,7 +280,7 @@ private:
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algorithm::Copy(ValueHandle_src, ValueHandle_dst);
@ -305,7 +301,7 @@ private:
};
VTKM_MAKE_BENCHMARK(Copy, BenchCopy);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchCopyIf
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -322,18 +318,18 @@ private:
{
vtkm::Id arraySize = Config.ComputeSize<Value>();
vtkm::Id modulo = arraySize / N_VALID;
Algorithm::Schedule(
FillTestValueKernel<Value>(ValueHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
arraySize);
Algorithm::Schedule(FillBinaryTestValueKernel<vtkm::Id>(
modulo, StencilHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
auto vHPortal = ValueHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillTestValueKernel<Value, decltype(vHPortal)>(vHPortal), arraySize);
auto sHPortal = StencilHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillBinaryTestValueKernel<vtkm::Id, decltype(sHPortal)>(modulo, sHPortal),
arraySize);
}
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algorithm::CopyIf(ValueHandle, StencilHandle, OutHandle);
@ -365,7 +361,7 @@ private:
VTKM_MAKE_BENCHMARK(CopyIf75, BenchCopyIf, 75);
VTKM_MAKE_BENCHMARK(CopyIf100, BenchCopyIf, 100);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchLowerBounds
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -381,18 +377,18 @@ private:
, PERCENT_VALUES(value_percent)
{
vtkm::Id arraySize = Config.ComputeSize<Value>();
Algorithm::Schedule(
FillTestValueKernel<Value>(InputHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
arraySize);
Algorithm::Schedule(FillScaledTestValueKernel<Value>(
2, ValueHandle.PrepareForOutput(N_VALS, DeviceAdapterTag())),
auto iHPortal = InputHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillTestValueKernel<Value, decltype(iHPortal)>(iHPortal), arraySize);
auto vHPortal = ValueHandle.PrepareForOutput(N_VALS, DeviceAdapter());
Algorithm::Schedule(FillScaledTestValueKernel<Value, decltype(vHPortal)>(2, vHPortal),
N_VALS);
}
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algorithm::LowerBounds(InputHandle, ValueHandle, OutHandle);
@ -424,7 +420,7 @@ private:
VTKM_MAKE_BENCHMARK(LowerBounds75, BenchLowerBounds, 75);
VTKM_MAKE_BENCHMARK(LowerBounds100, BenchLowerBounds, 100);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchReduce
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -438,9 +434,8 @@ private:
BenchReduce()
{
vtkm::Id arraySize = Config.ComputeSize<Value>();
Algorithm::Schedule(
FillTestValueKernel<Value>(InputHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
arraySize);
auto iHPortal = this->InputHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillTestValueKernel<Value, decltype(iHPortal)>(iHPortal), arraySize);
this->Result =
Algorithm::Reduce(this->InputHandle, vtkm::TypeTraits<Value>::ZeroInitialization());
}
@ -448,9 +443,11 @@ private:
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Value tmp = Algorithm::Reduce(InputHandle, vtkm::TypeTraits<Value>::ZeroInitialization());
Value tmp =
Algorithm::Reduce(this->InputHandle, vtkm::TypeTraits<Value>::ZeroInitialization());
vtkm::Float64 time = timer.GetElapsedTime();
if (tmp != this->Result)
{
@ -473,7 +470,7 @@ private:
};
VTKM_MAKE_BENCHMARK(Reduce, BenchReduce);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchReduceByKey
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -489,11 +486,10 @@ private:
, PERCENT_KEYS(key_percent)
{
vtkm::Id arraySize = Config.ComputeSize<Value>();
Algorithm::Schedule(
FillTestValueKernel<Value>(ValueHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
arraySize);
Algorithm::Schedule(FillModuloTestValueKernel<vtkm::Id>(
N_KEYS, KeyHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
auto vHPortal = ValueHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillTestValueKernel<Value, decltype(vHPortal)>(vHPortal), arraySize);
auto kHPortal = KeyHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillModuloTestValueKernel<vtkm::Id, decltype(kHPortal)>(N_KEYS, kHPortal),
arraySize);
Algorithm::SortByKey(KeyHandle, ValueHandle);
}
@ -501,7 +497,7 @@ private:
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algorithm::ReduceByKey(KeyHandle, ValueHandle, KeysOut, ValuesOut, vtkm::Add());
return timer.GetElapsedTime();
@ -532,7 +528,7 @@ private:
VTKM_MAKE_BENCHMARK(ReduceByKey75, BenchReduceByKey, 75);
VTKM_MAKE_BENCHMARK(ReduceByKey100, BenchReduceByKey, 100);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchScanInclusive
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -542,15 +538,14 @@ private:
BenchScanInclusive()
{
vtkm::Id arraySize = Config.ComputeSize<Value>();
Algorithm::Schedule(
FillTestValueKernel<Value>(ValueHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
arraySize);
auto vHPortal = ValueHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillTestValueKernel<Value, decltype(vHPortal)>(vHPortal), arraySize);
}
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algorithm::ScanInclusive(ValueHandle, OutHandle);
return timer.GetElapsedTime();
@ -570,7 +565,7 @@ private:
};
VTKM_MAKE_BENCHMARK(ScanInclusive, BenchScanInclusive);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchScanExclusive
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -581,15 +576,15 @@ private:
BenchScanExclusive()
{
vtkm::Id arraySize = Config.ComputeSize<Value>();
Algorithm::Schedule(
FillTestValueKernel<Value>(ValueHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
arraySize);
auto vHPortal = ValueHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillTestValueKernel<Value, decltype(vHPortal)>(vHPortal), arraySize);
}
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algorithm::ScanExclusive(ValueHandle, OutHandle);
return timer.GetElapsedTime();
@ -609,7 +604,7 @@ private:
};
VTKM_MAKE_BENCHMARK(ScanExclusive, BenchScanExclusive);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchSort
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -634,7 +629,7 @@ private:
ValueArrayHandle array;
Algorithm::Copy(this->ValueHandle, array);
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algorithm::Sort(array);
return timer.GetElapsedTime();
@ -654,7 +649,7 @@ private:
};
VTKM_MAKE_BENCHMARK(Sort, BenchSort);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchSortByKey
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -677,8 +672,8 @@ private:
{
portal.Set(vtkm::Id(i), TestValue(vtkm::Id(Rng()), Value()));
}
Algorithm::Schedule(FillModuloTestValueKernel<vtkm::Id>(
N_KEYS, KeyHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
auto kHPortal = KeyHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillModuloTestValueKernel<vtkm::Id, decltype(kHPortal)>(N_KEYS, kHPortal),
arraySize);
}
@ -690,7 +685,7 @@ private:
Algorithm::Copy(this->KeyHandle, keys);
Algorithm::Copy(this->ValueHandle, values);
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algorithm::SortByKey(keys, values);
return timer.GetElapsedTime();
@ -721,7 +716,7 @@ private:
VTKM_MAKE_BENCHMARK(SortByKey75, BenchSortByKey, 75);
VTKM_MAKE_BENCHMARK(SortByKey100, BenchSortByKey, 100);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchStableSortIndices
{
using SSI = vtkm::worklet::StableSortIndices;
@ -749,7 +744,7 @@ private:
vtkm::cont::ArrayHandle<vtkm::Id> indices;
Algorithm::Copy(vtkm::cont::ArrayHandleIndex(arraySize), indices);
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
SSI::Sort(ValueHandle, indices);
return timer.GetElapsedTime();
@ -769,7 +764,7 @@ private:
};
VTKM_MAKE_BENCHMARK(StableSortIndices, BenchStableSortIndices);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchStableSortIndicesUnique
{
using SSI = vtkm::worklet::StableSortIndices;
@ -787,19 +782,19 @@ private:
, PERCENT_VALID(percent_valid)
{
vtkm::Id arraySize = Config.ComputeSize<Value>();
Algorithm::Schedule(
FillModuloTestValueKernel<Value>(
N_VALID, this->ValueHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
arraySize);
auto vHPortal = this->ValueHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillModuloTestValueKernel<Value, decltype(vHPortal)>(N_VALID, vHPortal),
arraySize);
this->IndexHandle = SSI::Sort(this->ValueHandle);
}
VTKM_CONT
vtkm::Float64 operator()()
{
IndexArrayHandle indices;
Algorithm::Copy(this->IndexHandle, indices);
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
SSI::Unique(this->ValueHandle, indices);
return timer.GetElapsedTime();
@ -830,7 +825,7 @@ private:
VTKM_MAKE_BENCHMARK(StableSortIndicesUnique75, BenchStableSortIndicesUnique, 75);
VTKM_MAKE_BENCHMARK(StableSortIndicesUnique100, BenchStableSortIndicesUnique, 100);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchUnique
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -845,8 +840,8 @@ private:
, PERCENT_VALID(percent_valid)
{
vtkm::Id arraySize = Config.ComputeSize<Value>();
Algorithm::Schedule(FillModuloTestValueKernel<Value>(
N_VALID, ValueHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
auto vHPortal = ValueHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillModuloTestValueKernel<Value, decltype(vHPortal)>(N_VALID, vHPortal),
arraySize);
Algorithm::Sort(ValueHandle);
}
@ -854,10 +849,11 @@ private:
VTKM_CONT
vtkm::Float64 operator()()
{
ValueArrayHandle array;
Algorithm::Copy(this->ValueHandle, array);
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Algorithm::Unique(array);
return timer.GetElapsedTime();
@ -888,7 +884,7 @@ private:
VTKM_MAKE_BENCHMARK(Unique75, BenchUnique, 75);
VTKM_MAKE_BENCHMARK(Unique100, BenchUnique, 100);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchUpperBounds
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -904,18 +900,17 @@ private:
, PERCENT_VALS(percent_vals)
{
vtkm::Id arraySize = Config.ComputeSize<Value>();
Algorithm::Schedule(
FillTestValueKernel<Value>(InputHandle.PrepareForOutput(arraySize, DeviceAdapterTag())),
arraySize);
Algorithm::Schedule(FillScaledTestValueKernel<Value>(
2, ValueHandle.PrepareForOutput(N_VALS, DeviceAdapterTag())),
auto iHPortal = InputHandle.PrepareForOutput(arraySize, DeviceAdapter());
Algorithm::Schedule(FillTestValueKernel<Value, decltype(iHPortal)>(iHPortal), arraySize);
auto vHPortal = ValueHandle.PrepareForOutput(N_VALS, DeviceAdapter());
Algorithm::Schedule(FillScaledTestValueKernel<Value, decltype(vHPortal)>(2, vHPortal),
N_VALS);
}
VTKM_CONT
vtkm::Float64 operator()()
{
vtkm::cont::Timer timer;
vtkm::cont::Timer timer{ DeviceAdapter() };
timer.Start();
Algorithm::UpperBounds(InputHandle, ValueHandle, OutHandle);
return timer.GetElapsedTime();
@ -948,11 +943,8 @@ private:
VTKM_MAKE_BENCHMARK(UpperBounds100, BenchUpperBounds, 100);
public:
static VTKM_CONT int Run()
static VTKM_CONT int Run(vtkm::cont::DeviceAdapterId id)
{
std::cout << DIVIDER << "\nRunning DeviceAdapter benchmarks\n";
vtkm::cont::GetGlobalRuntimeDeviceTracker().ForceDevice(DeviceAdapterTag());
// Run fixed bytes / size tests:
for (int sizeType = 0; sizeType < 2; ++sizeType)
{
@ -962,11 +954,11 @@ public:
Config.DoByteSizes = true;
if (!Config.ExtendedTypeList)
{
RunInternal<BaseTypes>();
RunInternal<BaseTypes>(id);
}
else
{
RunInternal<ExtendedTypes>();
RunInternal<ExtendedTypes>(id);
}
}
if (sizeType == 1 && Config.TestArraySizeValues)
@ -975,11 +967,11 @@ public:
Config.DoByteSizes = false;
if (!Config.ExtendedTypeList)
{
RunInternal<BaseTypes>();
RunInternal<BaseTypes>(id);
}
else
{
RunInternal<ExtendedTypes>();
RunInternal<ExtendedTypes>(id);
}
}
}
@ -988,12 +980,12 @@ public:
}
template <typename ValueTypes>
static VTKM_CONT void RunInternal()
static VTKM_CONT void RunInternal(vtkm::cont::DeviceAdapterId id)
{
if (Config.BenchmarkFlags & COPY)
{
std::cout << DIVIDER << "\nBenchmarking Copy\n";
VTKM_RUN_BENCHMARK(Copy, ValueTypes());
VTKM_RUN_BENCHMARK(Copy, ValueTypes(), id);
}
if (Config.BenchmarkFlags & COPY_IF)
@ -1001,26 +993,26 @@ public:
std::cout << "\n" << DIVIDER << "\nBenchmarking CopyIf\n";
if (Config.DetailedOutputRangeScaling)
{
VTKM_RUN_BENCHMARK(CopyIf5, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf10, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf15, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf20, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf25, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf30, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf35, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf40, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf45, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf50, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf75, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf100, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf10, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf15, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf20, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf30, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf35, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf40, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf45, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf100, ValueTypes(), id);
}
else
{
VTKM_RUN_BENCHMARK(CopyIf5, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf25, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf50, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf75, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf100, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CopyIf100, ValueTypes(), id);
}
}
@ -1029,33 +1021,33 @@ public:
std::cout << DIVIDER << "\nBenchmarking LowerBounds\n";
if (Config.DetailedOutputRangeScaling)
{
VTKM_RUN_BENCHMARK(LowerBounds5, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds10, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds15, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds20, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds25, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds30, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds35, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds40, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds45, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds50, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds75, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds100, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds10, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds15, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds20, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds30, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds35, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds40, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds45, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds100, ValueTypes(), id);
}
else
{
VTKM_RUN_BENCHMARK(LowerBounds5, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds25, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds50, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds75, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds100, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(LowerBounds100, ValueTypes(), id);
}
}
if (Config.BenchmarkFlags & REDUCE)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking Reduce\n";
VTKM_RUN_BENCHMARK(Reduce, ValueTypes());
VTKM_RUN_BENCHMARK(Reduce, ValueTypes(), id);
}
if (Config.BenchmarkFlags & REDUCE_BY_KEY)
@ -1063,45 +1055,45 @@ public:
std::cout << "\n" << DIVIDER << "\nBenchmarking ReduceByKey\n";
if (Config.DetailedOutputRangeScaling)
{
VTKM_RUN_BENCHMARK(ReduceByKey5, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey10, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey15, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey20, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey25, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey30, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey35, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey40, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey45, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey50, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey75, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey100, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey10, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey15, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey20, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey30, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey35, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey40, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey45, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey100, ValueTypes(), id);
}
else
{
VTKM_RUN_BENCHMARK(ReduceByKey5, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey25, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey50, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey75, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey100, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ReduceByKey100, ValueTypes(), id);
}
}
if (Config.BenchmarkFlags & SCAN_INCLUSIVE)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking ScanInclusive\n";
VTKM_RUN_BENCHMARK(ScanInclusive, ValueTypes());
VTKM_RUN_BENCHMARK(ScanInclusive, ValueTypes(), id);
}
if (Config.BenchmarkFlags & SCAN_EXCLUSIVE)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking ScanExclusive\n";
VTKM_RUN_BENCHMARK(ScanExclusive, ValueTypes());
VTKM_RUN_BENCHMARK(ScanExclusive, ValueTypes(), id);
}
if (Config.BenchmarkFlags & SORT)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking Sort\n";
VTKM_RUN_BENCHMARK(Sort, ValueTypes());
VTKM_RUN_BENCHMARK(Sort, ValueTypes(), id);
}
if (Config.BenchmarkFlags & SORT_BY_KEY)
@ -1109,33 +1101,33 @@ public:
std::cout << "\n" << DIVIDER << "\nBenchmarking SortByKey\n";
if (Config.DetailedOutputRangeScaling)
{
VTKM_RUN_BENCHMARK(SortByKey5, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey10, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey15, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey20, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey25, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey30, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey35, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey40, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey45, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey50, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey75, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey100, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey10, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey15, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey20, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey30, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey35, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey40, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey45, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey100, ValueTypes(), id);
}
else
{
VTKM_RUN_BENCHMARK(SortByKey5, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey25, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey50, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey75, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey100, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(SortByKey100, ValueTypes(), id);
}
}
if (Config.BenchmarkFlags & STABLE_SORT_INDICES)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking StableSortIndices::Sort\n";
VTKM_RUN_BENCHMARK(StableSortIndices, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndices, ValueTypes(), id);
}
if (Config.BenchmarkFlags & STABLE_SORT_INDICES_UNIQUE)
@ -1143,26 +1135,26 @@ public:
std::cout << "\n" << DIVIDER << "\nBenchmarking StableSortIndices::Unique\n";
if (Config.DetailedOutputRangeScaling)
{
VTKM_RUN_BENCHMARK(StableSortIndicesUnique5, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique10, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique15, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique20, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique25, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique30, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique35, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique40, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique45, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique50, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique75, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique100, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique10, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique15, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique20, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique30, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique35, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique40, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique45, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique100, ValueTypes(), id);
}
else
{
VTKM_RUN_BENCHMARK(StableSortIndicesUnique5, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique25, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique50, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique75, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique100, ValueTypes());
VTKM_RUN_BENCHMARK(StableSortIndicesUnique5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(StableSortIndicesUnique100, ValueTypes(), id);
}
}
@ -1171,26 +1163,26 @@ public:
std::cout << "\n" << DIVIDER << "\nBenchmarking Unique\n";
if (Config.DetailedOutputRangeScaling)
{
VTKM_RUN_BENCHMARK(Unique5, ValueTypes());
VTKM_RUN_BENCHMARK(Unique10, ValueTypes());
VTKM_RUN_BENCHMARK(Unique15, ValueTypes());
VTKM_RUN_BENCHMARK(Unique20, ValueTypes());
VTKM_RUN_BENCHMARK(Unique25, ValueTypes());
VTKM_RUN_BENCHMARK(Unique30, ValueTypes());
VTKM_RUN_BENCHMARK(Unique35, ValueTypes());
VTKM_RUN_BENCHMARK(Unique40, ValueTypes());
VTKM_RUN_BENCHMARK(Unique45, ValueTypes());
VTKM_RUN_BENCHMARK(Unique50, ValueTypes());
VTKM_RUN_BENCHMARK(Unique75, ValueTypes());
VTKM_RUN_BENCHMARK(Unique100, ValueTypes());
VTKM_RUN_BENCHMARK(Unique5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique10, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique15, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique20, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique30, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique35, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique40, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique45, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique100, ValueTypes(), id);
}
else
{
VTKM_RUN_BENCHMARK(Unique5, ValueTypes());
VTKM_RUN_BENCHMARK(Unique25, ValueTypes());
VTKM_RUN_BENCHMARK(Unique50, ValueTypes());
VTKM_RUN_BENCHMARK(Unique75, ValueTypes());
VTKM_RUN_BENCHMARK(Unique100, ValueTypes());
VTKM_RUN_BENCHMARK(Unique5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(Unique100, ValueTypes(), id);
}
}
@ -1199,26 +1191,26 @@ public:
std::cout << "\n" << DIVIDER << "\nBenchmarking UpperBounds\n";
if (Config.DetailedOutputRangeScaling)
{
VTKM_RUN_BENCHMARK(UpperBounds5, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds10, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds15, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds20, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds25, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds30, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds35, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds40, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds45, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds50, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds75, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds100, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds10, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds15, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds20, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds30, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds35, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds40, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds45, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds100, ValueTypes(), id);
}
else
{
VTKM_RUN_BENCHMARK(UpperBounds5, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds25, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds50, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds75, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds100, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds5, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds25, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds50, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds75, ValueTypes(), id);
VTKM_RUN_BENCHMARK(UpperBounds100, ValueTypes(), id);
}
}
}
@ -1230,19 +1222,28 @@ public:
int main(int argc, char* argv[])
{
vtkm::cont::InitLogging(argc, argv);
auto opt = vtkm::cont::InitializeOptions::RequireDevice;
auto initConfig = vtkm::cont::Initialize(argc, argv, opt);
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
int numThreads = tbb::task_scheduler_init::automatic;
#elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_OPENMP
int numThreads = omp_get_max_threads();
#endif // TBB
int numThreads{ 0 };
#ifdef VTKM_ENABLE_TBB
if (initConfig.Device == vtkm::cont::DeviceAdapterTagTBB())
{
numThreads = tbb::task_scheduler_init::automatic;
}
#endif
#ifdef VTKM_ENABLE_OPENMP
if (initConfig.Device == vtkm::cont::DeviceAdapterTagOpenMP())
{
numThreads = omp_get_max_threads();
}
#endif
vtkm::benchmarking::BenchDevAlgoConfig& config = vtkm::benchmarking::Config;
for (int i = 1; i < argc; ++i)
for (size_t i = 0; i < initConfig.Arguments.size(); ++i)
{
std::string arg = argv[i];
std::string arg = initConfig.Arguments[i];
std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
@ -1301,7 +1302,7 @@ int main(int argc, char* argv[])
else if (arg == "typelist")
{
++i;
arg = argv[i];
arg = initConfig.Arguments[i];
std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
@ -1315,14 +1316,14 @@ int main(int argc, char* argv[])
}
else
{
std::cerr << "Unrecognized TypeList: " << argv[i] << std::endl;
std::cerr << "Unrecognized TypeList: " << initConfig.Arguments[i] << std::endl;
return 1;
}
}
else if (arg == "fixbytes")
{
++i;
arg = argv[i];
arg = initConfig.Arguments[i];
std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
@ -1340,7 +1341,7 @@ int main(int argc, char* argv[])
else if (arg == "fixsizes")
{
++i;
arg = argv[i];
arg = initConfig.Arguments[i];
std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
@ -1362,30 +1363,38 @@ int main(int argc, char* argv[])
else if (arg == "numthreads")
{
++i;
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
std::istringstream parse(argv[i]);
parse >> numThreads;
std::cout << "Selected " << numThreads << " TBB threads." << std::endl;
#elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_OPENMP
std::istringstream parse(argv[i]);
parse >> numThreads;
std::cout << "Selected " << numThreads << " OpenMP threads." << std::endl;
#else
std::cerr << "NumThreads not valid on this device. Ignoring." << std::endl;
#endif // TBB
if (initConfig.Device == vtkm::cont::DeviceAdapterTagTBB() ||
initConfig.Device == vtkm::cont::DeviceAdapterTagOpenMP())
{
std::istringstream parse(initConfig.Arguments[i]);
parse >> numThreads;
std::cout << "Selected " << numThreads << " " << initConfig.Device.GetName() << " threads."
<< std::endl;
}
else
{
std::cerr << "NumThreads not valid on this device. Ignoring." << std::endl;
}
}
else
{
std::cerr << "Unrecognized benchmark: " << argv[i] << std::endl;
std::cerr << "Unrecognized benchmark: " << initConfig.Arguments[i] << std::endl;
return 1;
}
}
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
#ifdef VTKM_ENABLE_TBB
// Must not be destroyed as long as benchmarks are running:
tbb::task_scheduler_init init(numThreads);
#elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_OPENMP
omp_set_num_threads(numThreads);
if (initConfig.Device == vtkm::cont::DeviceAdapterTagTBB())
{
tbb::task_scheduler_init init(numThreads);
}
#endif
#ifdef VTKM_ENABLE_OPENMP
if (initConfig.Device == vtkm::cont::DeviceAdapterTagOpenMP())
{
omp_set_num_threads(numThreads);
}
#endif // TBB
if (config.BenchmarkFlags == 0)
@ -1394,5 +1403,5 @@ int main(int argc, char* argv[])
}
//now actually execute the benchmarks
return vtkm::benchmarking::BenchmarkDeviceAdapter<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::Run();
return vtkm::benchmarking::BenchmarkDeviceAdapter::Run(initConfig.Device);
}

@ -24,6 +24,7 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/ImplicitFunctionHandle.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/cont/VariantArrayHandle.h>
@ -311,7 +312,6 @@ struct InterpValueTypes : vtkm::ListTagBase<vtkm::Float32, vtkm::Vec<vtkm::Float
/// This class runs a series of micro-benchmarks to measure
/// performance of different field operations
template <class DeviceAdapterTag>
class BenchmarkFieldAlgorithms
{
using StorageTag = vtkm::cont::StorageTagBasic;
@ -323,7 +323,7 @@ class BenchmarkFieldAlgorithms
using EdgeIdVariantHandle = vtkm::cont::VariantArrayHandleBase<vtkm::TypeListTagId2>;
private:
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchBlackScholes
{
using ValueArrayHandle = vtkm::cont::ArrayHandle<Value, StorageTag>;
@ -366,11 +366,10 @@ private:
const Value RISKFREE = 0.02f;
const Value VOLATILITY = 0.30f;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
BlackScholes<Value> worklet(RISKFREE, VOLATILITY);
vtkm::worklet::DispatcherMapField<BlackScholes<Value>> dispatcher(worklet);
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(
this->StockPrice, this->OptionStrike, this->OptionYears, callResultHandle, putResultHandle);
@ -391,8 +390,8 @@ private:
}
};
template <typename Value>
struct BenchBlackScholesDynamic : public BenchBlackScholes<Value>
template <typename Value, typename DeviceAdapter>
struct BenchBlackScholesDynamic : public BenchBlackScholes<Value, DeviceAdapter>
{
VTKM_CONT
@ -406,11 +405,10 @@ private:
const Value RISKFREE = 0.02f;
const Value VOLATILITY = 0.30f;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
BlackScholes<Value> worklet(RISKFREE, VOLATILITY);
vtkm::worklet::DispatcherMapField<BlackScholes<Value>> dispatcher(worklet);
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(dstocks, dstrikes, doptions, callResultHandle, putResultHandle);
@ -423,7 +421,7 @@ private:
VTKM_MAKE_BENCHMARK(BlackScholes, BenchBlackScholes);
VTKM_MAKE_BENCHMARK(BlackScholesDynamic, BenchBlackScholesDynamic);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchMath
{
std::vector<vtkm::Vec<Value, 3>> input;
@ -450,10 +448,10 @@ private:
vtkm::cont::ArrayHandle<Value> tempHandle1;
vtkm::cont::ArrayHandle<Value> tempHandle2;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
vtkm::worklet::Invoker invoke(DeviceAdapterTag{});
vtkm::worklet::Invoker invoke(DeviceAdapter{});
invoke(Mag{}, this->InputHandle, tempHandle1);
invoke(Sin{}, tempHandle1, tempHandle2);
invoke(Square{}, tempHandle2, tempHandle1);
@ -475,8 +473,8 @@ private:
}
};
template <typename Value>
struct BenchMathDynamic : public BenchMath<Value>
template <typename Value, typename DeviceAdapter>
struct BenchMathDynamic : public BenchMath<Value, DeviceAdapter>
{
VTKM_CONT
@ -490,10 +488,10 @@ private:
ValueVariantHandle dtemp1(temp1);
ValueVariantHandle dtemp2(temp2);
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
vtkm::worklet::Invoker invoke(DeviceAdapterTag{});
vtkm::worklet::Invoker invoke(DeviceAdapter{});
invoke(Mag{}, dinput, dtemp1);
invoke(Sin{}, dtemp1, dtemp2);
invoke(Square{}, dtemp2, dtemp1);
@ -508,7 +506,7 @@ private:
VTKM_MAKE_BENCHMARK(Math, BenchMath);
VTKM_MAKE_BENCHMARK(MathDynamic, BenchMathDynamic);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchFusedMath
{
std::vector<vtkm::Vec<Value, 3>> input;
@ -534,10 +532,9 @@ private:
{
vtkm::cont::ArrayHandle<Value> result;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
vtkm::worklet::DispatcherMapField<FusedMath> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->InputHandle, result);
return timer.GetElapsedTime();
@ -556,8 +553,8 @@ private:
}
};
template <typename Value>
struct BenchFusedMathDynamic : public BenchFusedMath<Value>
template <typename Value, typename DeviceAdapter>
struct BenchFusedMathDynamic : public BenchFusedMath<Value, DeviceAdapter>
{
VTKM_CONT
@ -569,10 +566,9 @@ private:
vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
vtkm::worklet::DispatcherMapField<FusedMath> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(dinput, result);
return timer.GetElapsedTime();
@ -584,7 +580,7 @@ private:
VTKM_MAKE_BENCHMARK(FusedMath, BenchFusedMath);
VTKM_MAKE_BENCHMARK(FusedMathDynamic, BenchFusedMathDynamic);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchEdgeInterp
{
std::vector<vtkm::Float32> weight;
@ -617,7 +613,6 @@ private:
this->EdgePairHandle.Allocate(numberOfEdges);
vtkm::worklet::DispatcherMapTopology<GenerateEdges> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(cellSet, this->EdgePairHandle);
this->weight.resize(esize);
@ -641,10 +636,9 @@ private:
{
vtkm::cont::ArrayHandle<Value> result;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
vtkm::worklet::DispatcherMapField<InterpolateField> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->EdgePairHandle, this->WeightHandle, this->FieldHandle, result);
return timer.GetElapsedTime();
@ -664,8 +658,8 @@ private:
}
};
template <typename Value>
struct BenchEdgeInterpDynamic : public BenchEdgeInterp<Value>
template <typename Value, typename DeviceAdapter>
struct BenchEdgeInterpDynamic : public BenchEdgeInterp<Value, DeviceAdapter>
{
VTKM_CONT
@ -676,10 +670,9 @@ private:
EdgeIdVariantHandle dedges(this->EdgePairHandle);
vtkm::cont::ArrayHandle<Value> result;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
vtkm::worklet::DispatcherMapField<InterpolateField> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(dedges, dweight, dfield, result);
return timer.GetElapsedTime();
@ -724,7 +717,7 @@ private:
return data;
}
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchImplicitFunction
{
BenchImplicitFunction()
@ -739,14 +732,12 @@ private:
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet>;
auto handle = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere1);
auto function =
static_cast<const vtkm::Sphere*>(handle.PrepareForExecution(DeviceAdapterTag()));
auto function = static_cast<const vtkm::Sphere*>(handle.PrepareForExecution(DeviceAdapter()));
EvalWorklet eval(function);
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
EvalDispatcher dispatcher(eval);
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
@ -764,7 +755,7 @@ private:
ImplicitFunctionBenchData Internal;
};
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchVirtualImplicitFunction
{
BenchVirtualImplicitFunction()
@ -779,12 +770,11 @@ private:
using EvalDispatcher = vtkm::worklet::DispatcherMapField<EvalWorklet>;
auto sphere = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere1);
EvalWorklet eval(sphere.PrepareForExecution(DeviceAdapterTag()));
EvalWorklet eval(sphere.PrepareForExecution(DeviceAdapter()));
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
EvalDispatcher dispatcher(eval);
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
@ -802,7 +792,7 @@ private:
ImplicitFunctionBenchData Internal;
};
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct Bench2ImplicitFunctions
{
Bench2ImplicitFunctions()
@ -818,14 +808,13 @@ private:
auto h1 = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere1);
auto h2 = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere2);
auto f1 = static_cast<const vtkm::Sphere*>(h1.PrepareForExecution(DeviceAdapterTag()));
auto f2 = static_cast<const vtkm::Sphere*>(h2.PrepareForExecution(DeviceAdapterTag()));
auto f1 = static_cast<const vtkm::Sphere*>(h1.PrepareForExecution(DeviceAdapter()));
auto f2 = static_cast<const vtkm::Sphere*>(h2.PrepareForExecution(DeviceAdapter()));
EvalWorklet eval(f1, f2);
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
EvalDispatcher dispatcher(eval);
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
@ -843,7 +832,7 @@ private:
ImplicitFunctionBenchData Internal;
};
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct Bench2VirtualImplicitFunctions
{
Bench2VirtualImplicitFunctions()
@ -860,13 +849,12 @@ private:
auto s1 = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere1);
auto s2 = vtkm::cont::make_ImplicitFunctionHandle(Internal.Sphere2);
EvalWorklet eval(s1.PrepareForExecution(DeviceAdapterTag()),
s2.PrepareForExecution(DeviceAdapterTag()));
EvalWorklet eval(s1.PrepareForExecution(DeviceAdapter()),
s2.PrepareForExecution(DeviceAdapter()));
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
EvalDispatcher dispatcher(eval);
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->Internal.Points, this->Internal.Result);
return timer.GetElapsedTime();
@ -890,36 +878,36 @@ private:
VTKM_MAKE_BENCHMARK(ImplicitFunctionVirtual2, Bench2VirtualImplicitFunctions);
public:
static VTKM_CONT int Run(int benchmarks)
static VTKM_CONT int Run(int benchmarks, vtkm::cont::DeviceAdapterId id)
{
std::cout << DIVIDER << "\nRunning Field Algorithm benchmarks\n";
if (benchmarks & BLACK_SCHOLES)
{
std::cout << DIVIDER << "\nBenchmarking BlackScholes\n";
VTKM_RUN_BENCHMARK(BlackScholes, ValueTypes());
VTKM_RUN_BENCHMARK(BlackScholesDynamic, ValueTypes());
VTKM_RUN_BENCHMARK(BlackScholes, ValueTypes(), id);
VTKM_RUN_BENCHMARK(BlackScholesDynamic, ValueTypes(), id);
}
if (benchmarks & MATH)
{
std::cout << DIVIDER << "\nBenchmarking Multiple Math Worklets\n";
VTKM_RUN_BENCHMARK(Math, ValueTypes());
VTKM_RUN_BENCHMARK(MathDynamic, ValueTypes());
VTKM_RUN_BENCHMARK(Math, ValueTypes(), id);
VTKM_RUN_BENCHMARK(MathDynamic, ValueTypes(), id);
}
if (benchmarks & FUSED_MATH)
{
std::cout << DIVIDER << "\nBenchmarking Single Fused Math Worklet\n";
VTKM_RUN_BENCHMARK(FusedMath, ValueTypes());
VTKM_RUN_BENCHMARK(FusedMathDynamic, ValueTypes());
VTKM_RUN_BENCHMARK(FusedMath, ValueTypes(), id);
VTKM_RUN_BENCHMARK(FusedMathDynamic, ValueTypes(), id);
}
if (benchmarks & INTERPOLATE_FIELD)
{
std::cout << DIVIDER << "\nBenchmarking Edge Based Field InterpolationWorklet\n";
VTKM_RUN_BENCHMARK(EdgeInterp, InterpValueTypes());
VTKM_RUN_BENCHMARK(EdgeInterpDynamic, InterpValueTypes());
VTKM_RUN_BENCHMARK(EdgeInterp, InterpValueTypes(), id);
VTKM_RUN_BENCHMARK(EdgeInterpDynamic, InterpValueTypes(), id);
}
if (benchmarks & IMPLICIT_FUNCTION)
@ -927,10 +915,10 @@ public:
using FloatDefaultType = vtkm::ListTagBase<vtkm::FloatDefault>;
std::cout << "\nBenchmarking Implicit Function\n";
VTKM_RUN_BENCHMARK(ImplicitFunction, FloatDefaultType());
VTKM_RUN_BENCHMARK(ImplicitFunctionVirtual, FloatDefaultType());
VTKM_RUN_BENCHMARK(ImplicitFunction2, FloatDefaultType());
VTKM_RUN_BENCHMARK(ImplicitFunctionVirtual2, FloatDefaultType());
VTKM_RUN_BENCHMARK(ImplicitFunction, FloatDefaultType(), id);
VTKM_RUN_BENCHMARK(ImplicitFunctionVirtual, FloatDefaultType(), id);
VTKM_RUN_BENCHMARK(ImplicitFunction2, FloatDefaultType(), id);
VTKM_RUN_BENCHMARK(ImplicitFunctionVirtual2, FloatDefaultType(), id);
}
return 0;
@ -943,18 +931,19 @@ public:
int main(int argc, char* argv[])
{
vtkm::cont::InitLogging(argc, argv);
auto opts = vtkm::cont::InitializeOptions::RequireDevice;
auto config = vtkm::cont::Initialize(argc, argv, opts);
int benchmarks = 0;
if (argc < 2)
if (!config.Arguments.size())
{
benchmarks = vtkm::benchmarking::ALL;
}
else
{
for (int i = 1; i < argc; ++i)
for (size_t i = 0; i < config.Arguments.size(); ++i)
{
std::string arg = argv[i];
std::string arg = config.Arguments[i];
std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
@ -980,16 +969,13 @@ int main(int argc, char* argv[])
}
else
{
std::cout << "Unrecognized benchmark: " << argv[i] << std::endl;
std::cout << "Unrecognized benchmark: " << config.Arguments[i] << std::endl;
return 1;
}
}
}
//now actually execute the benchmarks
using Device = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
tracker.ForceDevice(Device{});
return vtkm::benchmarking::BenchmarkFieldAlgorithms<Device>::Run(benchmarks);
return vtkm::benchmarking::BenchmarkFieldAlgorithms::Run(benchmarks, config.Device);
}

@ -62,9 +62,10 @@
#include <sstream>
#include <type_traits>
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
#ifdef VTKM_ENABLE_TBB
#include <tbb/task_scheduler_init.h>
#elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_OPENMP
#endif
#ifdef VTKM_ENABLE_OPENMP
#include <omp.h>
#endif
@ -97,8 +98,6 @@
namespace
{
using Device = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
using DevTraits = vtkm::cont::DeviceAdapterTraits<Device>;
// unscoped enum so we can use bitwise ops without a lot of hassle:
enum BenchmarkName
@ -156,6 +155,16 @@ using AllCellList = vtkm::ListTagJoin<StructuredCellList, UnstructuredCellList>;
using CoordinateList = vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 3>, vtkm::Vec<vtkm::Float64, 3>>;
struct WaveletGeneratorDataFunctor
{
template <typename DeviceAdapter>
bool operator()(DeviceAdapter, vtkm::worklet::WaveletGenerator& gen)
{
InputDataSet = gen.GenerateDataSet<DeviceAdapter>();
return true;
}
};
class BenchmarkFilterPolicy : public vtkm::filter::PolicyBase<BenchmarkFilterPolicy>
{
public:
@ -169,7 +178,6 @@ public:
};
// Class implementing all filter benchmarks:
template <class DeviceAdapterTag>
class BenchmarkFilters
{
using Timer = vtkm::cont::Timer;
@ -185,7 +193,7 @@ class BenchmarkFilters
ScalarInput = 1 << 6
};
template <typename>
template <typename, typename DeviceAdapter>
struct BenchGradient
{
vtkm::filter::Gradient Filter;
@ -229,7 +237,7 @@ class BenchmarkFilters
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
return timer.GetElapsedTime();
@ -293,7 +301,7 @@ class BenchmarkFilters
BenchGradient,
Gradient | PointGradient | Divergence | Vorticity | QCriterion);
template <typename>
template <typename, typename DeviceAdapter>
struct BenchThreshold
{
vtkm::filter::Threshold Filter;
@ -317,7 +325,7 @@ class BenchmarkFilters
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
return timer.GetElapsedTime();
@ -328,7 +336,7 @@ class BenchmarkFilters
};
VTKM_MAKE_BENCHMARK(Threshold, BenchThreshold);
template <typename>
template <typename, typename DeviceAdapter>
struct BenchThresholdPoints
{
bool CompactPoints;
@ -356,7 +364,7 @@ class BenchmarkFilters
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
return timer.GetElapsedTime();
@ -368,7 +376,7 @@ class BenchmarkFilters
VTKM_MAKE_BENCHMARK(ThresholdPoints, BenchThresholdPoints, false);
VTKM_MAKE_BENCHMARK(ThresholdPointsCompact, BenchThresholdPoints, true);
template <typename>
template <typename, typename DeviceAdapter>
struct BenchCellAverage
{
vtkm::filter::CellAverage Filter;
@ -382,7 +390,7 @@ class BenchmarkFilters
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
return timer.GetElapsedTime();
@ -393,7 +401,7 @@ class BenchmarkFilters
};
VTKM_MAKE_BENCHMARK(CellAverage, BenchCellAverage);
template <typename>
template <typename, typename DeviceAdapter>
struct BenchPointAverage
{
vtkm::filter::PointAverage Filter;
@ -407,7 +415,7 @@ class BenchmarkFilters
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
return timer.GetElapsedTime();
@ -418,7 +426,7 @@ class BenchmarkFilters
};
VTKM_MAKE_BENCHMARK(PointAverage, BenchPointAverage);
template <typename>
template <typename, typename DeviceAdapter>
struct BenchWarpScalar
{
vtkm::filter::WarpScalar Filter;
@ -435,7 +443,7 @@ class BenchmarkFilters
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
return timer.GetElapsedTime();
@ -446,7 +454,7 @@ class BenchmarkFilters
};
VTKM_MAKE_BENCHMARK(WarpScalar, BenchWarpScalar);
template <typename>
template <typename, typename DeviceAdapter>
struct BenchWarpVector
{
vtkm::filter::WarpVector Filter;
@ -462,7 +470,7 @@ class BenchmarkFilters
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
return timer.GetElapsedTime();
@ -473,7 +481,7 @@ class BenchmarkFilters
};
VTKM_MAKE_BENCHMARK(WarpVector, BenchWarpVector);
template <typename>
template <typename, typename DeviceAdapter>
struct BenchMarchingCubes
{
vtkm::filter::MarchingCubes Filter;
@ -505,7 +513,7 @@ class BenchmarkFilters
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
return timer.GetElapsedTime();
@ -535,7 +543,7 @@ class BenchmarkFilters
VTKM_MAKE_BENCHMARK(MarchingCubes3FTT, BenchMarchingCubes, 3, false, true, true);
VTKM_MAKE_BENCHMARK(MarchingCubes12FTT, BenchMarchingCubes, 12, false, true, true);
template <typename>
template <typename, typename DeviceAdapter>
struct BenchExternalFaces
{
vtkm::filter::ExternalFaces Filter;
@ -550,7 +558,7 @@ class BenchmarkFilters
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
return timer.GetElapsedTime();
@ -571,7 +579,7 @@ class BenchmarkFilters
VTKM_MAKE_BENCHMARK(ExternalFaces, BenchExternalFaces, false);
VTKM_MAKE_BENCHMARK(ExternalFacesCompact, BenchExternalFaces, true);
template <typename>
template <typename, typename DeviceAdapter>
struct BenchTetrahedralize
{
vtkm::filter::Tetrahedralize Filter;
@ -585,7 +593,7 @@ class BenchmarkFilters
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
return timer.GetElapsedTime();
@ -596,7 +604,7 @@ class BenchmarkFilters
};
VTKM_MAKE_BENCHMARK(Tetrahedralize, BenchTetrahedralize);
template <typename>
template <typename, typename DeviceAdapter>
struct BenchVertexClustering
{
vtkm::filter::VertexClustering Filter;
@ -611,7 +619,7 @@ class BenchmarkFilters
VTKM_CONT
vtkm::Float64 operator()()
{
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
this->Filter.Execute(InputDataSet, BenchmarkFilterPolicy());
return timer.GetElapsedTime();
@ -633,7 +641,7 @@ class BenchmarkFilters
VTKM_MAKE_BENCHMARK(VertexClustering512, BenchVertexClustering, 512);
VTKM_MAKE_BENCHMARK(VertexClustering1024, BenchVertexClustering, 1024);
template <typename>
template <typename, typename DeviceAdapter>
struct BenchCellToPoint
{
struct PrepareForInput
@ -661,10 +669,10 @@ class BenchmarkFilters
vtkm::TopologyElementTagPoint{});
}
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
cellSet.PrepareForInput(
Device{}, vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{});
DeviceAdapter(), vtkm::TopologyElementTagCell{}, vtkm::TopologyElementTagPoint{});
this->Time = timer.GetElapsedTime();
}
};
@ -692,7 +700,7 @@ class BenchmarkFilters
VTKM_MAKE_BENCHMARK(CellToPoint, BenchCellToPoint);
public:
static VTKM_CONT int Run(int benches)
static VTKM_CONT int Run(int benches, vtkm::cont::DeviceAdapterId id)
{
// This has no influence on the benchmarks. See issue #286.
auto dummyTypes = vtkm::ListTagBase<vtkm::Int32>{};
@ -703,104 +711,104 @@ public:
{
if (ReducedOptions)
{
VTKM_RUN_BENCHMARK(GradientScalar, dummyTypes);
VTKM_RUN_BENCHMARK(GradientVector, dummyTypes);
VTKM_RUN_BENCHMARK(GradientVectorRow, dummyTypes);
VTKM_RUN_BENCHMARK(GradientKitchenSink, dummyTypes);
VTKM_RUN_BENCHMARK(GradientScalar, dummyTypes, id);
VTKM_RUN_BENCHMARK(GradientVector, dummyTypes, id);
VTKM_RUN_BENCHMARK(GradientVectorRow, dummyTypes, id);
VTKM_RUN_BENCHMARK(GradientKitchenSink, dummyTypes, id);
}
else
{
VTKM_RUN_BENCHMARK(GradientScalar, dummyTypes);
VTKM_RUN_BENCHMARK(GradientVector, dummyTypes);
VTKM_RUN_BENCHMARK(GradientVectorRow, dummyTypes);
VTKM_RUN_BENCHMARK(GradientPoint, dummyTypes);
VTKM_RUN_BENCHMARK(GradientDivergence, dummyTypes);
VTKM_RUN_BENCHMARK(GradientVorticity, dummyTypes);
VTKM_RUN_BENCHMARK(GradientQCriterion, dummyTypes);
VTKM_RUN_BENCHMARK(GradientKitchenSink, dummyTypes);
VTKM_RUN_BENCHMARK(GradientScalar, dummyTypes, id);
VTKM_RUN_BENCHMARK(GradientVector, dummyTypes, id);
VTKM_RUN_BENCHMARK(GradientVectorRow, dummyTypes, id);
VTKM_RUN_BENCHMARK(GradientPoint, dummyTypes, id);
VTKM_RUN_BENCHMARK(GradientDivergence, dummyTypes, id);
VTKM_RUN_BENCHMARK(GradientVorticity, dummyTypes, id);
VTKM_RUN_BENCHMARK(GradientQCriterion, dummyTypes, id);
VTKM_RUN_BENCHMARK(GradientKitchenSink, dummyTypes, id);
}
}
if (benches & BenchmarkName::THRESHOLD)
{
VTKM_RUN_BENCHMARK(Threshold, dummyTypes);
VTKM_RUN_BENCHMARK(Threshold, dummyTypes, id);
}
if (benches & BenchmarkName::THRESHOLD_POINTS)
{
VTKM_RUN_BENCHMARK(ThresholdPoints, dummyTypes);
VTKM_RUN_BENCHMARK(ThresholdPointsCompact, dummyTypes);
VTKM_RUN_BENCHMARK(ThresholdPoints, dummyTypes, id);
VTKM_RUN_BENCHMARK(ThresholdPointsCompact, dummyTypes, id);
}
if (benches & BenchmarkName::CELL_AVERAGE)
{
VTKM_RUN_BENCHMARK(CellAverage, dummyTypes);
VTKM_RUN_BENCHMARK(CellAverage, dummyTypes, id);
}
if (benches & BenchmarkName::POINT_AVERAGE)
{
VTKM_RUN_BENCHMARK(PointAverage, dummyTypes);
VTKM_RUN_BENCHMARK(PointAverage, dummyTypes, id);
}
if (benches & BenchmarkName::WARP_SCALAR)
{
VTKM_RUN_BENCHMARK(WarpScalar, dummyTypes);
VTKM_RUN_BENCHMARK(WarpScalar, dummyTypes, id);
}
if (benches & BenchmarkName::WARP_VECTOR)
{
VTKM_RUN_BENCHMARK(WarpVector, dummyTypes);
VTKM_RUN_BENCHMARK(WarpVector, dummyTypes, id);
}
if (benches & BenchmarkName::MARCHING_CUBES)
{
if (ReducedOptions)
{
VTKM_RUN_BENCHMARK(MarchingCubes1FFF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes12FFF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes12TFF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes12FTF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes12FTT, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes1FFF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes12FFF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes12TFF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes12FTF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes12FTT, dummyTypes, id);
}
else
{
VTKM_RUN_BENCHMARK(MarchingCubes1FFF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes3FFF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes12FFF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes1TFF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes3TFF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes12TFF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes1FTF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes3FTF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes12FTF, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes1FTT, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes3FTT, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes12FTT, dummyTypes);
VTKM_RUN_BENCHMARK(MarchingCubes1FFF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes3FFF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes12FFF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes1TFF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes3TFF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes12TFF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes1FTF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes3FTF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes12FTF, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes1FTT, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes3FTT, dummyTypes, id);
VTKM_RUN_BENCHMARK(MarchingCubes12FTT, dummyTypes, id);
}
}
if (benches & BenchmarkName::EXTERNAL_FACES)
{
VTKM_RUN_BENCHMARK(ExternalFaces, dummyTypes);
VTKM_RUN_BENCHMARK(ExternalFacesCompact, dummyTypes);
VTKM_RUN_BENCHMARK(ExternalFaces, dummyTypes, id);
VTKM_RUN_BENCHMARK(ExternalFacesCompact, dummyTypes, id);
}
if (benches & BenchmarkName::TETRAHEDRALIZE)
{
VTKM_RUN_BENCHMARK(Tetrahedralize, dummyTypes);
VTKM_RUN_BENCHMARK(Tetrahedralize, dummyTypes, id);
}
if (benches & BenchmarkName::VERTEX_CLUSTERING)
{
if (ReducedOptions)
{
VTKM_RUN_BENCHMARK(VertexClustering32, dummyTypes);
VTKM_RUN_BENCHMARK(VertexClustering256, dummyTypes);
VTKM_RUN_BENCHMARK(VertexClustering1024, dummyTypes);
VTKM_RUN_BENCHMARK(VertexClustering32, dummyTypes, id);
VTKM_RUN_BENCHMARK(VertexClustering256, dummyTypes, id);
VTKM_RUN_BENCHMARK(VertexClustering1024, dummyTypes, id);
}
else
{
VTKM_RUN_BENCHMARK(VertexClustering32, dummyTypes);
VTKM_RUN_BENCHMARK(VertexClustering64, dummyTypes);
VTKM_RUN_BENCHMARK(VertexClustering128, dummyTypes);
VTKM_RUN_BENCHMARK(VertexClustering256, dummyTypes);
VTKM_RUN_BENCHMARK(VertexClustering512, dummyTypes);
VTKM_RUN_BENCHMARK(VertexClustering1024, dummyTypes);
VTKM_RUN_BENCHMARK(VertexClustering32, dummyTypes, id);
VTKM_RUN_BENCHMARK(VertexClustering64, dummyTypes, id);
VTKM_RUN_BENCHMARK(VertexClustering128, dummyTypes, id);
VTKM_RUN_BENCHMARK(VertexClustering256, dummyTypes, id);
VTKM_RUN_BENCHMARK(VertexClustering512, dummyTypes, id);
VTKM_RUN_BENCHMARK(VertexClustering1024, dummyTypes, id);
}
}
if (benches & BenchmarkName::CELL_TO_POINT)
{
VTKM_RUN_BENCHMARK(CellToPoint, dummyTypes);
VTKM_RUN_BENCHMARK(CellToPoint, dummyTypes, id);
}
return 0;
@ -936,7 +944,6 @@ void CreateFields(bool needPointScalars, bool needCellScalars, bool needPointVec
PointVectorGenerator worklet(bounds);
vtkm::worklet::DispatcherMapField<PointVectorGenerator> dispatch(worklet);
dispatch.SetDevice(Device());
dispatch.Invoke(points, pvecs);
InputDataSet.AddField(
vtkm::cont::Field("GeneratedPointVectors", vtkm::cont::Field::Association::POINTS, pvecs));
@ -1050,18 +1057,21 @@ void AssertFields(bool needPointScalars, bool needCellScalars, bool needPointVec
}
}
int BenchmarkBody(int argc, char* argv[])
int BenchmarkBody(const std::vector<std::string>& argv, vtkm::cont::DeviceAdapterId id)
{
int numThreads = 1;
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
numThreads = tbb::task_scheduler_init::automatic;
#elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_OPENMP
numThreads = omp_get_max_threads();
#endif // TBB
// Force the requested device in case a tracker is used internally by a filter:
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
tracker.ForceDevice(Device());
#ifdef VTKM_ENABLE_TBB
if (id == vtkm::cont::DeviceAdapterTagTBB())
{
numThreads = tbb::task_scheduler_init::automatic;
}
#endif
#ifdef VTKM_ENABLE_OPENMP
if (id == vtkm::cont::DeviceAdapterTagOpenMP())
{
numThreads = omp_get_max_threads();
}
#endif
int benches = BenchmarkName::NONE;
std::string filename;
@ -1073,7 +1083,7 @@ int BenchmarkBody(int argc, char* argv[])
ReducedOptions = false;
for (int i = 1; i < argc; ++i)
for (size_t i = 0; i < argv.size(); ++i)
{
std::string arg = argv[i];
std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
@ -1174,13 +1184,11 @@ int BenchmarkBody(int argc, char* argv[])
else if (arg == "numthreads")
{
++i;
if (Device{} == vtkm::cont::DeviceAdapterTagOpenMP{} ||
Device{} == vtkm::cont::DeviceAdapterTagTBB{})
if (id == vtkm::cont::DeviceAdapterTagOpenMP() || id == vtkm::cont::DeviceAdapterTagTBB())
{
std::istringstream parse(argv[i]);
parse >> numThreads;
std::cout << "Selected " << numThreads << " " << DevTraits::GetName() << " threads."
<< std::endl;
std::cout << "Selected " << numThreads << " " << id.GetName() << " threads." << std::endl;
}
else
{
@ -1194,12 +1202,19 @@ int BenchmarkBody(int argc, char* argv[])
}
}
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
#ifdef VTKM_ENABLE_TBB
// Must not be destroyed as long as benchmarks are running:
tbb::task_scheduler_init init(numThreads);
#elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_OPENMP
omp_set_num_threads(numThreads);
#endif // TBB
if (id == vtkm::cont::DeviceAdapterTagTBB())
{
tbb::task_scheduler_init init(numThreads);
}
#endif
#ifdef VTKM_ENABLE_OPENMP
if (id == vtkm::cont::DeviceAdapterTagOpenMP())
{
omp_set_num_threads(numThreads);
}
#endif
if (benches == BenchmarkName::NONE)
{
@ -1222,7 +1237,10 @@ int BenchmarkBody(int argc, char* argv[])
<< " wavelet...\n";
vtkm::worklet::WaveletGenerator gen;
gen.SetExtent({ 0 }, { waveletDim });
InputDataSet = gen.GenerateDataSet<Device>();
// WaveletGenerator needs a template device argument not a id to deduce the portal type.
WaveletGeneratorDataFunctor genFunctor;
vtkm::cont::TryExecuteOnDevice(id, genFunctor, gen);
}
if (tetra)
@ -1271,7 +1289,7 @@ int BenchmarkBody(int argc, char* argv[])
std::cout << "\n";
//now actually execute the benchmarks
int result = BenchmarkFilters<Device>::Run(benches);
int result = BenchmarkFilters::Run(benches, id);
// Explicitly free resources before exit.
InputDataSet.Clear();
@ -1283,15 +1301,13 @@ int BenchmarkBody(int argc, char* argv[])
int main(int argc, char* argv[])
{
vtkm::cont::Initialize(argc, argv);
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
tracker.ForceDevice(Device{});
auto opts = vtkm::cont::InitializeOptions::RequireDevice;
auto config = vtkm::cont::Initialize(argc, argv, opts);
int retval = 1;
try
{
retval = BenchmarkBody(argc, argv);
retval = BenchmarkBody(config.Arguments, config.Device);
}
catch (std::exception& e)
{

@ -47,21 +47,23 @@ namespace vtkm
namespace benchmarking
{
template <typename Precision>
template <typename Precision, typename DeviceAdapter>
struct BenchRayTracing
{
vtkm::rendering::raytracing::RayTracer Tracer;
vtkm::rendering::raytracing::Camera RayCamera;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Indices;
vtkm::rendering::raytracing::Ray<Precision> Rays;
vtkm::Id NumberOfTriangles;
vtkm::cont::CoordinateSystem Coords;
vtkm::cont::DataSet Data;
VTKM_CONT ~BenchRayTracing() {}
VTKM_CONT BenchRayTracing()
{
vtkm::Id3 dims(128, 128, 128);
vtkm::cont::testing::MakeTestDataSet maker;
Data = maker.Make3DUniformDataSet2();
Data = maker.Make3DUniformDataSet3(dims);
Coords = Data.GetCoordinateSystem();
vtkm::rendering::Camera camera;
@ -72,8 +74,10 @@ struct BenchRayTracing
vtkm::rendering::raytracing::TriangleExtractor triExtractor;
triExtractor.ExtractCells(cellset);
vtkm::rendering::raytracing::TriangleIntersector* triIntersector =
new vtkm::rendering::raytracing::TriangleIntersector();
auto triIntersector = std::make_shared<vtkm::rendering::raytracing::TriangleIntersector>(
vtkm::rendering::raytracing::TriangleIntersector());
triIntersector->SetData(Coords, triExtractor.GetTriangles());
Tracer.AddShapeIntersector(triIntersector);
@ -114,11 +118,18 @@ struct BenchRayTracing
VTKM_CONT
vtkm::Float64 operator()()
{
vtkm::cont::Timer timer;
vtkm::cont::Timer timer{ DeviceAdapter() };
timer.Start();
RayCamera.CreateRays(Rays, Coords.GetBounds());
Tracer.Render(Rays);
try
{
Tracer.Render(Rays);
}
catch (vtkm::cont::ErrorBadValue& e)
{
std::cout << "exception " << e.what() << "\n";
}
return timer.GetElapsedTime();
}
@ -131,14 +142,12 @@ VTKM_MAKE_BENCHMARK(RayTracing, BenchRayTracing);
}
} // end namespace vtkm::benchmarking
int main(int argc, char* argv[])
{
vtkm::cont::InitLogging(argc, argv);
auto opts = vtkm::cont::InitializeOptions::RequireDevice;
auto config = vtkm::cont::Initialize(argc, argv, opts);
using Device = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
tracker.ForceDevice(Device{});
VTKM_RUN_BENCHMARK(RayTracing, vtkm::ListTagBase<vtkm::Float32>());
VTKM_RUN_BENCHMARK(RayTracing, vtkm::ListTagBase<vtkm::Float32>(), config.Device);
return 0;
}

@ -135,7 +135,6 @@ struct ValueTypes
/// This class runs a series of micro-benchmarks to measure
/// performance of different field operations
template <class DeviceAdapterTag>
class BenchmarkTopologyAlgorithms
{
using StorageTag = vtkm::cont::StorageTagBasic;
@ -177,7 +176,7 @@ private:
T next() { return distribution(rng); }
};
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchCellToPointAvg
{
std::vector<Value> input;
@ -205,11 +204,10 @@ private:
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
vtkm::worklet::DispatcherMapTopology<AverageCellToPoint> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->InputHandle, cellSet, result);
return timer.GetElapsedTime();
@ -229,8 +227,8 @@ private:
}
};
template <typename Value>
struct BenchCellToPointAvgDynamic : public BenchCellToPointAvg<Value>
template <typename Value, typename DeviceAdapter>
struct BenchCellToPointAvgDynamic : public BenchCellToPointAvg<Value, DeviceAdapter>
{
VTKM_CONT
@ -242,11 +240,10 @@ private:
ValueVariantHandle dinput(this->InputHandle);
vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
vtkm::worklet::DispatcherMapTopology<AverageCellToPoint> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(dinput, cellSet, result);
return timer.GetElapsedTime();
@ -258,7 +255,7 @@ private:
VTKM_MAKE_BENCHMARK(CellToPointAvg, BenchCellToPointAvg);
VTKM_MAKE_BENCHMARK(CellToPointAvgDynamic, BenchCellToPointAvgDynamic);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchPointToCellAvg
{
std::vector<Value> input;
@ -286,11 +283,10 @@ private:
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
vtkm::worklet::DispatcherMapTopology<AveragePointToCell> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->InputHandle, cellSet, result);
return timer.GetElapsedTime();
@ -310,8 +306,8 @@ private:
}
};
template <typename Value>
struct BenchPointToCellAvgDynamic : public BenchPointToCellAvg<Value>
template <typename Value, typename DeviceAdapter>
struct BenchPointToCellAvgDynamic : public BenchPointToCellAvg<Value, DeviceAdapter>
{
VTKM_CONT
@ -323,11 +319,10 @@ private:
ValueVariantHandle dinput(this->InputHandle);
vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
vtkm::worklet::DispatcherMapTopology<AveragePointToCell> dispatcher;
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(dinput, cellSet, result);
return timer.GetElapsedTime();
@ -339,7 +334,7 @@ private:
VTKM_MAKE_BENCHMARK(PointToCellAvg, BenchPointToCellAvg);
VTKM_MAKE_BENCHMARK(PointToCellAvgDynamic, BenchPointToCellAvgDynamic);
template <typename Value>
template <typename Value, typename DeviceAdapter>
struct BenchClassification
{
std::vector<Value> input;
@ -371,12 +366,11 @@ private:
ValueVariantHandle dinput(this->InputHandle);
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Classification<Value> worklet(this->IsoValue);
vtkm::worklet::DispatcherMapTopology<Classification<Value>> dispatcher(worklet);
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(dinput, cellSet, result);
return timer.GetElapsedTime();
@ -396,8 +390,8 @@ private:
}
};
template <typename Value>
struct BenchClassificationDynamic : public BenchClassification<Value>
template <typename Value, typename DeviceAdapter>
struct BenchClassificationDynamic : public BenchClassification<Value, DeviceAdapter>
{
VTKM_CONT
vtkm::Float64 operator()()
@ -406,12 +400,11 @@ private:
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
vtkm::cont::ArrayHandle<vtkm::IdComponent, StorageTag> result;
Timer timer{ DeviceAdapterTag() };
Timer timer{ DeviceAdapter() };
timer.Start();
Classification<Value> worklet(this->IsoValue);
vtkm::worklet::DispatcherMapTopology<Classification<Value>> dispatcher(worklet);
dispatcher.SetDevice(DeviceAdapterTag());
dispatcher.Invoke(this->InputHandle, cellSet, result);
timer.Stop();
@ -425,29 +418,29 @@ private:
VTKM_MAKE_BENCHMARK(ClassificationDynamic, BenchClassificationDynamic);
public:
static VTKM_CONT int Run(int benchmarks)
static VTKM_CONT int Run(int benchmarks, vtkm::cont::DeviceAdapterId id)
{
std::cout << DIVIDER << "\nRunning Topology Algorithm benchmarks\n";
if (benchmarks & CELL_TO_POINT)
{
std::cout << DIVIDER << "\nBenchmarking Cell To Point Average\n";
VTKM_RUN_BENCHMARK(CellToPointAvg, ValueTypes());
VTKM_RUN_BENCHMARK(CellToPointAvgDynamic, ValueTypes());
VTKM_RUN_BENCHMARK(CellToPointAvg, ValueTypes(), id);
VTKM_RUN_BENCHMARK(CellToPointAvgDynamic, ValueTypes(), id);
}
if (benchmarks & POINT_TO_CELL)
{
std::cout << DIVIDER << "\nBenchmarking Point to Cell Average\n";
VTKM_RUN_BENCHMARK(PointToCellAvg, ValueTypes());
VTKM_RUN_BENCHMARK(PointToCellAvgDynamic, ValueTypes());
VTKM_RUN_BENCHMARK(PointToCellAvg, ValueTypes(), id);
VTKM_RUN_BENCHMARK(PointToCellAvgDynamic, ValueTypes(), id);
}
if (benchmarks & MC_CLASSIFY)
{
std::cout << DIVIDER << "\nBenchmarking Hex/Voxel MC Classification\n";
VTKM_RUN_BENCHMARK(Classification, ValueTypes());
VTKM_RUN_BENCHMARK(ClassificationDynamic, ValueTypes());
VTKM_RUN_BENCHMARK(Classification, ValueTypes(), id);
VTKM_RUN_BENCHMARK(ClassificationDynamic, ValueTypes(), id);
}
return 0;
@ -460,18 +453,19 @@ public:
int main(int argc, char* argv[])
{
vtkm::cont::InitLogging(argc, argv);
auto opts = vtkm::cont::InitializeOptions::RequireDevice;
auto config = vtkm::cont::Initialize(argc, argv, opts);
int benchmarks = 0;
if (argc < 2)
if (!config.Arguments.size())
{
benchmarks = vtkm::benchmarking::ALL;
}
else
{
for (int i = 1; i < argc; ++i)
for (size_t i = 0; i < config.Arguments.size(); ++i)
{
std::string arg = argv[i];
std::string arg = config.Arguments[i];
std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
@ -489,16 +483,13 @@ int main(int argc, char* argv[])
}
else
{
std::cout << "Unrecognized benchmark: " << argv[i] << std::endl;
std::cout << "Unrecognized benchmark: " << config.Arguments[i] << std::endl;
return 1;
}
}
}
//now actually execute the benchmarks
using Device = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
tracker.ForceDevice(Device{});
return vtkm::benchmarking::BenchmarkTopologyAlgorithms<Device>::Run(benchmarks);
return vtkm::benchmarking::BenchmarkTopologyAlgorithms::Run(benchmarks, config.Device);
}

@ -23,6 +23,8 @@
#include <vtkm/ListTag.h>
#include <vtkm/Math.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/cont/testing/Testing.h>
#include <algorithm>
@ -83,17 +85,18 @@
/*
* Use the VTKM_MAKE_BENCHMARK macro to define a maker functor for your benchmark.
* This is used to allow you to template the benchmark functor on the type being benchmarked
* so you can write init code in the constructor. Then the maker will return a constructed
* instance of your benchmark for the type being benchmarked. The VA_ARGS are used to
* pass any extra arguments needed by your benchmark
* and the device adapter so you can write init code in the constructor. Then the maker will
* return a constructed instance of your benchmark for the type being benchmarked.
* The VA_ARGS are used to pass any extra arguments needed by your benchmark
*/
#define VTKM_MAKE_BENCHMARK(Name, Bench, ...) \
struct MakeBench##Name \
{ \
template <typename Value> \
VTKM_CONT Bench<Value> operator()(const Value vtkmNotUsed(v)) const \
template <typename Value, typename DeviceAdapter> \
VTKM_CONT Bench<Value, DeviceAdapter> operator()(const Value vtkmNotUsed(v), \
DeviceAdapter vtkmNotUsed(id)) const \
{ \
return Bench<Value>(__VA_ARGS__); \
return Bench<Value, DeviceAdapter>(__VA_ARGS__); \
} \
}
@ -102,8 +105,8 @@
* You must have previously defined a maker functor with VTKM_MAKE_BENCHMARK that this
* macro will look for and use
*/
#define VTKM_RUN_BENCHMARK(Name, Types) \
vtkm::benchmarking::BenchmarkTypes(MakeBench##Name(), (Types))
#define VTKM_RUN_BENCHMARK(Name, Types, Id) \
vtkm::benchmarking::BenchmarkTypes(MakeBench##Name(), (Types), (Id))
namespace vtkm
{
@ -223,7 +226,7 @@ vtkm::Float64 MedianAbsDeviation(const std::vector<vtkm::Float64>& samples)
* in seconds, this lets us avoid including any per-run setup time in the benchmark.
* However any one-time setup should be done in the functor's constructor
*/
class Benchmarker
struct Benchmarker
{
std::vector<vtkm::Float64> Samples;
std::string BenchmarkName;
@ -286,11 +289,13 @@ public:
<< "\tmax = " << this->Samples.back() << "s\n";
}
template <typename Functor>
VTKM_CONT void operator()(Functor func)
template <typename DeviceAdapter, typename MakerFunctor, typename T>
VTKM_CONT bool operator()(DeviceAdapter id, MakerFunctor&& makerFunctor, T t)
{
auto func = makerFunctor(t, id);
this->GatherSamples(func);
this->PrintSummary();
return true;
}
VTKM_CONT const std::vector<vtkm::Float64>& GetSamples() const { return this->Samples; }
@ -315,13 +320,14 @@ public:
}
template <typename T>
VTKM_CONT void operator()(T t) const
VTKM_CONT void operator()(T t, vtkm::cont::DeviceAdapterId id) const
{
std::cout << "*** " << vtkm::testing::TypeName<T>::Name() << " ***************" << std::endl;
std::cout << "*** " << vtkm::testing::TypeName<T>::Name() << " on device " << id.GetName()
<< " ***************" << std::endl;
Benchmarker bench;
try
{
bench(Maker(t));
vtkm::cont::TryExecuteOnDevice(id, bench, Maker, t);
}
catch (std::exception& e)
{
@ -333,9 +339,10 @@ public:
};
template <class MakerFunctor, class TypeList>
VTKM_CONT void BenchmarkTypes(const MakerFunctor& maker, TypeList)
VTKM_CONT void BenchmarkTypes(MakerFunctor&& maker, TypeList, vtkm::cont::DeviceAdapterId id)
{
vtkm::ListForEach(InternalPrintTypeAndBench<MakerFunctor>(maker), TypeList());
vtkm::ListForEach(
InternalPrintTypeAndBench<MakerFunctor>(std::forward<MakerFunctor>(maker)), TypeList(), id);
}
}
}

@ -17,43 +17,32 @@
## Laboratory (LANL), the U.S. Government retains certain rights in
## this software.
##============================================================================
function(add_benchmark name files lib)
set(benchmarks )
add_executable(${name}_SERIAL ${files})
list(APPEND benchmarks ${name}_SERIAL)
target_compile_definitions(${name}_SERIAL PRIVATE "VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_SERIAL")
if (TARGET vtkm::tbb)
add_executable(${name}_TBB ${files})
list(APPEND benchmarks ${name}_TBB)
target_compile_definitions(${name}_TBB PRIVATE "VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_TBB")
endif()
if (TARGET vtkm::openmp)
add_executable(${name}_OPENMP ${files})
list(APPEND benchmarks ${name}_OPENMP)
target_compile_definitions(${name}_OPENMP PRIVATE "VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_OPENMP")
endif()
function(add_benchmark)
set(options)
set(oneValueArgs NAME FILE)
set(multiValueArgs LIBS)
cmake_parse_arguments(VTKm_AB
"${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)
set(exe_name ${VTKm_AB_NAME})
if (TARGET vtkm::cuda)
get_filename_component(fname "${name}" NAME_WE)
get_filename_component(fullpath "${name}.cxx" ABSOLUTE)
get_filename_component(fname ${VTKm_AB_FILE} NAME_WE)
get_filename_component(fullpath ${VTKm_AB_FILE} ABSOLUTE)
file(GENERATE
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${fname}.cu
CONTENT "#include \"${fullpath}\"")
add_executable(${name}_CUDA ${CMAKE_CURRENT_BINARY_DIR}/${fname}.cu)
list(APPEND benchmarks ${name}_CUDA)
target_compile_definitions(${name}_CUDA PRIVATE "VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_CUDA")
add_executable(${exe_name} ${CMAKE_CURRENT_BINARY_DIR}/${fname}.cu)
set_property(TARGET ${exe_name} PROPERTY CUDA_SEPARABLE_COMPILATION ON)
else()
add_executable(${exe_name} ${VTKm_AB_FILE})
endif()
foreach(benchmark ${benchmarks})
target_link_libraries(${benchmark} PRIVATE ${lib})
set_target_properties(${benchmark} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${VTKm_EXECUTABLE_OUTPUT_PATH}
)
endforeach()
target_link_libraries(${exe_name} PRIVATE ${VTKm_AB_LIBS})
set_target_properties(${exe_name} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${VTKm_EXECUTABLE_OUTPUT_PATH}
)
endfunction()
@ -69,9 +58,9 @@ set(benchmarks
)
foreach (benchmark ${benchmarks})
add_benchmark(${benchmark} ${benchmark}.cxx vtkm_filter)
add_benchmark(NAME ${benchmark} FILE ${benchmark}.cxx LIBS vtkm_filter vtkm_cont)
endforeach ()
if(TARGET vtkm_rendering)
add_benchmark(BenchmarkRayTracing BenchmarkRayTracing.cxx vtkm_rendering)
add_benchmark(NAME BenchmarkRayTracing FILE BenchmarkRayTracing.cxx LIBS vtkm_rendering)
endif()

@ -0,0 +1,11 @@
# Make ArrayHandleVirtual conform with other ArrayHandle structure
Previously, ArrayHandleVirtual was defined as a specialization of
ArrayHandle with the virtual storage tag. This was because the storage
object was polymorphic and needed to be handled special. These changes
moved the existing storage definition to an internal class, and then
managed the pointer to that implementation class in a Storage object that
can be managed like any other storage object.
Also moved the implementation of StorageAny into the implementation of the
internal storage object.

@ -0,0 +1,104 @@
# Allow masking of worklet invocations
There have recently been use cases where it would be helpful to mask out
some of the invocations of a worklet. The idea is that when invoking a
worklet with a mask array on the input domain, you might implement your
worklet more-or-less like the following.
```cpp
VTKM_EXEC void operator()(bool mask, /* other parameters */)
{
if (mask)
{
// Do interesting stuff
}
}
```
This works, but what if your mask has mostly false values? In that case,
you are spending tons of time loading data to and from memory where fields
are stored for no reason.
You could potentially get around this problem by adding a scatter to the
worklet. However, that will compress the output arrays to only values that
are active in the mask. That is problematic if you want the masked output
in the appropriate place in the original arrays. You will have to do some
complex (and annoying and possibly expensive) permutations of the output
arrays.
Thus, we would like a new feature similar to scatter that instead masks out
invocations so that the worklet is simply not run on those outputs.
## New Interface
The new "Mask" feature that is similar (and orthogonal) to the existing
"Scatter" feature. Worklet objects now define a `MaskType` that provides on
object that manages the selections of which invocations are skipped. The
following Mask objects are defined.
* `MaskNone` - This removes any mask of the output. All outputs are
generated. This is the default if no `MaskType` is explicitly defined.
* `MaskSelect` - The user to provides an array that specifies whether
each output is created with a 1 to mean that the output should be
created an 0 the mean that it should not.
* `MaskIndices` - The user provides an array with a list of indices for
all outputs that should be created.
It will be straightforward to implement other versions of masks. (For
example, you could make a mask class that selectes every Nth entry.) Those
could be made on an as-needed basis.
## Implementation
The implementation follows the same basic idea of how scatters are
implemented.
### Mask Classes
The mask class is required to implement the following items.
* `ThreadToOutputType` - A type for an array that maps a thread index (an
index in the array) to an output index. A reasonable type for this
could be `vtkm::cont::ArrayHandle<vtkm::Id>`.
* `GetThreadToOutputMap` - Given the range for the output (e.g. the
number of items in the output domain), returns an array of type
`ThreadToOutputType` that is the actual map.
* `GetThreadRange` - Given a range for the output (e.g. the number of
items in the output domain), returns the range for the threads (e.g.
the number of times the worklet will be invoked).
### Dispatching
The `vtkm::worklet::internal::DispatcherBase` manages a mask class in
the same way it manages the scatter class. It gets the `MaskType` from
the worklet it is templated on. It requires a `MaskType` object during
its construction.
Previously the dispatcher (and downstream) had to manage the range and
indices of inputs and threads. They now have to also manage a separate
output range/index as now all three may be different.
The `vtkm::Invocation` is changed to hold the ThreadToOutputMap array from
the mask. It likewises has a templated `ChangeThreadToOutputMap` method
added (similar to those already existing for the arrays from a scatter).
This method is used in `DispatcherBase::InvokeTransportParameters` to add
the mask's array to the invocation before calling `InvokeSchedule`.
### Thread Indices
With the addition of masks, the `ThreadIndices` classes are changed to
manage the actual output index. Previously, the output index was always the
same as the thread index. However, now these two can be different. The
`GetThreadIndices` methods of the worklet base classes have an argument
added that is the portal to the ThreadToOutputMap.
The worklet `GetThreadIndices` is called from the `Task` classes. These
classes are changed to pass in this additional argument. Since the `Task`
classes get an `Invocation` object from the dispatcher, which contains the
`ThreadToOutputMap`, this change is trivial.
## Interaction Between Mask and Scatter
Although it seems weird, it should work fine to mix scatters and masks. The
scatter will first be applied to the input to generate a (potential) list
of output elements. The mask will then be applied to these output elements.

@ -0,0 +1,6 @@
# Merge benchmark executables into a device dependent shared library
VTK-m has been updated to replace old per device benchmark executables with a device
dependent shared library so that it's able to accept a device adapter at runtime through
the "--device=" argument.

@ -0,0 +1,12 @@
# Added specialized operators for ArrayPortalValueReference
The ArrayPortalValueReference is supposed to behave just like the value it
encapsulates and does so by automatically converting to the base type when
necessary. However, when it is possible to convert that to something else,
it is possible to get errors about ambiguous overloads. To avoid these, add
specialized versions of the operators to specify which ones should be used.
Also consolidated the CUDA version of an ArrayPortalValueReference to the
standard one. The two implementations were equivalent and we would like
changes to apply to both.

@ -211,7 +211,8 @@ struct VTKM_ALWAYS_EXPORT TypeListTagAll
/// integers, floating points, and 3 dimensional vectors of floating points.
///
struct VTKM_ALWAYS_EXPORT TypeListTagCommon
: vtkm::ListTagBase<vtkm::Int32,
: vtkm::ListTagBase<vtkm::UInt8,
vtkm::Int32,
vtkm::Int64,
vtkm::Float32,
vtkm::Float64,

@ -122,7 +122,7 @@ struct ReduceFunctor
U result;
ReduceFunctor()
: result(U(0))
: result(vtkm::TypeTraits<U>::ZeroInitialization())
{
}
@ -148,12 +148,13 @@ struct ReduceByKeyFunctor
}
};
template <typename T>
template <typename U>
struct ScanInclusiveResultFunctor
{
T result;
U result;
ScanInclusiveResultFunctor()
: result(T(0))
: result(vtkm::TypeTraits<U>::ZeroInitialization())
{
}

@ -29,6 +29,7 @@
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/ErrorInternal.h>
#include <vtkm/cont/SerializableTypeString.h>
#include <vtkm/cont/Serialization.h>
#include <vtkm/cont/Storage.h>
#include <vtkm/cont/StorageBasic.h>
@ -163,6 +164,9 @@ struct GetTypeInParentheses<void(T)>
} \
\
VTKM_CONT \
classname(Thisclass&& src) noexcept : Superclass(std::move(src)) {} \
\
VTKM_CONT \
classname(const vtkm::cont::ArrayHandle<typename__ Superclass::ValueType, \
typename__ Superclass::StorageTag>& src) \
: Superclass(src) \
@ -170,12 +174,26 @@ struct GetTypeInParentheses<void(T)>
} \
\
VTKM_CONT \
classname(vtkm::cont::ArrayHandle<typename__ Superclass::ValueType, \
typename__ Superclass::StorageTag>&& src) noexcept \
: Superclass(std::move(src)) \
{ \
} \
\
VTKM_CONT \
Thisclass& operator=(const Thisclass& src) \
{ \
this->Superclass::operator=(src); \
return *this; \
} \
\
VTKM_CONT \
Thisclass& operator=(Thisclass&& src) noexcept \
{ \
this->Superclass::operator=(std::move(src)); \
return *this; \
} \
\
using ValueType = typename__ Superclass::ValueType; \
using StorageTag = typename__ Superclass::StorageTag
@ -683,11 +701,11 @@ namespace cont
{
template <typename T>
struct TypeString<ArrayHandle<T>>
struct SerializableTypeString<ArrayHandle<T>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "AH<" + TypeString<T>::Get() + ">";
static std::string name = "AH<" + SerializableTypeString<T>::Get() + ">";
return name;
}
};

@ -438,21 +438,21 @@ namespace cont
{
template <typename AH1, typename AH2, typename AH3>
struct TypeString<vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
struct SerializableTypeString<vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "AH_CartesianProduct<" + TypeString<AH1>::Get() + "," +
TypeString<AH2>::Get() + "," + TypeString<AH3>::Get() + ">";
static std::string name = "AH_CartesianProduct<" + SerializableTypeString<AH1>::Get() + "," +
SerializableTypeString<AH2>::Get() + "," + SerializableTypeString<AH3>::Get() + ">";
return name;
}
};
template <typename AH1, typename AH2, typename AH3>
struct TypeString<
struct SerializableTypeString<
vtkm::cont::ArrayHandle<vtkm::Vec<typename AH1::ValueType, 3>,
vtkm::cont::internal::StorageTagCartesianProduct<AH1, AH2, AH3>>>
: TypeString<vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
: SerializableTypeString<vtkm::cont::ArrayHandleCartesianProduct<AH1, AH2, AH3>>
{
};
}

@ -110,19 +110,19 @@ namespace cont
{
template <typename T1, typename T2>
struct TypeString<vtkm::cont::internal::Cast<T1, T2>>
struct SerializableTypeString<vtkm::cont::internal::Cast<T1, T2>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"AH_Cast_Functor<" + TypeString<T1>::Get() + "," + TypeString<T2>::Get() + ">";
static std::string name = "AH_Cast_Functor<" + SerializableTypeString<T1>::Get() + "," +
SerializableTypeString<T2>::Get() + ">";
return name;
}
};
template <typename T, typename AH>
struct TypeString<vtkm::cont::ArrayHandleCast<T, AH>>
: TypeString<
struct SerializableTypeString<vtkm::cont::ArrayHandleCast<T, AH>>
: SerializableTypeString<
vtkm::cont::ArrayHandleTransform<AH, vtkm::cont::internal::Cast<typename AH::ValueType, T>>>
{
};

@ -732,21 +732,21 @@ namespace cont
{
template <typename... AHs>
struct TypeString<vtkm::cont::ArrayHandleCompositeVector<AHs...>>
struct SerializableTypeString<vtkm::cont::ArrayHandleCompositeVector<AHs...>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"AH_CompositeVector<" + internal::GetVariadicTypeString(AHs{}...) + ">";
"AH_CompositeVector<" + internal::GetVariadicSerializableTypeString(AHs{}...) + ">";
return name;
}
};
template <typename... AHs>
struct TypeString<vtkm::cont::ArrayHandle<
struct SerializableTypeString<vtkm::cont::ArrayHandle<
typename vtkm::cont::internal::compvec::GetValueType<vtkmstd::tuple<AHs...>>::ValueType,
vtkm::cont::internal::StorageTagCompositeVector<vtkmstd::tuple<AHs...>>>>
: TypeString<vtkm::cont::ArrayHandleCompositeVector<AHs...>>
: SerializableTypeString<vtkm::cont::ArrayHandleCompositeVector<AHs...>>
{
};
}

@ -332,20 +332,20 @@ namespace cont
{
template <typename AH1, typename AH2>
struct TypeString<vtkm::cont::ArrayHandleConcatenate<AH1, AH2>>
struct SerializableTypeString<vtkm::cont::ArrayHandleConcatenate<AH1, AH2>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"AH_Concatenate<" + TypeString<AH1>::Get() + "," + TypeString<AH2>::Get() + ">";
static std::string name = "AH_Concatenate<" + SerializableTypeString<AH1>::Get() + "," +
SerializableTypeString<AH2>::Get() + ">";
return name;
}
};
template <typename AH1, typename AH2>
struct TypeString<
struct SerializableTypeString<
vtkm::cont::ArrayHandle<typename AH1::ValueType, vtkm::cont::StorageTagConcatenate<AH1, AH2>>>
: TypeString<vtkm::cont::ArrayHandleConcatenate<AH1, AH2>>
: SerializableTypeString<vtkm::cont::ArrayHandleConcatenate<AH1, AH2>>
{
};
}

@ -93,18 +93,18 @@ namespace cont
{
template <typename T>
struct TypeString<vtkm::cont::detail::ConstantFunctor<T>>
struct SerializableTypeString<vtkm::cont::detail::ConstantFunctor<T>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "AH_ConstantFunctor<" + TypeString<T>::Get() + ">";
static std::string name = "AH_ConstantFunctor<" + SerializableTypeString<T>::Get() + ">";
return name;
}
};
template <typename T>
struct TypeString<vtkm::cont::ArrayHandleConstant<T>>
: TypeString<vtkm::cont::ArrayHandleImplicit<vtkm::cont::detail::ConstantFunctor<T>>>
struct SerializableTypeString<vtkm::cont::ArrayHandleConstant<T>>
: SerializableTypeString<vtkm::cont::ArrayHandleImplicit<vtkm::cont::detail::ConstantFunctor<T>>>
{
};
}

@ -156,19 +156,19 @@ namespace cont
{
template <typename T>
struct TypeString<vtkm::cont::ArrayHandleCounting<T>>
struct SerializableTypeString<vtkm::cont::ArrayHandleCounting<T>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "AH_Counting<" + TypeString<T>::Get() + ">";
static std::string name = "AH_Counting<" + SerializableTypeString<T>::Get() + ">";
return name;
}
};
template <typename T>
struct TypeString<
struct SerializableTypeString<
vtkm::cont::ArrayHandle<T, typename vtkm::cont::ArrayHandleCounting<T>::StorageTag>>
: TypeString<vtkm::cont::ArrayHandleCounting<T>>
: SerializableTypeString<vtkm::cont::ArrayHandleCounting<T>>
{
};
}

@ -318,20 +318,20 @@ namespace cont
{
template <typename AH>
struct TypeString<vtkm::cont::ArrayHandleExtractComponent<AH>>
struct SerializableTypeString<vtkm::cont::ArrayHandleExtractComponent<AH>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "AH_ExtractComponent<" + TypeString<AH>::Get() + ">";
static std::string name = "AH_ExtractComponent<" + SerializableTypeString<AH>::Get() + ">";
return name;
}
};
template <typename AH>
struct TypeString<
struct SerializableTypeString<
vtkm::cont::ArrayHandle<typename vtkm::VecTraits<typename AH::ValueType>::ComponentType,
vtkm::cont::StorageTagExtractComponent<AH>>>
: TypeString<vtkm::cont::ArrayHandleExtractComponent<AH>>
: SerializableTypeString<vtkm::cont::ArrayHandleExtractComponent<AH>>
{
};
}

@ -374,20 +374,21 @@ namespace cont
{
template <typename AH, vtkm::IdComponent NUM_COMPS>
struct TypeString<vtkm::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
struct SerializableTypeString<vtkm::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"AH_GroupVec<" + TypeString<AH>::Get() + "," + std::to_string(NUM_COMPS) + ">";
"AH_GroupVec<" + SerializableTypeString<AH>::Get() + "," + std::to_string(NUM_COMPS) + ">";
return name;
}
};
template <typename AH, vtkm::IdComponent NUM_COMPS>
struct TypeString<vtkm::cont::ArrayHandle<vtkm::Vec<typename AH::ValueType, NUM_COMPS>,
vtkm::cont::internal::StorageTagGroupVec<AH, NUM_COMPS>>>
: TypeString<vtkm::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
struct SerializableTypeString<
vtkm::cont::ArrayHandle<vtkm::Vec<typename AH::ValueType, NUM_COMPS>,
vtkm::cont::internal::StorageTagGroupVec<AH, NUM_COMPS>>>
: SerializableTypeString<vtkm::cont::ArrayHandleGroupVec<AH, NUM_COMPS>>
{
};
}

@ -514,21 +514,21 @@ namespace cont
{
template <typename SAH, typename OAH>
struct TypeString<vtkm::cont::ArrayHandleGroupVecVariable<SAH, OAH>>
struct SerializableTypeString<vtkm::cont::ArrayHandleGroupVecVariable<SAH, OAH>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"AH_GroupVecVariable<" + TypeString<SAH>::Get() + "," + TypeString<OAH>::Get() + ">";
static std::string name = "AH_GroupVecVariable<" + SerializableTypeString<SAH>::Get() + "," +
SerializableTypeString<OAH>::Get() + ">";
return name;
}
};
template <typename SAH, typename OAH>
struct TypeString<
struct SerializableTypeString<
vtkm::cont::ArrayHandle<vtkm::VecFromPortal<typename SAH::PortalControl>,
vtkm::cont::internal::StorageTagGroupVecVariable<SAH, OAH>>>
: TypeString<vtkm::cont::ArrayHandleGroupVecVariable<SAH, OAH>>
: SerializableTypeString<vtkm::cont::ArrayHandleGroupVecVariable<SAH, OAH>>
{
};
}

@ -154,20 +154,20 @@ namespace cont
{
template <typename Functor>
struct TypeString<vtkm::cont::ArrayHandleImplicit<Functor>>
struct SerializableTypeString<vtkm::cont::ArrayHandleImplicit<Functor>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "AH_Implicit<" + TypeString<Functor>::Get() + ">";
static std::string name = "AH_Implicit<" + SerializableTypeString<Functor>::Get() + ">";
return name;
}
};
template <typename Functor>
struct TypeString<vtkm::cont::ArrayHandle<
struct SerializableTypeString<vtkm::cont::ArrayHandle<
typename vtkm::cont::detail::ArrayHandleImplicitTraits<Functor>::ValueType,
vtkm::cont::StorageTagImplicit<vtkm::cont::detail::ArrayPortalImplicit<Functor>>>>
: TypeString<vtkm::cont::ArrayHandleImplicit<Functor>>
: SerializableTypeString<vtkm::cont::ArrayHandleImplicit<Functor>>
{
};
}

@ -70,14 +70,14 @@ namespace cont
{
template <>
struct TypeString<vtkm::cont::detail::IndexFunctor>
struct SerializableTypeString<vtkm::cont::detail::IndexFunctor>
{
static VTKM_CONT const std::string Get() { return "AH_IndexFunctor"; }
};
template <>
struct TypeString<vtkm::cont::ArrayHandleIndex>
: TypeString<vtkm::cont::ArrayHandleImplicit<vtkm::cont::detail::IndexFunctor>>
struct SerializableTypeString<vtkm::cont::ArrayHandleIndex>
: SerializableTypeString<vtkm::cont::ArrayHandleImplicit<vtkm::cont::detail::IndexFunctor>>
{
};
}

@ -380,21 +380,21 @@ namespace cont
{
template <typename IdxAH, typename ValAH>
struct TypeString<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
struct SerializableTypeString<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"AH_Permutation<" + TypeString<IdxAH>::Get() + "," + TypeString<ValAH>::Get() + ">";
static std::string name = "AH_Permutation<" + SerializableTypeString<IdxAH>::Get() + "," +
SerializableTypeString<ValAH>::Get() + ">";
return name;
}
};
template <typename IdxAH, typename ValAH>
struct TypeString<
struct SerializableTypeString<
vtkm::cont::ArrayHandle<typename ValAH::ValueType,
vtkm::cont::internal::StorageTagPermutation<IdxAH, ValAH>>>
: TypeString<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
: SerializableTypeString<vtkm::cont::ArrayHandlePermutation<IdxAH, ValAH>>
{
};
}

@ -251,19 +251,19 @@ namespace cont
{
template <typename AH>
struct TypeString<vtkm::cont::ArrayHandleReverse<AH>>
struct SerializableTypeString<vtkm::cont::ArrayHandleReverse<AH>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "AH_Reverse<" + TypeString<AH>::Get() + ">";
static std::string name = "AH_Reverse<" + SerializableTypeString<AH>::Get() + ">";
return name;
}
};
template <typename AH>
struct TypeString<
struct SerializableTypeString<
vtkm::cont::ArrayHandle<typename AH::ValueType, vtkm::cont::StorageTagReverse<AH>>>
: TypeString<vtkm::cont::ArrayHandleReverse<AH>>
: SerializableTypeString<vtkm::cont::ArrayHandleReverse<AH>>
{
};
}

@ -406,21 +406,21 @@ namespace cont
{
template <typename AH, vtkm::IdComponent NComps>
struct TypeString<vtkm::cont::ArrayHandleSwizzle<AH, NComps>>
struct SerializableTypeString<vtkm::cont::ArrayHandleSwizzle<AH, NComps>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"AH_Swizzle<" + TypeString<AH>::Get() + "," + std::to_string(NComps) + ">";
"AH_Swizzle<" + SerializableTypeString<AH>::Get() + "," + std::to_string(NComps) + ">";
return name;
}
};
template <typename AH, vtkm::IdComponent NComps>
struct TypeString<vtkm::cont::ArrayHandle<
struct SerializableTypeString<vtkm::cont::ArrayHandle<
vtkm::Vec<typename vtkm::VecTraits<typename AH::ValueType>::ComponentType, NComps>,
vtkm::cont::StorageTagSwizzle<AH, NComps>>>
: TypeString<vtkm::cont::ArrayHandleSwizzle<AH, NComps>>
: SerializableTypeString<vtkm::cont::ArrayHandleSwizzle<AH, NComps>>
{
};
}

@ -747,32 +747,33 @@ namespace cont
{
template <typename AH, typename Functor, typename InvFunctor>
struct TypeString<vtkm::cont::ArrayHandleTransform<AH, Functor, InvFunctor>>
struct SerializableTypeString<vtkm::cont::ArrayHandleTransform<AH, Functor, InvFunctor>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "AH_Transform<" + TypeString<AH>::Get() + "," +
TypeString<Functor>::Get() + "," + TypeString<InvFunctor>::Get() + ">";
static std::string name = "AH_Transform<" + SerializableTypeString<AH>::Get() + "," +
SerializableTypeString<Functor>::Get() + "," + SerializableTypeString<InvFunctor>::Get() +
">";
return name;
}
};
template <typename AH, typename Functor>
struct TypeString<vtkm::cont::ArrayHandleTransform<AH, Functor>>
struct SerializableTypeString<vtkm::cont::ArrayHandleTransform<AH, Functor>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"AH_Transform<" + TypeString<AH>::Get() + "," + TypeString<Functor>::Get() + ">";
static std::string name = "AH_Transform<" + SerializableTypeString<AH>::Get() + "," +
SerializableTypeString<Functor>::Get() + ">";
return name;
}
};
template <typename AH, typename Functor, typename InvFunctor>
struct TypeString<vtkm::cont::ArrayHandle<
struct SerializableTypeString<vtkm::cont::ArrayHandle<
typename vtkm::cont::internal::StorageTagTransform<AH, Functor, InvFunctor>::ValueType,
vtkm::cont::internal::StorageTagTransform<AH, Functor, InvFunctor>>>
: TypeString<vtkm::cont::ArrayHandleTransform<AH, Functor, InvFunctor>>
: SerializableTypeString<vtkm::cont::ArrayHandleTransform<AH, Functor, InvFunctor>>
{
};
}

@ -70,16 +70,16 @@ namespace cont
{
template <>
struct TypeString<vtkm::cont::ArrayHandleUniformPointCoordinates>
struct SerializableTypeString<vtkm::cont::ArrayHandleUniformPointCoordinates>
{
static VTKM_CONT const std::string Get() { return "AH_UniformPointCoordinates"; }
};
template <>
struct TypeString<vtkm::cont::ArrayHandle<
struct SerializableTypeString<vtkm::cont::ArrayHandle<
vtkm::Vec<vtkm::FloatDefault, 3>,
vtkm::cont::StorageTagImplicit<vtkm::internal::ArrayPortalUniformPointCoordinates>>>
: TypeString<vtkm::cont::ArrayHandleUniformPointCoordinates>
: SerializableTypeString<vtkm::cont::ArrayHandleUniformPointCoordinates>
{
};
}

@ -0,0 +1,52 @@
//============================================================================
// 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 2019 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2019 UT-Battelle, LLC.
// Copyright 2019 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.
//============================================================================
#define vtk_m_cont_ArrayHandleVirtual_cxx
#include <vtkm/cont/ArrayHandleVirtual.h>
namespace vtkm
{
namespace cont
{
#define VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(T) \
template class VTKM_CONT_EXPORT ArrayHandle<T, StorageTagVirtual>; \
template class VTKM_CONT_EXPORT ArrayHandleVirtual<T>; \
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<T, 2>, StorageTagVirtual>; \
template class VTKM_CONT_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 2>>; \
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<T, 3>, StorageTagVirtual>; \
template class VTKM_CONT_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 3>>; \
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<T, 4>, StorageTagVirtual>; \
template class VTKM_CONT_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 4>>
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(char);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Int8);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::UInt8);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Int16);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::UInt16);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Int32);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::UInt32);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Int64);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::UInt64);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Float32);
VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE(vtkm::Float64);
#undef VTK_M_ARRAY_HANDLE_VIRTUAL_INSTANTIATE
}
} //namespace vtkm::cont

@ -6,9 +6,9 @@
// 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.
// Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2018 UT-Battelle, LLC.
// Copyright 2018 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
@ -26,7 +26,6 @@
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/cont/StorageAny.h>
#include <vtkm/cont/StorageVirtual.h>
#include <memory>
@ -36,33 +35,17 @@ 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
class VTKM_ALWAYS_EXPORT ArrayHandleVirtual
: public vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>
{
using StorageType = vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagVirtual>;
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)
{
}
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleVirtual,
(ArrayHandleVirtual<T>),
(vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagVirtual>));
///Construct a valid ArrayHandleVirtual from an existing ArrayHandle
///that doesn't derive from ArrayHandleVirtual.
@ -78,110 +61,13 @@ public:
/// 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))
ArrayHandleVirtual(const vtkm::cont::ArrayHandle<T, S>& ah)
: Superclass(StorageType(ah))
{
using is_base = std::is_base_of<vtkm::cont::StorageVirtual, S>;
using is_base = std::is_base_of<StorageType, 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 matches the type passed in.
///
template <typename ArrayHandleType>
@ -231,129 +117,11 @@ public:
/// Returns a new instance of an ArrayHandleVirtual with the same storage
///
VTKM_CONT ArrayHandle<T, ::vtkm::cont::StorageTagVirtual> NewInstance() const
VTKM_CONT ArrayHandleVirtual<T> NewInstance() const
{
return (this->Storage)
? ArrayHandle<T, ::vtkm::cont::StorageTagVirtual>(this->Storage->NewInstance())
: ArrayHandle<T, ::vtkm::cont::StorageTagVirtual>();
return ArrayHandleVirtual<T>(this->GetStorage().NewInstance());
}
/// 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>
inline bool IsSameType(std::false_type, std::true_type) const
@ -380,12 +148,13 @@ private:
inline bool IsSameType(std::true_type vtkmNotUsed(valueTypesMatch),
std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const
{
if (!this->Storage)
auto* storage = this->GetStorage().GetStorageVirtual();
if (!storage)
{
return false;
}
using S = typename ArrayHandleType::StorageTag;
return this->Storage->template IsType<vtkm::cont::StorageAny<T, S>>();
return storage->template IsType<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
}
template <typename ArrayHandleType>
@ -393,7 +162,7 @@ private:
std::true_type vtkmNotUsed(notFromArrayHandleVirtual)) const
{
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeName<ArrayHandleType>());
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeToString<ArrayHandleType>());
return ArrayHandleType{};
}
@ -402,7 +171,7 @@ private:
std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const
{
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeName<ArrayHandleType>());
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeToString<ArrayHandleType>());
return ArrayHandleType{};
}
@ -417,7 +186,7 @@ private:
if (!derived)
{
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeName<ArrayHandleType>());
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeToString<ArrayHandleType>());
}
VTKM_LOG_CAST_SUCC(*this, derived);
return *derived;
@ -428,11 +197,6 @@ private:
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.
@ -464,6 +228,17 @@ VTKM_CONT inline ArrayHandleType Cast(const vtkm::cont::ArrayHandleVirtual<T>& v
return virtHandle.template Cast<ArrayHandleType>();
}
#if 0
// The following specialization of CastAndCall has been disabled. The problem with it is that it
// causes some common versions of GCC to give the warning "type attributes ignored after type is
// already defined." GCC seems to have a problem with declaring an instance of a template twice
// even when the type attributes match. (In some cases it is OK, in others it is not.) The easiest
// solution is to just disable this CastAndCall that instantiates a specific version of
// ArrayHandleVirtual. This specialization might be better handled elsewhere where the uniform
// point coordinates are coupled with a structured cell set (and thus can derive several fast
// paths) rather than generally for any field or array containing vec3s.
//=============================================================================
// Specializations of CastAndCall to help make sure ArrayHandleVirtual
// holding a ArrayHandleUniformPointCoordinates works properly
@ -477,29 +252,59 @@ void CastAndCall(vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>
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)...);
const vtkm::cont::internal::detail::StorageVirtual* storage =
coords.GetStorage().GetStorageVirtual();
auto* virtualImpl = storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
f(virtualImpl->GetHandle(), std::forward<Args>(args)...);
}
else
{
f(coords, std::forward<Args>(args)...);
}
}
#endif
//=============================================================================
// Specializations of serialization related classes
template <typename T>
struct TypeString<vtkm::cont::ArrayHandleVirtual<T>>
struct SerializableTypeString<vtkm::cont::ArrayHandleVirtual<T>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "AH_Virtual<" + TypeString<T>::Get() + ">";
static std::string name = "AH_Virtual<" + SerializableTypeString<T>::Get() + ">";
return name;
}
};
#ifndef vtk_m_cont_ArrayHandleVirtual_cxx
#define VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(T) \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<T, StorageTagVirtual>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleVirtual<T>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Vec<T, 2>, StorageTagVirtual>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 2>>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Vec<T, 3>, StorageTagVirtual>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 3>>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Vec<T, 4>, StorageTagVirtual>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandleVirtual<vtkm::Vec<T, 4>>
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(char);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Int8);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::UInt8);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Int16);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::UInt16);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Int32);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::UInt32);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Int64);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::UInt64);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Float32);
VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT(vtkm::Float64);
#undef VTK_M_ARRAY_HANDLE_VIRTUAL_EXPORT
#endif //vtk_m_cont_ArrayHandleVirtual_cxx
}
} //namespace vtkm::cont

@ -6,9 +6,9 @@
// 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.
// Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2018 UT-Battelle, LLC.
// Copyright 2018 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
@ -21,7 +21,6 @@
#define vtk_m_cont_ArrayHandleVirtual_hxx
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/StorageAny.hxx>
#include <vtkm/cont/TryExecute.h>
namespace vtkm
@ -31,21 +30,23 @@ namespace cont
template <typename T>
template <typename ArrayHandleType>
ArrayHandleType inline ArrayHandle<T, StorageTagVirtual>::CastToType(
ArrayHandleType inline ArrayHandleVirtual<T>::CastToType(
std::true_type vtkmNotUsed(valueTypesMatch),
std::false_type vtkmNotUsed(notFromArrayHandleVirtual)) const
{
if (!this->Storage)
auto* storage = this->GetStorage().GetStorageVirtual();
if (!storage)
{
VTKM_LOG_CAST_FAIL(*this, ArrayHandleType);
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeName<ArrayHandleType>());
throwFailedDynamicCast("ArrayHandleVirtual", vtkm::cont::TypeToString<ArrayHandleType>());
}
using S = typename ArrayHandleType::StorageTag;
const auto* any = this->Storage->template Cast<vtkm::cont::StorageAny<T, S>>();
return any->GetHandle();
const auto* castStorage =
storage->template Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
return castStorage->GetHandle();
}
}
} // namespace vtkm::const
} // namespace vtkm::cont
#include <vtkm/cont/ArrayHandleConstant.h>
@ -86,25 +87,27 @@ struct IntAnySerializer
{
if (obj.template IsType<CountingType>())
{
vtkmdiy::save(bb, vtkm::cont::TypeString<CountingType>::Get());
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<CountingType>::Get());
using S = typename CountingType::StorageTag;
const vtkm::cont::StorageVirtual* storage = obj.GetStorage();
auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
vtkmdiy::save(bb, any->GetHandle());
const vtkm::cont::internal::detail::StorageVirtual* storage =
obj.GetStorage().GetStorageVirtual();
auto* castStorage = storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
vtkmdiy::save(bb, castStorage->GetHandle());
}
else if (obj.template IsType<ConstantType>())
{
vtkmdiy::save(bb, vtkm::cont::TypeString<ConstantType>::Get());
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<ConstantType>::Get());
using S = typename ConstantType::StorageTag;
const vtkm::cont::StorageVirtual* storage = obj.GetStorage();
auto* any = storage->Cast<vtkm::cont::StorageAny<T, S>>();
vtkmdiy::save(bb, any->GetHandle());
const vtkm::cont::internal::detail::StorageVirtual* storage =
obj.GetStorage().GetStorageVirtual();
auto* castStorage = storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
vtkmdiy::save(bb, castStorage->GetHandle());
}
else
{
vtkmdiy::save(bb, vtkm::cont::TypeString<BasicType>::Get());
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<BasicType>::Get());
vtkm::cont::internal::ArrayHandleDefaultSerialization(bb, obj);
}
}
@ -114,13 +117,13 @@ struct IntAnySerializer
std::string typeString;
vtkmdiy::load(bb, typeString);
if (typeString == vtkm::cont::TypeString<CountingType>::Get())
if (typeString == vtkm::cont::SerializableTypeString<CountingType>::Get())
{
CountingType array;
vtkmdiy::load(bb, array);
obj = std::move(vtkm::cont::ArrayHandleVirtual<T>{ array });
}
else if (typeString == vtkm::cont::TypeString<ConstantType>::Get())
else if (typeString == vtkm::cont::SerializableTypeString<ConstantType>::Get())
{
ConstantType array;
vtkmdiy::load(bb, array);

@ -43,38 +43,14 @@ 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_ARRAY_HANDLE_SUBCLASS_NT(ArrayHandleVirtualCoordinates,
(vtkm::cont::ArrayHandleVirtual<vtkm::Vec<vtkm::FloatDefault, 3>>));
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>()
template <typename T, typename S>
explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle<T, S>& ah)
: Superclass(vtkm::cont::make_ArrayHandleCast<ValueType>(ah))
{
}
explicit ArrayHandleVirtualCoordinates(
const vtkm::cont::ArrayHandle<ValueType, vtkm::cont::StorageTagVirtual>& ah)
: vtkm::cont::ArrayHandleVirtual<ValueType>(ah)
{
}
template <typename S>
explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle<ValueType, S>& ah)
: vtkm::cont::ArrayHandleVirtual<ValueType>(ah)
{
}
template <typename S>
explicit ArrayHandleVirtualCoordinates(const vtkm::cont::ArrayHandle<NonDefaultCoord, S>& ah)
: vtkm::cont::ArrayHandleVirtual<ValueType>()
{
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);
}
};
template <typename Functor, typename... Args>
@ -96,7 +72,7 @@ void CastAndCall(const vtkm::cont::ArrayHandleVirtualCoordinates& coords,
template <>
struct TypeString<vtkm::cont::ArrayHandleVirtualCoordinates>
struct SerializableTypeString<vtkm::cont::ArrayHandleVirtualCoordinates>
{
static VTKM_CONT const std::string Get() { return "AH_VirtualCoordinates"; }
};
@ -123,16 +99,18 @@ private:
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>;
public:
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& obj)
static VTKM_CONT void save(BinaryBuffer& bb, const BaseType& baseObj)
{
const vtkm::cont::StorageVirtual* storage = obj.GetStorage();
Type obj(baseObj);
const vtkm::cont::internal::detail::StorageVirtual* storage =
obj.GetStorage().GetStorageVirtual();
if (obj.IsType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
{
using HandleType = vtkm::cont::ArrayHandleUniformPointCoordinates;
using T = typename HandleType::ValueType;
using S = typename HandleType::StorageTag;
auto array = storage->Cast<vtkm::cont::StorageAny<T, S>>();
vtkmdiy::save(bb, vtkm::cont::TypeString<HandleType>::Get());
auto array = storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<HandleType>::Get());
vtkmdiy::save(bb, array->GetHandle());
}
else if (obj.IsType<RectilinearCoordsArrayType>())
@ -140,13 +118,13 @@ public:
using HandleType = RectilinearCoordsArrayType;
using T = typename HandleType::ValueType;
using S = typename HandleType::StorageTag;
auto array = storage->Cast<vtkm::cont::StorageAny<T, S>>();
vtkmdiy::save(bb, vtkm::cont::TypeString<HandleType>::Get());
auto array = storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<HandleType>::Get());
vtkmdiy::save(bb, array->GetHandle());
}
else
{
vtkmdiy::save(bb, vtkm::cont::TypeString<BasicCoordsType>::Get());
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<BasicCoordsType>::Get());
vtkm::cont::internal::ArrayHandleDefaultSerialization(bb, obj);
}
}
@ -156,19 +134,20 @@ public:
std::string typeString;
vtkmdiy::load(bb, typeString);
if (typeString == vtkm::cont::TypeString<vtkm::cont::ArrayHandleUniformPointCoordinates>::Get())
if (typeString ==
vtkm::cont::SerializableTypeString<vtkm::cont::ArrayHandleUniformPointCoordinates>::Get())
{
vtkm::cont::ArrayHandleUniformPointCoordinates array;
vtkmdiy::load(bb, array);
obj = vtkm::cont::ArrayHandleVirtualCoordinates(array);
}
else if (typeString == vtkm::cont::TypeString<RectilinearCoordsArrayType>::Get())
else if (typeString == vtkm::cont::SerializableTypeString<RectilinearCoordsArrayType>::Get())
{
RectilinearCoordsArrayType array;
vtkmdiy::load(bb, array);
obj = vtkm::cont::ArrayHandleVirtualCoordinates(array);
}
else if (typeString == vtkm::cont::TypeString<BasicCoordsType>::Get())
else if (typeString == vtkm::cont::SerializableTypeString<BasicCoordsType>::Get())
{
BasicCoordsType array;
vtkmdiy::load(bb, array);

@ -392,21 +392,21 @@ namespace cont
{
template <typename AH1, typename AH2>
struct TypeString<vtkm::cont::ArrayHandleZip<AH1, AH2>>
struct SerializableTypeString<vtkm::cont::ArrayHandleZip<AH1, AH2>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"AH_Zip<" + TypeString<AH1>::Get() + "," + TypeString<AH2>::Get() + ">";
static std::string name = "AH_Zip<" + SerializableTypeString<AH1>::Get() + "," +
SerializableTypeString<AH2>::Get() + ">";
return name;
}
};
template <typename AH1, typename AH2>
struct TypeString<
struct SerializableTypeString<
vtkm::cont::ArrayHandle<vtkm::Pair<typename AH1::ValueType, typename AH2::ValueType>,
vtkm::cont::internal::StorageTagZip<AH1, AH2>>>
: TypeString<vtkm::cont::ArrayHandleZip<AH1, AH2>>
: SerializableTypeString<vtkm::cont::ArrayHandleZip<AH1, AH2>>
{
};
}

@ -129,19 +129,23 @@ inline vtkm::cont::ArrayHandle<vtkm::Range> ArrayRangeCompute(
{
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>>();
const vtkm::cont::internal::detail::StorageVirtual* storage =
input.GetStorage().GetStorageVirtual();
const auto* castStorage =
storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
return ArrayRangeCompute(any->GetHandle(), tracker);
return ArrayRangeCompute(castStorage->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>>();
const vtkm::cont::internal::detail::StorageVirtual* storage =
input.GetStorage().GetStorageVirtual();
const auto* castStorage =
storage->Cast<vtkm::cont::internal::detail::StorageVirtualImpl<T, S>>();
return ArrayRangeCompute(any->GetHandle(), tracker);
return ArrayRangeCompute(castStorage->GetHandle(), tracker);
}
else
{

@ -100,14 +100,13 @@ set(headers
RuntimeDeviceTracker.h
Serialization.h
Storage.h
StorageAny.h
StorageBasic.h
StorageImplicit.h
StorageListTag.h
StorageVirtual.h
Timer.h
TryExecute.h
TypeString.h
SerializableTypeString.h
VariantArrayHandle.h
VirtualObjectHandle.h
)
@ -122,7 +121,6 @@ set(template_sources
CoordinateSystem.hxx
FieldRangeCompute.hxx
FieldRangeGlobalCompute.hxx
StorageAny.hxx
StorageBasic.hxx
StorageVirtual.hxx
VirtualObjectHandle.hxx
@ -130,6 +128,7 @@ set(template_sources
set(sources
ArrayHandle.cxx
ArrayHandleVirtual.cxx
AssignerMultiBlock.cxx
BoundsCompute.cxx
BoundsGlobalCompute.cxx
@ -159,7 +158,6 @@ set(sources
RuntimeDeviceInformation.cxx
RuntimeDeviceTracker.cxx
StorageBasic.cxx
StorageVirtual.cxx
TryExecute.cxx
VariantArrayHandle.cxx
)
@ -171,6 +169,7 @@ set(device_sources
BoundingIntervalHierarchy.cxx
CellSetExplicit.cxx
CoordinateSystem.cxx
StorageVirtual.cxx
Timer.cxx
)
@ -201,8 +200,6 @@ if(TARGET vtkm::openmp)
list(APPEND backends vtkm::openmp)
endif()
if (VTKm_ENABLE_LOGGING)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
list(APPEND DL_LIBS ${CMAKE_DL_LIBS} Threads::Threads) # dladdr function
endif()
target_link_libraries(vtkm_cont PUBLIC vtkm_compiler_flags ${backends} ${DL_LIBS})

@ -350,15 +350,16 @@ namespace cont
{
template <typename ShapeST, typename CountST, typename ConnectivityST, typename OffsetST>
struct TypeString<vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>>
struct SerializableTypeString<
vtkm::cont::CellSetExplicit<ShapeST, CountST, ConnectivityST, OffsetST>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name = "CS_Explicit<" +
TypeString<vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeST>>::Get() + "_ST," +
TypeString<vtkm::cont::ArrayHandle<vtkm::IdComponent, CountST>>::Get() + "_ST," +
TypeString<vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST>>::Get() + "_ST," +
TypeString<vtkm::cont::ArrayHandle<vtkm::Id, OffsetST>>::Get() + "_ST>";
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::UInt8, ShapeST>>::Get() + "_ST," +
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::IdComponent, CountST>>::Get() + "_ST," +
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST>>::Get() + "_ST," +
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, OffsetST>>::Get() + "_ST>";
return name;
}

@ -402,12 +402,12 @@ namespace cont
{
template <typename CSType, typename AHValidCellIds>
struct TypeString<vtkm::cont::CellSetPermutation<CSType, AHValidCellIds>>
struct SerializableTypeString<vtkm::cont::CellSetPermutation<CSType, AHValidCellIds>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"CS_Permutation<" + TypeString<CSType>::Get() + "," + TypeString<AHValidCellIds>::Get() + ">";
static std::string name = "CS_Permutation<" + SerializableTypeString<CSType>::Get() + "," +
SerializableTypeString<AHValidCellIds>::Get() + ">";
return name;
}
};

@ -269,12 +269,12 @@ namespace cont
{
template <typename ConnectivityST>
struct TypeString<vtkm::cont::CellSetSingleType<ConnectivityST>>
struct SerializableTypeString<vtkm::cont::CellSetSingleType<ConnectivityST>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"CS_Single<" + TypeString<vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST>>::Get() + "_ST>";
static std::string name = "CS_Single<" +
SerializableTypeString<vtkm::cont::ArrayHandle<vtkm::Id, ConnectivityST>>::Get() + "_ST>";
return name;
}

@ -132,7 +132,7 @@ namespace cont
{
template <vtkm::IdComponent DIMENSION>
struct TypeString<vtkm::cont::CellSetStructured<DIMENSION>>
struct SerializableTypeString<vtkm::cont::CellSetStructured<DIMENSION>>
{
static VTKM_CONT const std::string& Get()
{

@ -573,11 +573,11 @@ public:
this->StopReady = true;
}
VTKM_CONT bool Started() { return this->StartReady; }
VTKM_CONT bool Started() const { return this->StartReady; }
VTKM_CONT bool Stopped() { return this->StopReady; }
VTKM_CONT bool Stopped() const { return this->StopReady; }
VTKM_CONT bool Ready() { return true; }
VTKM_CONT bool Ready() const { return true; }
/// Returns the elapsed time in seconds between the construction of this
/// class or the last call to Reset and the time this function is called. The
@ -585,7 +585,7 @@ public:
/// number of times to get the progressive time. This method synchronizes all
/// asynchronous operations.
///
VTKM_CONT vtkm::Float64 GetElapsedTime()
VTKM_CONT vtkm::Float64 GetElapsedTime() const
{
assert(this->StartReady);
if (!this->StartReady)
@ -595,23 +595,18 @@ public:
return 0;
}
bool manualStop = true;
if (!this->StopReady)
{
manualStop = false;
this->Stop();
}
TimeStamp startTime = this->StartTime;
TimeStamp stopTime = this->StopReady ? this->StopTime : this->GetCurrentTime();
vtkm::Float64 elapsedTime;
elapsedTime = vtkm::Float64(this->StopTime.Seconds - this->StartTime.Seconds);
elapsedTime += (vtkm::Float64(this->StopTime.Microseconds - this->StartTime.Microseconds) /
vtkm::Float64(1000000));
// Reset StopReady flag to its original state
this->StopReady = manualStop;
elapsedTime = vtkm::Float64(stopTime.Seconds - startTime.Seconds);
elapsedTime +=
(vtkm::Float64(stopTime.Microseconds - startTime.Microseconds) / vtkm::Float64(1000000));
return elapsedTime;
}
VTKM_CONT TimeStamp GetCurrentTime()
VTKM_CONT TimeStamp GetCurrentTime() const
{
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>::Synchronize();

@ -375,7 +375,7 @@ struct DynamicCellSetSerializeFunctor
template <typename CellSetType>
void operator()(const CellSetType& cs, BinaryBuffer& bb) const
{
vtkmdiy::save(bb, vtkm::cont::TypeString<CellSetType>::Get());
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<CellSetType>::Get());
vtkmdiy::save(bb, cs);
}
};
@ -390,7 +390,7 @@ struct DynamicCellSetDeserializeFunctor
bool& success,
BinaryBuffer& bb) const
{
if (!success && (typeString == vtkm::cont::TypeString<CellSetType>::Get()))
if (!success && (typeString == vtkm::cont::SerializableTypeString<CellSetType>::Get()))
{
CellSetType cs;
vtkmdiy::load(bb, cs);

@ -102,7 +102,7 @@
///
/// The helper functions vtkm::cont::GetHumanReadableSize and
/// vtkm::cont::GetSizeString assist in formating byte sizes to a more readable
/// format. Similarly, the vtkm::cont::TypeName template functions provide RTTI
/// format. Similarly, the vtkm::cont::TypeToString template functions provide RTTI
/// based type-name information. When logging is enabled, these use the logging
/// backend to demangle symbol names on supported platforms.
///
@ -130,7 +130,7 @@
///
/// \code
/// VTKM_LOG_S(vtkm::cont::LogLevel::Perf,
/// "Executed functor " << vtkm::cont::TypeName(functor)
/// "Executed functor " << vtkm::cont::TypeToString(functor)
/// << " on device " << deviceId.GetName());
/// \endcode
@ -143,7 +143,7 @@
/// \code
/// VTKM_LOG_F(vtkm::cont::LogLevel::Perf,
/// "Executed functor %s on device %s",
/// vtkm::cont::TypeName(functor).c_str(),
/// vtkm::cont::TypeToString(functor).c_str(),
/// deviceId.GetName().c_str());
/// \endcode
@ -161,7 +161,7 @@
/// {
/// VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf,
/// "Executing filter %s",
/// vtkm::cont::TypeName(myFilter).c_str());
/// vtkm::cont::TypeToString(myFilter).c_str());
/// myFilter.Execute();
/// }
/// \endcode
@ -187,7 +187,7 @@
/// \brief Convenience macro for logging a TryExecute failure to the Error level.
/// If logging is disabled, a message is still printed to stderr.
/// \param errorMessage The error message detailing the failure.
/// \param functorName The name of the functor (see vtkm::cont::TypeName)
/// \param functorName The name of the functor (see vtkm::cont::TypeToString)
/// \param deviceId The device tag / id for the device on which the functor
/// failed.
@ -195,7 +195,7 @@
/// \brief Similar to VTKM_LOG_TRYEXECUTE_FAIL, but also informs the user
/// that the device has been disable for future TryExecute calls.
/// \param errorMessage The error message detailing the failure.
/// \param functorName The name of the functor (see vtkm::cont::TypeName)
/// \param functorName The name of the functor (see vtkm::cont::TypeToString)
/// \param deviceId The device tag / id for the device on which the functor
/// failed.
@ -219,18 +219,18 @@
#define VTKM_LOG_CAST_SUCC(inObj, outObj) \
VTKM_LOG_F(vtkm::cont::LogLevel::Cast, \
"Cast succeeded: %s (%p) --> %s (%p)", \
vtkm::cont::TypeName(inObj).c_str(), \
vtkm::cont::TypeToString(inObj).c_str(), \
&inObj, \
vtkm::cont::TypeName(outObj).c_str(), \
vtkm::cont::TypeToString(outObj).c_str(), \
&outObj)
// Cast failure:
#define VTKM_LOG_CAST_FAIL(inObj, outType) \
VTKM_LOG_F(vtkm::cont::LogLevel::Cast, \
"Cast failed: %s (%p) --> %s", \
vtkm::cont::TypeName(inObj).c_str(), \
vtkm::cont::TypeToString(inObj).c_str(), \
&inObj, \
vtkm::cont::TypeName<outType>().c_str())
vtkm::cont::TypeToString<outType>().c_str())
// TryExecute failure
#define VTKM_LOG_TRYEXECUTE_FAIL(errorMessage, functorName, deviceId) \
@ -427,7 +427,7 @@ std::string GetSizeString(vtkm::UInt64 bytes, int prec = 2);
* @{
*/
template <typename T>
static inline VTKM_CONT std::string TypeName()
static inline VTKM_CONT std::string TypeToString()
{
#ifdef VTKM_ENABLE_LOGGING
return loguru::demangle(typeid(T).name()).c_str();
@ -437,9 +437,9 @@ static inline VTKM_CONT std::string TypeName()
}
template <typename T>
static inline VTKM_CONT std::string TypeName(const T&)
static inline VTKM_CONT std::string TypeToString(const T&)
{
return TypeName<T>();
return TypeToString<T>();
}
/**@}*/
}

@ -17,8 +17,8 @@
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_TypeString_h
#define vtk_m_cont_TypeString_h
#ifndef vtk_m_cont_SerializableTypeString_h
#define vtk_m_cont_SerializableTypeString_h
#include <vtkm/Types.h>
@ -32,7 +32,7 @@ namespace cont
/// \brief A traits class that gives a unique name for a type. This class
/// should be specialized for every type that has to be serialized by diy.
template <typename T>
struct TypeString
struct SerializableTypeString
#ifdef VTKM_DOXYGEN_ONLY
{
static VTKM_CONT const std::string& Get()
@ -48,21 +48,21 @@ namespace internal
{
template <typename T, typename... Ts>
std::string GetVariadicTypeString(const T&, const Ts&... ts)
std::string GetVariadicSerializableTypeString(const T&, const Ts&... ts)
{
return TypeString<T>::Get() + "," + GetVariadicTypeString(ts...);
return SerializableTypeString<T>::Get() + "," + GetVariadicSerializableTypeString(ts...);
}
template <typename T>
std::string GetVariadicTypeString(const T&)
std::string GetVariadicSerializableTypeString(const T&)
{
return TypeString<T>::Get();
return SerializableTypeString<T>::Get();
}
} // internal
template <>
struct TypeString<vtkm::Int8>
struct SerializableTypeString<vtkm::Int8>
{
static VTKM_CONT const std::string& Get()
{
@ -72,7 +72,7 @@ struct TypeString<vtkm::Int8>
};
template <>
struct TypeString<vtkm::UInt8>
struct SerializableTypeString<vtkm::UInt8>
{
static VTKM_CONT const std::string& Get()
{
@ -82,7 +82,7 @@ struct TypeString<vtkm::UInt8>
};
template <>
struct TypeString<vtkm::Int16>
struct SerializableTypeString<vtkm::Int16>
{
static VTKM_CONT const std::string& Get()
{
@ -92,7 +92,7 @@ struct TypeString<vtkm::Int16>
};
template <>
struct TypeString<vtkm::UInt16>
struct SerializableTypeString<vtkm::UInt16>
{
static VTKM_CONT const std::string& Get()
{
@ -102,7 +102,7 @@ struct TypeString<vtkm::UInt16>
};
template <>
struct TypeString<vtkm::Int32>
struct SerializableTypeString<vtkm::Int32>
{
static VTKM_CONT const std::string& Get()
{
@ -112,7 +112,7 @@ struct TypeString<vtkm::Int32>
};
template <>
struct TypeString<vtkm::UInt32>
struct SerializableTypeString<vtkm::UInt32>
{
static VTKM_CONT const std::string& Get()
{
@ -122,7 +122,7 @@ struct TypeString<vtkm::UInt32>
};
template <>
struct TypeString<vtkm::Int64>
struct SerializableTypeString<vtkm::Int64>
{
static VTKM_CONT const std::string& Get()
{
@ -132,7 +132,7 @@ struct TypeString<vtkm::Int64>
};
template <>
struct TypeString<vtkm::UInt64>
struct SerializableTypeString<vtkm::UInt64>
{
static VTKM_CONT const std::string& Get()
{
@ -142,7 +142,7 @@ struct TypeString<vtkm::UInt64>
};
template <>
struct TypeString<vtkm::Float32>
struct SerializableTypeString<vtkm::Float32>
{
static VTKM_CONT const std::string& Get()
{
@ -152,7 +152,7 @@ struct TypeString<vtkm::Float32>
};
template <>
struct TypeString<vtkm::Float64>
struct SerializableTypeString<vtkm::Float64>
{
static VTKM_CONT const std::string& Get()
{
@ -162,27 +162,27 @@ struct TypeString<vtkm::Float64>
};
template <typename T, vtkm::IdComponent NumComponents>
struct TypeString<vtkm::Vec<T, NumComponents>>
struct SerializableTypeString<vtkm::Vec<T, NumComponents>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"V<" + TypeString<T>::Get() + "," + std::to_string(NumComponents) + ">";
"V<" + SerializableTypeString<T>::Get() + "," + std::to_string(NumComponents) + ">";
return name;
}
};
template <typename T1, typename T2>
struct TypeString<vtkm::Pair<T1, T2>>
struct SerializableTypeString<vtkm::Pair<T1, T2>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"vtkm::Pair<" + TypeString<T1>::Get() + "," + TypeString<T2>::Get() + ">";
static std::string name = "vtkm::Pair<" + SerializableTypeString<T1>::Get() + "," +
SerializableTypeString<T2>::Get() + ">";
return name;
}
};
}
} // vtkm::cont
#endif // vtk_m_cont_TypeString_h
#endif // vtk_m_cont_SerializableTypeString_h

@ -20,7 +20,7 @@
#ifndef vtk_m_cont_Serialization_h
#define vtk_m_cont_Serialization_h
#include <vtkm/cont/TypeString.h>
#include <vtkm/cont/SerializableTypeString.h>
#include <vtkm/thirdparty/diy/serialization.h>

@ -1,74 +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_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

@ -1,162 +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_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

@ -17,6 +17,7 @@
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#define vtk_m_cont_StorageVirtual_cxx
#include "StorageVirtual.h"
#include <vtkm/cont/internal/DeviceAdapterError.h>
@ -27,11 +28,12 @@ namespace cont
{
namespace internal
{
namespace detail
{
//--------------------------------------------------------------------
Storage<void, ::vtkm::cont::StorageTagVirtual>::Storage(
const Storage<void, vtkm::cont::StorageTagVirtual>& src)
StorageVirtual::StorageVirtual(const StorageVirtual& src)
: HostUpToDate(src.HostUpToDate)
, DeviceUpToDate(src.DeviceUpToDate)
, DeviceTransferState(src.DeviceTransferState)
@ -39,8 +41,7 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::Storage(
}
//--------------------------------------------------------------------
Storage<void, ::vtkm::cont::StorageTagVirtual>::Storage(
Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept
StorageVirtual::StorageVirtual(StorageVirtual&& src) noexcept
: HostUpToDate(src.HostUpToDate),
DeviceUpToDate(src.DeviceUpToDate),
DeviceTransferState(std::move(src.DeviceTransferState))
@ -48,8 +49,7 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::Storage(
}
//--------------------------------------------------------------------
Storage<void, vtkm::cont::StorageTagVirtual>& Storage<void, ::vtkm::cont::StorageTagVirtual>::
operator=(const Storage<void, vtkm::cont::StorageTagVirtual>& src)
StorageVirtual& StorageVirtual::operator=(const StorageVirtual& src)
{
this->HostUpToDate = src.HostUpToDate;
this->DeviceUpToDate = src.DeviceUpToDate;
@ -58,8 +58,7 @@ operator=(const Storage<void, vtkm::cont::StorageTagVirtual>& src)
}
//--------------------------------------------------------------------
Storage<void, vtkm::cont::StorageTagVirtual>& Storage<void, ::vtkm::cont::StorageTagVirtual>::
operator=(Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept
StorageVirtual& StorageVirtual::operator=(StorageVirtual&& src) noexcept
{
this->HostUpToDate = src.HostUpToDate;
this->DeviceUpToDate = src.DeviceUpToDate;
@ -68,19 +67,19 @@ operator=(Storage<void, vtkm::cont::StorageTagVirtual>&& src) noexcept
}
//--------------------------------------------------------------------
Storage<void, ::vtkm::cont::StorageTagVirtual>::~Storage()
StorageVirtual::~StorageVirtual()
{
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::ReleaseResourcesExecution()
void StorageVirtual::DropExecutionPortal()
{
this->DeviceTransferState->releaseDevice();
this->DeviceUpToDate = false;
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::ReleaseResources()
void StorageVirtual::DropAllPortals()
{
this->DeviceTransferState->releaseAll();
this->HostUpToDate = false;
@ -88,15 +87,13 @@ void Storage<void, ::vtkm::cont::StorageTagVirtual>::ReleaseResources()
}
//--------------------------------------------------------------------
std::unique_ptr<Storage<void, ::vtkm::cont::StorageTagVirtual>>
Storage<void, ::vtkm::cont::StorageTagVirtual>::NewInstance() const
std::unique_ptr<StorageVirtual> StorageVirtual::NewInstance() const
{
return this->MakeNewInstance();
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForInput(
const vtkm::internal::PortalVirtualBase* StorageVirtual::PrepareForInput(
vtkm::cont::DeviceAdapterId devId) const
{
if (devId == vtkm::cont::DeviceAdapterTagUndefined())
@ -122,9 +119,9 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForInput(
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId)
const vtkm::internal::PortalVirtualBase* StorageVirtual::PrepareForOutput(
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId)
{
if (devId == vtkm::cont::DeviceAdapterTagUndefined())
{
@ -147,8 +144,8 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForOutput(vtkm::Id number
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForInPlace(vtkm::cont::DeviceAdapterId devId)
const vtkm::internal::PortalVirtualBase* StorageVirtual::PrepareForInPlace(
vtkm::cont::DeviceAdapterId devId)
{
if (devId == vtkm::cont::DeviceAdapterTagUndefined())
{
@ -172,8 +169,7 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::PrepareForInPlace(vtkm::cont::De
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::GetPortalControl()
const vtkm::internal::PortalVirtualBase* StorageVirtual::GetPortalControl()
{
if (!this->HostUpToDate)
{
@ -188,8 +184,7 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::GetPortalControl()
}
//--------------------------------------------------------------------
const vtkm::internal::PortalVirtualBase*
Storage<void, ::vtkm::cont::StorageTagVirtual>::GetPortalConstControl() const
const vtkm::internal::PortalVirtualBase* StorageVirtual::GetPortalConstControl() const
{
if (!this->HostUpToDate)
{
@ -202,28 +197,67 @@ Storage<void, ::vtkm::cont::StorageTagVirtual>::GetPortalConstControl() const
}
//--------------------------------------------------------------------
DeviceAdapterId Storage<void, ::vtkm::cont::StorageTagVirtual>::GetDeviceAdapterId() const noexcept
DeviceAdapterId StorageVirtual::GetDeviceAdapterId() const noexcept
{
return this->DeviceTransferState->deviceId();
}
//--------------------------------------------------------------------
void Storage<void, ::vtkm::cont::StorageTagVirtual>::ControlPortalForOutput(
vtkm::cont::internal::TransferInfoArray&)
void StorageVirtual::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)
void StorageVirtual::TransferPortalForOutput(vtkm::cont::internal::TransferInfoArray&,
OutputMode,
vtkm::Id,
vtkm::cont::DeviceAdapterId)
{
throw vtkm::cont::ErrorBadValue("StorageTagVirtual by default doesn't support exec side writes.");
}
#define VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(T) \
template class VTKM_CONT_EXPORT ArrayTransferVirtual<T>; \
template class VTKM_CONT_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 2>>; \
template class VTKM_CONT_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 3>>; \
template class VTKM_CONT_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 4>>
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(char);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Int8);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::UInt8);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Int16);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::UInt16);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Int32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::UInt32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Int64);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::UInt64);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Float32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE(vtkm::Float64);
#undef VTK_M_ARRAY_TRANSFER_VIRTUAL_INSTANTIATE
#define VTK_M_STORAGE_VIRTUAL_INSTANTIATE(T) \
template class VTKM_CONT_EXPORT StorageVirtualImpl<T, VTKM_DEFAULT_STORAGE_TAG>; \
template class VTKM_CONT_EXPORT StorageVirtualImpl<vtkm::Vec<T, 2>, VTKM_DEFAULT_STORAGE_TAG>; \
template class VTKM_CONT_EXPORT StorageVirtualImpl<vtkm::Vec<T, 3>, VTKM_DEFAULT_STORAGE_TAG>; \
template class VTKM_CONT_EXPORT StorageVirtualImpl<vtkm::Vec<T, 4>, VTKM_DEFAULT_STORAGE_TAG>
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(char);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Int8);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::UInt8);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Int16);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::UInt16);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Int32);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::UInt32);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Int64);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::UInt64);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Float32);
VTK_M_STORAGE_VIRTUAL_INSTANTIATE(vtkm::Float64);
#undef VTK_M_STORAGE_VIRTUAL_INSTANTIATE
}
}
}
} // namespace vtkm::cont::internal::detail

@ -22,6 +22,7 @@
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/Storage.h>
#include <vtkm/cont/internal/TransferInfo.h>
@ -41,31 +42,33 @@ struct VTKM_ALWAYS_EXPORT StorageTagVirtual
namespace internal
{
template <>
class VTKM_CONT_EXPORT Storage<void, vtkm::cont::StorageTagVirtual>
namespace detail
{
class VTKM_CONT_EXPORT StorageVirtual
{
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;
StorageVirtual() = default;
StorageVirtual(const StorageVirtual& src);
StorageVirtual(StorageVirtual&& src) noexcept;
StorageVirtual& operator=(const StorageVirtual& src);
StorageVirtual& operator=(StorageVirtual&& src) noexcept;
virtual ~Storage();
virtual ~StorageVirtual();
/// 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();
virtual void ReleaseResourcesExecution() = 0;
/// 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();
virtual void ReleaseResources() = 0;
/// Returns the number of entries in the array.
///
@ -79,10 +82,7 @@ public:
/// 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); }
virtual void Allocate(vtkm::Id numberOfValues) = 0;
/// \brief Reduces the size of the array without changing its values.
///
@ -92,10 +92,7 @@ public:
/// \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); }
virtual void Shrink(vtkm::Id numberOfValues) = 0;
/// Determines if storage types matches the type passed in.
///
@ -111,7 +108,7 @@ public:
/// 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;
std::unique_ptr<StorageVirtual> NewInstance() const;
template <typename DerivedStorage>
const DerivedStorage* Cast() const
@ -120,7 +117,7 @@ public:
if (!derived)
{
VTKM_LOG_CAST_FAIL(*this, DerivedStorage);
throwFailedDynamicCast("StorageVirtual", vtkm::cont::TypeName<DerivedStorage>());
throwFailedDynamicCast("StorageVirtual", vtkm::cont::TypeToString<DerivedStorage>());
}
VTKM_LOG_CAST_SUCC(*this, derived);
return derived;
@ -153,14 +150,23 @@ public:
READ_WRITE
};
protected:
/// Drop the reference to the execution portal. The underlying array handle might still be
/// managing data on the execution side, but our references might be out of date, so drop
/// them and refresh them later if necessary.
void DropExecutionPortal();
/// Drop the reference to all portals. The underlying array handle might still be managing data,
/// but our references might be out of date, so drop them and refresh them later if necessary.
void DropAllPortals();
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;
virtual std::unique_ptr<StorageVirtual> MakeNewInstance() const = 0;
//Portal routines
virtual void ControlPortalForInput(vtkm::cont::internal::TransferInfoArray& payload) const = 0;
@ -181,10 +187,117 @@ private:
std::make_shared<vtkm::cont::internal::TransferInfoArray>();
};
} // namespace internal
template <typename T, typename S>
class VTKM_ALWAYS_EXPORT StorageVirtualImpl final
: public vtkm::cont::internal::detail::StorageVirtual
{
public:
VTKM_CONT
explicit StorageVirtualImpl(const vtkm::cont::ArrayHandle<T, S>& ah);
using StorageVirtual = internal::Storage<void, vtkm::cont::StorageTagVirtual>;
explicit StorageVirtualImpl(vtkm::cont::ArrayHandle<T, S>&& ah) noexcept;
VTKM_CONT
~StorageVirtualImpl() = default;
const vtkm::cont::ArrayHandle<T, S>& GetHandle() const { return this->Handle; }
vtkm::Id GetNumberOfValues() const override { return this->Handle.GetNumberOfValues(); }
void ReleaseResourcesExecution() override;
void ReleaseResources() override;
void Allocate(vtkm::Id numberOfValues) override;
void Shrink(vtkm::Id numberOfValues) override;
private:
std::unique_ptr<vtkm::cont::internal::detail::StorageVirtual> MakeNewInstance() const override
{
return std::unique_ptr<vtkm::cont::internal::detail::StorageVirtual>(
new StorageVirtualImpl<T, S>{ vtkm::cont::ArrayHandle<T, S>{} });
}
void ControlPortalForInput(vtkm::cont::internal::TransferInfoArray& payload) const override;
void ControlPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload) override;
void TransferPortalForInput(vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::DeviceAdapterId devId) const override;
void TransferPortalForOutput(vtkm::cont::internal::TransferInfoArray& payload,
OutputMode mode,
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId) override;
vtkm::cont::ArrayHandle<T, S> Handle;
};
} // namespace detail
template <typename T>
class VTKM_ALWAYS_EXPORT Storage<T, vtkm::cont::StorageTagVirtual>
{
public:
using ValueType = T;
using PortalType = vtkm::ArrayPortalRef<T>;
using PortalConstType = vtkm::ArrayPortalRef<T>;
Storage() = default;
// Should never really be used, but just in case.
Storage(const Storage<T, vtkm::cont::StorageTagVirtual>&) = default;
template <typename S>
Storage(const vtkm::cont::ArrayHandle<T, S>& srcArray)
: VirtualStorage(std::make_shared<detail::StorageVirtualImpl<T, S>>(srcArray))
{
}
~Storage() = default;
PortalType GetPortal()
{
return make_ArrayPortalRef(
static_cast<const vtkm::ArrayPortalVirtual<T>*>(this->VirtualStorage->GetPortalControl()),
this->GetNumberOfValues());
}
PortalConstType GetPortalConst() const
{
return make_ArrayPortalRef(static_cast<const vtkm::ArrayPortalVirtual<T>*>(
this->VirtualStorage->GetPortalConstControl()),
this->GetNumberOfValues());
}
vtkm::Id GetNumberOfValues() const { return this->VirtualStorage->GetNumberOfValues(); }
void Allocate(vtkm::Id numberOfValues);
void Shrink(vtkm::Id numberOfValues);
void ReleaseResources();
Storage<T, vtkm::cont::StorageTagVirtual> NewInstance() const;
const detail::StorageVirtual* GetStorageVirtual() const { return this->VirtualStorage.get(); }
detail::StorageVirtual* GetStorageVirtual() { return this->VirtualStorage.get(); }
private:
std::shared_ptr<detail::StorageVirtual> VirtualStorage;
Storage(std::shared_ptr<detail::StorageVirtual> virtualStorage)
: VirtualStorage(virtualStorage)
{
}
};
} // namespace internal
}
} // namespace vtkm::cont
#ifndef vtk_m_cont_StorageVirtual_hxx
#include <vtkm/cont/StorageVirtual.hxx>
#endif
#endif

@ -20,7 +20,7 @@
#ifndef vtk_m_cont_StorageVirtual_hxx
#define vtk_m_cont_StorageVirtual_hxx
#include <vtkm/cont/StorageAny.hxx>
#include <vtkm/cont/StorageVirtual.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/internal/TransferInfo.h>
@ -78,7 +78,7 @@ struct TransferToDevice
return true;
}
};
}
} // namespace detail
template <typename DerivedPortal, typename... Args>
inline void make_transferToDevice(vtkm::cont::DeviceAdapterId devId, Args&&... args)
@ -93,8 +93,351 @@ 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 internal
{
namespace detail
{
VTKM_CONT
template <typename T, typename S>
StorageVirtualImpl<T, S>::StorageVirtualImpl(const vtkm::cont::ArrayHandle<T, S>& ah)
: vtkm::cont::internal::detail::StorageVirtual()
, Handle(ah)
{
}
} // namespace vtkm::cont::
VTKM_CONT
template <typename T, typename S>
StorageVirtualImpl<T, S>::StorageVirtualImpl(vtkm::cont::ArrayHandle<T, S>&& ah) noexcept
: vtkm::cont::internal::detail::StorageVirtual(),
Handle(std::move(ah))
{
}
#endif
/// release execution side resources
template <typename T, typename S>
void StorageVirtualImpl<T, S>::ReleaseResourcesExecution()
{
this->DropExecutionPortal();
this->Handle.ReleaseResourcesExecution();
}
/// release control side resources
template <typename T, typename S>
void StorageVirtualImpl<T, S>::ReleaseResources()
{
this->DropAllPortals();
this->Handle.ReleaseResources();
}
template <typename T, typename S>
void StorageVirtualImpl<T, S>::Allocate(vtkm::Id numberOfValues)
{
this->DropAllPortals();
this->Handle.Allocate(numberOfValues);
}
template <typename T, typename S>
void StorageVirtualImpl<T, S>::Shrink(vtkm::Id numberOfValues)
{
this->DropAllPortals();
this->Handle.Shrink(numberOfValues);
}
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::internal::detail::StorageVirtual::OutputMode mode) const
{
using ACCESS_MODE = vtkm::cont::internal::detail::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 StorageVirtualImpl<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);
}
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 StorageVirtualImpl<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 StorageVirtualImpl<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 StorageVirtualImpl<T, S>::TransferPortalForOutput(
vtkm::cont::internal::TransferInfoArray& payload,
vtkm::cont::internal::detail::StorageVirtual::OutputMode mode,
vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId devId)
{
vtkm::cont::TryExecuteOnDevice(
devId, detail::PortalWrapperToDevice(), this->Handle, numberOfValues, payload, mode);
}
} // namespace detail
template <typename T>
void Storage<T, vtkm::cont::StorageTagVirtual>::Allocate(vtkm::Id numberOfValues)
{
if (this->VirtualStorage)
{
this->VirtualStorage->Allocate(numberOfValues);
}
else if (numberOfValues != 0)
{
throw vtkm::cont::ErrorBadAllocation("Attempted to allocate memory in a virtual array that "
"does not have an underlying concrete array.");
}
else
{
// Allocating a non-existing array to 0 is OK.
}
}
template <typename T>
void Storage<T, vtkm::cont::StorageTagVirtual>::Shrink(vtkm::Id numberOfValues)
{
if (this->VirtualStorage)
{
this->VirtualStorage->Shrink(numberOfValues);
}
else if (numberOfValues != 0)
{
throw vtkm::cont::ErrorBadAllocation(
"Attempted to shrink a virtual array that does not have an underlying concrete array.");
}
else
{
// Shrinking a non-existing array to 0 is OK.
}
}
template <typename T>
void Storage<T, vtkm::cont::StorageTagVirtual>::ReleaseResources()
{
if (this->VirtualStorage)
{
this->VirtualStorage->ReleaseResources();
}
else
{
// No concrete array, nothing allocated, nothing to do.
}
}
template <typename T>
Storage<T, vtkm::cont::StorageTagVirtual> Storage<T, vtkm::cont::StorageTagVirtual>::NewInstance()
const
{
if (this->GetStorageVirtual())
{
return Storage<T, vtkm::cont::StorageTagVirtual>(this->GetStorageVirtual()->NewInstance());
}
else
{
return Storage<T, vtkm::cont::StorageTagVirtual>();
}
}
namespace detail
{
template <typename T>
class VTKM_ALWAYS_EXPORT ArrayTransferVirtual
{
using StorageType = vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagVirtual>;
vtkm::cont::internal::detail::StorageVirtual* Storage;
public:
using ValueType = T;
using PortalControl = typename StorageType::PortalType;
using PortalConstControl = typename StorageType::PortalConstType;
using PortalExecution = vtkm::ArrayPortalRef<ValueType>;
using PortalConstExecution = vtkm::ArrayPortalRef<ValueType>;
VTKM_CONT ArrayTransferVirtual(StorageType* storage)
: Storage(storage->GetStorageVirtual())
{
}
VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }
VTKM_CONT PortalConstExecution PrepareForInput(vtkm::cont::DeviceAdapterId device)
{
return vtkm::make_ArrayPortalRef(static_cast<const vtkm::ArrayPortalVirtual<ValueType>*>(
this->Storage->PrepareForInput(device)),
this->GetNumberOfValues());
}
VTKM_CONT PortalExecution PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId device)
{
return make_ArrayPortalRef(static_cast<const vtkm::ArrayPortalVirtual<T>*>(
this->Storage->PrepareForOutput(numberOfValues, device)),
numberOfValues);
}
VTKM_CONT PortalExecution PrepareForInPlace(vtkm::cont::DeviceAdapterId device)
{
return vtkm::make_ArrayPortalRef(static_cast<const vtkm::ArrayPortalVirtual<ValueType>*>(
this->Storage->PrepareForInPlace(device)),
this->GetNumberOfValues());
}
VTKM_CONT
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
{
// Implementation of this method should be unnecessary. The internal array handles should
// automatically retrieve the output data as necessary.
}
VTKM_CONT void Shrink(vtkm::Id numberOfValues) { this->Storage->Shrink(numberOfValues); }
VTKM_CONT void ReleaseResources() { this->Storage->ReleaseResourcesExecution(); }
};
#ifndef vtk_m_cont_StorageVirtual_cxx
#define VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(T) \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayTransferVirtual<T>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 2>>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 3>>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayTransferVirtual<vtkm::Vec<T, 4>>
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(char);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Int8);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::UInt8);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Int16);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::UInt16);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Int32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::UInt32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Int64);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::UInt64);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Float32);
VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT(vtkm::Float64);
#undef VTK_M_ARRAY_TRANSFER_VIRTUAL_EXPORT
#define VTK_M_STORAGE_VIRTUAL_EXPORT(T) \
extern template class VTKM_CONT_TEMPLATE_EXPORT StorageVirtualImpl<T, VTKM_DEFAULT_STORAGE_TAG>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT \
StorageVirtualImpl<vtkm::Vec<T, 2>, VTKM_DEFAULT_STORAGE_TAG>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT \
StorageVirtualImpl<vtkm::Vec<T, 3>, VTKM_DEFAULT_STORAGE_TAG>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT \
StorageVirtualImpl<vtkm::Vec<T, 4>, VTKM_DEFAULT_STORAGE_TAG>
VTK_M_STORAGE_VIRTUAL_EXPORT(char);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Int8);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::UInt8);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Int16);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::UInt16);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Int32);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::UInt32);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Int64);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::UInt64);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Float32);
VTK_M_STORAGE_VIRTUAL_EXPORT(vtkm::Float64);
#undef VTK_M_STORAGE_VIRTUAL_EXPORT
#endif //!vtk_m_cont_StorageVirtual_cxx
} // namespace detail
template <typename T, typename Device>
struct ArrayTransfer<T, vtkm::cont::StorageTagVirtual, Device> : detail::ArrayTransferVirtual<T>
{
using Superclass = detail::ArrayTransferVirtual<T>;
VTKM_CONT ArrayTransfer(vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagVirtual>* storage)
: Superclass(storage)
{
}
VTKM_CONT typename Superclass::PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
{
return this->Superclass::PrepareForInput(Device());
}
VTKM_CONT typename Superclass::PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
{
return this->Superclass::PrepareForOutput(numberOfValues, Device());
}
VTKM_CONT typename Superclass::PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
{
return this->Superclass::PrepareForInPlace(Device());
}
};
}
}
} // namespace vtkm::cont::internal
#endif // vtk_m_cont_StorageVirtual_hxx

@ -23,12 +23,7 @@
#include <vtkm/internal/brigand.hpp>
namespace vtkm
{
namespace cont
{
namespace detail
namespace
{
template <typename State, typename T>
struct RemoveDisabledDevice
@ -37,31 +32,26 @@ struct RemoveDisabledDevice
};
/// TMP code to generate enabled device timer container
using AllDeviceList = DeviceAdapterListTagCommon::list;
using EnabledDeviceList =
brigand::fold<AllDeviceList,
brigand::list<>,
detail::RemoveDisabledDevice<brigand::_state, brigand::_element>>;
using AllDeviceList = vtkm::cont::DeviceAdapterListTagCommon::list;
using EnabledDeviceList = brigand::fold<AllDeviceList,
brigand::list<>,
RemoveDisabledDevice<brigand::_state, brigand::_element>>;
struct EnabledDeviceListTag : vtkm::ListTagBase<>
{
using list = EnabledDeviceList;
};
using EnabledTimerImpls =
brigand::transform<EnabledDeviceList,
brigand::bind<DeviceAdapterTimerImplementation, brigand::_1>>;
brigand::bind<vtkm::cont::DeviceAdapterTimerImplementation, brigand::_1>>;
using EnabledTimerImplTuple = brigand::as_tuple<EnabledTimerImpls>;
}
} // anonymous namespace
enum class TimerDispatchTag : int
namespace vtkm
{
namespace cont
{
namespace detail
{
Reset,
Start,
Stop,
Started,
Stopped,
Ready,
GetElapsedTime
};
class EnabledDeviceTimerImpls
{
@ -69,11 +59,15 @@ public:
EnabledDeviceTimerImpls() {}
~EnabledDeviceTimerImpls() {}
// A tuple of enabled timer implementations
detail::EnabledTimerImplTuple timerImplTuple;
EnabledTimerImplTuple timerImplTuple;
};
}
}
} // namespace vtkm::cont::detail
namespace detail
namespace
{
// C++11 does not support get tuple element by type. C++14 does support that.
// Get the index of a type in tuple elements
template <class T, class Tuple>
@ -91,164 +85,261 @@ struct Index<T, Container<U, Types...>>
static const std::size_t value = 1 + Index<T, Container<Types...>>::value;
};
struct TimerFunctor
template <typename Device>
VTKM_CONT inline
typename std::tuple_element<Index<Device, EnabledDeviceList>::value, EnabledTimerImplTuple>::type&
GetTimerImpl(Device, vtkm::cont::detail::EnabledDeviceTimerImpls* timerImpls)
{
TimerFunctor()
: elapsedTime(0)
, value(true)
{
}
template <typename DeviceAdapter>
VTKM_CONT void operator()(DeviceAdapter device, Timer* timer, TimerDispatchTag tag)
{
if (timer->Device == device || timer->Device == DeviceAdapterTagAny())
{
auto& timerImpl = std::get<Index<DeviceAdapter, detail::EnabledDeviceList>::value>(
timer->Internal->timerImplTuple);
switch (tag)
{
case TimerDispatchTag::Reset:
timerImpl.Reset();
break;
case TimerDispatchTag::Start:
timerImpl.Start();
break;
case TimerDispatchTag::Stop:
timerImpl.Stop();
break;
case TimerDispatchTag::Started:
value &= timerImpl.Started();
break;
case TimerDispatchTag::Stopped:
value &= timerImpl.Stopped();
break;
case TimerDispatchTag::Ready:
value &= timerImpl.Ready();
break;
case TimerDispatchTag::GetElapsedTime:
{
if (timer->Device == DeviceAdapterTagAny() &&
timer->DeviceForQuery == DeviceAdapterTagAny())
{ // Just want to do timing jobs
elapsedTime = std::max(elapsedTime, timerImpl.GetElapsedTime());
break;
}
else if (timer->Device == DeviceAdapterTagAny() && timer->DeviceForQuery == device)
{ // Given a generic timer, querying for a specific device time
elapsedTime = timerImpl.GetElapsedTime();
break;
}
else if (timer->Device == device && (timer->DeviceForQuery == DeviceAdapterTagAny() ||
timer->Device == timer->DeviceForQuery))
{ // Given a specific timer, querying its elapsed time
elapsedTime = timerImpl.GetElapsedTime();
break;
}
break;
}
}
}
}
vtkm::Float64 elapsedTime;
bool value;
};
return std::get<Index<Device, EnabledDeviceList>::value>(timerImpls->timerImplTuple);
}
template <typename Device>
VTKM_CONT inline const typename std::tuple_element<Index<Device, EnabledDeviceList>::value,
EnabledTimerImplTuple>::type&
GetTimerImpl(Device, const vtkm::cont::detail::EnabledDeviceTimerImpls* timerImpls)
{
return std::get<Index<Device, EnabledDeviceList>::value>(timerImpls->timerImplTuple);
}
struct ResetFunctor
{
template <typename Device>
VTKM_CONT void operator()(Device device,
vtkm::cont::Timer* timer,
vtkm::cont::detail::EnabledDeviceTimerImpls* timerImpls)
{
if ((timer->GetDevice() == device) || (timer->GetDevice() == vtkm::cont::DeviceAdapterTagAny()))
{
GetTimerImpl(device, timerImpls).Reset();
}
}
};
struct StartFunctor
{
template <typename Device>
VTKM_CONT void operator()(Device device,
vtkm::cont::Timer* timer,
vtkm::cont::detail::EnabledDeviceTimerImpls* timerImpls)
{
if ((timer->GetDevice() == device) || (timer->GetDevice() == vtkm::cont::DeviceAdapterTagAny()))
{
GetTimerImpl(device, timerImpls).Start();
}
}
};
struct StopFunctor
{
template <typename Device>
VTKM_CONT void operator()(Device device,
vtkm::cont::Timer* timer,
vtkm::cont::detail::EnabledDeviceTimerImpls* timerImpls)
{
if ((timer->GetDevice() == device) || (timer->GetDevice() == vtkm::cont::DeviceAdapterTagAny()))
{
GetTimerImpl(device, timerImpls).Stop();
}
}
};
struct StartedFunctor
{
bool Value = true;
template <typename Device>
VTKM_CONT void operator()(Device device,
const vtkm::cont::Timer* timer,
const vtkm::cont::detail::EnabledDeviceTimerImpls* timerImpls)
{
if ((timer->GetDevice() == device) || (timer->GetDevice() == vtkm::cont::DeviceAdapterTagAny()))
{
this->Value &= GetTimerImpl(device, timerImpls).Started();
}
}
};
struct StoppedFunctor
{
bool Value = true;
template <typename Device>
VTKM_CONT void operator()(Device device,
const vtkm::cont::Timer* timer,
const vtkm::cont::detail::EnabledDeviceTimerImpls* timerImpls)
{
if ((timer->GetDevice() == device) || (timer->GetDevice() == vtkm::cont::DeviceAdapterTagAny()))
{
this->Value &= GetTimerImpl(device, timerImpls).Stopped();
}
}
};
struct ReadyFunctor
{
bool Value = true;
template <typename Device>
VTKM_CONT void operator()(Device device,
const vtkm::cont::Timer* timer,
const vtkm::cont::detail::EnabledDeviceTimerImpls* timerImpls)
{
if ((timer->GetDevice() == device) || (timer->GetDevice() == vtkm::cont::DeviceAdapterTagAny()))
{
this->Value &= GetTimerImpl(device, timerImpls).Ready();
}
}
};
struct ElapsedTimeFunctor
{
vtkm::Float64 ElapsedTime = 0.0;
template <typename Device>
VTKM_CONT void operator()(Device deviceToTry,
vtkm::cont::DeviceAdapterId deviceToRunOn,
const vtkm::cont::detail::EnabledDeviceTimerImpls* timerImpls)
{
if ((deviceToRunOn == deviceToTry) || (deviceToRunOn == vtkm::cont::DeviceAdapterTagAny()))
{
this->ElapsedTime =
vtkm::Max(this->ElapsedTime, GetTimerImpl(deviceToTry, timerImpls).GetElapsedTime());
}
}
};
} // anonymous namespace
namespace vtkm
{
namespace cont
{
Timer::Timer()
: Device(vtkm::cont::DeviceAdapterTagAny())
, DeviceForQuery(vtkm::cont::DeviceAdapterTagAny())
, Internal(nullptr)
{
this->Init();
}
Timer::~Timer()
Timer::Timer(vtkm::cont::DeviceAdapterId device)
: Device(device)
, Internal(nullptr)
{
delete this->Internal;
vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
if (device != DeviceAdapterTagAny() && !tracker.CanRunOn(device))
{
VTKM_LOG_S(vtkm::cont::LogLevel::Error,
"Device '" << device.GetName() << "' can not run on current Device."
"Thus timer is not usable");
}
this->Init();
}
Timer::~Timer() = default;
void Timer::Init()
{
if (!this->Internal)
{
this->Internal = new EnabledDeviceTimerImpls();
this->Internal.reset(new detail::EnabledDeviceTimerImpls);
}
}
void Timer::Reset()
{
detail::TimerFunctor functor;
vtkm::ListForEach(functor, detail::EnabledDeviceListTag(), this, TimerDispatchTag::Reset);
vtkm::ListForEach(ResetFunctor(), EnabledDeviceListTag(), this, this->Internal.get());
}
void Timer::Reset(vtkm::cont::DeviceAdapterId device)
{
vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
if (device != DeviceAdapterTagAny() && !tracker.CanRunOn(device))
{
VTKM_LOG_S(vtkm::cont::LogLevel::Error,
"Device '" << device.GetName() << "' can not run on current Device."
"Thus timer is not usable");
}
this->Device = device;
this->Reset();
}
void Timer::Start()
{
detail::TimerFunctor functor;
vtkm::ListForEach(functor, detail::EnabledDeviceListTag(), this, TimerDispatchTag::Start);
vtkm::ListForEach(StartFunctor(), EnabledDeviceListTag(), this, this->Internal.get());
}
void Timer::Stop()
{
detail::TimerFunctor functor;
vtkm::ListForEach(functor, detail::EnabledDeviceListTag(), this, TimerDispatchTag::Stop);
vtkm::ListForEach(StopFunctor(), EnabledDeviceListTag(), this, this->Internal.get());
}
bool Timer::Started()
bool Timer::Started() const
{
detail::TimerFunctor functor;
vtkm::ListForEach(functor, detail::EnabledDeviceListTag(), this, TimerDispatchTag::Started);
return functor.value;
StartedFunctor functor;
vtkm::ListForEach(functor, EnabledDeviceListTag(), this, this->Internal.get());
return functor.Value;
}
bool Timer::Stopped()
bool Timer::Stopped() const
{
detail::TimerFunctor functor;
vtkm::ListForEach(functor, detail::EnabledDeviceListTag(), this, TimerDispatchTag::Stopped);
return functor.value;
StoppedFunctor functor;
vtkm::ListForEach(functor, EnabledDeviceListTag(), this, this->Internal.get());
return functor.Value;
}
bool Timer::Ready()
bool Timer::Ready() const
{
detail::TimerFunctor functor;
vtkm::ListForEach(functor, detail::EnabledDeviceListTag(), this, TimerDispatchTag::Ready);
return functor.value;
ReadyFunctor functor;
vtkm::ListForEach(functor, EnabledDeviceListTag(), this, this->Internal.get());
return functor.Value;
}
vtkm::Float64 Timer::GetElapsedTime(DeviceAdapterId id)
vtkm::Float64 Timer::GetElapsedTime(vtkm::cont::DeviceAdapterId device) const
{
// Timer is constructed with a specific device. Only querying this device is allowed.
if (this->Device != DeviceAdapterTagAny() && (id != DeviceAdapterTagAny() && this->Device != id))
vtkm::cont::DeviceAdapterId deviceToTime = device;
if (this->Device != DeviceAdapterTagAny())
{
// Timer is constructed for a specific device. Only querying on this device is allowed.
if (deviceToTime == vtkm::cont::DeviceAdapterTagAny())
{
// User did not specify a device to time on. Use the one set in the timer.
deviceToTime = this->Device;
}
else if (deviceToTime == this->Device)
{
// User asked for the same device already set for the timer. We are OK. Nothing to do.
}
else
{
// The user selected a device that is differnt than the one set for the timer. This query
// is not allowed.
VTKM_LOG_S(vtkm::cont::LogLevel::Error,
"Device '" << device.GetName() << "' is not supported for current timer"
<< "("
<< this->Device.GetName()
<< ")");
return 0.0;
}
}
// If we have specified a specific device, make sure we can run on it.
vtkm::cont::RuntimeDeviceTracker tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
if ((deviceToTime != vtkm::cont::DeviceAdapterTagAny()) && !tracker.CanRunOn(deviceToTime))
{
VTKM_LOG_S(vtkm::cont::LogLevel::Error,
"Device '" << id.GetName() << "' is not supported for current timer"
<< "("
<< this->Device.GetName()
<< ")");
"Device '" << device.GetName() << "' can not run on current Device."
"Thus timer is not usable");
return 0.0;
}
// Timer is constructed with any device. Only querying enabled device is allowed.
vtkm::cont::RuntimeDeviceTracker tracker;
if (this->Device == DeviceAdapterTagAny() &&
(id != DeviceAdapterTagAny() && !tracker.CanRunOn(id)))
{
VTKM_LOG_S(vtkm::cont::LogLevel::Error,
"Device '" << id.GetName() << "' can not run on current Device."
"Thus timer is not usable");
return 0.0;
}
ElapsedTimeFunctor functor;
vtkm::ListForEach(functor, EnabledDeviceListTag(), deviceToTime, this->Internal.get());
this->DeviceForQuery = id;
detail::TimerFunctor functor;
vtkm::ListForEach(
functor, detail::EnabledDeviceListTag(), this, TimerDispatchTag::GetElapsedTime);
return functor.elapsedTime;
return functor.ElapsedTime;
}
}
} // namespace vtkm::cont

@ -26,15 +26,16 @@
#include <vtkm/cont/vtkm_cont_export.h>
#include <memory>
namespace vtkm
{
namespace cont
{
namespace detail
{
struct TimerFunctor;
}
class EnabledDeviceTimerImpls;
}
/// A class that can be used to time operations in VTK-m that might be occuring
/// in parallel. Users are recommended to provide a device adapter at construction
@ -45,50 +46,49 @@ class EnabledDeviceTimerImpls;
/// have the longest execution time if enabled.
/// Per device adapter time query is also supported. It's useful when users want to reuse
/// the same timer to measure the cuda kernal call as well as the cuda device execution.
/// It is also possible to change the device adapter after construction by calling the form
/// of the Reset method with a new DeviceAdapterId.
///
/// The there is no guaranteed resolution of the time but should generally be
/// good to about a millisecond.
///
class VTKM_CONT_EXPORT Timer
{
friend struct detail::TimerFunctor;
public:
VTKM_CONT
Timer();
template <typename DeviceAdapter>
VTKM_CONT Timer(DeviceAdapter id)
: Device(id)
, DeviceForQuery(DeviceAdapterTagAny())
, Internal(nullptr)
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapter);
static_assert(DeviceAdapter::IsEnabled, "A disabled device is passed to the Timer");
this->Init();
}
VTKM_CONT Timer(vtkm::cont::DeviceAdapterId device);
VTKM_CONT ~Timer();
/// Resets the timer.
VTKM_CONT void Reset();
/// Resets the timer and changes the device to time on.
VTKM_CONT void Reset(vtkm::cont::DeviceAdapterId device);
/// Start would call Reset function before starting the timer for convenience
VTKM_CONT void Start();
VTKM_CONT void Stop();
VTKM_CONT bool Started();
VTKM_CONT bool Started() const;
VTKM_CONT bool Stopped();
VTKM_CONT bool Stopped() const;
/// Used to check if Timer has finished the synchronization to get the result from the device.
VTKM_CONT bool Ready();
VTKM_CONT bool Ready() const;
/// Get the elapsed time measured by the given device adapter. If no device is
/// specified, the max time of all device measurements will be returned.
VTKM_CONT
vtkm::Float64 GetElapsedTime(DeviceAdapterId id = DeviceAdapterTagAny());
vtkm::Float64 GetElapsedTime(
vtkm::cont::DeviceAdapterId id = vtkm::cont::DeviceAdapterTagAny()) const;
/// Returns the device for which this timer is synchronized. If the device adapter has the same
/// id as DeviceAdapterTagAny, then the timer will synchronize all devices.
VTKM_CONT vtkm::cont::DeviceAdapterId GetDevice() const { return this->Device; }
private:
VTKM_CONT void Init();
@ -97,8 +97,7 @@ private:
VTKM_CONT void operator=(const Timer&) = delete;
DeviceAdapterId Device;
DeviceAdapterId DeviceForQuery;
EnabledDeviceTimerImpls* Internal;
std::unique_ptr<detail::EnabledDeviceTimerImpls> Internal;
};
}
} // namespace vtkm::cont

@ -53,7 +53,7 @@ inline bool TryExecuteIfValid(std::true_type,
}
catch (...)
{
detail::HandleTryExecuteException(tag, tracker, vtkm::cont::TypeName<Functor>());
detail::HandleTryExecuteException(tag, tracker, vtkm::cont::TypeToString<Functor>());
}
}

@ -445,7 +445,7 @@ struct VariantArrayHandleSerializeFunctor
template <typename ArrayHandleType>
void operator()(const ArrayHandleType& ah, BinaryBuffer& bb) const
{
vtkmdiy::save(bb, vtkm::cont::TypeString<ArrayHandleType>::Get());
vtkmdiy::save(bb, vtkm::cont::SerializableTypeString<ArrayHandleType>::Get());
vtkmdiy::save(bb, ah);
}
};
@ -461,7 +461,7 @@ struct VariantArrayHandleDeserializeFunctor
{
using ArrayHandleType = vtkm::cont::ArrayHandleVirtual<T>;
if (!success && (typeString == vtkm::cont::TypeString<ArrayHandleType>::Get()))
if (!success && (typeString == vtkm::cont::SerializableTypeString<ArrayHandleType>::Get()))
{
ArrayHandleType ah;
vtkmdiy::load(bb, ah);

@ -64,15 +64,16 @@ void DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>::Start()
void DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>::Stop()
{
VTKM_CUDA_CALL(cudaEventRecord(this->StopEvent, cudaStreamPerThread));
VTKM_CUDA_CALL(cudaEventSynchronize(this->StopEvent));
this->StopReady = true;
}
bool DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>::Started()
bool DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>::Started() const
{
return this->StartReady;
}
bool DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>::Stopped()
bool DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>::Stopped() const
{
return this->StopReady;
}
@ -80,7 +81,7 @@ bool DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>::Stopped
// Callbacks without a mandated order(in independent streams) execute in undefined
// order and maybe serialized. So Instead CudaEventQuery is used here.
// Ref link: https://docs.nvidia.com/cuda/cuda-driver-api/group__CUDA__STREAM.html
bool DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>::Ready()
bool DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>::Ready() const
{
if (cudaEventQuery(this->StopEvent) == cudaSuccess)
{
@ -91,6 +92,7 @@ bool DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>::Ready()
vtkm::Float64 DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>::GetElapsedTime()
const
{
assert(this->StartReady);
if (!this->StartReady)
@ -99,18 +101,16 @@ vtkm::Float64 DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>
"Start() function should be called first then trying to call GetElapsedTime().");
return 0;
}
bool manualStop = true;
if (!this->StopReady)
{
manualStop = false;
this->Stop();
// Stop was not called, so we have to insert a new event into the stream
VTKM_CUDA_CALL(cudaEventRecord(this->StopEvent, cudaStreamPerThread));
VTKM_CUDA_CALL(cudaEventSynchronize(this->StopEvent));
}
VTKM_CUDA_CALL(cudaEventSynchronize(this->StopEvent));
float elapsedTimeMilliseconds;
VTKM_CUDA_CALL(cudaEventElapsedTime(&elapsedTimeMilliseconds, this->StartEvent, this->StopEvent));
// Reset Stop flag to its original state
this->StopReady = manualStop;
return static_cast<vtkm::Float64>(0.001f * elapsedTimeMilliseconds);
}
}

@ -54,13 +54,13 @@ public:
VTKM_CONT void Stop();
VTKM_CONT bool Started();
VTKM_CONT bool Started() const;
VTKM_CONT bool Stopped();
VTKM_CONT bool Stopped() const;
VTKM_CONT bool Ready();
VTKM_CONT bool Ready() const;
VTKM_CONT vtkm::Float64 GetElapsedTime();
VTKM_CONT vtkm::Float64 GetElapsedTime() const;
private:
// Copying CUDA events is problematic.

@ -38,7 +38,7 @@ namespace internal
// Binary function object wrapper which can detect and handle calling the
// wrapped operator with complex value types such as
// IteratorFromArrayPortalValue which happen when passed an input array that
// ArrayPortalValueReference which happen when passed an input array that
// is implicit.
template <typename ResultType, typename Function>
struct WrappedBinaryOperator

@ -164,8 +164,8 @@ struct VTKM_ALWAYS_EXPORT Caster
if (!IsValueType<T>(container))
{
VTKM_LOG_CAST_FAIL(container, ArrayHandleType);
throwFailedDynamicCast(vtkm::cont::TypeName(container),
vtkm::cont::TypeName<ArrayHandleType>());
throwFailedDynamicCast(vtkm::cont::TypeToString(container),
vtkm::cont::TypeToString<ArrayHandleType>());
}
const auto* derived = static_cast<const VariantArrayHandleContainer<T>*>(container);
@ -182,8 +182,8 @@ struct VTKM_ALWAYS_EXPORT Caster<T, vtkm::cont::StorageTagVirtual>
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>>());
throwFailedDynamicCast(vtkm::cont::TypeToString(container),
vtkm::cont::TypeToString<vtkm::cont::ArrayHandleVirtual<T>>());
}
// Technically, this method returns a copy of the \c ArrayHandle. But

@ -255,8 +255,9 @@ public:
template <class FunctorType>
VTKM_CONT static inline void Schedule(FunctorType functor, vtkm::Id numInstances)
{
VTKM_LOG_SCOPE(
vtkm::cont::LogLevel::Perf, "Schedule TBB 1D: '%s'", vtkm::cont::TypeName(functor).c_str());
VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf,
"Schedule TBB 1D: '%s'",
vtkm::cont::TypeToString(functor).c_str());
vtkm::exec::tbb::internal::TaskTiling1D kernel(functor);
ScheduleTask(kernel, numInstances);
@ -265,8 +266,9 @@ public:
template <class FunctorType>
VTKM_CONT static inline void Schedule(FunctorType functor, vtkm::Id3 rangeMax)
{
VTKM_LOG_SCOPE(
vtkm::cont::LogLevel::Perf, "Schedule TBB 3D: '%s'", vtkm::cont::TypeName(functor).c_str());
VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf,
"Schedule TBB 3D: '%s'",
vtkm::cont::TypeToString(functor).c_str());
vtkm::exec::tbb::internal::TaskTiling3D kernel(functor);
ScheduleTask(kernel, rangeMax);
@ -339,7 +341,6 @@ public:
VTKM_CONT void Reset()
{
vtkm::cont::DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagTBB>::Synchronize();
this->StartReady = false;
this->StopReady = false;
}
@ -347,23 +348,23 @@ public:
VTKM_CONT void Start()
{
this->Reset();
this->StartTime = ::tbb::tick_count::now();
this->StartTime = this->GetCurrentTime();
this->StartReady = true;
}
VTKM_CONT void Stop()
{
this->StopTime = ::tbb::tick_count::now();
this->StopTime = this->GetCurrentTime();
this->StopReady = true;
}
VTKM_CONT bool Started() { return this->StartReady; }
VTKM_CONT bool Started() const { return this->StartReady; }
VTKM_CONT bool Stopped() { return this->StopReady; }
VTKM_CONT bool Stopped() const { return this->StopReady; }
VTKM_CONT bool Ready() { return true; }
VTKM_CONT bool Ready() const { return true; }
VTKM_CONT vtkm::Float64 GetElapsedTime()
VTKM_CONT vtkm::Float64 GetElapsedTime() const
{
assert(this->StartReady);
if (!this->StartReady)
@ -373,21 +374,21 @@ public:
" GetElapsedTime().");
return 0;
}
bool manualStop = true;
if (!this->StopReady)
{
manualStop = false;
this->Stop();
}
vtkm::cont::DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagTBB>::Synchronize();
::tbb::tick_count::interval_t elapsedTime = this->StopTime - this->StartTime;
// Reset StopReady flag to its original state
this->StopReady = manualStop;
::tbb::tick_count startTime = this->StartTime;
::tbb::tick_count stopTime = this->StopReady ? this->StopTime : this->GetCurrentTime();
::tbb::tick_count::interval_t elapsedTime = stopTime - startTime;
return static_cast<vtkm::Float64>(elapsedTime.seconds());
}
VTKM_CONT::tbb::tick_count GetCurrentTime() const
{
vtkm::cont::DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagTBB>::Synchronize();
return ::tbb::tick_count::now();
}
private:
bool StartReady;
bool StopReady;

@ -51,23 +51,23 @@ struct Test
void TestConstructors()
{
VirtHandle nullStorage;
VTKM_TEST_ASSERT(nullStorage.GetStorage() == nullptr,
VTKM_TEST_ASSERT(nullStorage.GetStorage().GetStorageVirtual() == nullptr,
"storage should be empty when using ArrayHandleVirtual().");
VirtHandle fromArrayHandle{ ArrayHandle{} };
VTKM_TEST_ASSERT(fromArrayHandle.GetStorage() != nullptr,
VTKM_TEST_ASSERT(fromArrayHandle.GetStorage().GetStorageVirtual() != 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,
VTKM_TEST_ASSERT(fromVirtHandle.GetStorage().GetStorageVirtual() != 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,
VTKM_TEST_ASSERT(fromNullPtrHandle.GetStorage().GetStorageVirtual() == nullptr,
"storage should be empty when constructing from a ArrayHandleVirtual that has "
"nullptr storage.");
VTKM_TEST_ASSERT((vtkm::cont::IsType<ArrayHandle>(fromNullPtrHandle) == false),
@ -77,31 +77,6 @@ struct Test
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;

@ -535,24 +535,24 @@ namespace cont
{
template <typename T>
struct TypeString<TestArrayHandleImplicit::ImplicitFunctor<T>>
struct SerializableTypeString<TestArrayHandleImplicit::ImplicitFunctor<T>>
{
static VTKM_CONT const std::string& Get()
{
static std::string name =
"TestArrayHandleImplicit::ImplicitFunctor<" + TypeString<T>::Get() + ">";
"TestArrayHandleImplicit::ImplicitFunctor<" + SerializableTypeString<T>::Get() + ">";
return name;
}
};
template <>
struct TypeString<TestArrayHandleTransform::TransformFunctor>
struct SerializableTypeString<TestArrayHandleTransform::TransformFunctor>
{
static VTKM_CONT const std::string Get() { return "TestArrayHandleTransform::TransformFunctor"; }
};
template <>
struct TypeString<TestArrayHandleTransform::InverseTransformFunctor>
struct SerializableTypeString<TestArrayHandleTransform::InverseTransformFunctor>
{
static VTKM_CONT const std::string Get()
{

@ -18,117 +18,161 @@
// this software.
//============================================================================
#include <vtkm/cont/DeviceAdapterListTag.h>
#include <vtkm/cont/RuntimeDeviceTracker.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/cont/cuda/internal/DeviceAdapterTagCuda.h>
#include <vtkm/cont/openmp/internal/DeviceAdapterTagOpenMP.h>
#include <vtkm/cont/serial/internal/DeviceAdapterTagSerial.h>
#include <vtkm/cont/tbb/internal/DeviceAdapterTagTBB.h>
#include <vtkm/cont/internal/DeviceAdapterError.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/internal/Windows.h>
#include <chrono>
#include <thread>
namespace
{
void Time()
struct TimerTestDevices
: vtkm::ListTagAppend<VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG, vtkm::cont::DeviceAdapterTagAny>
{
vtkm::cont::Timer timer;
};
constexpr int waitTimeMilliseconds = 250;
constexpr vtkm::Float64 waitTimeSeconds = vtkm::Float64(waitTimeMilliseconds) / 1000;
void Wait()
{
std::cout << " Sleeping for " << waitTimeSeconds << "s" << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(waitTimeMilliseconds));
}
bool CanTimeOnDevice(const vtkm::cont::Timer& timer, vtkm::cont::DeviceAdapterId device)
{
if (device == vtkm::cont::DeviceAdapterTagAny())
{
// The timer can run on any device. It should pick up something (unless perhaps there are no
// devices, which would only happen if you explicitly disable serial, which we don't).
return true;
}
else if ((timer.GetDevice() == vtkm::cont::DeviceAdapterTagAny()) ||
(timer.GetDevice() == device))
{
// Device is specified and it is a match for the timer's device.
return vtkm::cont::GetGlobalRuntimeDeviceTracker().CanRunOn(device);
}
else
{
// The requested device does not match the device of the timer.
return false;
}
}
struct CheckTimeForDeviceFunctor
{
void operator()(vtkm::cont::DeviceAdapterId device,
const vtkm::cont::Timer& timer,
vtkm::Float64 expectedTime) const
{
std::cout << " Checking time for device " << device.GetName() << std::endl;
if (CanTimeOnDevice(timer, device))
{
vtkm::Float64 elapsedTime = timer.GetElapsedTime(device);
VTKM_TEST_ASSERT(
elapsedTime > (expectedTime - 0.001), "Timer did not capture full wait. ", elapsedTime);
VTKM_TEST_ASSERT(elapsedTime < (expectedTime + waitTimeSeconds),
"Timer counted too far or system really busy. ",
elapsedTime);
}
else
{
std::cout << " Device not supported. Expect 0 back and possible error in log."
<< std::endl;
VTKM_TEST_ASSERT(timer.GetElapsedTime(device) == 0.0,
"Disabled timer should return nothing.");
}
}
};
void CheckTime(const vtkm::cont::Timer& timer, vtkm::Float64 expectedTime)
{
std::cout << " Check time for " << expectedTime << "s" << std::endl;
vtkm::ListForEach(CheckTimeForDeviceFunctor(), TimerTestDevices(), timer, expectedTime);
}
void DoTimerCheck(vtkm::cont::Timer& timer)
{
std::cout << " Starting timer" << std::endl;
timer.Start();
VTKM_TEST_ASSERT(timer.Started(), "Timer fails to track started status");
VTKM_TEST_ASSERT(!timer.Stopped(), "Timer fails to track non stopped status");
#ifdef VTKM_WINDOWS
Sleep(1000);
#else
sleep(1);
#endif
vtkm::Float64 expectedTime = 0.0;
CheckTime(timer, expectedTime);
vtkm::Float64 elapsedTime = timer.GetElapsedTime();
Wait();
expectedTime += waitTimeSeconds;
CheckTime(timer, expectedTime);
std::cout << " Make sure timer is still running" << std::endl;
VTKM_TEST_ASSERT(!timer.Stopped(), "Timer fails to track stopped status");
std::cout << "Elapsed time measured by any Tag: " << elapsedTime << std::endl;
VTKM_TEST_ASSERT(elapsedTime > 0.999, "General Timer did not capture full second wait.");
VTKM_TEST_ASSERT(elapsedTime < 2.0, "General Timer counted too far or system really busy.");
Wait();
expectedTime += waitTimeSeconds;
vtkm::cont::RuntimeDeviceTracker tracker;
vtkm::Float64 elapsedTimeCuda = timer.GetElapsedTime(vtkm::cont::DeviceAdapterTagCuda());
if (tracker.CanRunOn(vtkm::cont::DeviceAdapterTagCuda()))
{
std::cout << " can on run cuda?: true" << std::endl;
std::cout << "Elapsed time measured by cuda Tag: " << elapsedTime << std::endl;
VTKM_TEST_ASSERT(elapsedTimeCuda > 0.999, "Cuda Timer did not capture full second wait.");
VTKM_TEST_ASSERT(elapsedTimeCuda < 2.0, "Cuda Timer counted too far or system really busy.");
}
else
{
VTKM_TEST_ASSERT(elapsedTimeCuda == 0.0, "Disabled Cuda Timer should return nothing.");
}
vtkm::Float64 elapsedTimeSerial = timer.GetElapsedTime(vtkm::cont::DeviceAdapterTagSerial());
std::cout << "Elapsed time measured by serial Tag: " << elapsedTime << std::endl;
VTKM_TEST_ASSERT(elapsedTimeSerial > 0.999, "Serial Timer did not capture full second wait.");
VTKM_TEST_ASSERT(elapsedTimeSerial < 2.0, "Serial Timer counted too far or system really busy.");
vtkm::Float64 elapsedTimeOpenMP = timer.GetElapsedTime(vtkm::cont::DeviceAdapterTagOpenMP());
if (vtkm::cont::DeviceAdapterTagOpenMP::IsEnabled)
{
std::cout << "Elapsed time measured by openmp Tag: " << elapsedTime << std::endl;
VTKM_TEST_ASSERT(elapsedTimeOpenMP > 0.999, "OpenMP Timer did not capture full second wait.");
VTKM_TEST_ASSERT(elapsedTimeOpenMP < 2.0,
"OpenMP Timer counted too far or system really busy.");
}
else
{
VTKM_TEST_ASSERT(elapsedTimeOpenMP == 0.0, "Disabled OpenMP Timer should return nothing.");
}
vtkm::Float64 elapsedTimeTBB = timer.GetElapsedTime(vtkm::cont::DeviceAdapterTagTBB());
if (vtkm::cont::DeviceAdapterTagTBB::IsEnabled)
{
std::cout << "Elapsed time measured by tbb Tag: " << elapsedTime << std::endl;
VTKM_TEST_ASSERT(elapsedTimeTBB > 0.999, "TBB Timer did not capture full second wait.");
VTKM_TEST_ASSERT(elapsedTimeTBB < 2.0, "TBB Timer counted too far or system really busy.");
}
else
{
VTKM_TEST_ASSERT(elapsedTimeOpenMP == 0.0, "Disabled TBB Timer should return nothing.");
}
std::cout << "Reuse the timer to test continuous timing." << std::endl;
#ifdef VTKM_WINDOWS
Sleep(1000);
#else
sleep(1);
#endif
elapsedTime = timer.GetElapsedTime();
std::cout << "Elapsed time measured by any Tag: " << elapsedTime << std::endl;
VTKM_TEST_ASSERT(elapsedTime > 1.999,
"General Timer did not capture two full seconds wait in second launch.");
VTKM_TEST_ASSERT(elapsedTime < 3.0,
"General Timer counted too far or system really busy in second launch.");
CheckTime(timer, expectedTime);
std::cout << " Stop the timer" << std::endl;
timer.Stop();
VTKM_TEST_ASSERT(timer.Stopped(), "Timer fails to track stopped status");
#ifdef VTKM_WINDOWS
Sleep(1000);
#else
sleep(1);
#endif
std::cout << "Elapsed time measured by any Tag with an early stop: " << elapsedTime << std::endl;
VTKM_TEST_ASSERT(elapsedTime > 1.999,
"General Timer did not capture two full seconds wait in second launch.");
VTKM_TEST_ASSERT(elapsedTime < 3.0,
"General Timer counted too far or system really busy in second launch.");
CheckTime(timer, expectedTime);
Wait();
std::cout << " Check that timer legitimately stopped" << std::endl;
CheckTime(timer, expectedTime);
}
struct TimerCheckFunctor
{
void operator()(vtkm::cont::DeviceAdapterId device) const
{
if ((device != vtkm::cont::DeviceAdapterTagAny()) &&
!vtkm::cont::GetGlobalRuntimeDeviceTracker().CanRunOn(device))
{
// A timer will not work if set on a device that is not supported. Just skip this test.
return;
}
{
std::cout << "Checking Timer on device " << device.GetName() << " set with constructor"
<< std::endl;
vtkm::cont::Timer timer(device);
DoTimerCheck(timer);
}
{
std::cout << "Checking Timer on device " << device.GetName() << " reset" << std::endl;
vtkm::cont::Timer timer;
timer.Reset(device);
DoTimerCheck(timer);
}
}
};
void DoTimerTest()
{
std::cout << "Check default timer" << std::endl;
vtkm::cont::Timer timer;
DoTimerCheck(timer);
vtkm::ListForEach(TimerCheckFunctor(), TimerTestDevices());
}
} // anonymous namespace
int UnitTestTimer(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(Time, argc, argv);
return vtkm::cont::testing::Testing::Run(DoTimerTest, argc, argv);
}

@ -49,14 +49,25 @@ public:
ThreadIndicesBasic(vtkm::Id threadIndex,
vtkm::Id inIndex,
vtkm::IdComponent visitIndex,
vtkm::Id outIndex,
vtkm::Id globalThreadIndexOffset = 0)
: InputIndex(inIndex)
, OutputIndex(threadIndex)
: ThreadIndex(threadIndex)
, InputIndex(inIndex)
, OutputIndex(outIndex)
, VisitIndex(visitIndex)
, GlobalThreadIndexOffset(globalThreadIndexOffset)
{
}
/// \brief The index of the thread or work invocation.
///
/// This index refers to which instance of the worklet is being invoked. Every invocation of the
/// worklet has a unique thread index. This is also called the work index depending on the
/// context.
///
VTKM_EXEC
vtkm::Id GetThreadIndex() const { return this->ThreadIndex; }
/// \brief The index into the input domain.
///
/// This index refers to the input element (array value, cell, etc.) that
@ -98,9 +109,10 @@ public:
///
/// Global index (for streaming)
VTKM_EXEC
vtkm::Id GetGlobalIndex() const { return (this->GlobalThreadIndexOffset + this->OutputIndex); }
vtkm::Id GetGlobalIndex() const { return (this->GlobalThreadIndexOffset + this->ThreadIndex); }
private:
vtkm::Id ThreadIndex;
vtkm::Id InputIndex;
vtkm::Id OutputIndex;
vtkm::IdComponent VisitIndex;

@ -65,19 +65,14 @@ class ThreadIndicesPointNeighborhood
{
public:
template <typename OutToInArrayType, typename VisitArrayType, vtkm::IdComponent Dimension>
template <vtkm::IdComponent Dimension>
VTKM_EXEC ThreadIndicesPointNeighborhood(
const vtkm::Id3& outIndex,
const OutToInArrayType&,
const VisitArrayType&,
const vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint,
Dimension>& connectivity,
vtkm::Id globalThreadIndexOffset = 0)
: State(outIndex, detail::To3D(connectivity.GetPointDimensions()))
, InputIndex(0)
, OutputIndex(0)
, VisitIndex(0)
, GlobalThreadIndexOffset(globalThreadIndexOffset)
{
using ConnectivityType = vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagCell,
@ -85,41 +80,27 @@ public:
Dimension>;
using ConnRangeType = typename ConnectivityType::SchedulingRangeType;
const ConnRangeType index = detail::Deflate(outIndex, ConnRangeType());
this->InputIndex = connectivity.LogicalToFlatToIndex(index);
this->OutputIndex = this->InputIndex;
}
template <typename OutToInArrayType, typename VisitArrayType, vtkm::IdComponent Dimension>
VTKM_EXEC ThreadIndicesPointNeighborhood(
const vtkm::Id& outIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
const vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint,
Dimension>& connectivity,
vtkm::Id globalThreadIndexOffset = 0)
: State(detail::To3D(connectivity.FlatToLogicalToIndex(outToIn.Get(outIndex))),
detail::To3D(connectivity.GetPointDimensions()))
, InputIndex(outToIn.Get(outIndex))
, OutputIndex(outIndex)
, VisitIndex(static_cast<vtkm::IdComponent>(visit.Get(outIndex)))
, GlobalThreadIndexOffset(globalThreadIndexOffset)
{
this->ThreadIndex = connectivity.LogicalToFlatToIndex(index);
this->InputIndex = this->ThreadIndex;
this->VisitIndex = 0;
this->OutputIndex = this->ThreadIndex;
}
template <vtkm::IdComponent Dimension>
VTKM_EXEC ThreadIndicesPointNeighborhood(
const vtkm::Id& outIndex,
const vtkm::Id& inIndex,
const vtkm::IdComponent& visitIndex,
vtkm::Id threadIndex,
vtkm::Id inputIndex,
vtkm::IdComponent visitIndex,
vtkm::Id outputIndex,
const vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagCell,
vtkm::TopologyElementTagPoint,
Dimension>& connectivity,
vtkm::Id globalThreadIndexOffset = 0)
: State(detail::To3D(connectivity.FlatToLogicalToIndex(inIndex)),
: State(detail::To3D(connectivity.FlatToLogicalToIndex(inputIndex)),
detail::To3D(connectivity.GetPointDimensions()))
, InputIndex(inIndex)
, OutputIndex(outIndex)
, ThreadIndex(threadIndex)
, InputIndex(inputIndex)
, OutputIndex(outputIndex)
, VisitIndex(visitIndex)
, GlobalThreadIndexOffset(globalThreadIndexOffset)
{
@ -128,6 +109,9 @@ public:
VTKM_EXEC
const vtkm::exec::BoundaryState& GetBoundaryState() const { return this->State; }
VTKM_EXEC
vtkm::Id GetThreadIndex() const { return this->ThreadIndex; }
VTKM_EXEC
vtkm::Id GetInputIndex() const { return this->InputIndex; }
@ -148,6 +132,7 @@ public:
private:
vtkm::exec::BoundaryState State;
vtkm::Id ThreadIndex;
vtkm::Id InputIndex;
vtkm::Id OutputIndex;
vtkm::IdComponent VisitIndex;

@ -48,9 +48,10 @@ public:
vtkm::Id threadIndex,
vtkm::Id inIndex,
vtkm::IdComponent visitIndex,
vtkm::Id outIndex,
const vtkm::exec::internal::ReduceByKeyLookup<P1, P2, P3>& keyLookup,
vtkm::Id globalThreadIndexOffset = 0)
: Superclass(threadIndex, inIndex, visitIndex, globalThreadIndexOffset)
: Superclass(threadIndex, inIndex, visitIndex, outIndex, globalThreadIndexOffset)
, ValueOffset(keyLookup.Offsets.Get(inIndex))
, NumberOfValues(keyLookup.Counts.Get(inIndex))
{

@ -100,41 +100,20 @@ public:
using CellShapeTag = typename ConnectivityType::CellShapeTag;
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename OutToInArrayType, typename VisitArrayType>
VTKM_EXEC ThreadIndicesTopologyMap(vtkm::Id threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
vtkm::Id inputIndex,
vtkm::IdComponent visitIndex,
vtkm::Id outputIndex,
const ConnectivityType& connectivity,
vtkm::Id globalThreadIndexOffset = 0)
: Superclass(threadIndex,
outToIn.Get(threadIndex),
visit.Get(threadIndex),
globalThreadIndexOffset)
: Superclass(threadIndex, inputIndex, visitIndex, outputIndex, globalThreadIndexOffset)
// The connectivity is stored in the invocation parameter at the given
// input domain index. If this class is being used correctly, the type
// of the domain will match the connectivity type used here. If there is
// a compile error here about a type mismatch, chances are a worklet has
// set its input domain incorrectly.
, IndicesFrom(connectivity.GetIndices(outToIn.Get(threadIndex)))
, CellShape(connectivity.GetCellShape(outToIn.Get(threadIndex)))
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
ThreadIndicesTopologyMap(vtkm::Id threadIndex,
vtkm::Id inIndex,
vtkm::IdComponent visitIndex,
const ConnectivityType& connectivity,
vtkm::Id globalThreadIndexOffset = 0)
: Superclass(threadIndex, inIndex, visitIndex, globalThreadIndexOffset)
// The connectivity is stored in the invocation parameter at the given
// input domain index. If this class is being used correctly, the type
// of the domain will match the connectivity type used here. If there is
// a compile error here about a type mismatch, chances are a worklet has
// set its input domain incorrectly.
, IndicesFrom(connectivity.GetIndices(inIndex))
, CellShape(connectivity.GetCellShape(inIndex))
, IndicesFrom(connectivity.GetIndices(inputIndex))
, CellShape(connectivity.GetCellShape(inputIndex))
{
}
@ -187,61 +166,51 @@ public:
using CellShapeTag = typename ConnectivityType::CellShapeTag;
using LogicalIndexType = typename ConnectivityType::SchedulingRangeType;
template <typename OutToInArrayType, typename VisitArrayType>
VTKM_EXEC ThreadIndicesTopologyMap(vtkm::Id threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
vtkm::Id inIndex,
vtkm::IdComponent visitIndex,
vtkm::Id outIndex,
const ConnectivityType& connectivity,
vtkm::Id globalThreadIndexOffset = 0)
{
this->InputIndex = outToIn.Get(threadIndex);
this->OutputIndex = threadIndex;
this->VisitIndex = visit.Get(threadIndex);
this->ThreadIndex = threadIndex;
this->InputIndex = inIndex;
this->VisitIndex = visitIndex;
this->OutputIndex = outIndex;
this->LogicalIndex = connectivity.FlatToLogicalToIndex(this->InputIndex);
this->IndicesFrom = connectivity.GetIndices(this->LogicalIndex);
this->CellShape = connectivity.GetCellShape(this->InputIndex);
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
}
template <typename OutToInArrayType, typename VisitArrayType>
VTKM_EXEC ThreadIndicesTopologyMap(const vtkm::Id3& threadIndex,
const OutToInArrayType&,
const VisitArrayType& visit,
const ConnectivityType& connectivity,
const vtkm::Id globalThreadIndexOffset = 0)
{
// We currently only support multidimensional indices on one-to-one input-
// to-output mappings. (We don't have a use case otherwise.)
// that is why the OutToInArrayType is ignored
// That is why we treat teh threadIndex as also the inputIndex and outputIndex
const LogicalIndexType logicalIndex = detail::Deflate(threadIndex, LogicalIndexType());
const vtkm::Id index = connectivity.LogicalToFlatToIndex(logicalIndex);
this->ThreadIndex = index;
this->InputIndex = index;
this->OutputIndex = index;
this->VisitIndex = visit.Get(index);
this->VisitIndex = 0;
this->LogicalIndex = logicalIndex;
this->IndicesFrom = connectivity.GetIndices(logicalIndex);
this->CellShape = connectivity.GetCellShape(index);
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
}
VTKM_SUPPRESS_EXEC_WARNINGS
/// \brief The index of the thread or work invocation.
///
/// This index refers to which instance of the worklet is being invoked. Every invocation of the
/// worklet has a unique thread index. This is also called the work index depending on the
/// context.
///
VTKM_EXEC
ThreadIndicesTopologyMap(vtkm::Id threadIndex,
vtkm::Id vtkmNotUsed(inIndex),
vtkm::IdComponent visitIndex,
const ConnectivityType& connectivity,
vtkm::Id globalThreadIndexOffset = 0)
{
this->InputIndex = threadIndex;
this->OutputIndex = threadIndex;
this->VisitIndex = visitIndex;
this->LogicalIndex = connectivity.FlatToLogicalToIndex(this->InputIndex);
this->IndicesFrom = connectivity.GetIndices(this->LogicalIndex);
this->CellShape = connectivity.GetCellShape(this->InputIndex);
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
}
vtkm::Id GetThreadIndex() const { return this->ThreadIndex; }
/// \brief The logical index into the input domain.
///
@ -321,9 +290,10 @@ public:
CellShapeTag GetCellShape() const { return this->CellShape; }
private:
vtkm::Id ThreadIndex;
vtkm::Id InputIndex;
vtkm::Id OutputIndex;
vtkm::IdComponent VisitIndex;
vtkm::Id OutputIndex;
LogicalIndexType LogicalIndex;
IndicesFromType IndicesFrom;
CellShapeTag CellShape;
@ -351,35 +321,17 @@ public:
using CellShapeTag = typename ConnectivityType::CellShapeTag;
using LogicalIndexType = typename ConnectivityType::SchedulingRangeType;
template <typename OutToInArrayType, typename VisitArrayType>
VTKM_EXEC ThreadIndicesTopologyMap(vtkm::Id threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
vtkm::Id inputIndex,
vtkm::IdComponent visitIndex,
vtkm::Id outputIndex,
const PermutedConnectivityType& permutation,
vtkm::Id globalThreadIndexOffset = 0)
{
this->InputIndex = outToIn.Get(threadIndex);
this->OutputIndex = threadIndex;
this->VisitIndex = visit.Get(threadIndex);
const vtkm::Id permutedIndex = permutation.Portal.Get(this->InputIndex);
this->LogicalIndex = permutation.Connectivity.FlatToLogicalToIndex(permutedIndex);
this->IndicesFrom = permutation.Connectivity.GetIndices(this->LogicalIndex);
this->CellShape = permutation.Connectivity.GetCellShape(permutedIndex);
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
ThreadIndicesTopologyMap(vtkm::Id threadIndex,
vtkm::Id vtkmNotUsed(inIndex),
vtkm::IdComponent visitIndex,
const PermutedConnectivityType& permutation,
vtkm::Id globalThreadIndexOffset = 0)
{
this->InputIndex = threadIndex;
this->OutputIndex = threadIndex;
this->ThreadIndex = threadIndex;
this->InputIndex = inputIndex;
this->VisitIndex = visitIndex;
this->OutputIndex = outputIndex;
const vtkm::Id permutedIndex = permutation.Portal.Get(this->InputIndex);
this->LogicalIndex = permutation.Connectivity.FlatToLogicalToIndex(permutedIndex);
@ -388,6 +340,15 @@ public:
this->GlobalThreadIndexOffset = globalThreadIndexOffset;
}
/// \brief The index of the thread or work invocation.
///
/// This index refers to which instance of the worklet is being invoked. Every invocation of the
/// worklet has a unique thread index. This is also called the work index depending on the
/// context.
///
VTKM_EXEC
vtkm::Id GetThreadIndex() const { return this->ThreadIndex; }
/// \brief The logical index into the input domain.
///
/// This is similar to \c GetIndex3D except the Vec size matches the actual
@ -466,9 +427,10 @@ public:
CellShapeTag GetCellShape() const { return this->CellShape; }
private:
vtkm::Id ThreadIndex;
vtkm::Id InputIndex;
vtkm::Id OutputIndex;
vtkm::IdComponent VisitIndex;
vtkm::Id OutputIndex;
LogicalIndexType LogicalIndex;
IndicesFromType IndicesFrom;
CellShapeTag CellShape;

@ -45,14 +45,6 @@ struct TestPortal
}
};
struct TestIndexPortal
{
using ValueType = vtkm::Id;
VTKM_EXEC_CONT
ValueType Get(vtkm::Id index) const { return index; }
};
template <typename NeighborhoodType, typename T>
void verify_neighbors(NeighborhoodType neighbors, vtkm::Id index, vtkm::Id3 index3d, T)
{
@ -127,8 +119,7 @@ struct FetchArrayNeighborhoodInTests
for (vtkm::Id i = 0; i < POINT_DIMS[0]; i++, index++)
{
index3d[0] = i;
vtkm::exec::arg::ThreadIndicesPointNeighborhood indices(
index3d, vtkm::internal::NullType(), vtkm::internal::NullType(), connectivity);
vtkm::exec::arg::ThreadIndicesPointNeighborhood indices(index3d, connectivity);
auto neighbors = fetch.Load(indices, execObject);
@ -149,8 +140,7 @@ struct FetchArrayNeighborhoodInTests
//Verify that 1D scheduling works with neighborhoods
for (vtkm::Id index = 0; index < (POINT_DIMS[0] * POINT_DIMS[1] * POINT_DIMS[2]); index++)
{
vtkm::exec::arg::ThreadIndicesPointNeighborhood indices(
index, TestIndexPortal(), TestIndexPortal(), connectivity);
vtkm::exec::arg::ThreadIndicesPointNeighborhood indices(index, index, 0, index, connectivity);
auto neighbors = fetch.Load(indices, execObject);

@ -82,8 +82,12 @@ struct FetchArrayTopologyMapInTests
FetchType fetch;
const vtkm::Id threadIndex = 0;
const vtkm::Id outputIndex = invocation.ThreadToOutputMap.Get(threadIndex);
const vtkm::Id inputIndex = invocation.OutputToInputMap.Get(outputIndex);
const vtkm::IdComponent visitIndex = invocation.VisitArray.Get(outputIndex);
ThreadIndicesType indices(
0, invocation.OutputToInputMap, invocation.VisitArray, invocation.GetInputDomain());
threadIndex, inputIndex, visitIndex, outputIndex, invocation.GetInputDomain());
typename FetchType::ValueType value =
fetch.Load(indices, invocation.Parameters.template GetParameter<ParamIndex>());
@ -125,7 +129,8 @@ struct FetchArrayTopologyMapInTests
BaseFunctionInterface(),
BaseFunctionInterface(),
TestIndexPortal(),
TestZeroPortal()));
TestZeroPortal(),
TestIndexPortal()));
}
};
@ -157,20 +162,32 @@ void TryStructuredPointCoordinatesInvocation(const Invocation& invocation)
vtkm::Vec<vtkm::FloatDefault, 3> origin = TestValue(0, vtkm::Vec<vtkm::FloatDefault, 3>());
vtkm::Vec<vtkm::FloatDefault, 3> spacing = TestValue(1, vtkm::Vec<vtkm::FloatDefault, 3>());
vtkm::VecAxisAlignedPointCoordinates<NumDimensions> value = fetch.Load(
ThreadIndicesType(
0, invocation.OutputToInputMap, invocation.VisitArray, invocation.GetInputDomain()),
invocation.Parameters.template GetParameter<ParamIndex>());
VTKM_TEST_ASSERT(test_equal(value.GetOrigin(), origin), "Bad origin.");
VTKM_TEST_ASSERT(test_equal(value.GetSpacing(), spacing), "Bad spacing.");
{
const vtkm::Id threadIndex = 0;
const vtkm::Id outputIndex = invocation.ThreadToOutputMap.Get(threadIndex);
const vtkm::Id inputIndex = invocation.OutputToInputMap.Get(outputIndex);
const vtkm::IdComponent visitIndex = invocation.VisitArray.Get(outputIndex);
vtkm::VecAxisAlignedPointCoordinates<NumDimensions> value =
fetch.Load(ThreadIndicesType(
threadIndex, inputIndex, visitIndex, outputIndex, invocation.GetInputDomain()),
invocation.Parameters.template GetParameter<ParamIndex>());
VTKM_TEST_ASSERT(test_equal(value.GetOrigin(), origin), "Bad origin.");
VTKM_TEST_ASSERT(test_equal(value.GetSpacing(), spacing), "Bad spacing.");
}
origin[0] += spacing[0];
value = fetch.Load(
ThreadIndicesType(
1, invocation.OutputToInputMap, invocation.VisitArray, invocation.GetInputDomain()),
invocation.Parameters.template GetParameter<ParamIndex>());
VTKM_TEST_ASSERT(test_equal(value.GetOrigin(), origin), "Bad origin.");
VTKM_TEST_ASSERT(test_equal(value.GetSpacing(), spacing), "Bad spacing.");
{
const vtkm::Id threadIndex = 1;
const vtkm::Id outputIndex = invocation.ThreadToOutputMap.Get(threadIndex);
const vtkm::Id inputIndex = invocation.OutputToInputMap.Get(outputIndex);
const vtkm::IdComponent visitIndex = invocation.VisitArray.Get(outputIndex);
vtkm::VecAxisAlignedPointCoordinates<NumDimensions> value =
fetch.Load(ThreadIndicesType(
threadIndex, inputIndex, visitIndex, outputIndex, invocation.GetInputDomain()),
invocation.Parameters.template GetParameter<ParamIndex>());
VTKM_TEST_ASSERT(test_equal(value.GetOrigin(), origin), "Bad origin.");
VTKM_TEST_ASSERT(test_equal(value.GetSpacing(), spacing), "Bad spacing.");
}
}
template <vtkm::IdComponent NumDimensions>
@ -192,14 +209,16 @@ void TryStructuredPointCoordinates(
BaseFunctionInterface(),
BaseFunctionInterface(),
TestIndexPortal(),
TestZeroPortal()));
TestZeroPortal(),
TestIndexPortal()));
// Try again with topology in argument 3 and point coordinates in argument 1
TryStructuredPointCoordinatesInvocation<NumDimensions, 1>(vtkm::internal::make_Invocation<3>(
BaseFunctionInterface().Replace<3>(connectivity).template Replace<1>(coordinates),
BaseFunctionInterface(),
BaseFunctionInterface(),
TestIndexPortal(),
TestZeroPortal()));
TestZeroPortal(),
TestIndexPortal()));
}
void TryStructuredPointCoordinates()

@ -22,6 +22,7 @@
#include <vtkm/Pair.h>
#include <vtkm/Types.h>
#include <vtkm/internal/ArrayPortalValueReference.h>
#include <vtkm/internal/ExportMacros.h>
// Disable warnings we check vtkm for but Thrust does not.
@ -40,57 +41,13 @@ namespace cuda
namespace internal
{
template <class ArrayPortalType>
struct PortalValue
{
using ValueType = typename ArrayPortalType::ValueType;
VTKM_EXEC_CONT
PortalValue(const ArrayPortalType& portal, vtkm::Id index)
: Portal(portal)
, Index(index)
{
}
VTKM_EXEC
void Swap(PortalValue<ArrayPortalType>& rhs) throw()
{
//we need use the explicit type not a proxy temp object
//A proxy temp object would point to the same underlying data structure
//and would not hold the old value of *this once *this was set to rhs.
const ValueType aValue = *this;
*this = rhs;
rhs = aValue;
}
VTKM_EXEC
PortalValue<ArrayPortalType>& operator=(const PortalValue<ArrayPortalType>& rhs)
{
this->Portal.Set(this->Index, rhs.Portal.Get(rhs.Index));
return *this;
}
VTKM_EXEC
ValueType operator=(const ValueType& value) const
{
this->Portal.Set(this->Index, value);
return value;
}
VTKM_EXEC
operator ValueType(void) const { return this->Portal.Get(this->Index); }
const ArrayPortalType& Portal;
vtkm::Id Index;
};
template <class ArrayPortalType>
class IteratorFromArrayPortal
: public ::thrust::iterator_facade<IteratorFromArrayPortal<ArrayPortalType>,
typename ArrayPortalType::ValueType,
::thrust::system::cuda::tag,
::thrust::random_access_traversal_tag,
PortalValue<ArrayPortalType>,
vtkm::internal::ArrayPortalValueReference<ArrayPortalType>,
std::ptrdiff_t>
{
public:
@ -109,9 +66,11 @@ public:
}
VTKM_EXEC
PortalValue<ArrayPortalType> operator[](std::ptrdiff_t idx) const //NEEDS to be signed
vtkm::internal::ArrayPortalValueReference<ArrayPortalType> operator[](
std::ptrdiff_t idx) const //NEEDS to be signed
{
return PortalValue<ArrayPortalType>(this->Portal, this->Index + static_cast<vtkm::Id>(idx));
return vtkm::internal::ArrayPortalValueReference<ArrayPortalType>(
this->Portal, this->Index + static_cast<vtkm::Id>(idx));
}
private:
@ -122,9 +81,9 @@ private:
friend class ::thrust::iterator_core_access;
VTKM_EXEC
PortalValue<ArrayPortalType> dereference() const
vtkm::internal::ArrayPortalValueReference<ArrayPortalType> dereference() const
{
return PortalValue<ArrayPortalType>(this->Portal, this->Index);
return vtkm::internal::ArrayPortalValueReference<ArrayPortalType>(this->Portal, this->Index);
}
VTKM_EXEC
@ -167,7 +126,8 @@ private:
//
//But for vtk-m we pass in facade objects, which are passed by value, but
//must be treated as references. So do to do that properly we need to specialize
//is_non_const_reference to state a PortalValue by value is valid for writing
//is_non_const_reference to state an ArrayPortalValueReference by value is valid
//for writing
namespace thrust
{
namespace detail
@ -177,7 +137,7 @@ template <typename T>
struct is_non_const_reference;
template <typename T>
struct is_non_const_reference<vtkm::exec::cuda::internal::PortalValue<T>>
struct is_non_const_reference<vtkm::internal::ArrayPortalValueReference<T>>
: thrust::detail::true_type
{
};

@ -87,6 +87,7 @@ public:
this->Worklet.GetThreadIndices(index,
this->Invocation.OutputToInputMap,
this->Invocation.VisitArray,
this->Invocation.ThreadToOutputMap,
this->Invocation.GetInputDomain(),
this->GlobalIndexOffset));
}
@ -157,6 +158,7 @@ public:
this->Worklet.GetThreadIndices(index,
this->Invocation.OutputToInputMap,
this->Invocation.VisitArray,
this->Invocation.ThreadToOutputMap,
this->Invocation.GetInputDomain(),
this->GlobalIndexOffset));
}

@ -42,7 +42,7 @@ namespace internal
// Unary function object wrapper which can detect and handle calling the
// wrapped operator with complex value types such as
// PortalValue which happen when passed an input array that
// ArrayPortalValueReference which happen when passed an input array that
// is implicit.
template <typename T_, typename Function>
struct WrappedUnaryPredicate
@ -70,9 +70,9 @@ struct WrappedUnaryPredicate
VTKM_EXEC bool operator()(const T& x) const { return m_f(x); }
template <typename U>
VTKM_EXEC bool operator()(const PortalValue<U>& x) const
VTKM_EXEC bool operator()(const vtkm::internal::ArrayPortalValueReference<U>& x) const
{
return m_f((T)x);
return m_f(x.Get());
}
VTKM_EXEC bool operator()(const T* x) const { return m_f(*x); }
@ -80,7 +80,7 @@ struct WrappedUnaryPredicate
// Binary function object wrapper which can detect and handle calling the
// wrapped operator with complex value types such as
// PortalValue which happen when passed an input array that
// ArrayPortalValueReference which happen when passed an input array that
// is implicit.
template <typename T_, typename Function>
struct WrappedBinaryOperator
@ -109,27 +109,24 @@ struct WrappedBinaryOperator
VTKM_EXEC T operator()(const T& x, const T& y) const { return m_f(x, y); }
template <typename U>
VTKM_EXEC T operator()(const T& x, const PortalValue<U>& y) const
VTKM_EXEC T operator()(const T& x, const vtkm::internal::ArrayPortalValueReference<U>& y) const
{
// to support proper implicit conversion, and avoid overload
// ambiguities.
T conv_y = y;
return m_f(x, conv_y);
return m_f(x, y.Get());
}
template <typename U>
VTKM_EXEC T operator()(const PortalValue<U>& x, const T& y) const
VTKM_EXEC T operator()(const vtkm::internal::ArrayPortalValueReference<U>& x, const T& y) const
{
T conv_x = x;
return m_f(conv_x, y);
return m_f(x.Get(), y);
}
template <typename U, typename V>
VTKM_EXEC T operator()(const PortalValue<U>& x, const PortalValue<V>& y) const
VTKM_EXEC T operator()(const vtkm::internal::ArrayPortalValueReference<U>& x,
const vtkm::internal::ArrayPortalValueReference<V>& y) const
{
T conv_x = x;
T conv_y = y;
return m_f(conv_x, conv_y);
return m_f(x.Get(), y.Get());
}
VTKM_EXEC T operator()(const T* const x, const T& y) const { return m_f(*x, y); }
@ -166,21 +163,22 @@ struct WrappedBinaryPredicate
VTKM_EXEC bool operator()(const T& x, const T& y) const { return m_f(x, y); }
template <typename U>
VTKM_EXEC bool operator()(const T& x, const PortalValue<U>& y) const
VTKM_EXEC bool operator()(const T& x, const vtkm::internal::ArrayPortalValueReference<U>& y) const
{
return m_f(x, (T)y);
return m_f(x, y.Get());
}
template <typename U>
VTKM_EXEC bool operator()(const PortalValue<U>& x, const T& y) const
VTKM_EXEC bool operator()(const vtkm::internal::ArrayPortalValueReference<U>& x, const T& y) const
{
return m_f((T)x, y);
return m_f(x.Get(), y);
}
template <typename U, typename V>
VTKM_EXEC bool operator()(const PortalValue<U>& x, const PortalValue<V>& y) const
VTKM_EXEC bool operator()(const vtkm::internal::ArrayPortalValueReference<U>& x,
const vtkm::internal::ArrayPortalValueReference<V>& y) const
{
return m_f((T)x, (T)y);
return m_f(x.Get(), y.Get());
}
VTKM_EXEC bool operator()(const T* const x, const T& y) const { return m_f(*x, y); }

@ -74,6 +74,13 @@ struct MyVisitArrayPortal
vtkm::IdComponent Get(vtkm::Id) const { return 1; }
};
struct MyThreadToOutputMapPortal
{
using ValueType = vtkm::Id;
VTKM_EXEC_CONT
vtkm::Id Get(vtkm::Id index) const { return index; }
};
struct TestFetchTagInput
{
};
@ -169,14 +176,16 @@ using InvocationType1 = vtkm::internal::Invocation<ExecutionParameterInterface,
TestExecutionInterface1,
1,
MyOutputToInputMapPortal,
MyVisitArrayPortal>;
MyVisitArrayPortal,
MyThreadToOutputMapPortal>;
using InvocationType2 = vtkm::internal::Invocation<ExecutionParameterInterface,
TestControlInterface,
TestExecutionInterface2,
1,
MyOutputToInputMapPortal,
MyVisitArrayPortal>;
MyVisitArrayPortal,
MyThreadToOutputMapPortal>;
template <typename TaskType>
static __global__ void ScheduleTaskStrided(TaskType task, vtkm::Id start, vtkm::Id end)
@ -202,17 +211,20 @@ struct TestWorkletProxy : vtkm::exec::FunctorBase
template <typename T,
typename OutToInArrayType,
typename VisitArrayType,
typename ThreadToOutArrayType,
typename InputDomainType,
typename G>
VTKM_EXEC vtkm::exec::arg::ThreadIndicesBasic GetThreadIndices(
const T& threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
const ThreadToOutArrayType& threadToOut,
const InputDomainType&,
const G& globalThreadIndexOffset) const
{
vtkm::Id outIndex = threadToOut.Get(threadIndex);
return vtkm::exec::arg::ThreadIndicesBasic(
threadIndex, outToIn.Get(threadIndex), visit.Get(threadIndex), globalThreadIndexOffset);
threadIndex, outToIn.Get(outIndex), visit.Get(outIndex), outIndex, globalThreadIndexOffset);
}
};
@ -227,17 +239,20 @@ struct TestWorkletErrorProxy : vtkm::exec::FunctorBase
template <typename T,
typename OutToInArrayType,
typename VisitArrayType,
typename ThreadToOutArrayType,
typename InputDomainType,
typename G>
VTKM_EXEC vtkm::exec::arg::ThreadIndicesBasic GetThreadIndices(
const T& threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
const ThreadToOutArrayType& threadToOut,
const InputDomainType&,
const G& globalThreadIndexOffset) const
{
vtkm::Id outIndex = threadToOut.Get(threadIndex);
return vtkm::exec::arg::ThreadIndicesBasic(
threadIndex, outToIn.Get(threadIndex), visit.Get(threadIndex), globalThreadIndexOffset);
threadIndex, outToIn.Get(outIndex), visit.Get(outIndex), outIndex, globalThreadIndexOffset);
}
};

@ -65,13 +65,15 @@ public:
VTKM_EXEC void operator()(T index) const
{
//Todo: rename this function to DoTaskSingular
detail::DoWorkletInvokeFunctor(this->Worklet,
this->Invocation,
this->Worklet.GetThreadIndices(index,
this->Invocation.OutputToInputMap,
this->Invocation.VisitArray,
this->Invocation.GetInputDomain(),
GlobalIndexOffset));
detail::DoWorkletInvokeFunctor(
this->Worklet,
this->Invocation,
this->Worklet.GetThreadIndices(index,
this->Invocation.OutputToInputMap,
this->Invocation.VisitArray,
this->Invocation.ThreadToOutputMap,
this->Invocation.GetInputDomain(),
GlobalIndexOffset));
}
private:

@ -91,6 +91,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1>
@ -101,7 +102,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -147,7 +148,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1>
VTKM_EXEC void DoWorkletInvokeFunctor(
@ -157,7 +158,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -197,6 +198,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -208,7 +210,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -264,7 +266,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2>
@ -275,7 +277,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -325,6 +327,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -337,7 +340,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -403,7 +406,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -415,7 +418,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -475,6 +478,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -488,7 +492,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -564,7 +568,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -577,7 +581,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -647,6 +651,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -661,7 +666,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -747,7 +752,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -761,7 +766,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -841,6 +846,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -856,7 +862,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -952,7 +958,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -967,7 +973,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -1057,6 +1063,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -1073,7 +1080,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -1179,7 +1186,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -1195,7 +1202,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -1295,6 +1302,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -1312,7 +1320,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -1428,7 +1436,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -1445,7 +1453,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -1555,6 +1563,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -1573,7 +1582,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -1699,7 +1708,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -1717,7 +1726,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -1837,6 +1846,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -1856,7 +1866,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -1992,7 +2002,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -2011,7 +2021,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -2141,6 +2151,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -2161,7 +2172,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -2307,7 +2318,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -2327,7 +2338,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -2467,6 +2478,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -2488,7 +2500,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -2644,7 +2656,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -2665,7 +2677,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -2815,6 +2827,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -2837,7 +2850,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -3003,7 +3016,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -3025,7 +3038,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -3185,6 +3198,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -3208,7 +3222,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -3384,7 +3398,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -3407,7 +3421,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -3577,6 +3591,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -3601,7 +3616,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -3787,7 +3802,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -3811,7 +3826,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -3991,6 +4006,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -4016,7 +4032,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -4212,7 +4228,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -4237,7 +4253,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -4427,6 +4443,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -4453,7 +4470,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -4659,7 +4676,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -4685,7 +4702,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -4885,6 +4902,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -4912,7 +4930,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -5128,7 +5146,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -5155,7 +5173,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -5365,6 +5383,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -5393,7 +5412,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -5619,7 +5638,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -5647,7 +5666,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =
@ -5867,6 +5886,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename R,
typename P1,
@ -5896,7 +5916,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -6132,7 +6152,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
typename P1,
typename P2,
@ -6161,7 +6181,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =

@ -153,6 +153,7 @@ template <typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename ThreadToOutputMapType,
typename ThreadIndicesType,
$template_params(num_params)>
VTKM_EXEC void DoWorkletInvokeFunctor(
@ -162,7 +163,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<$signature(num_params)>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation = vtkm::internal::Invocation<ParameterInterface,
@ -212,7 +213,7 @@ template <typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename OutputToInputMapType,
typename VisitArrayType,
typename VisitArrayType, typename ThreadToOutputMapType,
typename ThreadIndicesType,
$template_params(num_params, start=1)>
VTKM_EXEC void DoWorkletInvokeFunctor(
@ -222,7 +223,7 @@ VTKM_EXEC void DoWorkletInvokeFunctor(
vtkm::internal::FunctionInterface<$signature(num_params, return_type='void')>,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>& invocation,
VisitArrayType, ThreadToOutputMapType>& invocation,
const ThreadIndicesType& threadIndices)
{
using Invocation =

@ -76,6 +76,13 @@ struct MyVisitArrayPortal
vtkm::IdComponent Get(vtkm::Id) const { return 1; }
};
struct MyThreadToOutputMapPortal
{
using ValueType = vtkm::Id;
VTKM_EXEC_CONT
vtkm::Id Get(vtkm::Id index) const { return index; }
};
struct TestFetchTagInput
{
};
@ -181,14 +188,16 @@ using InvocationType1 = vtkm::internal::Invocation<ExecutionParameterInterface,
TestExecutionInterface1,
1,
MyOutputToInputMapPortal,
MyVisitArrayPortal>;
MyVisitArrayPortal,
MyThreadToOutputMapPortal>;
using InvocationType2 = vtkm::internal::Invocation<ExecutionParameterInterface,
TestControlInterface,
TestExecutionInterface2,
1,
MyOutputToInputMapPortal,
MyVisitArrayPortal>;
MyVisitArrayPortal,
MyThreadToOutputMapPortal>;
// Not a full worklet, but provides operators that we expect in a worklet.
struct TestWorkletProxy : vtkm::exec::FunctorBase
@ -201,33 +210,42 @@ struct TestWorkletProxy : vtkm::exec::FunctorBase
template <typename OutToInArrayType,
typename VisitArrayType,
typename ThreadToOutputArrayType,
typename InputDomainType,
typename G>
VTKM_EXEC vtkm::exec::arg::ThreadIndicesBasic GetThreadIndices(
const vtkm::Id& threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
const ThreadToOutputArrayType& threadToOut,
const InputDomainType&,
const G& globalThreadIndexOffset) const
{
const vtkm::Id outIndex = threadToOut.Get(threadIndex);
return vtkm::exec::arg::ThreadIndicesBasic(
threadIndex, outToIn.Get(threadIndex), visit.Get(threadIndex), globalThreadIndexOffset);
threadIndex, outToIn.Get(outIndex), visit.Get(outIndex), outIndex, globalThreadIndexOffset);
}
template <typename OutToInArrayType,
typename VisitArrayType,
typename ThreadToOutArrayType,
typename InputDomainType,
typename G>
VTKM_EXEC vtkm::exec::arg::ThreadIndicesBasic GetThreadIndices(
const vtkm::Id3& threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
const ThreadToOutArrayType& threadToOut,
const InputDomainType&,
const G& globalThreadIndexOffset) const
{
const vtkm::Id index = vtkm::Dot(threadIndex, vtkm::Id3(1, 8, 64));
return vtkm::exec::arg::ThreadIndicesBasic(
index, outToIn.Get(index), visit.Get(index), globalThreadIndexOffset);
const vtkm::Id flatThreadIndex = vtkm::Dot(threadIndex, vtkm::Id3(1, 8, 64));
const vtkm::Id outIndex = threadToOut.Get(flatThreadIndex);
return vtkm::exec::arg::ThreadIndicesBasic(flatThreadIndex,
outToIn.Get(outIndex),
visit.Get(outIndex),
outIndex,
globalThreadIndexOffset);
}
};
@ -241,33 +259,42 @@ struct TestWorkletErrorProxy : vtkm::exec::FunctorBase
template <typename OutToInArrayType,
typename VisitArrayType,
typename ThreadToOutArrayType,
typename InputDomainType,
typename G>
VTKM_EXEC vtkm::exec::arg::ThreadIndicesBasic GetThreadIndices(
const vtkm::Id& threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
const ThreadToOutArrayType& threadToOut,
const InputDomainType&,
const G& globalThreadIndexOffset) const
{
const vtkm::Id outIndex = threadToOut.Get(threadIndex);
return vtkm::exec::arg::ThreadIndicesBasic(
threadIndex, outToIn.Get(threadIndex), visit.Get(threadIndex), globalThreadIndexOffset);
threadIndex, outToIn.Get(outIndex), visit.Get(outIndex), outIndex, globalThreadIndexOffset);
}
template <typename OutToInArrayType,
typename VisitArrayType,
typename ThreadToOutputArrayType,
typename InputDomainType,
typename G>
VTKM_EXEC vtkm::exec::arg::ThreadIndicesBasic GetThreadIndices(
const vtkm::Id3& threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
const ThreadToOutputArrayType& threadToOutput,
const InputDomainType&,
const G& globalThreadIndexOffset) const
{
const vtkm::Id index = vtkm::Dot(threadIndex, vtkm::Id3(1, 8, 64));
return vtkm::exec::arg::ThreadIndicesBasic(
index, outToIn.Get(index), visit.Get(index), globalThreadIndexOffset);
const vtkm::Id outputIndex = threadToOutput.Get(index);
return vtkm::exec::arg::ThreadIndicesBasic(index,
outToIn.Get(outputIndex),
visit.Get(outputIndex),
outputIndex,
globalThreadIndexOffset);
}
};

@ -64,6 +64,13 @@ struct MyVisitArrayPortal
vtkm::IdComponent Get(vtkm::Id) const { return 1; }
};
struct MyThreadToOutputMapPortal
{
using ValueType = vtkm::Id;
VTKM_EXEC_CONT
vtkm::Id Get(vtkm::Id index) const { return index; }
};
struct TestFetchTagInput
{
};
@ -159,14 +166,16 @@ using InvocationType1 = vtkm::internal::Invocation<ExecutionParameterInterface,
TestExecutionInterface1,
1,
MyOutputToInputMapPortal,
MyVisitArrayPortal>;
MyVisitArrayPortal,
MyThreadToOutputMapPortal>;
using InvocationType2 = vtkm::internal::Invocation<ExecutionParameterInterface,
TestControlInterface,
TestExecutionInterface2,
1,
MyOutputToInputMapPortal,
MyVisitArrayPortal>;
MyVisitArrayPortal,
MyThreadToOutputMapPortal>;
// Not a full worklet, but provides operators that we expect in a worklet.
struct TestWorkletProxy : vtkm::exec::FunctorBase
@ -180,17 +189,20 @@ struct TestWorkletProxy : vtkm::exec::FunctorBase
template <typename T,
typename OutToInArrayType,
typename VisitArrayType,
typename ThreadToOutArrayType,
typename InputDomainType,
typename G>
VTKM_EXEC vtkm::exec::arg::ThreadIndicesBasic GetThreadIndices(
const T& threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
const ThreadToOutArrayType& threadToOut,
const InputDomainType&,
const G& globalThreadIndexOffset) const
{
const vtkm::Id outIndex = threadToOut.Get(threadIndex);
return vtkm::exec::arg::ThreadIndicesBasic(
threadIndex, outToIn.Get(threadIndex), visit.Get(threadIndex), globalThreadIndexOffset);
threadIndex, outToIn.Get(outIndex), visit.Get(outIndex), outIndex, globalThreadIndexOffset);
}
};
@ -205,17 +217,20 @@ struct TestWorkletErrorProxy : vtkm::exec::FunctorBase
template <typename T,
typename OutToInArrayType,
typename VisitArrayType,
typename ThreadToOutArrayType,
typename InputDomainType,
typename G>
VTKM_EXEC vtkm::exec::arg::ThreadIndicesBasic GetThreadIndices(
const T& threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
const ThreadToOutArrayType& threadToOut,
const InputDomainType&,
const G& globalThreadIndexOffset) const
{
const vtkm::Id outIndex = threadToOut.Get(threadIndex);
return vtkm::exec::arg::ThreadIndicesBasic(
threadIndex, outToIn.Get(threadIndex), visit.Get(threadIndex), globalThreadIndexOffset);
threadIndex, outToIn.Get(outIndex), visit.Get(outIndex), outIndex, globalThreadIndexOffset);
}
};

@ -64,6 +64,13 @@ struct MyVisitArrayPortal
vtkm::IdComponent Get(vtkm::Id) const { return 1; }
};
struct MyThreadToOutputMapPortal
{
using ValueType = vtkm::Id;
VTKM_EXEC_CONT
vtkm::Id Get(vtkm::Id index) const { return index; }
};
struct TestFetchTagInput
{
};
@ -163,28 +170,34 @@ struct TestWorkletProxy : vtkm::exec::FunctorBase
template <typename T,
typename OutToInArrayType,
typename VisitArrayType,
typename ThreadToOutArrayType,
typename InputDomainType,
typename G>
VTKM_EXEC vtkm::exec::arg::ThreadIndicesBasic GetThreadIndices(
const T& threadIndex,
const OutToInArrayType& outToIn,
const VisitArrayType& visit,
const ThreadToOutArrayType& threadToOut,
const InputDomainType&,
const G& globalThreadIndexOffset) const
{
const vtkm::Id outIndex = threadToOut.Get(threadIndex);
return vtkm::exec::arg::ThreadIndicesBasic(
threadIndex, outToIn.Get(threadIndex), visit.Get(threadIndex), globalThreadIndexOffset);
threadIndex, outToIn.Get(outIndex), visit.Get(outIndex), outIndex, globalThreadIndexOffset);
}
};
template <typename Invocation>
void CallDoWorkletInvokeFunctor(const Invocation& invocation, vtkm::Id index)
{
const vtkm::Id outputIndex = invocation.ThreadToOutputMap.Get(index);
vtkm::exec::internal::detail::DoWorkletInvokeFunctor(
TestWorkletProxy(),
invocation,
vtkm::exec::arg::ThreadIndicesBasic(
index, invocation.OutputToInputMap.Get(index), invocation.VisitArray.Get(index)));
vtkm::exec::arg::ThreadIndicesBasic(index,
invocation.OutputToInputMap.Get(outputIndex),
invocation.VisitArray.Get(outputIndex),
outputIndex));
}
void TestDoWorkletInvoke()
@ -204,7 +217,8 @@ void TestDoWorkletInvoke()
TestControlInterface(),
TestExecutionInterface1(),
MyOutputToInputMapPortal(),
MyVisitArrayPortal()),
MyVisitArrayPortal(),
MyThreadToOutputMapPortal()),
1);
VTKM_TEST_ASSERT(inputTestValue == 5, "Input value changed.");
VTKM_TEST_ASSERT(outputTestValue == inputTestValue + 100 + 30, "Output value not set right.");
@ -216,7 +230,8 @@ void TestDoWorkletInvoke()
TestControlInterface(),
TestExecutionInterface2(),
MyOutputToInputMapPortal(),
MyVisitArrayPortal()),
MyVisitArrayPortal(),
MyThreadToOutputMapPortal()),
2);
VTKM_TEST_ASSERT(inputTestValue == 6, "Input value changed.");
VTKM_TEST_ASSERT(outputTestValue == inputTestValue + 200 + 30 * 2, "Output value not set right.");

@ -66,6 +66,7 @@ void VTKM_NEVER_EXPORT TaskTiling1DExecute(void* w,
worklet->GetThreadIndices(index,
invocation->OutputToInputMap,
invocation->VisitArray,
invocation->ThreadToOutputMap,
invocation->GetInputDomain(),
globalIndexOffset));
}
@ -110,6 +111,7 @@ void VTKM_NEVER_EXPORT TaskTiling3DExecute(void* w,
worklet->GetThreadIndices(index,
invocation->OutputToInputMap,
invocation->VisitArray,
invocation->ThreadToOutputMap,
invocation->GetInputDomain(),
globalIndexOffset));
}

@ -281,7 +281,7 @@ inline VTKM_CONT vtkm::cont::DataSet Filter<Derived>::Execute(
const vtkm::filter::PolicyBase<DerivedPolicy>& policy)
{
VTKM_LOG_SCOPE(
vtkm::cont::LogLevel::Perf, "Filter: '%s'", vtkm::cont::TypeName<Derived>().c_str());
vtkm::cont::LogLevel::Perf, "Filter: '%s'", vtkm::cont::TypeToString<Derived>().c_str());
Derived* self = static_cast<Derived*>(this);
vtkm::cont::MultiBlock output = self->Execute(vtkm::cont::MultiBlock(input), policy);
@ -301,7 +301,7 @@ inline VTKM_CONT vtkm::cont::MultiBlock Filter<Derived>::Execute(
{
VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf,
"Filter (MultiBlock): '%s'",
vtkm::cont::TypeName<Derived>().c_str());
vtkm::cont::TypeToString<Derived>().c_str());
Derived* self = static_cast<Derived*>(this);

@ -66,8 +66,7 @@ template <>
class FilterTraits<ZFPCompressor1D>
{
public:
struct TypeListTagMCScalars
: vtkm::ListTagBase<vtkm::UInt8, vtkm::Int8, vtkm::Float32, vtkm::Float64>
struct TypeListTagMCScalars : vtkm::ListTagBase<vtkm::Int32, vtkm::Float32, vtkm::Float64>
{
};
using InputFieldTypeList = TypeListTagMCScalars;

@ -66,8 +66,7 @@ template <>
class FilterTraits<ZFPCompressor2D>
{
public:
struct TypeListTagMCScalars
: vtkm::ListTagBase<vtkm::UInt8, vtkm::Int8, vtkm::Float32, vtkm::Float64>
struct TypeListTagMCScalars : vtkm::ListTagBase<vtkm::Int32, vtkm::Float32, vtkm::Float64>
{
};
using InputFieldTypeList = TypeListTagMCScalars;

@ -66,8 +66,7 @@ template <>
class FilterTraits<ZFPCompressor3D>
{
public:
struct TypeListTagMCScalars
: vtkm::ListTagBase<vtkm::UInt8, vtkm::Int8, vtkm::Float32, vtkm::Float64>
struct TypeListTagMCScalars : vtkm::ListTagBase<vtkm::Int32, vtkm::Float32, vtkm::Float64>
{
};
using InputFieldTypeList = TypeListTagMCScalars;

@ -74,7 +74,7 @@ class FilterTraits<ZFPDecompressor1D>
{
public:
struct TypeListTagZFP1DScalars
: vtkm::ListTagBase<vtkm::UInt8, vtkm::Int8, vtkm::Int64, vtkm::Float32, vtkm::Float64>
: vtkm::ListTagBase<vtkm::Int32, vtkm::Int64, vtkm::Float32, vtkm::Float64>
{
};
using InputFieldTypeList = TypeListTagZFP1DScalars;

@ -74,7 +74,7 @@ class FilterTraits<ZFPDecompressor2D>
{
public:
struct TypeListTagZFP1DScalars
: vtkm::ListTagBase<vtkm::UInt8, vtkm::Int8, vtkm::Int64, vtkm::Float32, vtkm::Float64>
: vtkm::ListTagBase<vtkm::Int32, vtkm::Int64, vtkm::Float32, vtkm::Float64>
{
};
using InputFieldTypeList = TypeListTagZFP1DScalars;

@ -74,7 +74,7 @@ class FilterTraits<ZFPDecompressor3D>
{
public:
struct TypeListTagZFP3DScalars
: vtkm::ListTagBase<vtkm::UInt8, vtkm::Int8, vtkm::Int64, vtkm::Float32, vtkm::Float64>
: vtkm::ListTagBase<vtkm::Int32, vtkm::Int64, vtkm::Float32, vtkm::Float64>
{
};
using InputFieldTypeList = TypeListTagZFP3DScalars;

@ -57,8 +57,30 @@ struct ArrayPortalValueReference
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ValueType Get() const { return this->Portal.Get(this->Index); }
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
operator ValueType(void) const { return this->Portal.Get(this->Index); }
// Declaring Set as const seems a little weird because we are changing the value. But remember
// that ArrayPortalReference is only a reference class. The reference itself does not change,
// just the thing that it is referencing. So declaring as const is correct and necessary so that
// you can set the value of a reference returned from a function (which is a right hand side
// value).
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
void Set(ValueType&& value) const { this->Portal.Set(this->Index, std::move(value)); }
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
void Set(const ValueType& value) const { this->Portal.Set(this->Index, value); }
VTKM_CONT
void Swap(ArrayPortalValueReference<ArrayPortalType>& rhs) throw()
void Swap(const ArrayPortalValueReference<ArrayPortalType>& rhs) const throw()
{
//we need use the explicit type not a proxy temp object
//A proxy temp object would point to the same underlying data structure
@ -68,27 +90,231 @@ struct ArrayPortalValueReference
rhs = aValue;
}
// Declaring operator= as const seems a little weird because we are changing the value. But
// remember that ArrayPortalReference is only a reference class. The reference itself does not
// change, just the thing that it is referencing. So declaring as const is correct and necessary
// so that you can set the value of a reference returned from a function (which is a right hand
// side value).
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ArrayPortalValueReference<ArrayPortalType>& operator=(
const ArrayPortalValueReference<ArrayPortalType>& rhs)
const ArrayPortalValueReference<ArrayPortalType>& operator=(ValueType&& value) const
{
this->Portal.Set(this->Index, rhs.Portal.Get(rhs.Index));
this->Set(std::move(value));
return *this;
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ValueType operator=(const ValueType& value)
const ArrayPortalValueReference<ArrayPortalType>& operator=(const ValueType& value) const
{
this->Portal.Set(this->Index, value);
return value;
this->Set(value);
return *this;
}
// This special overload of the operator= is to override the behavior of the default operator=
// (which has the wrong behavior) with behavior consistent with the other operator= methods.
// It is not declared const because the default operator= is not declared const. If you try
// to do this assignment with a const object, you will get one of the operator= above.
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT ArrayPortalValueReference<ArrayPortalType>& operator=(
const ArrayPortalValueReference<ArrayPortalType>& rhs)
{
this->Set(static_cast<ValueType>(rhs.Portal.Get(rhs.Index)));
return *this;
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
operator ValueType(void) const { return this->Portal.Get(this->Index); }
template <typename T>
VTKM_EXEC_CONT ValueType operator+=(const T& rhs) const
{
ValueType lhs = this->Get();
lhs += rhs;
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator+=(const ArrayPortalValueReference<T>& rhs) const
{
ValueType lhs = this->Get();
lhs += rhs.Get();
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator-=(const T& rhs) const
{
ValueType lhs = this->Get();
lhs -= rhs;
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator-=(const ArrayPortalValueReference<T>& rhs) const
{
ValueType lhs = this->Get();
lhs -= rhs.Get();
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator*=(const T& rhs) const
{
ValueType lhs = this->Get();
lhs *= rhs;
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator*=(const ArrayPortalValueReference<T>& rhs) const
{
ValueType lhs = this->Get();
lhs *= rhs.Get();
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator/=(const T& rhs) const
{
ValueType lhs = this->Get();
lhs /= rhs;
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator/=(const ArrayPortalValueReference<T>& rhs) const
{
ValueType lhs = this->Get();
lhs /= rhs.Get();
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator%=(const T& rhs) const
{
ValueType lhs = this->Get();
lhs %= rhs;
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator%=(const ArrayPortalValueReference<T>& rhs) const
{
ValueType lhs = this->Get();
lhs %= rhs.Get();
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator&=(const T& rhs) const
{
ValueType lhs = this->Get();
lhs &= rhs;
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator&=(const ArrayPortalValueReference<T>& rhs) const
{
ValueType lhs = this->Get();
lhs &= rhs.Get();
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator|=(const T& rhs) const
{
ValueType lhs = this->Get();
lhs |= rhs;
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator|=(const ArrayPortalValueReference<T>& rhs) const
{
ValueType lhs = this->Get();
lhs |= rhs.Get();
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator^=(const T& rhs) const
{
ValueType lhs = this->Get();
lhs ^= rhs;
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator^=(const ArrayPortalValueReference<T>& rhs) const
{
ValueType lhs = this->Get();
lhs ^= rhs.Get();
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator>>=(const T& rhs) const
{
ValueType lhs = this->Get();
lhs >>= rhs;
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator>>=(const ArrayPortalValueReference<T>& rhs) const
{
ValueType lhs = this->Get();
lhs >>= rhs.Get();
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator<<=(const T& rhs) const
{
ValueType lhs = this->Get();
lhs <<= rhs;
this->Set(lhs);
return lhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename T>
VTKM_EXEC_CONT ValueType operator<<=(const ArrayPortalValueReference<T>& rhs) const
{
ValueType lhs = this->Get();
lhs <<= rhs.Get();
this->Set(lhs);
return lhs;
}
private:
const ArrayPortalType& Portal;
vtkm::Id Index;
};
@ -96,14 +322,14 @@ struct ArrayPortalValueReference
//implement a custom swap function, since the std::swap won't work
//since we return RValues instead of Lvalues
template <typename T>
void swap(vtkm::internal::ArrayPortalValueReference<T> a,
vtkm::internal::ArrayPortalValueReference<T> b)
void swap(const vtkm::internal::ArrayPortalValueReference<T>& a,
const vtkm::internal::ArrayPortalValueReference<T>& b)
{
a.Swap(b);
}
template <typename T>
void swap(vtkm::internal::ArrayPortalValueReference<T> a,
void swap(const vtkm::internal::ArrayPortalValueReference<T>& a,
typename vtkm::internal::ArrayPortalValueReference<T>::ValueType& b)
{
using ValueType = typename vtkm::internal::ArrayPortalValueReference<T>::ValueType;
@ -114,13 +340,484 @@ void swap(vtkm::internal::ArrayPortalValueReference<T> a,
template <typename T>
void swap(typename vtkm::internal::ArrayPortalValueReference<T>::ValueType& a,
vtkm::internal::ArrayPortalValueReference<T> b)
const vtkm::internal::ArrayPortalValueReference<T>& b)
{
using ValueType = typename vtkm::internal::ArrayPortalValueReference<T>::ValueType;
const ValueType tmp = b;
b = a;
a = tmp;
}
// The reason why all the operators on ArrayPortalValueReference are defined outside of the class
// is so that in the case that the operator in question is not defined in the value type, these
// operators will not be instantiated (and therefore cause a compile error) unless they are
// directly used (in which case a compile error is appropriate).
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator==(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() == rhs)
{
return lhs.Get() == rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator==(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() == rhs.Get())
{
return lhs.Get() == rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator==(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs == rhs.Get())
{
return lhs == rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator!=(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() != rhs)
{
return lhs.Get() != rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator!=(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() != rhs.Get())
{
return lhs.Get() != rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator!=(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs != rhs.Get())
{
return lhs != rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator<(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() < rhs)
{
return lhs.Get() < rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator<(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() < rhs.Get())
{
return lhs.Get() < rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator<(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs < rhs.Get())
{
return lhs < rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator>(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() > rhs)
{
return lhs.Get() > rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator>(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() > rhs.Get())
{
return lhs.Get() > rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator>(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs > rhs.Get())
{
return lhs > rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator<=(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() <= rhs)
{
return lhs.Get() <= rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator<=(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() <= rhs.Get())
{
return lhs.Get() <= rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator<=(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs <= rhs.Get())
{
return lhs <= rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator>=(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() >= rhs)
{
return lhs.Get() >= rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator>=(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() >= rhs.Get())
{
return lhs.Get() >= rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator>=(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs >= rhs.Get())
{
return lhs >= rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator+(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() + rhs)
{
return lhs.Get() + rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator+(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() + rhs.Get())
{
return lhs.Get() + rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator+(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs + rhs.Get())
{
return lhs + rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator-(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() - rhs)
{
return lhs.Get() - rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator-(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() - rhs.Get())
{
return lhs.Get() - rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator-(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs - rhs.Get())
{
return lhs - rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator*(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() * rhs)
{
return lhs.Get() * rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator*(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() * rhs.Get())
{
return lhs.Get() * rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator*(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs * rhs.Get())
{
return lhs * rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator/(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() / rhs)
{
return lhs.Get() / rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator/(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() / rhs.Get())
{
return lhs.Get() / rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator/(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs / rhs.Get())
{
return lhs / rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator%(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() % rhs)
{
return lhs.Get() % rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator%(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() % rhs.Get())
{
return lhs.Get() % rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator%(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs % rhs.Get())
{
return lhs % rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator^(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() ^ rhs)
{
return lhs.Get() ^ rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator^(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() ^ rhs.Get())
{
return lhs.Get() ^ rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator^(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs ^ rhs.Get())
{
return lhs ^ rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator|(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() | rhs)
{
return lhs.Get() | rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator|(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() | rhs.Get())
{
return lhs.Get() | rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator|(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs | rhs.Get())
{
return lhs | rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator&(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() & rhs)
{
return lhs.Get() & rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator&(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() & rhs.Get())
{
return lhs.Get() & rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator&(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs & rhs.Get())
{
return lhs & rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator<<(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() << rhs)
{
return lhs.Get() << rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator<<(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() << rhs.Get())
{
return lhs.Get() << rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator<<(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs << rhs.Get())
{
return lhs << rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator>>(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() >> rhs)
{
return lhs.Get() >> rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator>>(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() >> rhs.Get())
{
return lhs.Get() >> rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator>>(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs >> rhs.Get())
{
return lhs >> rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename PortalType>
VTKM_EXEC_CONT auto operator~(const ArrayPortalValueReference<PortalType>& ref)
-> decltype(~ref.Get())
{
return ~ref.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename PortalType>
VTKM_EXEC_CONT auto operator!(const ArrayPortalValueReference<PortalType>& ref)
-> decltype(!ref.Get())
{
return !ref.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator&&(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() && rhs)
{
return lhs.Get() && rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator&&(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() && rhs.Get())
{
return lhs.Get() && rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator&&(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs && rhs.Get())
{
return lhs && rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType>
VTKM_EXEC_CONT auto operator||(const ArrayPortalValueReference<LhsPortalType>& lhs,
const typename LhsPortalType::ValueType& rhs)
-> decltype(lhs.Get() || rhs)
{
return lhs.Get() || rhs;
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename LhsPortalType, typename RhsPortalType>
VTKM_EXEC_CONT auto operator||(const ArrayPortalValueReference<LhsPortalType>& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs.Get() || rhs.Get())
{
return lhs.Get() || rhs.Get();
}
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename RhsPortalType>
VTKM_EXEC_CONT auto operator||(const typename RhsPortalType::ValueType& lhs,
const ArrayPortalValueReference<RhsPortalType>& rhs)
-> decltype(lhs || rhs.Get())
{
return lhs || rhs.Get();
}
}
} // namespace vtkm::internal

@ -38,7 +38,8 @@ template <typename _ParameterInterface,
typename _ExecutionInterface,
vtkm::IdComponent _InputDomainIndex,
typename _OutputToInputMapType = vtkm::internal::NullType,
typename _VisitArrayType = vtkm::internal::NullType>
typename _VisitArrayType = vtkm::internal::NullType,
typename _ThreadToOutputMapType = vtkm::internal::NullType>
struct Invocation
{
/// \brief The types of the parameters
@ -90,15 +91,25 @@ struct Invocation
///
using VisitArrayType = _VisitArrayType;
/// \brief An array representing the thread to output map.
///
/// When a worklet is invoked, there is an optional mask operation that will
/// prevent the worklet to be run on masked-out elements of the output. This
/// is represented with a map where each thread points to an output it creates.
///
using ThreadToOutputMapType = _ThreadToOutputMapType;
/// \brief Default Invocation constructors that holds the given parameters
/// by reference.
VTKM_CONT
Invocation(const ParameterInterface& parameters,
OutputToInputMapType outputToInputMap = OutputToInputMapType(),
VisitArrayType visitArray = VisitArrayType())
VisitArrayType visitArray = VisitArrayType(),
ThreadToOutputMapType threadToOutputMap = ThreadToOutputMapType())
: Parameters(parameters)
, OutputToInputMap(outputToInputMap)
, VisitArray(visitArray)
, ThreadToOutputMap(threadToOutputMap)
{
}
@ -113,7 +124,8 @@ struct Invocation
ExecutionInterface,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>;
VisitArrayType,
ThreadToOutputMapType>;
};
/// Returns a new \c Invocation that is the same as this one except that the
@ -124,7 +136,7 @@ struct Invocation
const NewParameterInterface& newParameters) const
{
return typename ChangeParametersType<NewParameterInterface>::type(
newParameters, this->OutputToInputMap, this->VisitArray);
newParameters, this->OutputToInputMap, this->VisitArray, this->ThreadToOutputMap);
}
/// Defines a new \c Invocation type that is the same as this type except
@ -133,8 +145,13 @@ struct Invocation
template <typename NewControlInterface>
struct ChangeControlInterfaceType
{
using type =
Invocation<ParameterInterface, NewControlInterface, ExecutionInterface, InputDomainIndex>;
using type = Invocation<ParameterInterface,
NewControlInterface,
ExecutionInterface,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType,
ThreadToOutputMapType>;
};
/// Returns a new \c Invocation that is the same as this one except that the
@ -145,7 +162,7 @@ struct Invocation
NewControlInterface) const
{
return typename ChangeControlInterfaceType<NewControlInterface>::type(
this->Parameters, this->OutputToInputMap, this->VisitArray);
this->Parameters, this->OutputToInputMap, this->VisitArray, this->ThreadToOutputMap);
}
/// Defines a new \c Invocation type that is the same as this type except
@ -154,8 +171,13 @@ struct Invocation
template <typename NewExecutionInterface>
struct ChangeExecutionInterfaceType
{
using type =
Invocation<ParameterInterface, NewExecutionInterface, ExecutionInterface, InputDomainIndex>;
using type = Invocation<ParameterInterface,
NewExecutionInterface,
ExecutionInterface,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType,
ThreadToOutputMapType>;
};
/// Returns a new \c Invocation that is the same as this one except that the
@ -166,7 +188,7 @@ struct Invocation
NewExecutionInterface) const
{
return typename ChangeExecutionInterfaceType<NewExecutionInterface>::type(
this->Parameters, this->OutputToInputMap, this->VisitArray);
this->Parameters, this->OutputToInputMap, this->VisitArray, this->ThreadToOutputMap);
}
/// Defines a new \c Invocation type that is the same as this type except
@ -175,8 +197,13 @@ struct Invocation
template <vtkm::IdComponent NewInputDomainIndex>
struct ChangeInputDomainIndexType
{
using type =
Invocation<ParameterInterface, ControlInterface, ExecutionInterface, NewInputDomainIndex>;
using type = Invocation<ParameterInterface,
ControlInterface,
ExecutionInterface,
NewInputDomainIndex,
OutputToInputMapType,
VisitArrayType,
ThreadToOutputMapType>;
};
/// Returns a new \c Invocation that is the same as this one except that the
@ -187,7 +214,7 @@ struct Invocation
ChangeInputDomainIndex() const
{
return typename ChangeInputDomainIndexType<NewInputDomainIndex>::type(
this->Parameters, this->OutputToInputMap, this->VisitArray);
this->Parameters, this->OutputToInputMap, this->VisitArray, this->ThreadToOutputMap);
}
/// Defines a new \c Invocation type that is the same as this type except
@ -201,7 +228,8 @@ struct Invocation
ExecutionInterface,
InputDomainIndex,
NewOutputToInputMapType,
VisitArrayType>;
VisitArrayType,
ThreadToOutputMapType>;
};
/// Returns a new \c Invocation that is the same as this one except that the
@ -212,7 +240,7 @@ struct Invocation
ChangeOutputToInputMap(NewOutputToInputMapType newOutputToInputMap) const
{
return typename ChangeOutputToInputMapType<NewOutputToInputMapType>::type(
this->Parameters, newOutputToInputMap, this->VisitArray);
this->Parameters, newOutputToInputMap, this->VisitArray, this->ThreadToOutputMap);
}
/// Defines a new \c Invocation type that is the same as this type except
@ -226,7 +254,8 @@ struct Invocation
ExecutionInterface,
InputDomainIndex,
OutputToInputMapType,
NewVisitArrayType>;
NewVisitArrayType,
ThreadToOutputMapType>;
};
/// Returns a new \c Invocation that is the same as this one except that the
@ -237,7 +266,33 @@ struct Invocation
NewVisitArrayType newVisitArray) const
{
return typename ChangeVisitArrayType<NewVisitArrayType>::type(
this->Parameters, this->OutputToInputMap, newVisitArray);
this->Parameters, this->OutputToInputMap, newVisitArray, this->ThreadToOutputMap);
}
/// Defines a new \c Invocation type that is the same as this type except
/// with the \c ThreadToOutputMapType replaced.
///
template <typename NewThreadToOutputMapType>
struct ChangeThreadToOutputMapType
{
using type = Invocation<ParameterInterface,
ControlInterface,
ExecutionInterface,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType,
NewThreadToOutputMapType>;
};
/// Returns a new \c Invocation that is the same as this one except that the
/// \c OutputToInputMap is replaced with that provided.
///
template <typename NewThreadToOutputMapType>
VTKM_CONT typename ChangeThreadToOutputMapType<NewThreadToOutputMapType>::type
ChangeThreadToOutputMap(NewThreadToOutputMapType newThreadToOutputMap) const
{
return typename ChangeThreadToOutputMapType<NewThreadToOutputMapType>::type(
this->Parameters, this->OutputToInputMap, this->VisitArray, newThreadToOutputMap);
}
/// A convenience alias for the input domain type.
@ -268,6 +323,7 @@ struct Invocation
ParameterInterface Parameters;
OutputToInputMapType OutputToInputMap;
VisitArrayType VisitArray;
ThreadToOutputMapType ThreadToOutputMap;
private:
// Do not allow assignment of one Invocation to another. It is too expensive.
@ -276,7 +332,8 @@ private:
ExecutionInterface,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>&) = delete;
VisitArrayType,
ThreadToOutputMapType>&) = delete;
};
/// Convenience function for creating an Invocation object.
@ -286,25 +343,30 @@ template <vtkm::IdComponent InputDomainIndex,
typename ExecutionInterface,
typename ParameterInterface,
typename OutputToInputMapType,
typename VisitArrayType>
typename VisitArrayType,
typename ThreadToOutputMapType>
VTKM_CONT vtkm::internal::Invocation<ParameterInterface,
ControlInterface,
ExecutionInterface,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>
VisitArrayType,
ThreadToOutputMapType>
make_Invocation(const ParameterInterface& params,
ControlInterface,
ExecutionInterface,
OutputToInputMapType outputToInputMap,
VisitArrayType visitArray)
VisitArrayType visitArray,
ThreadToOutputMapType threadToOutputMap)
{
return vtkm::internal::Invocation<ParameterInterface,
ControlInterface,
ExecutionInterface,
InputDomainIndex,
OutputToInputMapType,
VisitArrayType>(params, outputToInputMap, visitArray);
VisitArrayType,
ThreadToOutputMapType>(
params, outputToInputMap, visitArray, threadToOutputMap);
}
template <vtkm::IdComponent InputDomainIndex,
typename ControlInterface,
@ -320,6 +382,7 @@ VTKM_CONT vtkm::internal::
ControlInterface(),
ExecutionInterface(),
vtkm::internal::NullType(),
vtkm::internal::NullType(),
vtkm::internal::NullType());
}
}

@ -22,11 +22,15 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
static constexpr vtkm::Id ARRAY_SIZE = 10;
template <typename ArrayPortalType>
void SetReference(vtkm::Id index, vtkm::internal::ArrayPortalValueReference<ArrayPortalType> ref)
{
@ -41,7 +45,204 @@ void CheckReference(vtkm::Id index, vtkm::internal::ArrayPortalValueReference<Ar
VTKM_TEST_ASSERT(test_equal(ref, TestValue(index, ValueType())), "Got bad value from reference.");
}
static constexpr vtkm::Id ARRAY_SIZE = 10;
template <typename ArrayPortalType>
void TryOperatorsNoVec(vtkm::Id index,
vtkm::internal::ArrayPortalValueReference<ArrayPortalType> ref,
vtkm::TypeTraitsScalarTag)
{
using ValueType = typename ArrayPortalType::ValueType;
ValueType expected = TestValue(index, ValueType());
VTKM_TEST_ASSERT(ref.Get() == expected, "Reference did not start out as expected.");
VTKM_TEST_ASSERT(!(ref < ref));
VTKM_TEST_ASSERT(ref < ValueType(expected + ValueType(1)));
VTKM_TEST_ASSERT(ValueType(expected - ValueType(1)) < ref);
VTKM_TEST_ASSERT(!(ref > ref));
VTKM_TEST_ASSERT(ref > ValueType(expected - ValueType(1)));
VTKM_TEST_ASSERT(ValueType(expected + ValueType(1)) > ref);
VTKM_TEST_ASSERT(ref <= ref);
VTKM_TEST_ASSERT(ref <= ValueType(expected + ValueType(1)));
VTKM_TEST_ASSERT(ValueType(expected - ValueType(1)) <= ref);
VTKM_TEST_ASSERT(ref >= ref);
VTKM_TEST_ASSERT(ref >= ValueType(expected - ValueType(1)));
VTKM_TEST_ASSERT(ValueType(expected + ValueType(1)) >= ref);
}
template <typename ArrayPortalType>
void TryOperatorsNoVec(vtkm::Id,
vtkm::internal::ArrayPortalValueReference<ArrayPortalType>,
vtkm::TypeTraitsVectorTag)
{
}
template <typename ArrayPortalType>
void TryOperatorsInt(vtkm::Id index,
vtkm::internal::ArrayPortalValueReference<ArrayPortalType> ref,
vtkm::TypeTraitsScalarTag,
vtkm::TypeTraitsIntegerTag)
{
using ValueType = typename ArrayPortalType::ValueType;
const ValueType operand = TestValue(ARRAY_SIZE, ValueType());
ValueType expected = TestValue(index, ValueType());
VTKM_TEST_ASSERT(ref.Get() == expected, "Reference did not start out as expected.");
VTKM_TEST_ASSERT((ref % ref) == (expected % expected));
VTKM_TEST_ASSERT((ref % expected) == (expected % expected));
VTKM_TEST_ASSERT((expected % ref) == (expected % expected));
VTKM_TEST_ASSERT((ref ^ ref) == (expected ^ expected));
VTKM_TEST_ASSERT((ref ^ expected) == (expected ^ expected));
VTKM_TEST_ASSERT((expected ^ ref) == (expected ^ expected));
VTKM_TEST_ASSERT((ref | ref) == (expected | expected));
VTKM_TEST_ASSERT((ref | expected) == (expected | expected));
VTKM_TEST_ASSERT((expected | ref) == (expected | expected));
VTKM_TEST_ASSERT((ref & ref) == (expected & expected));
VTKM_TEST_ASSERT((ref & expected) == (expected & expected));
VTKM_TEST_ASSERT((expected & ref) == (expected & expected));
VTKM_TEST_ASSERT((ref << ref) == (expected << expected));
VTKM_TEST_ASSERT((ref << expected) == (expected << expected));
VTKM_TEST_ASSERT((expected << ref) == (expected << expected));
VTKM_TEST_ASSERT((ref << ref) == (expected << expected));
VTKM_TEST_ASSERT((ref << expected) == (expected << expected));
VTKM_TEST_ASSERT((expected << ref) == (expected << expected));
VTKM_TEST_ASSERT(~ref == ~expected);
VTKM_TEST_ASSERT(!(!ref));
VTKM_TEST_ASSERT(ref && ref);
VTKM_TEST_ASSERT(ref && expected);
VTKM_TEST_ASSERT(expected && ref);
VTKM_TEST_ASSERT(ref || ref);
VTKM_TEST_ASSERT(ref || expected);
VTKM_TEST_ASSERT(expected || ref);
ref &= ref;
expected &= expected;
VTKM_TEST_ASSERT(ref == expected);
ref &= operand;
expected &= operand;
VTKM_TEST_ASSERT(ref == expected);
ref |= ref;
expected |= expected;
VTKM_TEST_ASSERT(ref == expected);
ref |= operand;
expected |= operand;
VTKM_TEST_ASSERT(ref == expected);
ref >>= ref;
expected >>= expected;
VTKM_TEST_ASSERT(ref == expected);
ref >>= operand;
expected >>= operand;
VTKM_TEST_ASSERT(ref == expected);
ref <<= ref;
expected <<= expected;
VTKM_TEST_ASSERT(ref == expected);
ref <<= operand;
expected <<= operand;
VTKM_TEST_ASSERT(ref == expected);
ref ^= ref;
expected ^= expected;
VTKM_TEST_ASSERT(ref == expected);
ref ^= operand;
expected ^= operand;
VTKM_TEST_ASSERT(ref == expected);
}
template <typename ArrayPortalType, typename DimTag, typename NumericTag>
void TryOperatorsInt(vtkm::Id,
vtkm::internal::ArrayPortalValueReference<ArrayPortalType>,
DimTag,
NumericTag)
{
}
template <typename ArrayPortalType>
void TryOperators(vtkm::Id index, vtkm::internal::ArrayPortalValueReference<ArrayPortalType> ref)
{
using ValueType = typename ArrayPortalType::ValueType;
const ValueType operand = TestValue(ARRAY_SIZE, ValueType());
ValueType expected = TestValue(index, ValueType());
VTKM_TEST_ASSERT(ref.Get() == expected, "Reference did not start out as expected.");
// Test comparison operators.
VTKM_TEST_ASSERT(ref == ref);
VTKM_TEST_ASSERT(ref == expected);
VTKM_TEST_ASSERT(expected == ref);
VTKM_TEST_ASSERT(!(ref != ref));
VTKM_TEST_ASSERT(!(ref != expected));
VTKM_TEST_ASSERT(!(expected != ref));
TryOperatorsNoVec(index, ref, typename vtkm::TypeTraits<ValueType>::DimensionalityTag());
VTKM_TEST_ASSERT((ref + ref) == (expected + expected));
VTKM_TEST_ASSERT((ref + expected) == (expected + expected));
VTKM_TEST_ASSERT((expected + ref) == (expected + expected));
VTKM_TEST_ASSERT((ref - ref) == (expected - expected));
VTKM_TEST_ASSERT((ref - expected) == (expected - expected));
VTKM_TEST_ASSERT((expected - ref) == (expected - expected));
VTKM_TEST_ASSERT((ref * ref) == (expected * expected));
VTKM_TEST_ASSERT((ref * expected) == (expected * expected));
VTKM_TEST_ASSERT((expected * ref) == (expected * expected));
VTKM_TEST_ASSERT((ref / ref) == (expected / expected));
VTKM_TEST_ASSERT((ref / expected) == (expected / expected));
VTKM_TEST_ASSERT((expected / ref) == (expected / expected));
ref += ref;
expected += expected;
VTKM_TEST_ASSERT(ref == expected);
ref += operand;
expected += operand;
VTKM_TEST_ASSERT(ref == expected);
ref -= ref;
expected -= expected;
VTKM_TEST_ASSERT(ref == expected);
ref -= operand;
expected -= operand;
VTKM_TEST_ASSERT(ref == expected);
ref *= ref;
expected *= expected;
VTKM_TEST_ASSERT(ref == expected);
ref *= operand;
expected *= operand;
VTKM_TEST_ASSERT(ref == expected);
ref /= ref;
expected /= expected;
VTKM_TEST_ASSERT(ref == expected);
ref /= operand;
expected /= operand;
VTKM_TEST_ASSERT(ref == expected);
// Reset ref
ref = TestValue(index, ValueType());
TryOperatorsInt(index,
ref,
typename vtkm::TypeTraits<ValueType>::DimensionalityTag(),
typename vtkm::TypeTraits<ValueType>::NumericTag());
}
struct DoTestForType
{
@ -54,7 +255,7 @@ struct DoTestForType
std::cout << "Set array using reference" << std::endl;
using PortalType = typename vtkm::cont::ArrayHandle<ValueType>::PortalControl;
PortalType portal = array.GetPortalControl();
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
{
SetReference(index, vtkm::internal::ArrayPortalValueReference<PortalType>(portal, index));
}
@ -63,16 +264,29 @@ struct DoTestForType
CheckPortal(portal);
std::cout << "Check references in set array." << std::endl;
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
{
CheckReference(index, vtkm::internal::ArrayPortalValueReference<PortalType>(portal, index));
}
std::cout << "Check that operators work." << std::endl;
// Start at 1 to avoid issues with 0.
for (vtkm::Id index = 1; index < ARRAY_SIZE; ++index)
{
TryOperators(index, vtkm::internal::ArrayPortalValueReference<PortalType>(portal, index));
}
}
};
void DoTest()
{
vtkm::testing::Testing::TryTypes(DoTestForType());
// We are not testing on the default (exemplar) types because they include unsigned bytes, and
// simply doing a += (or similar) operation on them automatically creates a conversion warning
// on some compilers. Since we want to test these operators, just remove the short types from
// the list to avoid the warning.
vtkm::testing::Testing::TryTypes(
DoTestForType(),
vtkm::ListTagBase<vtkm::Id, vtkm::FloatDefault, vtkm::Vec<vtkm::Float64, 3>>());
}
} // anonymous namespace

@ -184,7 +184,7 @@ void MapperCylinder::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
if (cylExtractor.GetNumberOfCylinders() > 0)
{
raytracing::CylinderIntersector* cylIntersector = new raytracing::CylinderIntersector();
auto cylIntersector = std::make_shared<raytracing::CylinderIntersector>();
cylIntersector->SetData(coords, cylExtractor.GetCylIds(), cylExtractor.GetRadii());
this->Internals->Tracer.AddShapeIntersector(cylIntersector);
shapeBounds.Include(cylIntersector->GetShapeBounds());

@ -182,7 +182,7 @@ void MapperPoint::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
if (sphereExtractor.GetNumberOfSpheres() > 0)
{
raytracing::SphereIntersector* sphereIntersector = new raytracing::SphereIntersector();
auto sphereIntersector = std::make_shared<raytracing::SphereIntersector>();
sphereIntersector->SetData(coords, sphereExtractor.GetPointIds(), sphereExtractor.GetRadii());
this->Internals->Tracer.AddShapeIntersector(sphereIntersector);
shapeBounds.Include(sphereIntersector->GetShapeBounds());

@ -104,7 +104,7 @@ void MapperQuad::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
quadExtractor.ExtractCells(cellset);
if (quadExtractor.GetNumberOfQuads() > 0)
{
raytracing::QuadIntersector* quadIntersector = new raytracing::QuadIntersector();
auto quadIntersector = std::make_shared<raytracing::QuadIntersector>();
quadIntersector->SetData(coords, quadExtractor.GetQuadIds());
this->Internals->Tracer.AddShapeIntersector(quadIntersector);
shapeBounds.Include(quadIntersector->GetShapeBounds());

@ -108,7 +108,7 @@ void MapperRayTracer::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
triExtractor.ExtractCells(cellset);
if (triExtractor.GetNumberOfTriangles() > 0)
{
raytracing::TriangleIntersector* triIntersector = new raytracing::TriangleIntersector();
auto triIntersector = std::make_shared<raytracing::TriangleIntersector>();
triIntersector->SetData(coords, triExtractor.GetTriangles());
this->Internals->Tracer.AddShapeIntersector(triIntersector);
shapeBounds.Include(triIntersector->GetShapeBounds());

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