Merge branch 'cuda_DeviceAdapterAlgorithm'

This commit is contained in:
Robert Maynard 2015-01-20 15:29:08 -05:00
commit 7f73c4f404
53 changed files with 3954 additions and 1403 deletions

75
CMake/FindThrust.cmake Normal file

@ -0,0 +1,75 @@
##============================================================================
## 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 Sandia Corporation.
## Copyright 2014 UT-Battelle, LLC.
## Copyright 2014. Los Alamos National Security
##
## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
## 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.
##============================================================================
#
# FindThrust
#
# This module finds the Thrust header files and extrats their version. It
# sets the following variables.
#
# THRUST_INCLUDE_DIR - Include directory for thrust header files. (All header
# files will actually be in the thrust subdirectory.)
# THRUST_VERSION - Version of thrust in the form "major.minor.patch".
#
find_path( THRUST_INCLUDE_DIR
HINTS
/usr/include/cuda
/usr/local/include
/usr/local/cuda/include
${CUDA_INCLUDE_DIRS}
${CUDA_TOOLKIT_ROOT_DIR}
${CUDA_SDK_ROOT_DIR}
NAMES thrust/version.h
DOC "Thrust headers"
)
if( THRUST_INCLUDE_DIR )
list( REMOVE_DUPLICATES THRUST_INCLUDE_DIR )
endif( THRUST_INCLUDE_DIR )
# Find thrust version
file( STRINGS ${THRUST_INCLUDE_DIR}/thrust/version.h
version
REGEX "#define THRUST_VERSION[ \t]+([0-9x]+)"
)
string( REGEX REPLACE
"#define THRUST_VERSION[ \t]+"
""
version
"${version}"
)
string( REGEX MATCH "^[0-9]" major ${version} )
string( REGEX REPLACE "^${major}00" "" version "${version}" )
string( REGEX MATCH "^[0-9]" minor ${version} )
string( REGEX REPLACE "^${minor}0" "" version "${version}" )
set( THRUST_VERSION "${major}.${minor}.${version}")
set( THRUST_MAJOR_VERSION "${major}")
set( THRUST_MINOR_VERSION "${minor}")
# Check for required components
include( FindPackageHandleStandardArgs )
find_package_handle_standard_args( Thrust
REQUIRED_VARS THRUST_INCLUDE_DIR
VERSION_VAR THRUST_VERSION
)
set(THRUST_INCLUDE_DIRS ${THRUST_INCLUDE_DIR})
mark_as_advanced(THRUST_INCLUDE_DIR)

84
CMake/UseVTKmCuda.cmake Normal file

@ -0,0 +1,84 @@
##============================================================================
## 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 Sandia Corporation.
## Copyright 2014 UT-Battelle, LLC.
## Copyright 2014. Los Alamos National Security
##
## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
## 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.
##============================================================================
if (VTKm_Cuda_initialize_complete)
return()
endif (VTKm_Cuda_initialize_complete)
set(VTKm_Cuda_FOUND ${VTKm_ENABLE_CUDA})
if (NOT VTKm_Cuda_FOUND)
message(STATUS "This build of VTKm does not include Cuda.")
endif (NOT VTKm_Cuda_FOUND)
# Find the Boost library.
if (VTKm_Cuda_FOUND)
if(NOT Boost_FOUND)
find_package(BoostHeaders ${VTKm_REQUIRED_BOOST_VERSION})
endif()
if (NOT Boost_FOUND)
message(STATUS "Boost not found")
set(VTKm_Cuda_FOUND)
endif (NOT Boost_FOUND)
endif (VTKm_Cuda_FOUND)
#-----------------------------------------------------------------------------
# Find CUDA library.
#-----------------------------------------------------------------------------
if (VTKm_Cuda_FOUND)
find_package(CUDA)
mark_as_advanced(CUDA_BUILD_CUBIN
CUDA_BUILD_EMULATION
CUDA_HOST_COMPILER
CUDA_SDK_ROOT_DIR
CUDA_SEPARABLE_COMPILATION
CUDA_TOOLKIT_ROOT_DIR
CUDA_VERBOSE_BUILD
)
if (NOT CUDA_FOUND)
message(STATUS "CUDA not found")
set(VTKm_Cuda_FOUND)
endif (NOT CUDA_FOUND)
endif ()
#-----------------------------------------------------------------------------
# Find Thrust library.
#-----------------------------------------------------------------------------
if (VTKm_Cuda_FOUND)
find_package(Thrust)
if (NOT THRUST_FOUND)
message(STATUS "Thrust not found")
set(VTKm_Cuda_FOUND)
endif (NOT THRUST_FOUND)
endif ()
#-----------------------------------------------------------------------------
# Set up all these dependent packages (if they were all found).
#-----------------------------------------------------------------------------
if (VTKm_Cuda_FOUND)
cuda_include_directories(
${Boost_INCLUDE_DIRS}
${THRUST_INCLUDE_DIRS}
${VTKm_INCLUDE_DIRS}
)
set(VTKm_Cuda_initialize_complete TRUE)
endif (VTKm_Cuda_FOUND)

47
CMake/UseVTKmSerial.cmake Normal file

@ -0,0 +1,47 @@
##============================================================================
## 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 Sandia Corporation.
## Copyright 2014 UT-Battelle, LLC.
## Copyright 2014. Los Alamos National Security
##
## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
## 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.
##============================================================================
if (VTKm_Serial_initialize_complete)
return()
endif (VTKm_Serial_initialize_complete)
# Find the Boost library.
if (NOT VTKm_Serial_FOUND)
if(NOT Boost_FOUND)
find_package(BoostHeaders ${VTKm_REQUIRED_BOOST_VERSION})
endif()
if (NOT Boost_FOUND)
message(STATUS "Boost not found")
set(VTKm_Serial_FOUND FALSE)
else(NOT Boost_FOUND)
set(VTKm_Serial_FOUND TRUE)
endif (NOT Boost_FOUND)
endif (NOT VTKm_Serial_FOUND)
# Set up all these dependent packages (if they were all found).
if (VTKm_Serial_FOUND)
include_directories(
${Boost_INCLUDE_DIRS}
${VTKm_INCLUDE_DIRS}
)
set(VTKm_Serial_initialize_complete TRUE)
endif (VTKm_Serial_FOUND)

@ -293,24 +293,33 @@ function(vtkm_worklet_unit_tests device_adapter)
#detect if we are generating a .cu files
set(is_cuda FALSE)
set(old_nvcc_flags ${CUDA_NVCC_FLAGS})
if("${device_adapter}" STREQUAL "VTKm_DEVICE_ADAPTER_CUDA")
if("${device_adapter}" STREQUAL "VTKM_DEVICE_ADAPTER_CUDA")
set(is_cuda TRUE)
#if we are generating cu files need to setup three things.
#1. us the configured .cu files
#2. Set BOOST_SP_DISABLE_THREADS to disable threading warnings
#3. Disable unused function warnings
#the FindCUDA module and helper methods don't read target level
#properties so we have to modify CUDA_NVCC_FLAGS instead of using
# target and source level COMPILE_FLAGS and COMPILE_DEFINITIONS
#
#2. Explicitly set the cuda device adapter as a define this is currently
# done as a work around since the cuda executable ignores compile
# definitions
#3. Set BOOST_SP_DISABLE_THREADS to disable threading warnings
#4. Disable unused function warnings
# the FindCUDA module and helper methods don't read target level
# properties so we have to modify CUDA_NVCC_FLAGS instead of using
# target and source level COMPILE_FLAGS and COMPILE_DEFINITIONS
get_property(unit_test_srcs GLOBAL PROPERTY vtkm_worklet_unit_tests_cu_sources )
list(APPEND CUDA_NVCC_FLAGS -DBOOST_SP_DISABLE_THREADS)
list(APPEND CUDA_NVCC_FLAGS "-DVTKM_DEVICE_ADAPTER=${device_adapter}")
list(APPEND CUDA_NVCC_FLAGS "-DBOOST_SP_DISABLE_THREADS")
list(APPEND CUDA_NVCC_FLAGS "-w")
endif()
if(VTKm_ENABLE_TESTING)
string(REPLACE "VTKM_DEVICE_ADAPTER_" "" device_type ${device_adapter})
vtkm_get_kit_name(kit)
set(test_prog WorkletTests_${kit})
#inject the device adapter into the test program name so each one is unique
set(test_prog WorkletTests_${device_type})
if(is_cuda)
cuda_add_executable(${test_prog} ${unit_test_drivers} ${unit_test_srcs})
@ -321,9 +330,6 @@ function(vtkm_worklet_unit_tests device_adapter)
#add a test for each worklet test file. We will inject the device
#adapter type into the test name so that it is easier to see what
#exact device a test is failing on.
string(REPLACE "VTKm_DEVICE_ADAPTER_" "" device_type ${device_adapter})
foreach (test ${unit_test_srcs})
get_filename_component(tname ${test} NAME_WE)
add_test(NAME "${tname}${device_type}"
@ -336,13 +342,13 @@ function(vtkm_worklet_unit_tests device_adapter)
#generates
if(VTKm_EXTRA_COMPILER_WARNINGS)
set_property(TARGET ${test_prog}
APPEND PROPERTY COMPILE_FLAGS ${CMAKE_CXX_FLAGS_WARN_EXTRA} )
APPEND PROPERTY COMPILE_FLAGS ${CMAKE_CXX_FLAGS_WARN_EXTRA} )
endif()
#set the device adapter on the executable
set_property(TARGET ${test_prog}
APPEND
PROPERTY COMPILE_DEFINITIONS VTKm_DEVICE_ADAPTER=${device_adapter})
APPEND
PROPERTY COMPILE_DEFINITIONS "VTKM_DEVICE_ADAPTER=${device_adapter}" )
endif()
set(CUDA_NVCC_FLAGS ${old_nvcc_flags})
@ -368,3 +374,14 @@ macro(vtkm_disable_troublesome_thrust_warnings_var flags_var)
string(REPLACE "-Wall" "" new_flags "${new_flags}")
set(${flags_var} "${new_flags}")
endmacro(vtkm_disable_troublesome_thrust_warnings_var)
# Set up configuration for a given device.
macro(vtkm_configure_device device)
string(TOUPPER "${device}" device_uppercase)
set(VTKm_ENABLE_${device_uppercase} ON)
include("${VTKm_SOURCE_DIR}/CMake/UseVTKm${device}.cmake")
if(NOT VTKm_${device}_FOUND)
message(SEND_ERROR "Could not configure for using VTKm with ${device}")
endif(NOT VTKm_${device}_FOUND)
endmacro(vtkm_configure_device)

@ -53,6 +53,7 @@ include(CMake/VTKmCompilerExtras.cmake)
#-----------------------------------------------------------------------------
# Configurable Options
option(VTKm_ENABLE_CUDA "Enable Cuda support" OFF)
option(VTKm_ENABLE_TESTING "Enable VTKm Testing" ON)
option(VTKm_USE_DOUBLE_PRECISION
@ -66,6 +67,13 @@ if (VTKm_ENABLE_TESTING)
include(CTest)
endif()
#-----------------------------------------------------------------------------
# Set up devices selected.
vtkm_configure_device(Serial)
if (VTKm_ENABLE_CUDA)
vtkm_configure_device(Cuda)
endif (VTKm_ENABLE_CUDA)
#-----------------------------------------------------------------------------
## Set the directory where the binaries will be stored
@ -122,12 +130,6 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/vtkm/internal/Configure.h.in
vtkm_install_headers(
vtkm/internal ${CMAKE_CURRENT_BINARY_DIR}/vtkm/internal/Configure.h)
# List of Boost features used:
# * Smart Ptr
# * Meta programming language
find_package(BoostHeaders ${VTKm_REQUIRED_BOOST_VERSION} REQUIRED)
find_package(Pyexpander)
#-----------------------------------------------------------------------------
@ -183,6 +185,15 @@ install(
DESTINATION ${VTKm_INSTALL_CMAKE_MODULE_DIR}
)
# Install Use files.
install(
FILES
${VTKm_SOURCE_DIR}/CMake/UseVTKmSerial.cmake
${VTKm_SOURCE_DIR}/CMake/UseVTKmCuda.cmake
DESTINATION ${VTKm_INSTALL_CMAKE_MODULE_DIR}
)
# Enable CPack packaging
set(CPACK_PACKAGE_DESCRIPTION_FILE ${VTKm_SOURCE_DIR}/README.md)
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The VTKm Toolkit")

@ -1172,6 +1172,18 @@ VTK_M_SCALAR_DOT(vtkm::UInt64)
VTK_M_SCALAR_DOT(vtkm::Float32)
VTK_M_SCALAR_DOT(vtkm::Float64)
/// Predicate that takes a single argument \c x, and returns
/// True if it isn't the identity of the Type \p T.
template<typename T>
struct not_default_constructor
{
VTKM_EXEC_CONT_EXPORT bool operator()(const T &x)
{
return (x != T());
}
};
} // End of namespace vtkm
// Declared outside of vtkm namespace so that the operator works with all code.

@ -30,6 +30,8 @@
#include <boost/static_assert.hpp>
#include <sstream>
namespace vtkm {
namespace cont {
@ -128,16 +130,17 @@ struct CompositeVectorArrayToPortalCont {
template<typename DeviceAdapterTag>
struct CompositeVectorArrayToPortalExec {
template<typename ArrayHandleType>
template<typename ArrayHandleType, vtkm::IdComponent Index>
struct ReturnType {
typedef typename ArrayHandleType::template ExecutionTypes<
DeviceAdapterTag>::PortalConst type;
};
template<typename ArrayHandleType>
template<typename ArrayHandleType, vtkm::IdComponent Index>
VTKM_CONT_EXPORT
typename ReturnType<ArrayHandleType>::type
operator()(const ArrayHandleType &array) const {
typename ReturnType<ArrayHandleType, Index>::type
operator()(const ArrayHandleType &array,
vtkm::internal::IndexTag<Index>) const {
return array.PrepareForInput(DeviceAdapterTag());
}
};
@ -146,12 +149,15 @@ struct CheckArraySizeFunctor {
vtkm::Id ExpectedSize;
CheckArraySizeFunctor(vtkm::Id expectedSize) : ExpectedSize(expectedSize) { }
template<typename T>
void operator()(const T &a) const {
template<typename T, vtkm::IdComponent Index>
void operator()(const T &a, vtkm::internal::IndexTag<Index>) const {
if (a.GetNumberOfValues() != this->ExpectedSize)
{
throw vtkm::cont::ErrorControlBadValue(
"All input arrays to ArrayHandleCompositeVector must be the same size.");
std::stringstream message;
message << "All input arrays to ArrayHandleCompositeVector must be the same size.\n"
<< "Array " << Index-1 << " has " << a.GetNumberOfValues()
<< ". Expected " << this->ExpectedSize << ".";
throw vtkm::cont::ErrorControlBadValue(message.str().c_str());
}
}
};

@ -35,6 +35,9 @@ class ArrayPortalCounting
public:
typedef CountingValueType ValueType;
typedef vtkm::cont::internal::IteratorFromArrayPortal<
ArrayPortalCounting < ValueType> > IteratorType;
VTKM_EXEC_CONT_EXPORT
ArrayPortalCounting() :
StartingValue(),

@ -29,6 +29,7 @@ set(headers
ArrayPortalToIterators.h
Assert.h
DeviceAdapter.h
DeviceAdapterAlgorithm.h
DeviceAdapterSerial.h
DynamicArrayHandle.h
DynamicPointCoordinates.h
@ -56,6 +57,9 @@ add_subdirectory(arg)
vtkm_declare_headers(${impl_headers} ${headers})
if (VTKm_ENABLE_CUDA)
add_subdirectory(cuda)
endif (VTKm_ENABLE_CUDA)
#-----------------------------------------------------------------------------
add_subdirectory(testing)

@ -24,9 +24,9 @@
// order in which the sub-files are loaded. (But the compile should still
// succeed of the order is changed.)
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/cont/internal/ArrayManagerExecution.h>
#include <vtkm/cont/internal/DeviceAdapterAlgorithm.h>
namespace vtkm {
namespace cont {

@ -395,8 +395,8 @@ public:
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_SERIAL
#include <vtkm/cont/internal/DeviceAdapterAlgorithmSerial.h>
// #elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_CUDA
// #include <vtkm/cuda/cont/internal/DeviceAdapterAlgorithmCuda.h>
#elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_CUDA
#include <vtkm/cont/cuda/internal/DeviceAdapterAlgorithmCuda.h>
// #elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_OPENMP
// #include <vtkm/openmp/cont/internal/DeviceAdapterAlgorithmOpenMP.h>
// #elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB

@ -72,7 +72,7 @@ namespace detail {
// arguments.
template<typename T>
struct UndefinedArrayPortal {
BOOST_STATIC_ASSERT(sizeof(T) == -1);
BOOST_STATIC_ASSERT(sizeof(T) == static_cast<size_t>(-1));
};
} // namespace detail

@ -132,9 +132,10 @@ public:
this->PortalValid = true;
}
VTKM_CONT_EXPORT void LoadDataForInput(const StorageType &controlArray)
VTKM_CONT_EXPORT void LoadDataForInput(const StorageType& vtkmNotUsed(controlArray) )
{
this->LoadDataForInput(controlArray.GetPortalConst());
throw vtkm::cont::ErrorControlBadValue(
"Implicit arrays have no storage, you need to load from a portal");
}
VTKM_CONT_EXPORT

@ -0,0 +1,36 @@
##============================================================================
## 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 Sandia Corporation.
## Copyright 2014 UT-Battelle, LLC.
## Copyright 2014. Los Alamos National Security
##
## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
## 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.
##============================================================================
set(headers
ChooseCudaDevice.h
DeviceAdapterCuda.h
)
vtkm_disable_troublesome_thrust_warnings()
#-----------------------------------------------------------------------------
CUDA_INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
add_subdirectory(internal)
#-----------------------------------------------------------------------------
vtkm_declare_headers(CUDA ${headers})
add_subdirectory(testing)

@ -0,0 +1,145 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cuda_ChooseCudaDevice_h
#define vtk_m_cont_cuda_ChooseCudaDevice_h
#include <vtkm/cont/ErrorExecution.h>
#include <cuda.h>
#include <algorithm>
#include <vector>
namespace vtkm{
namespace cuda{
namespace cont {
namespace {
struct compute_info
{
compute_info(cudaDeviceProp prop, int index)
{
this->Index = index;
this->Major = prop.major;
this->MemorySize = prop.totalGlobalMem;
this->Performance = prop.multiProcessorCount *
prop.maxThreadsPerMultiProcessor *
(prop.clockRate / 100000.0f);
//9999 is equal to emulation make sure it is a super bad device
if(this->Major >= 9999)
{
this->Major = -1;
this->Performance = -1;
}
}
//sort from fastest to slowest
bool operator<(const compute_info other) const
{
//if we are both SM2 or greater check performance
//if we both the same SM level check performance
if( (this->Major >= 2 && other.Major >= 2) ||
(this->Major == other.Major) )
{
return betterPerfomance(other);
}
//prefer the greater SM otherwise
return this->Major > other.Major;
}
bool betterPerfomance(const compute_info other) const
{
if ( this->Performance == other.Performance)
{
if( this->MemorySize == other.MemorySize )
{
//prefer first device over second device
//this will be subjective I bet
return this->Index < other.Index;
}
return this->MemorySize > other.MemorySize;
}
return this->Performance > other.Performance;
}
int GetIndex() const { return Index; }
private:
int Index;
int Major;
int MemorySize;
int Performance;
};
}
///Returns the fastest cuda device id that the current system has
///A result of zero means no cuda device has been found
static int FindFastestDeviceId()
{
//get the number of devices and store information
int numberOfDevices=0;
cudaGetDeviceCount(&numberOfDevices);
std::vector<compute_info> devices;
for(int i=0; i < numberOfDevices; ++i)
{
cudaDeviceProp properties;
cudaGetDeviceProperties(&properties, i);
if(properties.computeMode != cudaComputeModeProhibited)
{
//only add devices that have compute mode allowed
devices.push_back( compute_info(properties,i) );
}
}
//sort from fastest to slowest
std::sort(devices.begin(),devices.end());
int device=0;
if(devices.size()> 0)
{
device = devices.front().GetIndex();
}
return device;
}
//choose a cuda compute device. This can't be used if you are setting
//up open gl interop
static void SetCudaDevice(int id)
{
cudaError_t cError = cudaSetDevice(id);
if(cError != cudaSuccess)
{
std::string cuda_error_msg(
"Unable to bind to the given cuda device. Error: ");
cuda_error_msg.append(cudaGetErrorString(cError));
throw vtkm::cont::ErrorExecution(cuda_error_msg);
}
}
}
}
} //namespace
#endif

@ -0,0 +1,27 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cuda_DeviceAdapterCuda_h
#define vtk_m_cont_cuda_DeviceAdapterCuda_h
#include <vtkm/cont/cuda/internal/DeviceAdapterTagCuda.h>
#include <vtkm/cont/cuda/internal/ArrayManagerExecutionCuda.h>
#include <vtkm/cont/cuda/internal/DeviceAdapterAlgorithmCuda.h>
#endif //vtk_m_cont_cuda_DeviceAdapterCuda_h

@ -0,0 +1,97 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cuda_internal_ArrayManagerExecutionCuda_h
#define vtk_m_cont_cuda_internal_ArrayManagerExecutionCuda_h
#include <vtkm/cont/cuda/internal/SetThrustForCuda.h>
#include <vtkm/cont/cuda/internal/DeviceAdapterTagCuda.h>
#include <vtkm/cont/Storage.h>
#include <vtkm/cont/internal/ArrayManagerExecution.h>
#include <vtkm/cont/cuda/internal/ArrayManagerExecutionThrustDevice.h>
// These must be placed in the vtkm::cont::internal namespace so that
// the template can be found.
namespace vtkm {
namespace cont {
namespace internal {
template <typename T, class StorageTag>
class ArrayManagerExecution
<T, StorageTag, vtkm::cont::DeviceAdapterTagCuda>
: public vtkm::cont::cuda::internal::ArrayManagerExecutionThrustDevice
<T, StorageTag>
{
public:
typedef vtkm::cont::cuda::internal::ArrayManagerExecutionThrustDevice
<T, StorageTag> Superclass;
typedef typename Superclass::ValueType ValueType;
typedef typename Superclass::PortalType PortalType;
typedef typename Superclass::PortalConstType PortalConstType;
template<class PortalControl>
VTKM_CONT_EXPORT void LoadDataForInput(PortalControl arrayPortal)
{
try
{
this->Superclass::LoadDataForInput(arrayPortal);
}
catch (vtkm::cont::ErrorControlOutOfMemory error)
{
// Thrust does not seem to be clearing the CUDA error, so do it here.
cudaError_t cudaError = cudaPeekAtLastError();
if (cudaError == cudaErrorMemoryAllocation)
{
cudaGetLastError();
}
throw error;
}
}
VTKM_CONT_EXPORT void AllocateArrayForOutput(
vtkm::cont::internal::Storage<ValueType,StorageTag>
&container,
vtkm::Id numberOfValues)
{
try
{
this->Superclass::AllocateArrayForOutput(container, numberOfValues);
}
catch (vtkm::cont::ErrorControlOutOfMemory error)
{
// Thrust does not seem to be clearing the CUDA error, so do it here.
cudaError_t cudaError = cudaPeekAtLastError();
if (cudaError == cudaErrorMemoryAllocation)
{
cudaGetLastError();
}
throw error;
}
}
};
}
}
} // namespace vtkm::cont::internal
#endif //vtk_m_cont_cuda_internal_ArrayManagerExecutionCuda_h

@ -0,0 +1,382 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cuda_internal_ArrayManagerExecutionThrustDevice_h
#define vtk_m_cont_cuda_internal_ArrayManagerExecutionThrustDevice_h
#include <vtkm/cont/Storage.h>
#include <vtkm/cont/ErrorControlOutOfMemory.h>
// Disable GCC warnings we check vtkmfor but Thrust does not.
#if defined(__GNUC__) && !defined(VTKM_CUDA)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif // gcc version >= 4.6
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 2)
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif // gcc version >= 4.2
#endif // gcc && !CUDA
#include <thrust/system/cuda/memory.h>
#include <thrust/copy.h>
#if defined(__GNUC__) && !defined(VTKM_CUDA)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif // gcc version >= 4.6
#endif // gcc && !CUDA
#include <vtkm/exec/cuda/internal/ArrayPortalFromThrust.h>
#include <vtkm/exec/cuda/internal/ArrayPortalFromTexture.h>
#include <boost/utility/enable_if.hpp>
namespace vtkm {
namespace cont {
namespace cuda {
namespace internal {
template<typename T> struct UseTexturePortal {typedef boost::false_type type;};
//Currently disabled as we are still tracking down issues with Texture
//Memory. The major issue is that in testing it is slower than classic arrays
#ifdef VTKM_USE_TEXTURE_MEM
template<> struct UseTexturePortal<vtkm::Int8> {typedef boost::true_type type; };
template<> struct UseTexturePortal<vtkm::UInt8> {typedef boost::true_type type; };
template<> struct UseTexturePortal<vtkm::Int16> {typedef boost::true_type type; };
template<> struct UseTexturePortal<vtkm::UInt16> {typedef boost::true_type type; };
template<> struct UseTexturePortal<vtkm::Int32> {typedef boost::true_type type; };
template<> struct UseTexturePortal<vtkm::UInt32> {typedef boost::true_type type; };
template<> struct UseTexturePortal<vtkm::Float32> {typedef boost::true_type type; };
#endif
/// \c ArrayManagerExecutionThrustDevice provides an implementation for a \c
/// ArrayManagerExecution class for a thrust device adapter that is designed
/// for the cuda backend which has separate memory spaces for host and device. This
/// implementation contains a ::thrust::system::cuda::vector to allocate and manage
/// the array.
///
/// This array manager should only be used with the cuda device adapter,
/// since in the future it will take advantage of texture memory and
/// the unique memory access patterns of cuda systems.
template<typename T, class StorageTag, typename Enable= void>
class ArrayManagerExecutionThrustDevice
{
//we need a way to detect that we are using FERMI or lower and disable
//the usage of texture iterator. The __CUDA_ARCH__ define is only around
//for device code so that can't be used. I expect that we will have to devise
//some form of Try/Compile with CUDA or just offer this as an advanced CMake
//option. We could also try and see if a runtime switch is possible.
public:
typedef T ValueType;
typedef vtkm::cont::internal::Storage<ValueType, StorageTag> ContainerType;
typedef vtkm::exec::cuda::internal::ArrayPortalFromThrust< T > PortalType;
typedef vtkm::exec::cuda::internal::ConstArrayPortalFromThrust< T > PortalConstType;
VTKM_CONT_EXPORT ArrayManagerExecutionThrustDevice():
NumberOfValues(0),
ArrayBegin(),
ArrayEnd()
{
}
/// Returns the size of the array.
///
VTKM_CONT_EXPORT vtkm::Id GetNumberOfValues() const {
return this->NumberOfValues;
}
/// Allocates the appropriate size of the array and copies the given data
/// into the array.
///
template<class PortalControl>
VTKM_CONT_EXPORT void LoadDataForInput(PortalControl arrayPortal)
{
//don't bind to the texture yet, as we could have allocate the array
//on a previous call with AllocateArrayForOutput and now are directly
//calling get portal const
try
{
this->NumberOfValues = arrayPortal.GetNumberOfValues();
this->ArrayBegin = ::thrust::system::cuda::malloc<T>( static_cast<std::size_t>(this->NumberOfValues) );
this->ArrayEnd = this->ArrayBegin + this->NumberOfValues;
::thrust::copy(arrayPortal.GetRawIterator(),
arrayPortal.GetRawIterator() + this->NumberOfValues,
this->ArrayBegin);
}
catch (std::bad_alloc error)
{
throw vtkm::cont::ErrorControlOutOfMemory(error.what());
}
}
/// Allocates the appropriate size of the array and copies the given data
/// into the array.
///
template<class PortalControl>
VTKM_CONT_EXPORT void LoadDataForInPlace(PortalControl arrayPortal)
{
this->LoadDataForInput(arrayPortal);
}
/// Allocates the array to the given size.
///
VTKM_CONT_EXPORT void AllocateArrayForOutput(
ContainerType &vtkmNotUsed(container),
vtkm::Id numberOfValues)
{
if(this->NumberOfValues > 0)
{
::thrust::system::cuda::free( this->ArrayBegin );
}
this->NumberOfValues = numberOfValues;
this->ArrayBegin = ::thrust::system::cuda::malloc<T>( this->NumberOfValues );
this->ArrayEnd = this->ArrayBegin + numberOfValues;
}
/// Allocates enough space in \c controlArray and copies the data in the
/// device vector into it.
///
VTKM_CONT_EXPORT void RetrieveOutputData(ContainerType &controlArray) const
{
controlArray.Allocate(this->NumberOfValues);
::thrust::copy(this->ArrayBegin,
this->ArrayEnd,
controlArray.GetPortal().GetRawIterator());
}
/// Resizes the device vector.
///
VTKM_CONT_EXPORT void Shrink(vtkm::Id numberOfValues)
{
// The operation will succeed even if this assertion fails, but this
// is still supposed to be a precondition to Shrink.
VTKM_ASSERT_CONT(numberOfValues <= this->NumberOfValues);
this->NumberOfValues = numberOfValues;
this->ArrayEnd = this->ArrayBegin + this->NumberOfValues;
}
VTKM_CONT_EXPORT PortalType GetPortal()
{
return PortalType(this->ArrayBegin, this->ArrayEnd);
}
VTKM_CONT_EXPORT PortalConstType GetPortalConst() const
{
return PortalConstType(this->ArrayBegin, this->ArrayEnd);
}
/// Frees all memory.
///
VTKM_CONT_EXPORT void ReleaseResources()
{
::thrust::system::cuda::free( this->ArrayBegin );
this->ArrayBegin = ::thrust::system::cuda::pointer<ValueType>();
this->ArrayEnd = ::thrust::system::cuda::pointer<ValueType>();
}
private:
// Not implemented
ArrayManagerExecutionThrustDevice(
ArrayManagerExecutionThrustDevice<T, StorageTag> &);
void operator=(
ArrayManagerExecutionThrustDevice<T, StorageTag> &);
vtkm::Id NumberOfValues;
::thrust::system::cuda::pointer<ValueType> ArrayBegin;
::thrust::system::cuda::pointer<ValueType> ArrayEnd;
};
/// This is a specialization that is used to enable texture memory iterators
template<typename T, class StorageTag>
class ArrayManagerExecutionThrustDevice<T, StorageTag,
typename ::boost::enable_if< typename UseTexturePortal<T>::type >::type >
{
//we need a way to detect that we are using FERMI or lower and disable
//the usage of texture iterator. The __CUDA_ARCH__ define is only around
//for device code so that can't be used. I expect that we will have to devise
//some form of Try/Compile with CUDA or just offer this as an advanced CMake
//option. We could also try and see if a runtime switch is possible.
public:
typedef T ValueType;
typedef vtkm::cont::internal::Storage<ValueType, StorageTag> ContainerType;
typedef vtkm::exec::cuda::internal::ArrayPortalFromThrust< T > PortalType;
typedef ::vtkm::exec::cuda::internal::DaxTexObjInputIterator<T> TextureIteratorType;
typedef ::vtkm::exec::cuda::internal::ConstArrayPortalFromTexture< TextureIteratorType > PortalConstType;
VTKM_CONT_EXPORT ArrayManagerExecutionThrustDevice():
NumberOfValues(0),
ArrayBegin(),
ArrayEnd(),
HaveTextureBound(false),
InputArrayIterator()
{
}
~ArrayManagerExecutionThrustDevice()
{
if(this->HaveTextureBound)
{
this->HaveTextureBound = false;
this->InputArrayIterator.UnbindTexture();
}
}
/// Returns the size of the array.
///
VTKM_CONT_EXPORT vtkm::Id GetNumberOfValues() const {
return this->NumberOfValues;
}
/// Allocates the appropriate size of the array and copies the given data
/// into the array.
///
template<class PortalControl>
VTKM_CONT_EXPORT void LoadDataForInput(PortalControl arrayPortal)
{
//don't bind to the texture yet, as we could have allocate the array
//on a previous call with AllocateArrayForOutput and now are directly
//calling get portal const
try
{
this->NumberOfValues = arrayPortal.GetNumberOfValues();
this->ArrayBegin = ::thrust::system::cuda::malloc<T>( static_cast<std::size_t>(this->NumberOfValues) );
this->ArrayEnd = this->ArrayBegin + this->NumberOfValues;
::thrust::copy(arrayPortal.GetRawIterator(),
arrayPortal.GetRawIterator() + this->NumberOfValues,
this->ArrayBegin);
}
catch (std::bad_alloc error)
{
throw vtkm::cont::ErrorControlOutOfMemory(error.what());
}
}
/// Allocates the appropriate size of the array and copies the given data
/// into the array.
///
template<class PortalControl>
VTKM_CONT_EXPORT void LoadDataForInPlace(PortalControl arrayPortal)
{
this->LoadDataForInput(arrayPortal);
}
/// Allocates the array to the given size.
///
VTKM_CONT_EXPORT void AllocateArrayForOutput(
ContainerType &vtkmNotUsed(container),
vtkm::Id numberOfValues)
{
if(this->NumberOfValues > 0)
{
::thrust::system::cuda::free( this->ArrayBegin );
}
this->NumberOfValues = numberOfValues;
this->ArrayBegin = ::thrust::system::cuda::malloc<T>( this->NumberOfValues );
this->ArrayEnd = this->ArrayBegin + numberOfValues;
}
/// Allocates enough space in \c controlArray and copies the data in the
/// device vector into it.
///
VTKM_CONT_EXPORT void RetrieveOutputData(ContainerType &controlArray) const
{
controlArray.Allocate(this->NumberOfValues);
::thrust::copy(this->ArrayBegin,
this->ArrayEnd,
controlArray.GetPortal().GetRawIterator());
}
/// Resizes the device vector.
///
VTKM_CONT_EXPORT void Shrink(vtkm::Id numberOfValues)
{
// The operation will succeed even if this assertion fails, but this
// is still supposed to be a precondition to Shrink.
VTKM_ASSERT_CONT(numberOfValues <= this->NumberOfValues);
this->NumberOfValues = numberOfValues;
this->ArrayEnd = this->ArrayBegin + this->NumberOfValues;
}
VTKM_CONT_EXPORT PortalType GetPortal()
{
return PortalType(this->ArrayBegin, this->ArrayEnd);
}
VTKM_CONT_EXPORT PortalConstType GetPortalConst() const
{
if(!this->HaveTextureBound)
{
this->HaveTextureBound = true;
this->InputArrayIterator.BindTexture(ArrayBegin,this->NumberOfValues);
}
//if we have a texture iterator bound use that
return PortalConstType(this->InputArrayIterator, this->NumberOfValues);
}
/// Frees all memory.
///
VTKM_CONT_EXPORT void ReleaseResources() {
if(this->HaveTextureBound)
{
this->HaveTextureBound = false;
this->InputArrayIterator.UnbindTexture();
}
::thrust::system::cuda::free( this->ArrayBegin );
this->ArrayBegin = ::thrust::system::cuda::pointer<ValueType>();
this->ArrayEnd = ::thrust::system::cuda::pointer<ValueType>();
}
private:
// Not implemented
ArrayManagerExecutionThrustDevice(
ArrayManagerExecutionThrustDevice<T, StorageTag> &);
void operator=(
ArrayManagerExecutionThrustDevice<T, StorageTag> &);
vtkm::Id NumberOfValues;
::thrust::system::cuda::pointer<ValueType> ArrayBegin;
::thrust::system::cuda::pointer<ValueType> ArrayEnd;
mutable bool HaveTextureBound;
mutable TextureIteratorType InputArrayIterator;
};
}
}
}
} // namespace vtkm::cont::cuda::internal
#endif // vtk_m_cont_cuda_internal_ArrayManagerExecutionThrustDevice_h

@ -0,0 +1,32 @@
##============================================================================
## 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 Sandia Corporation.
## Copyright 2014 UT-Battelle, LLC.
## Copyright 2014. Los Alamos National Security
##
## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
## 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.
##============================================================================
set(headers
ArrayManagerExecutionCuda.h
ArrayManagerExecutionThrustDevice.h
DeviceAdapterAlgorithmCuda.h
DeviceAdapterAlgorithmThrust.h
DeviceAdapterTagCuda.h
SetThrustForCuda.h
)
vtkm_declare_headers(CUDA ${headers})
add_subdirectory(testing)

@ -0,0 +1,97 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cuda_internal_DeviceAdapterAlgorithmCuda_h
#define vtk_m_cont_cuda_internal_DeviceAdapterAlgorithmCuda_h
#include <vtkm/cont/cuda/internal/SetThrustForCuda.h>
#include <vtkm/cont/cuda/internal/DeviceAdapterTagCuda.h>
#include <vtkm/cont/cuda/internal/ArrayManagerExecutionCuda.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
// Here are the actual implementation of the algorithms.
#include <vtkm/cont/cuda/internal/DeviceAdapterAlgorithmThrust.h>
#include <cuda.h>
namespace vtkm {
namespace cont {
template<>
struct DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagCuda>
: public vtkm::cont::cuda::internal::DeviceAdapterAlgorithmThrust<
vtkm::cont::DeviceAdapterTagCuda>
{
VTKM_CONT_EXPORT static void Synchronize()
{
cudaError_t error = cudaDeviceSynchronize();
}
};
/// CUDA contains its own high resolution timer.
///
template<>
class DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda>
{
public:
VTKM_CONT_EXPORT DeviceAdapterTimerImplementation()
{
cudaEventCreate(&this->StartEvent);
cudaEventCreate(&this->EndEvent);
this->Reset();
}
VTKM_CONT_EXPORT ~DeviceAdapterTimerImplementation()
{
cudaEventDestroy(this->StartEvent);
cudaEventDestroy(this->EndEvent);
}
VTKM_CONT_EXPORT void Reset()
{
cudaEventRecord(this->StartEvent, 0);
}
VTKM_CONT_EXPORT vtkm::Float64 GetElapsedTime()
{
cudaEventRecord(this->EndEvent, 0);
cudaEventSynchronize(this->EndEvent);
float elapsedTimeMilliseconds;
cudaEventElapsedTime(&elapsedTimeMilliseconds,
this->StartEvent,
this->EndEvent);
return static_cast<vtkm::Float64>(0.001f*elapsedTimeMilliseconds);
}
private:
// Copying CUDA events is problematic.
DeviceAdapterTimerImplementation(const DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda> &);
void operator=(const DeviceAdapterTimerImplementation<vtkm::cont::DeviceAdapterTagCuda> &);
cudaEvent_t StartEvent;
cudaEvent_t EndEvent;
};
}
} // namespace vtkm::cont
#endif //vtk_m_cont_cuda_internal_DeviceAdapterAlgorithmCuda_h

@ -0,0 +1,609 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cuda_internal_DeviceAdapterThrust_h
#define vtk_m_cont_cuda_internal_DeviceAdapterThrust_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/cuda/internal/MakeThrustIterator.h>
#include <vtkm/exec/internal/ErrorMessageBuffer.h>
#include <vtkm/exec/internal/WorkletInvokeFunctor.h>
// Disable GCC warnings we check vtkmfor but Thrust does not.
#if defined(__GNUC__) && !defined(VTKM_CUDA)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif // gcc version >= 4.6
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 2)
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif // gcc version >= 4.2
#endif // gcc && !CUDA
#include <thrust/advance.h>
#include <thrust/binary_search.h>
#include <thrust/copy.h>
#include <thrust/count.h>
#include <thrust/scan.h>
#include <thrust/sort.h>
#include <thrust/unique.h>
#include <thrust/system/cuda/vector.h>
#include <thrust/iterator/counting_iterator.h>
#if defined(__GNUC__) && !defined(VTKM_CUDA)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif // gcc version >= 4.6
#endif // gcc && !CUDA
namespace vtkm {
namespace cont {
namespace cuda {
namespace internal {
/// This class can be subclassed to implement the DeviceAdapterAlgorithm for a
/// device that uses thrust as its implementation. The subclass should pass in
/// the correct device adapter tag as the template parameter.
///
template<class DeviceAdapterTag>
struct DeviceAdapterAlgorithmThrust
{
// Because of some funny code conversions in nvcc, kernels for devices have to
// be public.
#ifndef VTKM_CUDA
private:
#endif
template<class InputPortal, class OutputPortal>
VTKM_CONT_EXPORT static void CopyPortal(const InputPortal &input,
const OutputPortal &output)
{
::thrust::copy(IteratorBegin(input),
IteratorEnd(input),
IteratorBegin(output));
}
template<class InputPortal, class ValuesPortal, class OutputPortal>
VTKM_CONT_EXPORT static void LowerBoundsPortal(const InputPortal &input,
const ValuesPortal &values,
const OutputPortal &output)
{
::thrust::lower_bound(IteratorBegin(input),
IteratorEnd(input),
IteratorBegin(values),
IteratorEnd(values),
IteratorBegin(output));
}
template<class InputPortal, class ValuesPortal, class OutputPortal,
class Compare>
VTKM_CONT_EXPORT static void LowerBoundsPortal(const InputPortal &input,
const ValuesPortal &values,
const OutputPortal &output,
Compare comp)
{
::thrust::lower_bound(IteratorBegin(input),
IteratorEnd(input),
IteratorBegin(values),
IteratorEnd(values),
IteratorBegin(output),
comp);
}
template<class InputPortal, class OutputPortal>
VTKM_CONT_EXPORT static
void LowerBoundsPortal(const InputPortal &input,
const OutputPortal &values_output)
{
::thrust::lower_bound(IteratorBegin(input),
IteratorEnd(input),
IteratorBegin(values_output),
IteratorEnd(values_output),
IteratorBegin(values_output));
}
template<class InputPortal, class OutputPortal>
VTKM_CONT_EXPORT static
typename InputPortal::ValueType ScanExclusivePortal(const InputPortal &input,
const OutputPortal &output)
{
// Use iterator to get value so that thrust device_ptr has chance to handle
// data on device.
typename InputPortal::ValueType inputEnd = *(IteratorEnd(input) - 1);
::thrust::exclusive_scan(IteratorBegin(input),
IteratorEnd(input),
IteratorBegin(output));
//return the value at the last index in the array, as that is the sum
return *(IteratorEnd(output) - 1) + inputEnd;
}
template<class InputPortal, class OutputPortal>
VTKM_CONT_EXPORT static
typename InputPortal::ValueType ScanInclusivePortal(const InputPortal &input,
const OutputPortal &output)
{
::thrust::inclusive_scan(IteratorBegin(input),
IteratorEnd(input),
IteratorBegin(output));
//return the value at the last index in the array, as that is the sum
return *(IteratorEnd(output) - 1);
}
template<class ValuesPortal>
VTKM_CONT_EXPORT static void SortPortal(const ValuesPortal &values)
{
::thrust::sort(IteratorBegin(values),
IteratorEnd(values));
}
template<class ValuesPortal, class Compare>
VTKM_CONT_EXPORT static void SortPortal(const ValuesPortal &values,
Compare comp)
{
::thrust::sort(IteratorBegin(values),
IteratorEnd(values),
comp);
}
template<class KeysPortal, class ValuesPortal>
VTKM_CONT_EXPORT static void SortByKeyPortal(const KeysPortal &keys,
const ValuesPortal &values)
{
::thrust::sort_by_key(IteratorBegin(keys),
IteratorEnd(keys),
IteratorBegin(values));
}
template<class KeysPortal, class ValuesPortal, class Compare>
VTKM_CONT_EXPORT static void SortByKeyPortal(const KeysPortal &keys,
const ValuesPortal &values,
Compare comp)
{
::thrust::sort_by_key(IteratorBegin(keys),
IteratorEnd(keys),
IteratorBegin(values),
comp);
}
template<class StencilPortal>
VTKM_CONT_EXPORT static vtkm::Id CountIfPortal(const StencilPortal &stencil)
{
typedef typename StencilPortal::ValueType ValueType;
return ::thrust::count_if(IteratorBegin(stencil),
IteratorEnd(stencil),
::vtkm::not_default_constructor<ValueType>());
}
template<class ValueIterator,
class StencilPortal,
class OutputPortal>
VTKM_CONT_EXPORT static void CopyIfPortal(ValueIterator valuesBegin,
ValueIterator valuesEnd,
const StencilPortal &stencil,
const OutputPortal &output)
{
typedef typename StencilPortal::ValueType ValueType;
::thrust::copy_if(valuesBegin,
valuesEnd,
IteratorBegin(stencil),
IteratorBegin(output),
::vtkm::not_default_constructor<ValueType>());
}
template<class ValueIterator,
class StencilArrayHandle,
class OutputArrayHandle>
VTKM_CONT_EXPORT static void RemoveIf(ValueIterator valuesBegin,
ValueIterator valuesEnd,
const StencilArrayHandle& stencil,
OutputArrayHandle& output)
{
vtkm::Id numLeft = CountIfPortal(stencil.PrepareForInput(DeviceAdapterTag()));
CopyIfPortal(valuesBegin,
valuesEnd,
stencil.PrepareForInput(DeviceAdapterTag()),
output.PrepareForOutput(numLeft, DeviceAdapterTag()));
}
template<class InputPortal,
class StencilArrayHandle,
class OutputArrayHandle>
VTKM_CONT_EXPORT static
void StreamCompactPortal(const InputPortal& inputPortal,
const StencilArrayHandle &stencil,
OutputArrayHandle& output)
{
RemoveIf(IteratorBegin(inputPortal),
IteratorEnd(inputPortal),
stencil,
output);
}
template<class ValuesPortal>
VTKM_CONT_EXPORT static
vtkm::Id UniquePortal(const ValuesPortal values)
{
typedef typename detail::IteratorTraits<ValuesPortal>::IteratorType
IteratorType;
IteratorType begin = IteratorBegin(values);
IteratorType newLast = ::thrust::unique(begin, IteratorEnd(values));
return ::thrust::distance(begin, newLast);
}
template<class ValuesPortal, class Compare>
VTKM_CONT_EXPORT static
vtkm::Id UniquePortal(const ValuesPortal values, Compare comp)
{
typedef typename detail::IteratorTraits<ValuesPortal>::IteratorType
IteratorType;
IteratorType begin = IteratorBegin(values);
IteratorType newLast = ::thrust::unique(begin, IteratorEnd(values), comp);
return ::thrust::distance(begin, newLast);
}
template<class InputPortal, class ValuesPortal, class OutputPortal>
VTKM_CONT_EXPORT static
void UpperBoundsPortal(const InputPortal &input,
const ValuesPortal &values,
const OutputPortal &output)
{
::thrust::upper_bound(IteratorBegin(input),
IteratorEnd(input),
IteratorBegin(values),
IteratorEnd(values),
IteratorBegin(output));
}
template<class InputPortal, class ValuesPortal, class OutputPortal,
class Compare>
VTKM_CONT_EXPORT static void UpperBoundsPortal(const InputPortal &input,
const ValuesPortal &values,
const OutputPortal &output,
Compare comp)
{
::thrust::upper_bound(IteratorBegin(input),
IteratorEnd(input),
IteratorBegin(values),
IteratorEnd(values),
IteratorBegin(output),
comp);
}
template<class InputPortal, class OutputPortal>
VTKM_CONT_EXPORT static
void UpperBoundsPortal(const InputPortal &input,
const OutputPortal &values_output)
{
::thrust::upper_bound(IteratorBegin(input),
IteratorEnd(input),
IteratorBegin(values_output),
IteratorEnd(values_output),
IteratorBegin(values_output));
}
//-----------------------------------------------------------------------------
public:
template<typename T, class SIn, class SOut>
VTKM_CONT_EXPORT static void Copy(
const vtkm::cont::ArrayHandle<T,SIn> &input,
vtkm::cont::ArrayHandle<T,SOut> &output)
{
vtkm::Id numberOfValues = input.GetNumberOfValues();
CopyPortal(input.PrepareForInput(DeviceAdapterTag()),
output.PrepareForOutput(numberOfValues, DeviceAdapterTag()));
}
template<typename T, class SIn, class SVal, class SOut>
VTKM_CONT_EXPORT static void LowerBounds(
const vtkm::cont::ArrayHandle<T,SIn>& input,
const vtkm::cont::ArrayHandle<T,SVal>& values,
vtkm::cont::ArrayHandle<vtkm::Id,SOut>& output)
{
vtkm::Id numberOfValues = values.GetNumberOfValues();
LowerBoundsPortal(input.PrepareForInput(DeviceAdapterTag()),
values.PrepareForInput(DeviceAdapterTag()),
output.PrepareForOutput(numberOfValues, DeviceAdapterTag()));
}
template<typename T, class SIn, class SVal, class SOut, class Compare>
VTKM_CONT_EXPORT static void LowerBounds(
const vtkm::cont::ArrayHandle<T,SIn>& input,
const vtkm::cont::ArrayHandle<T,SVal>& values,
vtkm::cont::ArrayHandle<vtkm::Id,SOut>& output,
Compare comp)
{
vtkm::Id numberOfValues = values.GetNumberOfValues();
LowerBoundsPortal(input.PrepareForInput(DeviceAdapterTag()),
values.PrepareForInput(DeviceAdapterTag()),
output.PrepareForOutput(numberOfValues, DeviceAdapterTag()),
comp);
}
template<class SIn, class SOut>
VTKM_CONT_EXPORT static void LowerBounds(
const vtkm::cont::ArrayHandle<vtkm::Id,SIn> &input,
vtkm::cont::ArrayHandle<vtkm::Id,SOut> &values_output)
{
LowerBoundsPortal(input.PrepareForInput(DeviceAdapterTag()),
values_output.PrepareForInPlace(DeviceAdapterTag()));
}
template<typename T, class SIn, class SOut>
VTKM_CONT_EXPORT static T ScanExclusive(
const vtkm::cont::ArrayHandle<T,SIn> &input,
vtkm::cont::ArrayHandle<T,SOut>& output)
{
vtkm::Id numberOfValues = input.GetNumberOfValues();
if (numberOfValues <= 0)
{
output.PrepareForOutput(0, DeviceAdapterTag());
return 0;
}
return ScanExclusivePortal(input.PrepareForInput(DeviceAdapterTag()),
output.PrepareForOutput(numberOfValues, DeviceAdapterTag()));
}
template<typename T, class SIn, class SOut>
VTKM_CONT_EXPORT static T ScanInclusive(
const vtkm::cont::ArrayHandle<T,SIn> &input,
vtkm::cont::ArrayHandle<T,SOut>& output)
{
vtkm::Id numberOfValues = input.GetNumberOfValues();
if (numberOfValues <= 0)
{
output.PrepareForOutput(0, DeviceAdapterTag());
return 0;
}
return ScanInclusivePortal(input.PrepareForInput(DeviceAdapterTag()),
output.PrepareForOutput(numberOfValues, DeviceAdapterTag()));
}
// Because of some funny code conversions in nvcc, kernels for devices have to
// be public.
#ifndef VTKM_CUDA
private:
#endif
// we use cuda pinned memory to reduce the amount of synchronization
// and mem copies between the host and device.
VTKM_CONT_EXPORT
static char* GetPinnedErrorArray(vtkm::Id &arraySize, char** hostPointer)
{
const vtkm::Id ERROR_ARRAY_SIZE = 1024;
static bool errorArrayInit = false;
static char* hostPtr = NULL;
static char* devicePtr = NULL;
if( !errorArrayInit )
{
cudaMallocHost( (void**)&hostPtr, ERROR_ARRAY_SIZE, cudaHostAllocMapped );
cudaHostGetDevicePointer(&devicePtr, hostPtr, 0);
errorArrayInit = true;
}
//set the size of the array
arraySize = ERROR_ARRAY_SIZE;
//specify the host pointer to the memory
*hostPointer = hostPtr;
(void) hostPointer;
return devicePtr;
}
template<class FunctorType>
class ScheduleKernel
{
public:
VTKM_CONT_EXPORT ScheduleKernel(const FunctorType &functor)
: Functor(functor)
{ }
VTKM_EXEC_EXPORT void operator()(vtkm::Id index) const {
this->Functor(index);
}
private:
FunctorType Functor;
};
public:
template<class Functor>
VTKM_CONT_EXPORT static void Schedule(Functor functor, vtkm::Id numInstances)
{
//since the memory is pinned we can access it safely on the host
//without a memcpy
vtkm::Id errorArraySize = 0;
char* hostErrorPtr = NULL;
char* deviceErrorPtr = GetPinnedErrorArray(errorArraySize, &hostErrorPtr);
//clear the first character which means that we don't contain an error
hostErrorPtr[0] = '\0';
vtkm::exec::internal::ErrorMessageBuffer errorMessage( deviceErrorPtr,
errorArraySize);
functor.SetErrorMessageBuffer(errorMessage);
ScheduleKernel<Functor> kernel(functor);
::thrust::for_each(::thrust::make_counting_iterator<vtkm::Id>(0),
::thrust::make_counting_iterator<vtkm::Id>(numInstances),
kernel);
//sync so that we can check the results of the call.
//In the future I want move this before the for_each call, and throwing
//an exception if the previous schedule wrote an error. This would help
//cuda to run longer before we hard sync.
cudaDeviceSynchronize();
//check what the value is
if (hostErrorPtr[0] != '\0')
{
throw vtkm::cont::ErrorExecution(hostErrorPtr);
}
}
template<class FunctorType>
VTKM_CONT_EXPORT
static void Schedule(FunctorType functor, const vtkm::Id3& rangeMax)
{
//default behavior for the general algorithm is to defer to the default
//schedule implementation. if you want to customize schedule for certain
//grid types, you need to specialize this method
DeviceAdapterAlgorithmThrust<DeviceAdapterTag>::Schedule(functor,
rangeMax[0] * rangeMax[1] * rangeMax[2] );
}
template<typename T, class Storage>
VTKM_CONT_EXPORT static void Sort(
vtkm::cont::ArrayHandle<T,Storage>& values)
{
SortPortal(values.PrepareForInPlace(DeviceAdapterTag()));
}
template<typename T, class Storage, class Compare>
VTKM_CONT_EXPORT static void Sort(
vtkm::cont::ArrayHandle<T,Storage>& values,
Compare comp)
{
SortPortal(values.PrepareForInPlace(DeviceAdapterTag()),comp);
}
template<typename T, typename U,
class StorageT, class StorageU>
VTKM_CONT_EXPORT static void SortByKey(
vtkm::cont::ArrayHandle<T,StorageT>& keys,
vtkm::cont::ArrayHandle<U,StorageU>& values)
{
SortByKeyPortal(keys.PrepareForInPlace(DeviceAdapterTag()),
values.PrepareForInPlace(DeviceAdapterTag()));
}
template<typename T, typename U,
class StorageT, class StorageU,
class Compare>
VTKM_CONT_EXPORT static void SortByKey(
vtkm::cont::ArrayHandle<T,StorageT>& keys,
vtkm::cont::ArrayHandle<U,StorageU>& values,
Compare comp)
{
SortByKeyPortal(keys.PrepareForInPlace(DeviceAdapterTag()),
values.PrepareForInPlace(DeviceAdapterTag()),
comp);
}
template<typename T, class SStencil, class SOut>
VTKM_CONT_EXPORT static void StreamCompact(
const vtkm::cont::ArrayHandle<T,SStencil>& stencil,
vtkm::cont::ArrayHandle<vtkm::Id,SOut>& output)
{
vtkm::Id stencilSize = stencil.GetNumberOfValues();
RemoveIf(::thrust::make_counting_iterator<vtkm::Id>(0),
::thrust::make_counting_iterator<vtkm::Id>(stencilSize),
stencil,
output);
}
template<typename T,
typename U,
class SIn,
class SStencil,
class SOut>
VTKM_CONT_EXPORT static void StreamCompact(
const vtkm::cont::ArrayHandle<U,SIn>& input,
const vtkm::cont::ArrayHandle<T,SStencil>& stencil,
vtkm::cont::ArrayHandle<U,SOut>& output)
{
StreamCompactPortal(input.PrepareForInput(DeviceAdapterTag()), stencil, output);
}
template<typename T, class Storage>
VTKM_CONT_EXPORT static void Unique(
vtkm::cont::ArrayHandle<T,Storage> &values)
{
vtkm::Id newSize = UniquePortal(values.PrepareForInPlace(DeviceAdapterTag()));
values.Shrink(newSize);
}
template<typename T, class Storage, class Compare>
VTKM_CONT_EXPORT static void Unique(
vtkm::cont::ArrayHandle<T,Storage> &values,
Compare comp)
{
vtkm::Id newSize = UniquePortal(values.PrepareForInPlace(DeviceAdapterTag()),comp);
values.Shrink(newSize);
}
template<typename T, class SIn, class SVal, class SOut>
VTKM_CONT_EXPORT static void UpperBounds(
const vtkm::cont::ArrayHandle<T,SIn>& input,
const vtkm::cont::ArrayHandle<T,SVal>& values,
vtkm::cont::ArrayHandle<vtkm::Id,SOut>& output)
{
vtkm::Id numberOfValues = values.GetNumberOfValues();
UpperBoundsPortal(input.PrepareForInput(DeviceAdapterTag()),
values.PrepareForInput(DeviceAdapterTag()),
output.PrepareForOutput(numberOfValues, DeviceAdapterTag()));
}
template<typename T, class SIn, class SVal, class SOut, class Compare>
VTKM_CONT_EXPORT static void UpperBounds(
const vtkm::cont::ArrayHandle<T,SIn>& input,
const vtkm::cont::ArrayHandle<T,SVal>& values,
vtkm::cont::ArrayHandle<vtkm::Id,SOut>& output,
Compare comp)
{
vtkm::Id numberOfValues = values.GetNumberOfValues();
UpperBoundsPortal(input.PrepareForInput(DeviceAdapterTag()),
values.PrepareForInput(DeviceAdapterTag()),
output.PrepareForOutput(numberOfValues, DeviceAdapterTag()),
comp);
}
template<class SIn, class SOut>
VTKM_CONT_EXPORT static void UpperBounds(
const vtkm::cont::ArrayHandle<vtkm::Id,SIn> &input,
vtkm::cont::ArrayHandle<vtkm::Id,SOut> &values_output)
{
UpperBoundsPortal(input.PrepareForInput(DeviceAdapterTag()),
values_output.PrepareForInPlace(DeviceAdapterTag()));
}
};
}
}
}
} // namespace vtkm::cont::cuda::internal
#endif //vtk_m_cont_cuda_internal_DeviceAdapterThrust_h

@ -0,0 +1,28 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cuda_internal_DeviceAdapterTagCuda_h
#define vtk_m_cont_cuda_internal_DeviceAdapterTagCuda_h
#include <vtkm/cont/internal/DeviceAdapterTag.h>
VTKM_CREATE_DEVICE_ADAPTER(Cuda);
#endif //vtk_m_cont_cuda_internal_DeviceAdapterTagCuda_h

@ -0,0 +1,256 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cuda_internal_MakeThrustIterator_h
#define vtk_m_cont_cuda_internal_MakeThrustIterator_h
#include <vtkm/Types.h>
#include <vtkm/internal/ExportMacros.h>
#include <vtkm/exec/cuda/internal/ArrayPortalFromThrust.h>
#include <vtkm/exec/cuda/internal/ArrayPortalFromTexture.h>
// Disable GCC warnings we check vtkmfor but Thrust does not.
#if defined(__GNUC__) && !defined(VTKM_CUDA)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif // gcc version >= 4.6
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 2)
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif // gcc version >= 4.2
#endif // gcc && !CUDA
#include <thrust/system/cuda/memory.h>
#include <thrust/functional.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/iterator/transform_iterator.h>
#if defined(__GNUC__) && !defined(VTKM_CUDA)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif // gcc version >= 4.6
#endif // gcc && !CUDA
namespace vtkm {
namespace cont {
namespace cuda {
namespace internal {
namespace detail {
// Tags to specify what type of thrust iterator to use.
struct ThrustIteratorTransformTag { };
struct ThrustIteratorDevicePtrTag { };
struct ThrustIteratorDeviceTextureTag { };
// Traits to help classify what thrust iterators will be used.
template<class IteratorType>
struct ThrustIteratorTag {
typedef ThrustIteratorTransformTag Type;
};
template<typename T>
struct ThrustIteratorTag<T *> {
typedef ThrustIteratorDevicePtrTag Type;
};
template<typename T>
struct ThrustIteratorTag<const T*> {
typedef ThrustIteratorDevicePtrTag Type;
};
template<typename T> struct ThrustStripPointer;
template<typename T> struct ThrustStripPointer<T *> {
typedef T Type;
};
template<typename T> struct ThrustStripPointer<const T *> {
typedef const T Type;
};
template<class PortalType>
struct PortalValue {
typedef typename PortalType::ValueType ValueType;
VTKM_EXEC_EXPORT
PortalValue(const PortalType &portal, vtkm::Id index)
: Portal(portal), Index(index) { }
VTKM_EXEC_EXPORT
ValueType operator=(ValueType value) {
this->Portal.Set(this->Index, value);
return value;
}
VTKM_EXEC_EXPORT
operator ValueType(void) const {
return this->Portal.Get(this->Index);
}
const PortalType Portal;
const vtkm::Id Index;
};
template<class PortalType>
class LookupFunctor
: public ::thrust::unary_function<vtkm::Id,
PortalValue<PortalType> >
{
public:
VTKM_CONT_EXPORT LookupFunctor(PortalType portal)
: Portal(portal) { }
VTKM_EXEC_EXPORT
PortalValue<PortalType>
operator()(vtkm::Id index)
{
return PortalValue<PortalType>(this->Portal, index);
}
private:
PortalType Portal;
};
template<class PortalType, class Tag> struct IteratorChooser;
template<class PortalType>
struct IteratorChooser<PortalType, detail::ThrustIteratorTransformTag> {
typedef ::thrust::transform_iterator<
LookupFunctor<PortalType>,
::thrust::counting_iterator<vtkm::Id> > Type;
};
template<class PortalType>
struct IteratorChooser<PortalType, detail::ThrustIteratorDevicePtrTag> {
typedef ::thrust::cuda::pointer<
typename detail::ThrustStripPointer<
typename PortalType::IteratorType>::Type> Type;
};
template<class PortalType>
struct IteratorTraits
{
typedef typename PortalType::IteratorType BaseIteratorType;
typedef typename detail::ThrustIteratorTag<BaseIteratorType>::Type Tag;
typedef typename IteratorChooser<PortalType, Tag>::Type IteratorType;
};
template<typename T>
struct IteratorTraits< vtkm::exec::cuda::internal::ConstArrayPortalFromTexture< T > >
{
typedef vtkm::exec::cuda::internal::ConstArrayPortalFromTexture< T > PortalType;
typedef ThrustIteratorDeviceTextureTag Tag;
typedef typename PortalType::IteratorType IteratorType;
};
template<typename T>
VTKM_CONT_EXPORT static
::thrust::cuda::pointer<T>
MakeDevicePtr(T *iter)
{
return::thrust::cuda::pointer<T>(iter);
}
template<typename T>
VTKM_CONT_EXPORT static
::thrust::cuda::pointer<const T>
MakeDevicePtr(const T *iter)
{
return ::thrust::cuda::pointer<const T>(iter);
}
template<class PortalType>
VTKM_CONT_EXPORT static
typename IteratorTraits<PortalType>::IteratorType
MakeIteratorBegin(PortalType portal, detail::ThrustIteratorTransformTag)
{
return ::thrust::make_transform_iterator(
::thrust::make_counting_iterator(vtkm::Id(0)),
LookupFunctor<PortalType>(portal));
}
template<class PortalType>
VTKM_CONT_EXPORT static
typename IteratorTraits<PortalType>::IteratorType
MakeIteratorBegin(PortalType portal, detail::ThrustIteratorDevicePtrTag)
{
return MakeDevicePtr(portal.GetIteratorBegin());
}
template<class PortalType>
VTKM_CONT_EXPORT static
typename IteratorTraits<PortalType>::IteratorType
MakeIteratorBegin(PortalType portal, detail::ThrustIteratorDeviceTextureTag)
{
return portal.GetIteratorBegin();
}
} // namespace detail
template<class PortalType>
VTKM_CONT_EXPORT
typename detail::IteratorTraits<PortalType>::IteratorType
IteratorBegin(PortalType portal)
{
typedef typename detail::IteratorTraits<PortalType>::Tag IteratorTag;
return detail::MakeIteratorBegin(portal, IteratorTag());
}
template<class PortalType>
VTKM_CONT_EXPORT
typename detail::IteratorTraits<PortalType>::IteratorType
IteratorEnd(PortalType portal)
{
return IteratorBegin(portal) + portal.GetNumberOfValues();
}
}
}
}
} //namespace vtkm::cont::cuda::internal
namespace thrust {
template< typename PortalType >
struct less< vtkm::cont::cuda::internal::detail::PortalValue< PortalType > > :
public binary_function<
vtkm::cont::cuda::internal::detail::PortalValue< PortalType >,
vtkm::cont::cuda::internal::detail::PortalValue< PortalType >,
bool>
{
typedef vtkm::cont::cuda::internal::detail::PortalValue< PortalType > T;
typedef typename vtkm::cont::cuda::internal::detail::PortalValue<
PortalType >::ValueType ValueType;
/*! Function call operator. The return value is <tt>lhs < rhs</tt>.
*/
__host__ __device__ bool operator()(const T &lhs, const T &rhs) const
{return (ValueType)lhs < (ValueType)rhs;}
/*! Function call operator. The return value is <tt>lhs < rhs</tt>.
specially designed to work with vtkm portal values, which can
be compared to their underline type
*/
__host__ __device__ bool operator()(const T &lhs,
const ValueType &rhs) const
{return (ValueType)lhs < rhs;}
}; // end less
}
#endif

@ -0,0 +1,56 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cuda_internal_SetThrustForCuda_h
#define vtk_m_cont_cuda_internal_SetThrustForCuda_h
#include <vtkm/internal/Configure.h>
#ifdef DAX_ENABLE_THRUST
#if DAX_THRUST_MAJOR_VERSION == 1 && DAX_THRUST_MINOR_VERSION >= 6
#ifndef THRUST_DEVICE_SYSTEM
#define THRUST_DEVICE_SYSTEM THRUST_DEVICE_SYSTEM_CUDA
#else // defined THRUST_DEVICE_BACKEND
#if THRUST_DEVICE_SYSTEM != THRUST_DEVICE_SYSTEM_CUDA
#error Thrust device backend set incorrectly.
#endif // THRUST_DEVICE_SYSTEM != THRUST_DEVICE_SYSTEM_CUDA
#endif // defined(THRUST_DEVICE_SYSTEM)
#else //DAX_THRUST_MAJOR_VERSION == 1 && DAX_THRUST_MINOR_VERSION >= 6
#ifndef THRUST_DEVICE_BACKEND
#define THRUST_DEVICE_BACKEND THRUST_DEVICE_BACKEND_CUDA
#else // defined THRUST_DEVICE_BACKEND
#if THRUST_DEVICE_BACKEND != THRUST_DEVICE_BACKEND_CUDA
#error Thrust device backend set incorrectly.
#endif // THRUST_DEVICE_BACKEND != THRUST_DEVICE_BACKEND_CUDA
#endif // defined THRUST_DEVICE_BACKEND
#endif //DAX_THRUST_MAJOR_VERSION == 1 && DAX_THRUST_MINOR_VERSION >= 6
#endif //DAX_ENABLE_THRUST
#endif //vtk_m_cont_cuda_internal_SetThrustForCuda_h

@ -0,0 +1,26 @@
##============================================================================
## 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 Sandia Corporation.
## Copyright 2014 UT-Battelle, LLC.
## Copyright 2014. Los Alamos National Security
##
## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
## 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.
##============================================================================
set(headers
Testing.h
)
vtkm_declare_headers(CUDA ${headers})

@ -0,0 +1,64 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_cuda_internal_Testing_h
#define vtk_m_cont_cuda_internal_Testing_h
#include <vtkm/cont/testing/Testing.h>
#include <cuda.h>
namespace vtkm {
namespace cont {
namespace cuda {
namespace internal {
struct Testing
{
public:
static VTKM_CONT_EXPORT int CheckCudaBeforeExit(int result)
{
cudaError_t cudaError = cudaPeekAtLastError();
if (cudaError != cudaSuccess)
{
std::cout << "***** Unchecked Cuda error." << std::endl
<< cudaGetErrorString(cudaError) << std::endl;
return 1;
}
else
{
std::cout << "No Cuda error detected." << std::endl;
}
return result;
}
template<class Func>
static VTKM_CONT_EXPORT int Run(Func function)
{
int result = vtkm::cont::testing::Testing::Run(function);
return CheckCudaBeforeExit(result);
}
};
}
}
}
} // namespace vtkm::cont::cuda::internal
#endif //vtk_m_cont_cuda_internal_Testing_h

@ -0,0 +1,26 @@
##============================================================================
## 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 Sandia Corporation.
## Copyright 2014 UT-Battelle, LLC.
## Copyright 2014. Los Alamos National Security
##
## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
## 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.
##============================================================================
set(unit_tests
UnitTestCudaArrayHandle.cu
UnitTestCudaArrayHandleCounting.cu
UnitTestDeviceAdapterCuda.cu
)
vtkm_unit_tests(CUDA SOURCES ${unit_tests})

@ -0,0 +1,101 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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 VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_CUDA
#define BOOST_SP_DISABLE_THREADS
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/cuda/internal/testing/Testing.h>
namespace ut_handle_explicit{
const vtkm::Id ARRAY_SIZE = 300;
struct PassThrough : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn<>, FieldOut<>);
typedef _2 ExecutionSignature(_1);
template<class ValueType>
VTKM_EXEC_EXPORT
ValueType operator()(const ValueType &inValue) const
{ return inValue; }
};
template< typename ValueType >
struct CountingTest
{
void operator()(const ValueType v) const
{
std::vector< ValueType > inputVector(ARRAY_SIZE);
for(int i=0; i < ARRAY_SIZE; ++i)
{
inputVector[i] = v + i;
}
vtkm::cont::ArrayHandle< ValueType > input =
vtkm::cont::make_ArrayHandle( inputVector );
vtkm::cont::ArrayHandle< ValueType > result;
vtkm::worklet::DispatcherMapField< ut_handle_explicit::PassThrough > dispatcher;
dispatcher.Invoke(input, result);
//verify that the control portal works
for(int i=v; i < ARRAY_SIZE; ++i)
{
const ValueType result_v = result.GetPortalConstControl().Get(i);
const ValueType correct_value = v + ValueType(i);
VTKM_TEST_ASSERT(result_v == correct_value, "Counting Handle Failed");
}
}
};
template <typename T>
void RunCountingTest(const T t)
{
CountingTest<T> tests;
tests(t);
}
void TestArrayHandle()
{
RunCountingTest( vtkm::Id(42) );
RunCountingTest( vtkm::Float32(3) );
// RunCountingTest( vtkm::Vec< vtkm::Float32, 3>() );
}
} // ut_handle_explicit namespace
int UnitTestCudaArrayHandle(int, char *[])
{
return vtkm::cont::cuda::internal::Testing::Run(
ut_handle_explicit::TestArrayHandle);
}

@ -0,0 +1,101 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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 VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_CUDA
#define BOOST_SP_DISABLE_THREADS
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/cuda/internal/testing/Testing.h>
namespace ut_handle_counting{
const vtkm::Id ARRAY_SIZE = 300;
struct PassThrough : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn<>, FieldOut<>);
typedef _2 ExecutionSignature(_1);
template<class ValueType>
VTKM_EXEC_EXPORT
ValueType operator()(const ValueType &inValue) const
{ return inValue; }
};
template< typename ValueType >
struct CountingTest
{
void operator()(const ValueType v) const
{
const ValueType start = v;
const ValueType end = start + ARRAY_SIZE;
vtkm::cont::ArrayHandleCounting< ValueType > implicit =
vtkm::cont::make_ArrayHandleCounting(start, end);
vtkm::cont::ArrayHandle< ValueType > result;
vtkm::worklet::DispatcherMapField< ut_handle_counting::PassThrough > dispatcher;
dispatcher.Invoke(implicit, result);
//verify that the control portal works
for(int i=v; i < ARRAY_SIZE; ++i)
{
const ValueType result_v = result.GetPortalConstControl().Get(i);
const ValueType correct_value = v + ValueType(i);
VTKM_TEST_ASSERT(result_v == correct_value, "Counting Handle Failed");
}
}
};
template <typename T>
void RunCountingTest(const T t)
{
CountingTest<T> tests;
tests(t);
}
void TestArrayHandleCounting()
{
RunCountingTest( vtkm::Id(42) );
RunCountingTest( vtkm::Float32(3) );
// RunCountingTest( vtkm::Vec< vtkm::Float32, 3>() );
}
} // ut_handle_counting namespace
int UnitTestCudaArrayHandleCounting(int, char *[])
{
return vtkm::cont::cuda::internal::Testing::Run(
ut_handle_counting::TestArrayHandleCounting);
}

@ -0,0 +1,66 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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 VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_ERROR
#define BOOST_SP_DISABLE_THREADS
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/testing/TestingDeviceAdapter.h>
#include <vtkm/cont/cuda/internal/testing/Testing.h>
namespace vtkm {
namespace cont {
namespace testing {
template<>
struct CopyInto<vtkm::cont::DeviceAdapterTagCuda>
{
template<typename T, typename StorageTagType>
VTKM_CONT_EXPORT
void operator()( vtkm::cont::internal::ArrayManagerExecution<
T,
StorageTagType,
vtkm::cont::DeviceAdapterTagCuda>& manager,
T* start)
{
typedef vtkm::cont::internal::Storage< T, StorageTagType > StorageType;
StorageType outputArray;
std::cout << "now calling RetrieveOutputData: " << std::endl;
manager.RetrieveOutputData( outputArray );
vtkm::cont::ArrayPortalToIterators<
typename StorageType::PortalConstType>
iterators(outputArray.GetPortalConst());
std::copy(iterators.GetBegin(), iterators.GetEnd(), start);
}
};
}
}
}
int UnitTestDeviceAdapterCuda(int, char *[])
{
int result = vtkm::cont::testing::TestingDeviceAdapter
<vtkm::cont::DeviceAdapterTagCuda>::Run();
return vtkm::cont::cuda::internal::Testing::CheckCudaBeforeExit(result);
}

@ -26,7 +26,6 @@ set(headers
ArrayPortalFromIterators.h
ArrayPortalShrink.h
ArrayTransfer.h
DeviceAdapterAlgorithm.h
DeviceAdapterAlgorithmGeneral.h
DeviceAdapterAlgorithmSerial.h
DeviceAdapterError.h

@ -31,20 +31,6 @@
#include <algorithm>
namespace {
/// Predicate that takes a single argument \c x, and returns
/// True if it isn't the identity of the Type \p T.
template<typename T>
struct not_default_constructor
{
VTKM_EXEC_CONT_EXPORT bool operator()(const T &x)
{
return (x != T());
}
};
}
namespace vtkm {
namespace cont {
namespace internal {
@ -621,7 +607,7 @@ private:
void operator()(vtkm::Id index) const
{
StencilValueType value = this->StencilPortal.Get(index);
bool flag = not_default_constructor<StencilValueType>()(value);
bool flag = ::vtkm::not_default_constructor<StencilValueType>()(value);
this->OutputPortal.Set(index, flag ? 1 : 0);
}
@ -656,7 +642,7 @@ private:
{
typedef typename StencilPortalType::ValueType StencilValueType;
StencilValueType stencilValue = this->StencilPortal.Get(index);
if (not_default_constructor<StencilValueType>()(stencilValue))
if (::vtkm::not_default_constructor<StencilValueType>()(stencilValue))
{
vtkm::Id outputIndex = this->IndexPortal.Get(index);

@ -22,8 +22,8 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/internal/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/internal/DeviceAdapterAlgorithmGeneral.h>
#include <vtkm/cont/internal/DeviceAdapterTagSerial.h>

@ -30,6 +30,7 @@
#define VTKM_DEVICE_ADAPTER_ERROR -2
#define VTKM_DEVICE_ADAPTER_UNDEFINED -1
#define VTKM_DEVICE_ADAPTER_SERIAL 1
#define VTKM_DEVICE_ADAPTER_CUDA 2
#ifndef VTKM_DEVICE_ADAPTER
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
@ -92,6 +93,11 @@ struct DeviceAdapterTagCheck
#include <vtkm/cont/internal/DeviceAdapterTagSerial.h>
#define VTKM_DEFAULT_DEVICE_ADAPTER_TAG ::vtkm::cont::DeviceAdapterTagSerial
#elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_CUDA
#include <vtkm/cont/cuda/internal/DeviceAdapterTagCuda.h>
#define VTKM_DEFAULT_DEVICE_ADAPTER_TAG ::vtkm::cont::DeviceAdapterTagCuda
#elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_ERROR
#include <vtkm/cont/internal/DeviceAdapterError.h>

@ -20,7 +20,7 @@
#ifndef vtk_m_cont_internal_DynamicTransform_h
#define vtk_m_cont_internal_DynamicTransform_h
#include "vtkm/internal/ExportMacros.h"
#include "vtkm/internal/IndexTag.h"
namespace vtkm {
namespace cont {
@ -62,10 +62,13 @@ struct DynamicTransformTraits {
///
struct DynamicTransform
{
template<typename InputType, typename ContinueFunctor>
template<typename InputType,
typename ContinueFunctor,
vtkm::IdComponent Index>
VTKM_CONT_EXPORT
void operator()(const InputType &input,
const ContinueFunctor &continueFunc) const
const ContinueFunctor &continueFunc,
vtkm::internal::IndexTag<Index>) const
{
this->DoTransform(
input,

@ -85,22 +85,24 @@ void TestBasicTransform()
std::cout << "Testing basic transform." << std::endl;
vtkm::cont::internal::DynamicTransform transform;
vtkm::internal::IndexTag<1> indexTag;
std::cout << " Trying with simple scalar." << std::endl;
TRY_TRANSFORM(transform(vtkm::FloatDefault(5), ScalarFunctor()));
TRY_TRANSFORM(transform(vtkm::FloatDefault(5), ScalarFunctor(), indexTag));
std::cout << " Trying with basic scalar array." << std::endl;
vtkm::cont::ArrayHandle<vtkm::FloatDefault> concreteArray;
TRY_TRANSFORM(transform(concreteArray, ArrayHandleScalarFunctor()));
TRY_TRANSFORM(transform(concreteArray, ArrayHandleScalarFunctor(), indexTag));
std::cout << " Trying scalar dynamic array." << std::endl;
vtkm::cont::DynamicArrayHandle dynamicArray = concreteArray;
TRY_TRANSFORM(transform(dynamicArray, ArrayHandleScalarFunctor()));
TRY_TRANSFORM(transform(dynamicArray, ArrayHandleScalarFunctor(), indexTag));
std::cout << " Trying with unusual (string) dynamic array." << std::endl;
dynamicArray = vtkm::cont::ArrayHandle<std::string>();
TRY_TRANSFORM(transform(dynamicArray.ResetTypeList(TypeListTagString()),
ArrayHandleStringFunctor()));
ArrayHandleStringFunctor(),
indexTag));
}
void TestFunctionTransform()

@ -26,7 +26,7 @@
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/StorageBasic.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/cont/internal/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/internal/DeviceAdapterError.h>
@ -103,6 +103,31 @@ struct SortGreater
};
}
//in the namespace vtkm::cont::testing so device adapters
//that don't use shared memory space can specialize this
template<typename DeviceTagType>
struct CopyInto
{
template<typename T, typename StorageTagType>
VTKM_CONT_EXPORT
void operator()( vtkm::cont::internal::ArrayManagerExecution<
T,
StorageTagType,
DeviceTagType>& manager,
T* start)
{
typedef vtkm::cont::internal::ArrayManagerExecution< T,
StorageTagType, DeviceTagType> ArrayManagerExecution;
vtkm::cont::ArrayPortalToIterators<
typename ArrayManagerExecution::PortalConstType>
iterators(manager.GetPortalConst());
std::copy(iterators.GetBegin(), iterators.GetEnd(), start);
}
};
#define ERROR_MESSAGE "Got an error."
#define ARRAY_SIZE 500
#define OFFSET 1000
@ -375,12 +400,16 @@ private:
// Change size.
inputManager.Shrink(ARRAY_SIZE);
// Copy array back.
// Copy array back. The issue is we need to know if we are accessing
// an array manger that shares memory with the control side. If so
// it doesn't support RetrieveOutputData.
// the naive way is to use ArrayPortalToIteratorBegin but that fails
// since it only works with portals from arrayhandles, as the
// arrayhandle does all the syncing.
//The solution is to a class that the cuda device adapter can specialize
//that handles copying back into control space
vtkm::FloatDefault outputArray[ARRAY_SIZE];
vtkm::cont::ArrayPortalToIterators<
typename ArrayManagerExecution::PortalConstType>
iterators(inputManager.GetPortalConst());
std::copy(iterators.GetBegin(), iterators.GetEnd(), outputArray);
CopyInto<DeviceAdapterTag>()(inputManager, outputArray);
// Check array.
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
@ -1289,22 +1318,22 @@ private:
{
std::cout << "Doing DeviceAdapter tests" << std::endl;
TestArrayManagerExecution();
TestOutOfMemory();
TestTimer();
// TestOutOfMemory();
// TestTimer();
TestAlgorithmSchedule();
TestErrorExecution();
TestScanInclusive();
TestScanExclusive();
TestSortWithComparisonObject();
// TestSortByKey();
TestLowerBoundsWithComparisonObject();
TestUpperBoundsWithComparisonObject();
TestUniqueWithComparisonObject();
TestOrderedUniqueValues(); //tests Copy, LowerBounds, Sort, Unique
// TestDispatcher();
TestStreamCompactWithStencil();
TestStreamCompact();
// TestAlgorithmSchedule();
// TestErrorExecution();
// TestScanInclusive();
// TestScanExclusive();
// TestSortWithComparisonObject();
// // TestSortByKey();
// TestLowerBoundsWithComparisonObject();
// TestUpperBoundsWithComparisonObject();
// TestUniqueWithComparisonObject();
// TestOrderedUniqueValues(); //tests Copy, LowerBounds, Sort, Unique
// // TestDispatcher();
// TestStreamCompactWithStencil();
// TestStreamCompact();
// std::cout << "Doing Worklet tests with all grid type" << std::endl;

@ -0,0 +1,490 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
/******************************************************************************
* Copyright (c) 2011, Duane Merrill. All rights reserved.
* Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the NVIDIA CORPORATION nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef vtk_m_exec_cuda_internal_ArrayPortalFromTexture_h
#define vtk_m_exec_cuda_internal_ArrayPortalFromTexture_h
#include <vtkm/Types.h>
#include <iterator>
// Disable GCC warnings we check vtkmfor but Thrust does not.
#if defined(__GNUC__) && !defined(VTKM_CUDA)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif // gcc version >= 4.6
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 2)
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif // gcc version >= 4.2
#endif // gcc && !CUDA
#include <thrust/system/cuda/memory.h>
#include <thrust/iterator/iterator_facade.h>
#if defined(__GNUC__) && !defined(VTKM_CUDA)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif // gcc version >= 4.6
#endif // gcc && !CUDA
namespace
{
/**
* \brief Type selection (<tt>IF ? ThenType : ElseType</tt>)
*/
template <bool IF, typename ThenType, typename ElseType>
struct If
{
/// Conditional type result
typedef ThenType Type; // true
};
template <typename ThenType, typename ElseType>
struct If<false, ThenType, ElseType>
{
typedef ElseType Type; // false
};
/******************************************************************************
* Size and alignment
******************************************************************************/
/// Structure alignment
template <typename T>
struct AlignBytes
{
struct Pad
{
T val;
char byte;
};
enum
{
/// The alignment of T in bytes
ALIGN_BYTES = sizeof(Pad) - sizeof(T)
};
};
// Specializations where host C++ compilers (e.g., Windows) may disagree with device C++ compilers (EDG)
template <> struct AlignBytes<short4> { enum { ALIGN_BYTES = 8 }; };
template <> struct AlignBytes<ushort4> { enum { ALIGN_BYTES = 8 }; };
template <> struct AlignBytes<int2> { enum { ALIGN_BYTES = 8 }; };
template <> struct AlignBytes<uint2> { enum { ALIGN_BYTES = 8 }; };
#ifdef _WIN32
template <> struct AlignBytes<long2> { enum { ALIGN_BYTES = 8 }; };
template <> struct AlignBytes<ulong2> { enum { ALIGN_BYTES = 8 }; };
#endif
template <> struct AlignBytes<long long> { enum { ALIGN_BYTES = 8 }; };
template <> struct AlignBytes<unsigned long long> { enum { ALIGN_BYTES = 8 }; };
template <> struct AlignBytes<float2> { enum { ALIGN_BYTES = 8 }; };
template <> struct AlignBytes<double> { enum { ALIGN_BYTES = 8 }; };
template <> struct AlignBytes<int4> { enum { ALIGN_BYTES = 16 }; };
template <> struct AlignBytes<uint4> { enum { ALIGN_BYTES = 16 }; };
template <> struct AlignBytes<float4> { enum { ALIGN_BYTES = 16 }; };
#ifndef _WIN32
template <> struct AlignBytes<long2> { enum { ALIGN_BYTES = 16 }; };
template <> struct AlignBytes<ulong2> { enum { ALIGN_BYTES = 16 }; };
#endif
template <> struct AlignBytes<long4> { enum { ALIGN_BYTES = 16 }; };
template <> struct AlignBytes<ulong4> { enum { ALIGN_BYTES = 16 }; };
template <> struct AlignBytes<longlong2> { enum { ALIGN_BYTES = 16 }; };
template <> struct AlignBytes<ulonglong2> { enum { ALIGN_BYTES = 16 }; };
template <> struct AlignBytes<double2> { enum { ALIGN_BYTES = 16 }; };
template <> struct AlignBytes<longlong4> { enum { ALIGN_BYTES = 16 }; };
template <> struct AlignBytes<ulonglong4> { enum { ALIGN_BYTES = 16 }; };
template <> struct AlignBytes<double4> { enum { ALIGN_BYTES = 16 }; };
/// Unit-words of data movement
template <typename T>
struct UnitWord
{
enum {
ALIGN_BYTES = AlignBytes<T>::ALIGN_BYTES
};
template <typename Unit>
struct IsMultiple
{
enum {
UNIT_ALIGN_BYTES = AlignBytes<Unit>::ALIGN_BYTES,
IS_MULTIPLE = (sizeof(T) % sizeof(Unit) == 0) && (ALIGN_BYTES % UNIT_ALIGN_BYTES == 0)
};
};
/// Biggest shuffle word that T is a whole multiple of and is not larger than the alignment of T
typedef typename If<IsMultiple<int>::IS_MULTIPLE,
unsigned int,
typename If<IsMultiple<short>::IS_MULTIPLE,
unsigned short,
unsigned char>::Type>::Type ShuffleWord;
/// Biggest volatile word that T is a whole multiple of and is not larger than the alignment of T
typedef typename If<IsMultiple<long long>::IS_MULTIPLE,
unsigned long long,
ShuffleWord>::Type VolatileWord;
/// Biggest memory-access word that T is a whole multiple of and is not larger than the alignment of T
typedef typename If<IsMultiple<longlong2>::IS_MULTIPLE,
ulonglong2,
VolatileWord>::Type DeviceWord;
/// Biggest texture reference word that T is a whole multiple of and is not larger than the alignment of T
typedef typename If<IsMultiple<int4>::IS_MULTIPLE,
uint4,
typename If<IsMultiple<int2>::IS_MULTIPLE,
uint2,
ShuffleWord>::Type>::Type TextureWord;
};
}
namespace vtkm {
namespace exec {
namespace cuda {
namespace internal {
template <
typename T,
typename Offset = ptrdiff_t>
class DaxTexObjInputIterator
{
public:
// Required iterator traits
typedef DaxTexObjInputIterator self_type; ///< My own type
typedef Offset difference_type; ///< Type to express the result of subtracting one iterator from another
typedef T value_type; ///< The type of the element the iterator can point to
typedef T* pointer; ///< The type of a pointer to an element the iterator can point to
typedef T reference; ///< The type of a reference to an element the iterator can point to
// Use Thrust's iterator categories so we can use these iterators in Thrust 1.7 (or newer) methods
typedef typename ::thrust::detail::iterator_facade_category<
::thrust::device_system_tag,
::thrust::random_access_traversal_tag,
value_type,
reference
>::type iterator_category; ///< The iterator category
private:
// Largest texture word we can use in device
typedef typename UnitWord<T>::TextureWord TextureWord;
// Number of texture words per T
enum { TEXTURE_MULTIPLE = sizeof(T) / sizeof(TextureWord) };
private:
const T* ptr;
difference_type tex_offset;
cudaTextureObject_t tex_obj;
public:
/// Constructor
__host__ __device__ __forceinline__ DaxTexObjInputIterator()
:
ptr(NULL),
tex_offset(0),
tex_obj(0)
{}
/// Use this iterator to bind \p ptr with a texture reference
cudaError_t BindTexture(
const ::thrust::system::cuda::pointer<T> ptr, ///< Native pointer to wrap that is aligned to cudaDeviceProp::textureAlignment
size_t numElements, ///< Number of elements in the range
size_t tex_offset = 0) ///< Offset (in items) from \p ptr denoting the position of the iterator
{
this->ptr = ptr.get();
this->tex_offset = tex_offset;
cudaChannelFormatDesc channel_desc = cudaCreateChannelDesc<TextureWord>();
cudaResourceDesc res_desc;
cudaTextureDesc tex_desc;
memset(&res_desc, 0, sizeof(cudaResourceDesc));
memset(&tex_desc, 0, sizeof(cudaTextureDesc));
res_desc.resType = cudaResourceTypeLinear;
res_desc.res.linear.devPtr = (void*)ptr.get();
res_desc.res.linear.desc = channel_desc;
res_desc.res.linear.sizeInBytes = numElements * sizeof(T);
tex_desc.readMode = cudaReadModeElementType;
return cudaCreateTextureObject(&tex_obj, &res_desc, &tex_desc, NULL);
}
/// Unbind this iterator from its texture reference
cudaError_t UnbindTexture()
{
return cudaDestroyTextureObject(tex_obj);
}
/// Postfix increment
__host__ __device__ __forceinline__ self_type operator++(int)
{
self_type retval = *this;
tex_offset++;
return retval;
}
/// Prefix increment
__host__ __device__ __forceinline__ self_type operator++()
{
tex_offset++;
return *this;
}
/// Postfix decrement
__host__ __device__ __forceinline__ self_type operator--(int)
{
self_type retval = *this;
tex_offset--;
return retval;
}
/// Prefix decrement
__host__ __device__ __forceinline__ self_type operator--()
{
tex_offset--;
return *this;
}
/// Indirection
__host__ __device__ __forceinline__ reference operator*() const
{
#ifndef DAX_CUDA_COMPILATION
// Simply dereference the pointer on the host
return ptr[tex_offset];
#else
// Move array of uninitialized words, then alias and assign to return value
TextureWord words[TEXTURE_MULTIPLE];
#pragma unroll
for (int i = 0; i < TEXTURE_MULTIPLE; ++i)
{
words[i] = tex1Dfetch<TextureWord>(
tex_obj,
(tex_offset * TEXTURE_MULTIPLE) + i);
}
// Load from words
return *reinterpret_cast<T*>(words);
#endif
}
/// Addition
template <typename Distance>
__host__ __device__ __forceinline__ self_type operator+(Distance n) const
{
self_type retval;
retval.ptr = ptr;
retval.tex_obj = tex_obj;
retval.tex_offset = tex_offset + n;
return retval;
}
/// Addition assignment
template <typename Distance>
__host__ __device__ __forceinline__ self_type& operator+=(Distance n)
{
tex_offset += n;
return *this;
}
/// Subtraction
template <typename Distance>
__host__ __device__ __forceinline__ self_type operator-(Distance n) const
{
self_type retval;
retval.ptr = ptr;
retval.tex_obj = tex_obj;
retval.tex_offset = tex_offset - n;
return retval;
}
/// Subtraction assignment
template <typename Distance>
__host__ __device__ __forceinline__ self_type& operator-=(Distance n)
{
tex_offset -= n;
return *this;
}
/// Distance
__host__ __device__ __forceinline__ difference_type operator-(self_type other) const
{
return tex_offset - other.tex_offset;
}
/// Array subscript
template <typename Distance>
__host__ __device__ __forceinline__ reference operator[](Distance n) const
{
return *(*this + n);
}
/// Structure dereference
__host__ __device__ __forceinline__ pointer operator->()
{
return &(*(*this));
}
/// Equal to
__host__ __device__ __forceinline__ bool operator==(const self_type& rhs) const
{
return ((ptr == rhs.ptr) && (tex_offset == rhs.tex_offset) && (tex_obj == rhs.tex_obj));
}
/// Not equal to
__host__ __device__ __forceinline__ bool operator!=(const self_type& rhs) const
{
return ((ptr != rhs.ptr) || (tex_offset != rhs.tex_offset) || (tex_obj != rhs.tex_obj));
}
/// less than
__host__ __device__ __forceinline__ bool operator<(const self_type& rhs)
{
return (tex_offset < rhs.tex_offset);
}
/// ostream operator
friend std::ostream& operator<<(std::ostream& os, const self_type& itr)
{
return os;
}
};
template<class TextureIterator>
class ConstArrayPortalFromTexture
{
public:
typedef typename TextureIterator::value_type ValueType;
typedef TextureIterator IteratorType;
VTKM_EXEC_CONT_EXPORT ConstArrayPortalFromTexture() { }
VTKM_CONT_EXPORT
ConstArrayPortalFromTexture(IteratorType begin, ptrdiff_t size)
: Length(size),
BeginIterator(begin),
EndIterator(begin+size)
{ }
/// Copy constructor for any other ConstArrayPortalFromTexture with an iterator
/// type that can be copied to this iterator type. This allows us to do any
/// type casting that the iterators do (like the non-const to const cast).
///
template<typename OtherIteratorT>
VTKM_EXEC_CONT_EXPORT
ConstArrayPortalFromTexture(const ConstArrayPortalFromTexture<OtherIteratorT> &src)
: Length(src.Length),
BeginIterator(src.BeginIterator),
EndIterator(src.EndIterator)
{ }
template<typename OtherIteratorT>
VTKM_EXEC_CONT_EXPORT
ConstArrayPortalFromTexture<IteratorType> &operator=(
const ConstArrayPortalFromTexture<OtherIteratorT> &src)
{
this->Length = src.Length;
this->BeginIterator = src.BeginIterator;
this->EndIterator = src.EndIterator;
return *this;
}
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfValues() const {
return static_cast<vtkm::Id>(this->Length);
}
VTKM_EXEC_EXPORT
ValueType Get(vtkm::Id index) const {
return *this->IteratorAt(index);
}
VTKM_EXEC_EXPORT
void Set(vtkm::Id index, ValueType value) const {
*this->IteratorAt(index) = value;
}
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const { return this->BeginIterator; }
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const { return this->EndIterator; }
private:
ptrdiff_t Length;
IteratorType BeginIterator;
IteratorType EndIterator;
VTKM_EXEC_EXPORT
IteratorType IteratorAt(vtkm::Id index) const {
// Not using std::advance because on CUDA it cannot be used on a device.
return (this->BeginIterator + index);
}
};
}
}
}
} // namespace vtkm::exec::cuda::internal
#endif //vtk_m_exec_cuda_internal_ArrayPortalFromTexture_h

@ -0,0 +1,202 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_exec_cuda_internal_ArrayPortalFromThrust_h
#define vtk_m_exec_cuda_internal_ArrayPortalFromThrust_h
#include <vtkm/Types.h>
#include <iterator>
// Disable GCC warnings we check vtkmfor but Thrust does not.
#if defined(__GNUC__) && !defined(VTKM_CUDA)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif // gcc version >= 4.6
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 2)
#pragma GCC diagnostic ignored "-Wshadow"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif // gcc version >= 4.2
#endif // gcc && !CUDA
#include <thrust/system/cuda/memory.h>
#if defined(__GNUC__) && !defined(VTKM_CUDA)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif // gcc version >= 4.6
#endif // gcc && !CUDA
namespace vtkm {
namespace exec {
namespace cuda {
namespace internal {
class ArrayPortalFromThrustBase {};
/// This templated implementation of an ArrayPortal allows you to adapt a pair
/// of begin/end iterators to an ArrayPortal interface.
///
template<typename T>
class ArrayPortalFromThrust : public ArrayPortalFromThrustBase
{
public:
typedef T ValueType;
typedef typename thrust::system::cuda::pointer< T > PointerType;
typedef T* IteratorType;
VTKM_EXEC_CONT_EXPORT ArrayPortalFromThrust() { }
VTKM_CONT_EXPORT
ArrayPortalFromThrust(PointerType begin, PointerType end)
: BeginIterator( begin ),
EndIterator( end )
{ }
/// Copy constructor for any other ArrayPortalFromThrust with an iterator
/// type that can be copied to this iterator type. This allows us to do any
/// type casting that the iterators do (like the non-const to const cast).
///
template<typename OtherT>
VTKM_EXEC_CONT_EXPORT
ArrayPortalFromThrust(const ArrayPortalFromThrust<OtherT> &src)
: BeginIterator(src.BeginIterator),
EndIterator(src.EndIterator)
{ }
template<typename OtherT>
VTKM_EXEC_CONT_EXPORT
ArrayPortalFromThrust<T> &operator=(
const ArrayPortalFromThrust<OtherT> &src)
{
this->BeginIterator = src.BeginIterator;
this->EndIterator = src.EndIterator;
return *this;
}
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfValues() const {
// Not using std::distance because on CUDA it cannot be used on a device.
return (this->EndIterator - this->BeginIterator);
}
VTKM_EXEC_EXPORT
ValueType Get(vtkm::Id index) const {
return *this->IteratorAt(index);
}
VTKM_EXEC_EXPORT
void Set(vtkm::Id index, ValueType value) const {
*this->IteratorAt(index) = value;
}
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const { return this->BeginIterator.get(); }
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const { return this->EndIterator.get(); }
private:
PointerType BeginIterator;
PointerType EndIterator;
VTKM_EXEC_EXPORT
PointerType IteratorAt(vtkm::Id index) const {
// Not using std::advance because on CUDA it cannot be used on a device.
return (this->BeginIterator + index);
}
};
template<typename T>
class ConstArrayPortalFromThrust : public ArrayPortalFromThrustBase
{
public:
typedef T ValueType;
typedef typename thrust::system::cuda::pointer< T > PointerType;
typedef const T* IteratorType;
VTKM_EXEC_CONT_EXPORT ConstArrayPortalFromThrust() { }
VTKM_CONT_EXPORT
ConstArrayPortalFromThrust(const PointerType begin, const PointerType end)
: BeginIterator( begin ),
EndIterator( end )
{ }
/// Copy constructor for any other ConstArrayPortalFromThrust with an iterator
/// type that can be copied to this iterator type. This allows us to do any
/// type casting that the iterators do (like the non-const to const cast).
///
template<typename OtherT>
VTKM_EXEC_CONT_EXPORT
ConstArrayPortalFromThrust(const ConstArrayPortalFromThrust<OtherT> &src)
: BeginIterator(src.BeginIterator),
EndIterator(src.EndIterator)
{ }
template<typename OtherT>
VTKM_EXEC_CONT_EXPORT
ConstArrayPortalFromThrust<T> &operator=(
const ConstArrayPortalFromThrust<OtherT> &src)
{
this->BeginIterator = src.BeginIterator;
this->EndIterator = src.EndIterator;
return *this;
}
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfValues() const {
// Not using std::distance because on CUDA it cannot be used on a device.
return (this->EndIterator - this->BeginIterator);
}
VTKM_EXEC_EXPORT
ValueType Get(vtkm::Id index) const {
return *this->IteratorAt(index);
}
VTKM_EXEC_EXPORT
void Set(vtkm::Id index, ValueType value) const {
*this->IteratorAt(index) = value;
}
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const { return this->BeginIterator.get(); }
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const { return this->EndIterator.get(); }
private:
PointerType BeginIterator;
PointerType EndIterator;
VTKM_EXEC_EXPORT
PointerType IteratorAt(vtkm::Id index) const {
// Not using std::advance because on CUDA it cannot be used on a device.
return (this->BeginIterator + index);
}
};
}
}
}
} // namespace vtkm::exec::cuda::internal
#endif //vtk_m_exec_cuda_internal_ArrayPortalFromThrust_h

@ -83,6 +83,7 @@ template<typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename R,
typename P1>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -117,6 +118,7 @@ template<typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
typename P1>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -148,6 +150,7 @@ template<typename WorkletType,
typename R,
typename P1,
typename P2>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -188,6 +191,7 @@ template<typename WorkletType,
vtkm::IdComponent InputDomainIndex,
typename P1,
typename P2>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -225,6 +229,7 @@ template<typename WorkletType,
typename P1,
typename P2,
typename P3>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -271,6 +276,7 @@ template<typename WorkletType,
typename P1,
typename P2,
typename P3>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -314,6 +320,7 @@ template<typename WorkletType,
typename P2,
typename P3,
typename P4>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -366,6 +373,7 @@ template<typename WorkletType,
typename P2,
typename P3,
typename P4>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -415,6 +423,7 @@ template<typename WorkletType,
typename P3,
typename P4,
typename P5>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -473,6 +482,7 @@ template<typename WorkletType,
typename P3,
typename P4,
typename P5>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -528,6 +538,7 @@ template<typename WorkletType,
typename P4,
typename P5,
typename P6>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -592,6 +603,7 @@ template<typename WorkletType,
typename P4,
typename P5,
typename P6>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -653,6 +665,7 @@ template<typename WorkletType,
typename P5,
typename P6,
typename P7>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -723,6 +736,7 @@ template<typename WorkletType,
typename P5,
typename P6,
typename P7>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -790,6 +804,7 @@ template<typename WorkletType,
typename P6,
typename P7,
typename P8>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -866,6 +881,7 @@ template<typename WorkletType,
typename P6,
typename P7,
typename P8>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -939,6 +955,7 @@ template<typename WorkletType,
typename P7,
typename P8,
typename P9>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -1021,6 +1038,7 @@ template<typename WorkletType,
typename P7,
typename P8,
typename P9>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -1100,6 +1118,7 @@ template<typename WorkletType,
typename P8,
typename P9,
typename P10>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -1188,6 +1207,7 @@ template<typename WorkletType,
typename P8,
typename P9,
typename P10>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<

@ -144,6 +144,7 @@ template<typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
$template_params(num_params)>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<
@ -182,6 +183,7 @@ template<typename WorkletType,
typename ControlInterface,
vtkm::IdComponent InputDomainIndex,
$template_params(num_params, start=1)>
VTKM_EXEC_EXPORT
void DoWorkletInvokeFunctor(
const WorkletType &worklet,
const vtkm::internal::Invocation<

@ -25,6 +25,7 @@ set(headers
FunctionInterface.h
FunctionInterfaceDetailPost.h
FunctionInterfaceDetailPre.h
IndexTag.h
Invocation.h
ListTagDetail.h
)

@ -20,9 +20,10 @@
#ifndef vtk_m_internal_FunctionInterface_h
#define vtk_m_internal_FunctionInterface_h
#include <vtkm/Pair.h>
#include <vtkm/Types.h>
#include <vtkm/internal/IndexTag.h>
#include <boost/function_types/components.hpp>
#include <boost/function_types/function_arity.hpp>
#include <boost/function_types/function_type.hpp>
@ -301,27 +302,75 @@ public:
}
/// Gets the value for the parameter of the given index. Parameters are
/// indexed starting at 1. To use this method you have to specify the index
/// as a template parameter. If you are using FunctionInterface within a
/// template (which is almost always the case), then you will have to use the
/// template keyword. For example, here is a simple implementation of a
/// method that grabs the first parameter of FunctionInterface.
/// indexed starting at 1. To use this method you have to specify a static,
/// compile time index. There are two ways to specify the index. The first is
/// to specify a specific template parameter (e.g.
/// <tt>GetParameter<1>()</tt>). Note that if you are using FunctionInterface
/// within a template (which is almost always the case), then you will have
/// to use the template keyword. For example, here is a simple implementation
/// of a method that grabs the first parameter of FunctionInterface.
///
/// \code{.cpp}
/// template<FunctionSignature>
/// void Foo(const vtkm::cont::internal::FunctionInterface<FunctionSignature> &fInterface)
/// void Foo(const vtkm::internal::FunctionInterface<FunctionSignature> &fInterface)
/// {
/// bar(fInterface.template GetParameter<1>());
/// }
/// \endcode
///
/// Alternatively the \c GetParameter method also has an optional argument
/// that can be a \c IndexTag that specifies the parameter index. Here is
/// a repeat of the previous example using this method.
///
/// \code{.cpp}
/// template<FunctionSignature>
/// void Foo(const vtkm::internal::FunctionInterface<FunctionSignature> &fInterface)
/// {
/// using vtkm::internal::IndexTag;
/// bar(fInterface.GetParameter(IndexTag<1>()));
/// }
/// \endcode
///
template<vtkm::IdComponent ParameterIndex>
VTKM_EXEC_CONT_EXPORT
typename ParameterType<ParameterIndex>::type
GetParameter() const {
GetParameter(
vtkm::internal::IndexTag<ParameterIndex> =
vtkm::internal::IndexTag<ParameterIndex>()) const {
return detail::GetParameter<ParameterIndex>(this->Parameters);
}
/// Sets the value for the parameter of the given index. Parameters are
/// indexed starting at 1. To use this method you have to specify a static,
/// compile time index. There are two ways to specify the index. The first is
/// to specify a specific template parameter (e.g.
/// <tt>SetParameter<1>(value)</tt>). Note that if you are using
/// FunctionInterface within a template (which is almost always the case),
/// then you will have to use the template keyword. For example, here is a
/// simple implementation of a method that grabs the first parameter of
/// FunctionInterface.
///
/// \code{.cpp}
/// template<FunctionSignature>
/// void Foo(vtkm::internal::FunctionInterface<FunctionSignature> &fInterface)
/// {
/// fInterface.template SetParameter<1>(bar);
/// }
/// \endcode
///
/// Alternatively the \c GetParameter method also has an optional argument
/// that can be a \c IndexTag that specifies the parameter index. Here is
/// a repeat of the previous example using this method.
///
/// \code{.cpp}
/// template<FunctionSignature>
/// void Foo(vtkm::internal::FunctionInterface<FunctionSignature> &fInterface)
/// {
/// using vtkm::internal::IndexTag;
/// fInterface.SetParameter(bar, IndexTag<1>());
/// }
/// \endcode
///
/// Sets the value for the parameter of the given index. Parameters are
/// indexed starting at 1. To use this method you have to specify the index
/// as a template parameter. If you are using FunctionInterface within a
@ -330,7 +379,10 @@ public:
///
template<vtkm::IdComponent ParameterIndex>
VTKM_EXEC_CONT_EXPORT
void SetParameter(typename ParameterType<ParameterIndex>::type parameter)
void SetParameter(
typename ParameterType<ParameterIndex>::type parameter,
vtkm::internal::IndexTag<ParameterIndex> =
vtkm::internal::IndexTag<ParameterIndex>())
{
detail::SetParameter<ParameterIndex>(this->Parameters, parameter);
}
@ -438,7 +490,7 @@ public:
/// template.
///
template<typename NewType>
VTKM_EXEC_CONT_EXPORT
VTKM_CONT_EXPORT
typename AppendType<NewType>::type
Append(NewType newParameter) const {
typename AppendType<NewType>::type appendedFuncInterface;
@ -461,15 +513,47 @@ public:
/// Returns a new \c FunctionInterface with all the parameters of this \c
/// FunctionInterface except that the parameter indexed at the template
/// parameter \c ParameterIndex is replaced with the given argument. This
/// method can be used in place of SetParameter when the parameter type
/// changes. The return type can be determined with the \c ReplaceType
/// template.
/// parameter \c ParameterIndex (also specified with the optional second
/// argument) is replaced with the given argument. This method can be used in
/// place of SetParameter when the parameter type changes. The return type
/// can be determined with the \c ReplaceType template.
/// Gets the value for the parameter of the given index. Parameters are
/// indexed starting at 1. To use this method you have to specify a static,
/// compile time index. There are two ways to specify the index. The first is
/// to specify a specific template parameter (e.g.
/// <tt>GetParameter<1>()</tt>). Note that if you are using FunctionInterface
/// within a template (which is almost always the case), then you will have
/// to use the template keyword. For example, here is a simple implementation
/// of a method that grabs the first parameter of FunctionInterface.
///
/// \code{.cpp}
/// template<FunctionSignature>
/// void Foo(const vtkm::internal::FunctionInterface<FunctionSignature> &fInterface)
/// {
/// bar(fInterface.template GetParameter<1>());
/// }
/// \endcode
///
/// Alternatively the \c GetParameter method also has an optional argument
/// that can be a \c IndexTag that specifies the parameter index. Here is
/// a repeat of the previous example using this method.
///
/// \code{.cpp}
/// template<FunctionSignature>
/// void Foo(const vtkm::internal::FunctionInterface<FunctionSignature> &fInterface)
/// {
/// using vtkm::internal::IndexTag;
/// bar(fInterface.GetParameter(IndexTag<1>()));
/// }
/// \endcode
///
///
template<vtkm::IdComponent ParameterIndex, typename NewType>
VTKM_EXEC_CONT_EXPORT
VTKM_CONT_EXPORT
typename ReplaceType<ParameterIndex, NewType>::type
Replace(NewType newParameter) const {
Replace(NewType newParameter,
vtkm::internal::IndexTag<ParameterIndex> =
vtkm::internal::IndexTag<ParameterIndex>()) const {
typename ReplaceType<ParameterIndex, NewType>::type replacedFuncInterface;
detail::FunctionInterfaceCopyParameters<ParameterIndex-1>::
Copy(replacedFuncInterface.Parameters, this->Parameters);
@ -491,11 +575,13 @@ public:
///
/// The \c StaticTransform methods transform all the parameters of this \c
/// FunctionInterface to different types and values based on compile-time
/// information. It operates by accepting a functor that defines a unary
/// function whose argument is the parameter to transform and the return
/// value is the transformed value. The functor must also contain a templated
/// struct name ReturnType with an internal type named \c type that defines
/// the return type of the transform for a given input type.
/// information. It operates by accepting a functor that two arguments. The
/// first argument is the parameter to transform and the second argument is
/// an \c IndexTag specifying the index of the parameter (which can be
/// ignored in many cases). The functor's return value is the transformed
/// value. The functor must also contain a templated struct name ReturnType
/// with an internal type named \c type that defines the return type of the
/// transform for a given input type and parameter index.
///
/// The transformation is only applied to the parameters of the function. The
/// return argument is unaffected.
@ -509,14 +595,14 @@ public:
///
/// \code
/// struct MyTransformFunctor {
/// template<typename T>
/// template<typename T, vtkm::IdComponent Index>
/// struct ReturnType {
/// typedef const T *type;
/// };
///
/// template<typename T>
/// template<typename T, vtkm::IdComponent Index>
/// VTKM_CONT_EXPORT
/// const T *operator()(const T &x) const {
/// const T *operator()(const T &x, vtkm::internal::IndexTag<Index>) const {
/// return &x;
/// }
/// };
@ -557,10 +643,11 @@ public:
/// The \c DynamicTransform method transforms all the parameters of this \c
/// FunctionInterface to different types and values based on run-time
/// information. It operates by accepting two functors. The first functor
/// accepts two arguments. The first argument is a parameter to transform and
/// the second is a functor to call with the transformed result.
/// accepts three arguments. The first argument is a parameter to transform,
/// the second is a functor to call with the transformed result, and the third
/// is an instance of \c IndexTag denoting the index parameter..
///
/// The second argument to \c DynamicTransform is another function that
/// The second argument to \c DynamicTransform is another functor that
/// accepts the transformed \c FunctionInterface and does something. If that
/// transformed \c FunctionInterface has a return value, that return value
/// will be passed back to this \c FunctionInterface.
@ -568,23 +655,27 @@ public:
/// Here is a contrived but illustrative example. This transformation will
/// pass all arguments except any string that looks like a number will be
/// converted to a vtkm::FloatDefault. Note that because the types are not
/// determined till runtime, this transform cannot be determined at compile
/// determined until runtime, this transform cannot be determined at compile
/// time with meta-template programming.
///
/// \code
/// struct MyTransformFunctor {
/// template<typename InputType, typename ContinueFunctor>
/// template<typename InputType,
/// typename ContinueFunctor,
/// vtkm::IdComponent Index>
/// VTKM_CONT_EXPORT
/// void operator()(const InputType &input,
/// const ContinueFunctor &continueFunc) const
/// const ContinueFunctor &continueFunc,
/// vtkm::internal::IndexTag<Index>) const
/// {
/// continueFunc(input);
/// }
///
/// template<typename ContinueFunctor>
/// template<typename ContinueFunctor, vtkm::IdComponent Index>
/// VTKM_CONT_EXPORT
/// void operator()(const std::string &input,
/// const ContinueFunctor &continueFunc) const
/// const ContinueFunctor &continueFunc,
/// vtkm::internal::IndexTag<Index>) const
/// {
/// if ((input[0] >= '0' && (input[0] <= '9'))
/// {
@ -642,9 +733,11 @@ public:
/// \brief Applies a function to all the parameters.
///
/// The \c ForEach methods take a function and apply that function to each
/// of the parameters in the \c FunctionInterface. (Return values are not
/// effected.)
/// The \c ForEach methods take a functor and apply that functor to each of
/// the parameters in the \c FunctionInterface. (Return values are not
/// effected.) The first argument of the functor is the parameter value and
/// the second argument is an \c IndexTag, which can be used to identify the
/// index of the parameter.
///
template<typename Functor>
VTKM_CONT_EXPORT
@ -721,8 +814,12 @@ public:
nextInterface,
this->Transform,
this->Finish);
this->Transform(this->OriginalInterface.template GetParameter<vtkm::internal::FunctionInterface<NextFunction>::ARITY + 1>(),
nextContinue);
static const vtkm::IdComponent Index =
vtkm::internal::FunctionInterface<NextFunction>::ARITY + 1;
vtkm::internal::IndexTag<Index> indexTag;
this->Transform(this->OriginalInterface.GetParameter(indexTag),
nextContinue,
indexTag);
}
template<typename NextFunction>
@ -746,27 +843,8 @@ private:
const FinishFunctor &Finish;
};
template<typename FirstType, typename SecondType>
struct FunctionInterfaceZipReturn
{
typedef vtkm::Pair<FirstType,SecondType> type;
};
template<>
struct FunctionInterfaceZipReturn<void, void>
{
typedef void type;
};
} // namespace detail
/// Used to determine the type returned from \c make_FunctionInterfaceZip.
/// Contains a typedef named \c type that is the appropriate \c
/// FunctionInterface type.
///
template<typename FirstFunctionInterface, typename SecondFunctionInterface>
struct FunctionInterfaceZipType;
}
} // namespace vtkm::internal

@ -53,7 +53,7 @@ template<typename Transform,
typename P1>
struct FunctionInterfaceStaticTransformType<R(P1), Transform> {
typedef R(type)(
typename Transform::template ReturnType<P1>::type
typename Transform::template ReturnType<P1,1>::type
);
};
@ -63,8 +63,8 @@ template<typename Transform,
typename P2>
struct FunctionInterfaceStaticTransformType<R(P1,P2), Transform> {
typedef R(type)(
typename Transform::template ReturnType<P1>::type,
typename Transform::template ReturnType<P2>::type
typename Transform::template ReturnType<P1,1>::type,
typename Transform::template ReturnType<P2,2>::type
);
};
@ -75,9 +75,9 @@ template<typename Transform,
typename P3>
struct FunctionInterfaceStaticTransformType<R(P1,P2,P3), Transform> {
typedef R(type)(
typename Transform::template ReturnType<P1>::type,
typename Transform::template ReturnType<P2>::type,
typename Transform::template ReturnType<P3>::type
typename Transform::template ReturnType<P1,1>::type,
typename Transform::template ReturnType<P2,2>::type,
typename Transform::template ReturnType<P3,3>::type
);
};
@ -89,10 +89,10 @@ template<typename Transform,
typename P4>
struct FunctionInterfaceStaticTransformType<R(P1,P2,P3,P4), Transform> {
typedef R(type)(
typename Transform::template ReturnType<P1>::type,
typename Transform::template ReturnType<P2>::type,
typename Transform::template ReturnType<P3>::type,
typename Transform::template ReturnType<P4>::type
typename Transform::template ReturnType<P1,1>::type,
typename Transform::template ReturnType<P2,2>::type,
typename Transform::template ReturnType<P3,3>::type,
typename Transform::template ReturnType<P4,4>::type
);
};
@ -105,11 +105,11 @@ template<typename Transform,
typename P5>
struct FunctionInterfaceStaticTransformType<R(P1,P2,P3,P4,P5), Transform> {
typedef R(type)(
typename Transform::template ReturnType<P1>::type,
typename Transform::template ReturnType<P2>::type,
typename Transform::template ReturnType<P3>::type,
typename Transform::template ReturnType<P4>::type,
typename Transform::template ReturnType<P5>::type
typename Transform::template ReturnType<P1,1>::type,
typename Transform::template ReturnType<P2,2>::type,
typename Transform::template ReturnType<P3,3>::type,
typename Transform::template ReturnType<P4,4>::type,
typename Transform::template ReturnType<P5,5>::type
);
};
@ -123,12 +123,12 @@ template<typename Transform,
typename P6>
struct FunctionInterfaceStaticTransformType<R(P1,P2,P3,P4,P5,P6), Transform> {
typedef R(type)(
typename Transform::template ReturnType<P1>::type,
typename Transform::template ReturnType<P2>::type,
typename Transform::template ReturnType<P3>::type,
typename Transform::template ReturnType<P4>::type,
typename Transform::template ReturnType<P5>::type,
typename Transform::template ReturnType<P6>::type
typename Transform::template ReturnType<P1,1>::type,
typename Transform::template ReturnType<P2,2>::type,
typename Transform::template ReturnType<P3,3>::type,
typename Transform::template ReturnType<P4,4>::type,
typename Transform::template ReturnType<P5,5>::type,
typename Transform::template ReturnType<P6,6>::type
);
};
@ -143,13 +143,13 @@ template<typename Transform,
typename P7>
struct FunctionInterfaceStaticTransformType<R(P1,P2,P3,P4,P5,P6,P7), Transform> {
typedef R(type)(
typename Transform::template ReturnType<P1>::type,
typename Transform::template ReturnType<P2>::type,
typename Transform::template ReturnType<P3>::type,
typename Transform::template ReturnType<P4>::type,
typename Transform::template ReturnType<P5>::type,
typename Transform::template ReturnType<P6>::type,
typename Transform::template ReturnType<P7>::type
typename Transform::template ReturnType<P1,1>::type,
typename Transform::template ReturnType<P2,2>::type,
typename Transform::template ReturnType<P3,3>::type,
typename Transform::template ReturnType<P4,4>::type,
typename Transform::template ReturnType<P5,5>::type,
typename Transform::template ReturnType<P6,6>::type,
typename Transform::template ReturnType<P7,7>::type
);
};
@ -165,14 +165,14 @@ template<typename Transform,
typename P8>
struct FunctionInterfaceStaticTransformType<R(P1,P2,P3,P4,P5,P6,P7,P8), Transform> {
typedef R(type)(
typename Transform::template ReturnType<P1>::type,
typename Transform::template ReturnType<P2>::type,
typename Transform::template ReturnType<P3>::type,
typename Transform::template ReturnType<P4>::type,
typename Transform::template ReturnType<P5>::type,
typename Transform::template ReturnType<P6>::type,
typename Transform::template ReturnType<P7>::type,
typename Transform::template ReturnType<P8>::type
typename Transform::template ReturnType<P1,1>::type,
typename Transform::template ReturnType<P2,2>::type,
typename Transform::template ReturnType<P3,3>::type,
typename Transform::template ReturnType<P4,4>::type,
typename Transform::template ReturnType<P5,5>::type,
typename Transform::template ReturnType<P6,6>::type,
typename Transform::template ReturnType<P7,7>::type,
typename Transform::template ReturnType<P8,8>::type
);
};
@ -189,15 +189,15 @@ template<typename Transform,
typename P9>
struct FunctionInterfaceStaticTransformType<R(P1,P2,P3,P4,P5,P6,P7,P8,P9), Transform> {
typedef R(type)(
typename Transform::template ReturnType<P1>::type,
typename Transform::template ReturnType<P2>::type,
typename Transform::template ReturnType<P3>::type,
typename Transform::template ReturnType<P4>::type,
typename Transform::template ReturnType<P5>::type,
typename Transform::template ReturnType<P6>::type,
typename Transform::template ReturnType<P7>::type,
typename Transform::template ReturnType<P8>::type,
typename Transform::template ReturnType<P9>::type
typename Transform::template ReturnType<P1,1>::type,
typename Transform::template ReturnType<P2,2>::type,
typename Transform::template ReturnType<P3,3>::type,
typename Transform::template ReturnType<P4,4>::type,
typename Transform::template ReturnType<P5,5>::type,
typename Transform::template ReturnType<P6,6>::type,
typename Transform::template ReturnType<P7,7>::type,
typename Transform::template ReturnType<P8,8>::type,
typename Transform::template ReturnType<P9,9>::type
);
};
@ -215,16 +215,16 @@ template<typename Transform,
typename P10>
struct FunctionInterfaceStaticTransformType<R(P1,P2,P3,P4,P5,P6,P7,P8,P9,P10), Transform> {
typedef R(type)(
typename Transform::template ReturnType<P1>::type,
typename Transform::template ReturnType<P2>::type,
typename Transform::template ReturnType<P3>::type,
typename Transform::template ReturnType<P4>::type,
typename Transform::template ReturnType<P5>::type,
typename Transform::template ReturnType<P6>::type,
typename Transform::template ReturnType<P7>::type,
typename Transform::template ReturnType<P8>::type,
typename Transform::template ReturnType<P9>::type,
typename Transform::template ReturnType<P10>::type
typename Transform::template ReturnType<P1,1>::type,
typename Transform::template ReturnType<P2,2>::type,
typename Transform::template ReturnType<P3,3>::type,
typename Transform::template ReturnType<P4,4>::type,
typename Transform::template ReturnType<P5,5>::type,
typename Transform::template ReturnType<P6,6>::type,
typename Transform::template ReturnType<P7,7>::type,
typename Transform::template ReturnType<P8,8>::type,
typename Transform::template ReturnType<P9,9>::type,
typename Transform::template ReturnType<P10,10>::type
);
};
@ -641,753 +641,6 @@ make_FunctionInterface(
}
template<typename TR,
typename UR>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR()>,
vtkm::internal::FunctionInterface<UR()> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<TR,UR>::type (
)> type;
};
template<typename TR,
typename TP1,
typename UR,
typename UP1>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1)>,
vtkm::internal::FunctionInterface<UR(UP1)> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<TR,UR>::type (
vtkm::Pair<TP1, UP1>
)> type;
};
template<typename TR,
typename TP1,
typename TP2,
typename UR,
typename UP1,
typename UP2>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2)> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<TR,UR>::type (
vtkm::Pair<TP1, UP1>,
vtkm::Pair<TP2, UP2>
)> type;
};
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename UR,
typename UP1,
typename UP2,
typename UP3>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3)> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<TR,UR>::type (
vtkm::Pair<TP1, UP1>,
vtkm::Pair<TP2, UP2>,
vtkm::Pair<TP3, UP3>
)> type;
};
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4)> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<TR,UR>::type (
vtkm::Pair<TP1, UP1>,
vtkm::Pair<TP2, UP2>,
vtkm::Pair<TP3, UP3>,
vtkm::Pair<TP4, UP4>
)> type;
};
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5)> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<TR,UR>::type (
vtkm::Pair<TP1, UP1>,
vtkm::Pair<TP2, UP2>,
vtkm::Pair<TP3, UP3>,
vtkm::Pair<TP4, UP4>,
vtkm::Pair<TP5, UP5>
)> type;
};
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename TP6,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5,
typename UP6>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6)> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<TR,UR>::type (
vtkm::Pair<TP1, UP1>,
vtkm::Pair<TP2, UP2>,
vtkm::Pair<TP3, UP3>,
vtkm::Pair<TP4, UP4>,
vtkm::Pair<TP5, UP5>,
vtkm::Pair<TP6, UP6>
)> type;
};
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename TP6,
typename TP7,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5,
typename UP6,
typename UP7>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7)> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<TR,UR>::type (
vtkm::Pair<TP1, UP1>,
vtkm::Pair<TP2, UP2>,
vtkm::Pair<TP3, UP3>,
vtkm::Pair<TP4, UP4>,
vtkm::Pair<TP5, UP5>,
vtkm::Pair<TP6, UP6>,
vtkm::Pair<TP7, UP7>
)> type;
};
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename TP6,
typename TP7,
typename TP8,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5,
typename UP6,
typename UP7,
typename UP8>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8)> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<TR,UR>::type (
vtkm::Pair<TP1, UP1>,
vtkm::Pair<TP2, UP2>,
vtkm::Pair<TP3, UP3>,
vtkm::Pair<TP4, UP4>,
vtkm::Pair<TP5, UP5>,
vtkm::Pair<TP6, UP6>,
vtkm::Pair<TP7, UP7>,
vtkm::Pair<TP8, UP8>
)> type;
};
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename TP6,
typename TP7,
typename TP8,
typename TP9,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5,
typename UP6,
typename UP7,
typename UP8,
typename UP9>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8,TP9)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8,UP9)> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<TR,UR>::type (
vtkm::Pair<TP1, UP1>,
vtkm::Pair<TP2, UP2>,
vtkm::Pair<TP3, UP3>,
vtkm::Pair<TP4, UP4>,
vtkm::Pair<TP5, UP5>,
vtkm::Pair<TP6, UP6>,
vtkm::Pair<TP7, UP7>,
vtkm::Pair<TP8, UP8>,
vtkm::Pair<TP9, UP9>
)> type;
};
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename TP6,
typename TP7,
typename TP8,
typename TP9,
typename TP10,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5,
typename UP6,
typename UP7,
typename UP8,
typename UP9,
typename UP10>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8,TP9,TP10)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8,UP9,UP10)> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<TR,UR>::type (
vtkm::Pair<TP1, UP1>,
vtkm::Pair<TP2, UP2>,
vtkm::Pair<TP3, UP3>,
vtkm::Pair<TP4, UP4>,
vtkm::Pair<TP5, UP5>,
vtkm::Pair<TP6, UP6>,
vtkm::Pair<TP7, UP7>,
vtkm::Pair<TP8, UP8>,
vtkm::Pair<TP9, UP9>,
vtkm::Pair<TP10, UP10>
)> type;
};
/// Creates a "zipped" version of two \c FunctionInterface objects. Each
/// parameter in the returned object is a \c vtkm::Pair that is a combination
/// of the corresponding pair of the input objects.
///
template<typename TR,
typename TP1,
typename UR,
typename UP1>
VTKM_EXEC_CONT_EXPORT
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1)>,
vtkm::internal::FunctionInterface<UR(UP1)> >::type
make_FunctionInterfaceZip(
const vtkm::internal::FunctionInterface<TR(TP1)> &first,
const vtkm::internal::FunctionInterface<UR(UP1)> &second)
{
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1)>,
vtkm::internal::FunctionInterface<UR(UP1)> >::type result;
result.template SetParameter<1>(
vtkm::make_Pair(first.template GetParameter<1>(),
second.template GetParameter<1>()));
return result;
}
template<typename TR,
typename TP1,
typename TP2,
typename UR,
typename UP1,
typename UP2>
VTKM_EXEC_CONT_EXPORT
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2)> >::type
make_FunctionInterfaceZip(
const vtkm::internal::FunctionInterface<TR(TP1,TP2)> &first,
const vtkm::internal::FunctionInterface<UR(UP1,UP2)> &second)
{
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2)> >::type result;
result.template SetParameter<1>(
vtkm::make_Pair(first.template GetParameter<1>(),
second.template GetParameter<1>()));
result.template SetParameter<2>(
vtkm::make_Pair(first.template GetParameter<2>(),
second.template GetParameter<2>()));
return result;
}
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename UR,
typename UP1,
typename UP2,
typename UP3>
VTKM_EXEC_CONT_EXPORT
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3)> >::type
make_FunctionInterfaceZip(
const vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3)> &first,
const vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3)> &second)
{
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3)> >::type result;
result.template SetParameter<1>(
vtkm::make_Pair(first.template GetParameter<1>(),
second.template GetParameter<1>()));
result.template SetParameter<2>(
vtkm::make_Pair(first.template GetParameter<2>(),
second.template GetParameter<2>()));
result.template SetParameter<3>(
vtkm::make_Pair(first.template GetParameter<3>(),
second.template GetParameter<3>()));
return result;
}
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4>
VTKM_EXEC_CONT_EXPORT
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4)> >::type
make_FunctionInterfaceZip(
const vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4)> &first,
const vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4)> &second)
{
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4)> >::type result;
result.template SetParameter<1>(
vtkm::make_Pair(first.template GetParameter<1>(),
second.template GetParameter<1>()));
result.template SetParameter<2>(
vtkm::make_Pair(first.template GetParameter<2>(),
second.template GetParameter<2>()));
result.template SetParameter<3>(
vtkm::make_Pair(first.template GetParameter<3>(),
second.template GetParameter<3>()));
result.template SetParameter<4>(
vtkm::make_Pair(first.template GetParameter<4>(),
second.template GetParameter<4>()));
return result;
}
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5>
VTKM_EXEC_CONT_EXPORT
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5)> >::type
make_FunctionInterfaceZip(
const vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5)> &first,
const vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5)> &second)
{
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5)> >::type result;
result.template SetParameter<1>(
vtkm::make_Pair(first.template GetParameter<1>(),
second.template GetParameter<1>()));
result.template SetParameter<2>(
vtkm::make_Pair(first.template GetParameter<2>(),
second.template GetParameter<2>()));
result.template SetParameter<3>(
vtkm::make_Pair(first.template GetParameter<3>(),
second.template GetParameter<3>()));
result.template SetParameter<4>(
vtkm::make_Pair(first.template GetParameter<4>(),
second.template GetParameter<4>()));
result.template SetParameter<5>(
vtkm::make_Pair(first.template GetParameter<5>(),
second.template GetParameter<5>()));
return result;
}
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename TP6,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5,
typename UP6>
VTKM_EXEC_CONT_EXPORT
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6)> >::type
make_FunctionInterfaceZip(
const vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6)> &first,
const vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6)> &second)
{
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6)> >::type result;
result.template SetParameter<1>(
vtkm::make_Pair(first.template GetParameter<1>(),
second.template GetParameter<1>()));
result.template SetParameter<2>(
vtkm::make_Pair(first.template GetParameter<2>(),
second.template GetParameter<2>()));
result.template SetParameter<3>(
vtkm::make_Pair(first.template GetParameter<3>(),
second.template GetParameter<3>()));
result.template SetParameter<4>(
vtkm::make_Pair(first.template GetParameter<4>(),
second.template GetParameter<4>()));
result.template SetParameter<5>(
vtkm::make_Pair(first.template GetParameter<5>(),
second.template GetParameter<5>()));
result.template SetParameter<6>(
vtkm::make_Pair(first.template GetParameter<6>(),
second.template GetParameter<6>()));
return result;
}
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename TP6,
typename TP7,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5,
typename UP6,
typename UP7>
VTKM_EXEC_CONT_EXPORT
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7)> >::type
make_FunctionInterfaceZip(
const vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7)> &first,
const vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7)> &second)
{
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7)> >::type result;
result.template SetParameter<1>(
vtkm::make_Pair(first.template GetParameter<1>(),
second.template GetParameter<1>()));
result.template SetParameter<2>(
vtkm::make_Pair(first.template GetParameter<2>(),
second.template GetParameter<2>()));
result.template SetParameter<3>(
vtkm::make_Pair(first.template GetParameter<3>(),
second.template GetParameter<3>()));
result.template SetParameter<4>(
vtkm::make_Pair(first.template GetParameter<4>(),
second.template GetParameter<4>()));
result.template SetParameter<5>(
vtkm::make_Pair(first.template GetParameter<5>(),
second.template GetParameter<5>()));
result.template SetParameter<6>(
vtkm::make_Pair(first.template GetParameter<6>(),
second.template GetParameter<6>()));
result.template SetParameter<7>(
vtkm::make_Pair(first.template GetParameter<7>(),
second.template GetParameter<7>()));
return result;
}
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename TP6,
typename TP7,
typename TP8,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5,
typename UP6,
typename UP7,
typename UP8>
VTKM_EXEC_CONT_EXPORT
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8)> >::type
make_FunctionInterfaceZip(
const vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8)> &first,
const vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8)> &second)
{
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8)> >::type result;
result.template SetParameter<1>(
vtkm::make_Pair(first.template GetParameter<1>(),
second.template GetParameter<1>()));
result.template SetParameter<2>(
vtkm::make_Pair(first.template GetParameter<2>(),
second.template GetParameter<2>()));
result.template SetParameter<3>(
vtkm::make_Pair(first.template GetParameter<3>(),
second.template GetParameter<3>()));
result.template SetParameter<4>(
vtkm::make_Pair(first.template GetParameter<4>(),
second.template GetParameter<4>()));
result.template SetParameter<5>(
vtkm::make_Pair(first.template GetParameter<5>(),
second.template GetParameter<5>()));
result.template SetParameter<6>(
vtkm::make_Pair(first.template GetParameter<6>(),
second.template GetParameter<6>()));
result.template SetParameter<7>(
vtkm::make_Pair(first.template GetParameter<7>(),
second.template GetParameter<7>()));
result.template SetParameter<8>(
vtkm::make_Pair(first.template GetParameter<8>(),
second.template GetParameter<8>()));
return result;
}
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename TP6,
typename TP7,
typename TP8,
typename TP9,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5,
typename UP6,
typename UP7,
typename UP8,
typename UP9>
VTKM_EXEC_CONT_EXPORT
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8,TP9)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8,UP9)> >::type
make_FunctionInterfaceZip(
const vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8,TP9)> &first,
const vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8,UP9)> &second)
{
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8,TP9)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8,UP9)> >::type result;
result.template SetParameter<1>(
vtkm::make_Pair(first.template GetParameter<1>(),
second.template GetParameter<1>()));
result.template SetParameter<2>(
vtkm::make_Pair(first.template GetParameter<2>(),
second.template GetParameter<2>()));
result.template SetParameter<3>(
vtkm::make_Pair(first.template GetParameter<3>(),
second.template GetParameter<3>()));
result.template SetParameter<4>(
vtkm::make_Pair(first.template GetParameter<4>(),
second.template GetParameter<4>()));
result.template SetParameter<5>(
vtkm::make_Pair(first.template GetParameter<5>(),
second.template GetParameter<5>()));
result.template SetParameter<6>(
vtkm::make_Pair(first.template GetParameter<6>(),
second.template GetParameter<6>()));
result.template SetParameter<7>(
vtkm::make_Pair(first.template GetParameter<7>(),
second.template GetParameter<7>()));
result.template SetParameter<8>(
vtkm::make_Pair(first.template GetParameter<8>(),
second.template GetParameter<8>()));
result.template SetParameter<9>(
vtkm::make_Pair(first.template GetParameter<9>(),
second.template GetParameter<9>()));
return result;
}
template<typename TR,
typename TP1,
typename TP2,
typename TP3,
typename TP4,
typename TP5,
typename TP6,
typename TP7,
typename TP8,
typename TP9,
typename TP10,
typename UR,
typename UP1,
typename UP2,
typename UP3,
typename UP4,
typename UP5,
typename UP6,
typename UP7,
typename UP8,
typename UP9,
typename UP10>
VTKM_EXEC_CONT_EXPORT
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8,TP9,TP10)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8,UP9,UP10)> >::type
make_FunctionInterfaceZip(
const vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8,TP9,TP10)> &first,
const vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8,UP9,UP10)> &second)
{
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<TR(TP1,TP2,TP3,TP4,TP5,TP6,TP7,TP8,TP9,TP10)>,
vtkm::internal::FunctionInterface<UR(UP1,UP2,UP3,UP4,UP5,UP6,UP7,UP8,UP9,UP10)> >::type result;
result.template SetParameter<1>(
vtkm::make_Pair(first.template GetParameter<1>(),
second.template GetParameter<1>()));
result.template SetParameter<2>(
vtkm::make_Pair(first.template GetParameter<2>(),
second.template GetParameter<2>()));
result.template SetParameter<3>(
vtkm::make_Pair(first.template GetParameter<3>(),
second.template GetParameter<3>()));
result.template SetParameter<4>(
vtkm::make_Pair(first.template GetParameter<4>(),
second.template GetParameter<4>()));
result.template SetParameter<5>(
vtkm::make_Pair(first.template GetParameter<5>(),
second.template GetParameter<5>()));
result.template SetParameter<6>(
vtkm::make_Pair(first.template GetParameter<6>(),
second.template GetParameter<6>()));
result.template SetParameter<7>(
vtkm::make_Pair(first.template GetParameter<7>(),
second.template GetParameter<7>()));
result.template SetParameter<8>(
vtkm::make_Pair(first.template GetParameter<8>(),
second.template GetParameter<8>()));
result.template SetParameter<9>(
vtkm::make_Pair(first.template GetParameter<9>(),
second.template GetParameter<9>()));
result.template SetParameter<10>(
vtkm::make_Pair(first.template GetParameter<10>(),
second.template GetParameter<10>()));
return result;
}
}
} // namespace vtkm::internal

@ -94,7 +94,7 @@ template<typename Transform,
struct FunctionInterfaceStaticTransformType<$signature(num_params), Transform> {
typedef $ptype(0)(type)(
$for(param_index in xrange(1, num_params+1))\
typename Transform::template ReturnType<$ptype(param_index)>::type$comma_if(param_index<num_params)
typename Transform::template ReturnType<$ptype(param_index),$(param_index)>::type$comma_if(param_index<num_params)
$endfor\
);
};
@ -136,53 +136,6 @@ $endfor\
$endfor\
$for(num_params in xrange(0, max_parameters+1))\
template<$template_params(num_params, name='T'),
$template_params(num_params, name='U')>
struct FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<$signature(num_params, name='T')>,
vtkm::internal::FunctionInterface<$signature(num_params, name='U')> >
{
typedef vtkm::internal::FunctionInterface<
typename detail::FunctionInterfaceZipReturn<$ptype(0,name='T'),$ptype(0,name='U')>::type (
$for(param_index in xrange(1, num_params+1))\
vtkm::Pair<$ptype(param_index,name='T'), $ptype(param_index,name='U')>$comma_if(num_params-param_index)
$endfor\
)> type;
};
$endfor\
/// Creates a "zipped" version of two \c FunctionInterface objects. Each
/// parameter in the returned object is a \c vtkm::Pair that is a combination
/// of the corresponding pair of the input objects.
///
$for(num_params in xrange(1, max_parameters+1))\
template<$template_params(num_params, name='T'),
$template_params(num_params, name='U')>
VTKM_EXEC_CONT_EXPORT
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<$signature(num_params, name='T')>,
vtkm::internal::FunctionInterface<$signature(num_params, name='U')> >::type
make_FunctionInterfaceZip(
const vtkm::internal::FunctionInterface<$signature(num_params, name='T')> &first,
const vtkm::internal::FunctionInterface<$signature(num_params, name='U')> &second)
{
typename vtkm::internal::FunctionInterfaceZipType<
vtkm::internal::FunctionInterface<$signature(num_params, name='T')>,
vtkm::internal::FunctionInterface<$signature(num_params, name='U')> >::type result;
$for(param_index in xrange(1, num_params+1))\
result.template SetParameter<$(param_index)>(
vtkm::make_Pair(first.template GetParameter<$(param_index)>(),
second.template GetParameter<$(param_index)>()));
$endfor\
return result;
}
$endfor\
}
} // namespace vtkm::internal

@ -28,6 +28,7 @@
#endif
#include <vtkm/Types.h>
#include <vtkm/internal/IndexTag.h>
#include <boost/function_types/function_type.hpp>
#include <boost/mpl/at.hpp>
@ -2478,7 +2479,8 @@ void DoStaticTransformCont(
const ParameterContainer<OriginalR(OriginalP1)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
}
template<typename Transform,
@ -2492,7 +2494,8 @@ void DoStaticTransformExec(
const ParameterContainer<OriginalR(OriginalP1)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
}
template<typename Transform,
@ -2508,8 +2511,10 @@ void DoStaticTransformCont(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
}
template<typename Transform,
@ -2525,8 +2530,10 @@ void DoStaticTransformExec(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
}
template<typename Transform,
@ -2544,9 +2551,12 @@ void DoStaticTransformCont(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
}
template<typename Transform,
@ -2564,9 +2574,12 @@ void DoStaticTransformExec(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
}
template<typename Transform,
@ -2586,10 +2599,14 @@ void DoStaticTransformCont(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
}
template<typename Transform,
@ -2609,10 +2626,14 @@ void DoStaticTransformExec(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
}
template<typename Transform,
@ -2634,11 +2655,16 @@ void DoStaticTransformCont(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4,OriginalP5)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4,TransformedP5)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter5 = transform(originalParameters.Parameter5);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
transformedParameters.Parameter5 =
transform(originalParameters.Parameter5, vtkm::internal::IndexTag<5>());
}
template<typename Transform,
@ -2660,11 +2686,16 @@ void DoStaticTransformExec(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4,OriginalP5)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4,TransformedP5)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter5 = transform(originalParameters.Parameter5);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
transformedParameters.Parameter5 =
transform(originalParameters.Parameter5, vtkm::internal::IndexTag<5>());
}
template<typename Transform,
@ -2688,12 +2719,18 @@ void DoStaticTransformCont(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4,OriginalP5,OriginalP6)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4,TransformedP5,TransformedP6)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter5 = transform(originalParameters.Parameter5);
transformedParameters.Parameter6 = transform(originalParameters.Parameter6);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
transformedParameters.Parameter5 =
transform(originalParameters.Parameter5, vtkm::internal::IndexTag<5>());
transformedParameters.Parameter6 =
transform(originalParameters.Parameter6, vtkm::internal::IndexTag<6>());
}
template<typename Transform,
@ -2717,12 +2754,18 @@ void DoStaticTransformExec(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4,OriginalP5,OriginalP6)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4,TransformedP5,TransformedP6)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter5 = transform(originalParameters.Parameter5);
transformedParameters.Parameter6 = transform(originalParameters.Parameter6);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
transformedParameters.Parameter5 =
transform(originalParameters.Parameter5, vtkm::internal::IndexTag<5>());
transformedParameters.Parameter6 =
transform(originalParameters.Parameter6, vtkm::internal::IndexTag<6>());
}
template<typename Transform,
@ -2748,13 +2791,20 @@ void DoStaticTransformCont(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4,OriginalP5,OriginalP6,OriginalP7)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4,TransformedP5,TransformedP6,TransformedP7)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter5 = transform(originalParameters.Parameter5);
transformedParameters.Parameter6 = transform(originalParameters.Parameter6);
transformedParameters.Parameter7 = transform(originalParameters.Parameter7);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
transformedParameters.Parameter5 =
transform(originalParameters.Parameter5, vtkm::internal::IndexTag<5>());
transformedParameters.Parameter6 =
transform(originalParameters.Parameter6, vtkm::internal::IndexTag<6>());
transformedParameters.Parameter7 =
transform(originalParameters.Parameter7, vtkm::internal::IndexTag<7>());
}
template<typename Transform,
@ -2780,13 +2830,20 @@ void DoStaticTransformExec(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4,OriginalP5,OriginalP6,OriginalP7)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4,TransformedP5,TransformedP6,TransformedP7)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter5 = transform(originalParameters.Parameter5);
transformedParameters.Parameter6 = transform(originalParameters.Parameter6);
transformedParameters.Parameter7 = transform(originalParameters.Parameter7);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
transformedParameters.Parameter5 =
transform(originalParameters.Parameter5, vtkm::internal::IndexTag<5>());
transformedParameters.Parameter6 =
transform(originalParameters.Parameter6, vtkm::internal::IndexTag<6>());
transformedParameters.Parameter7 =
transform(originalParameters.Parameter7, vtkm::internal::IndexTag<7>());
}
template<typename Transform,
@ -2814,14 +2871,22 @@ void DoStaticTransformCont(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4,OriginalP5,OriginalP6,OriginalP7,OriginalP8)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4,TransformedP5,TransformedP6,TransformedP7,TransformedP8)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter5 = transform(originalParameters.Parameter5);
transformedParameters.Parameter6 = transform(originalParameters.Parameter6);
transformedParameters.Parameter7 = transform(originalParameters.Parameter7);
transformedParameters.Parameter8 = transform(originalParameters.Parameter8);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
transformedParameters.Parameter5 =
transform(originalParameters.Parameter5, vtkm::internal::IndexTag<5>());
transformedParameters.Parameter6 =
transform(originalParameters.Parameter6, vtkm::internal::IndexTag<6>());
transformedParameters.Parameter7 =
transform(originalParameters.Parameter7, vtkm::internal::IndexTag<7>());
transformedParameters.Parameter8 =
transform(originalParameters.Parameter8, vtkm::internal::IndexTag<8>());
}
template<typename Transform,
@ -2849,14 +2914,22 @@ void DoStaticTransformExec(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4,OriginalP5,OriginalP6,OriginalP7,OriginalP8)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4,TransformedP5,TransformedP6,TransformedP7,TransformedP8)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter5 = transform(originalParameters.Parameter5);
transformedParameters.Parameter6 = transform(originalParameters.Parameter6);
transformedParameters.Parameter7 = transform(originalParameters.Parameter7);
transformedParameters.Parameter8 = transform(originalParameters.Parameter8);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
transformedParameters.Parameter5 =
transform(originalParameters.Parameter5, vtkm::internal::IndexTag<5>());
transformedParameters.Parameter6 =
transform(originalParameters.Parameter6, vtkm::internal::IndexTag<6>());
transformedParameters.Parameter7 =
transform(originalParameters.Parameter7, vtkm::internal::IndexTag<7>());
transformedParameters.Parameter8 =
transform(originalParameters.Parameter8, vtkm::internal::IndexTag<8>());
}
template<typename Transform,
@ -2886,15 +2959,24 @@ void DoStaticTransformCont(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4,OriginalP5,OriginalP6,OriginalP7,OriginalP8,OriginalP9)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4,TransformedP5,TransformedP6,TransformedP7,TransformedP8,TransformedP9)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter5 = transform(originalParameters.Parameter5);
transformedParameters.Parameter6 = transform(originalParameters.Parameter6);
transformedParameters.Parameter7 = transform(originalParameters.Parameter7);
transformedParameters.Parameter8 = transform(originalParameters.Parameter8);
transformedParameters.Parameter9 = transform(originalParameters.Parameter9);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
transformedParameters.Parameter5 =
transform(originalParameters.Parameter5, vtkm::internal::IndexTag<5>());
transformedParameters.Parameter6 =
transform(originalParameters.Parameter6, vtkm::internal::IndexTag<6>());
transformedParameters.Parameter7 =
transform(originalParameters.Parameter7, vtkm::internal::IndexTag<7>());
transformedParameters.Parameter8 =
transform(originalParameters.Parameter8, vtkm::internal::IndexTag<8>());
transformedParameters.Parameter9 =
transform(originalParameters.Parameter9, vtkm::internal::IndexTag<9>());
}
template<typename Transform,
@ -2924,15 +3006,24 @@ void DoStaticTransformExec(
const ParameterContainer<OriginalR(OriginalP1,OriginalP2,OriginalP3,OriginalP4,OriginalP5,OriginalP6,OriginalP7,OriginalP8,OriginalP9)> &originalParameters,
ParameterContainer<TransformedR(TransformedP1,TransformedP2,TransformedP3,TransformedP4,TransformedP5,TransformedP6,TransformedP7,TransformedP8,TransformedP9)> &transformedParameters)
{
transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
transformedParameters.Parameter3 = transform(originalParameters.Parameter3);
transformedParameters.Parameter4 = transform(originalParameters.Parameter4);
transformedParameters.Parameter5 = transform(originalParameters.Parameter5);
transformedParameters.Parameter6 = transform(originalParameters.Parameter6);
transformedParameters.Parameter7 = transform(originalParameters.Parameter7);
transformedParameters.Parameter8 = transform(originalParameters.Parameter8);
transformedParameters.Parameter9 = transform(originalParameters.Parameter9);
transformedParameters.Parameter1 =
transform(originalParameters.Parameter1, vtkm::internal::IndexTag<1>());
transformedParameters.Parameter2 =
transform(originalParameters.Parameter2, vtkm::internal::IndexTag<2>());
transformedParameters.Parameter3 =
transform(originalParameters.Parameter3, vtkm::internal::IndexTag<3>());
transformedParameters.Parameter4 =
transform(originalParameters.Parameter4, vtkm::internal::IndexTag<4>());
transformedParameters.Parameter5 =
transform(originalParameters.Parameter5, vtkm::internal::IndexTag<5>());
transformedParameters.Parameter6 =
transform(originalParameters.Parameter6, vtkm::internal::IndexTag<6>());
transformedParameters.Parameter7 =
transform(originalParameters.Parameter7, vtkm::internal::IndexTag<7>());
transformedParameters.Parameter8 =
transform(originalParameters.Parameter8, vtkm::internal::IndexTag<8>());
transformedParameters.Parameter9 =
transform(originalParameters.Parameter9, vtkm::internal::IndexTag<9>());
}
@ -2990,7 +3081,7 @@ void DoForEachCont(
const Functor &f,
const ParameterContainer<R(P1)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
}
template<typename Functor,
@ -3001,7 +3092,7 @@ void DoForEachCont(
const Functor &f,
ParameterContainer<R(P1)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
}
template<typename Functor,
@ -3012,7 +3103,7 @@ void DoForEachExec(
const Functor &f,
const ParameterContainer<R(P1)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
}
template<typename Functor,
@ -3023,7 +3114,7 @@ void DoForEachExec(
const Functor &f,
ParameterContainer<R(P1)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
}
template<typename Functor,
@ -3035,8 +3126,8 @@ void DoForEachCont(
const Functor &f,
const ParameterContainer<R(P1,P2)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
}
template<typename Functor,
@ -3048,8 +3139,8 @@ void DoForEachCont(
const Functor &f,
ParameterContainer<R(P1,P2)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
}
template<typename Functor,
@ -3061,8 +3152,8 @@ void DoForEachExec(
const Functor &f,
const ParameterContainer<R(P1,P2)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
}
template<typename Functor,
@ -3074,8 +3165,8 @@ void DoForEachExec(
const Functor &f,
ParameterContainer<R(P1,P2)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
}
template<typename Functor,
@ -3088,9 +3179,9 @@ void DoForEachCont(
const Functor &f,
const ParameterContainer<R(P1,P2,P3)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
}
template<typename Functor,
@ -3103,9 +3194,9 @@ void DoForEachCont(
const Functor &f,
ParameterContainer<R(P1,P2,P3)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
}
template<typename Functor,
@ -3118,9 +3209,9 @@ void DoForEachExec(
const Functor &f,
const ParameterContainer<R(P1,P2,P3)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
}
template<typename Functor,
@ -3133,9 +3224,9 @@ void DoForEachExec(
const Functor &f,
ParameterContainer<R(P1,P2,P3)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
}
template<typename Functor,
@ -3149,10 +3240,10 @@ void DoForEachCont(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
}
template<typename Functor,
@ -3166,10 +3257,10 @@ void DoForEachCont(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
}
template<typename Functor,
@ -3183,10 +3274,10 @@ void DoForEachExec(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
}
template<typename Functor,
@ -3200,10 +3291,10 @@ void DoForEachExec(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
}
template<typename Functor,
@ -3218,11 +3309,11 @@ void DoForEachCont(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4,P5)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
}
template<typename Functor,
@ -3237,11 +3328,11 @@ void DoForEachCont(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4,P5)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
}
template<typename Functor,
@ -3256,11 +3347,11 @@ void DoForEachExec(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4,P5)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
}
template<typename Functor,
@ -3275,11 +3366,11 @@ void DoForEachExec(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4,P5)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
}
template<typename Functor,
@ -3295,12 +3386,12 @@ void DoForEachCont(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4,P5,P6)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
}
template<typename Functor,
@ -3316,12 +3407,12 @@ void DoForEachCont(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4,P5,P6)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
}
template<typename Functor,
@ -3337,12 +3428,12 @@ void DoForEachExec(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4,P5,P6)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
}
template<typename Functor,
@ -3358,12 +3449,12 @@ void DoForEachExec(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4,P5,P6)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
}
template<typename Functor,
@ -3380,13 +3471,13 @@ void DoForEachCont(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
}
template<typename Functor,
@ -3403,13 +3494,13 @@ void DoForEachCont(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
}
template<typename Functor,
@ -3426,13 +3517,13 @@ void DoForEachExec(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
}
template<typename Functor,
@ -3449,13 +3540,13 @@ void DoForEachExec(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
}
template<typename Functor,
@ -3473,14 +3564,14 @@ void DoForEachCont(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7,P8)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter8);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
f(parameters.Parameter8, vtkm::internal::IndexTag<8>());
}
template<typename Functor,
@ -3498,14 +3589,14 @@ void DoForEachCont(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7,P8)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter8);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
f(parameters.Parameter8, vtkm::internal::IndexTag<8>());
}
template<typename Functor,
@ -3523,14 +3614,14 @@ void DoForEachExec(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7,P8)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter8);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
f(parameters.Parameter8, vtkm::internal::IndexTag<8>());
}
template<typename Functor,
@ -3548,14 +3639,14 @@ void DoForEachExec(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7,P8)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter8);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
f(parameters.Parameter8, vtkm::internal::IndexTag<8>());
}
template<typename Functor,
@ -3574,15 +3665,15 @@ void DoForEachCont(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7,P8,P9)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter8);
f(parameters.Parameter9);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
f(parameters.Parameter8, vtkm::internal::IndexTag<8>());
f(parameters.Parameter9, vtkm::internal::IndexTag<9>());
}
template<typename Functor,
@ -3601,15 +3692,15 @@ void DoForEachCont(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7,P8,P9)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter8);
f(parameters.Parameter9);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
f(parameters.Parameter8, vtkm::internal::IndexTag<8>());
f(parameters.Parameter9, vtkm::internal::IndexTag<9>());
}
template<typename Functor,
@ -3628,15 +3719,15 @@ void DoForEachExec(
const Functor &f,
const ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7,P8,P9)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter8);
f(parameters.Parameter9);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
f(parameters.Parameter8, vtkm::internal::IndexTag<8>());
f(parameters.Parameter9, vtkm::internal::IndexTag<9>());
}
template<typename Functor,
@ -3655,15 +3746,15 @@ void DoForEachExec(
const Functor &f,
ParameterContainer<R(P1,P2,P3,P4,P5,P6,P7,P8,P9)> &parameters)
{
f(parameters.Parameter1);
f(parameters.Parameter2);
f(parameters.Parameter3);
f(parameters.Parameter4);
f(parameters.Parameter5);
f(parameters.Parameter6);
f(parameters.Parameter7);
f(parameters.Parameter8);
f(parameters.Parameter9);
f(parameters.Parameter1, vtkm::internal::IndexTag<1>());
f(parameters.Parameter2, vtkm::internal::IndexTag<2>());
f(parameters.Parameter3, vtkm::internal::IndexTag<3>());
f(parameters.Parameter4, vtkm::internal::IndexTag<4>());
f(parameters.Parameter5, vtkm::internal::IndexTag<5>());
f(parameters.Parameter6, vtkm::internal::IndexTag<6>());
f(parameters.Parameter7, vtkm::internal::IndexTag<7>());
f(parameters.Parameter8, vtkm::internal::IndexTag<8>());
f(parameters.Parameter9, vtkm::internal::IndexTag<9>());
}

@ -40,6 +40,7 @@ $# Ignore the following comment. It is meant for the generated file.
#endif
#include <vtkm/Types.h>
#include <vtkm/internal/IndexTag.h>
#include <boost/function_types/function_type.hpp>
#include <boost/mpl/at.hpp>
@ -228,7 +229,8 @@ $if(num_params < 1)\
(void)transformedParameters;
$else\
$for(param_index in xrange(1, num_params+1))\
transformedParameters.Parameter$(param_index) = transform(originalParameters.Parameter$(param_index));
transformedParameters.Parameter$(param_index) =
transform(originalParameters.Parameter$(param_index), vtkm::internal::IndexTag<$(param_index)>());
$endfor\
$endif\
}
@ -255,7 +257,7 @@ $if(num_params < 1)\
(void)parameters;
$else\
$for(param_index in xrange(1, num_params+1))\
f(parameters.Parameter$(param_index));
f(parameters.Parameter$(param_index), vtkm::internal::IndexTag<$(param_index)>());
$endfor\
$endif\
}

46
vtkm/internal/IndexTag.h Normal file

@ -0,0 +1,46 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// 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_internal_StaticIndex_h
#define vtk_m_internal_StaticIndex_h
#include <vtkm/Types.h>
namespace vtkm {
namespace internal {
/// \brief A convenience tag to represent static indices.
///
/// Some classes like \c FunctionInterface have a list of items that have
/// numeric indices that must be resolved at compile time. Typically these are
/// referenced with an integer template argument. However, such template
/// arguments have to be explicitly defined in the template. They cannot be
/// resolved through function or method arguments. In such cases, it is
/// convenient to use this tag to encapsulate the index.
///
template<vtkm::IdComponent Index>
struct IndexTag
{
static const vtkm::IdComponent INDEX = Index;
};
}
} // namespace vtkm::internal
#endif //vtk_m_internal_StaticIndex_h

@ -86,7 +86,7 @@ struct Invocation
/// \c Parameters are replaced with those provided.
///
template<typename NewParameterInterface>
VTKM_EXEC_CONT_EXPORT
VTKM_CONT_EXPORT
typename ChangeParametersType<NewParameterInterface>::type
ChangeParameters(NewParameterInterface newParameters) const {
return typename ChangeParametersType<NewParameterInterface>::type(

@ -83,13 +83,13 @@ struct GetReferenceFunctor
};
struct PointerTransform {
template<typename T>
template<typename T, vtkm::IdComponent Index>
struct ReturnType {
typedef const T *type;
};
template<typename T>
const T *operator()(const T &x) const {
template<typename T, typename IndexTag>
const T *operator()(const T &x, IndexTag) const {
return &x;
}
};
@ -216,15 +216,19 @@ struct ThreeArgStringFunctorWithReturn
struct DynamicTransformFunctor
{
template<typename T, typename ContinueFunctor>
void operator()(const T &input, const ContinueFunctor continueFunc) const
template<typename T, typename ContinueFunctor, vtkm::IdComponent Index>
void operator()(const T &input,
const ContinueFunctor continueFunc,
vtkm::internal::IndexTag<Index>) const
{
continueFunc(input);
continueFunc(ToString(input));
continueFunc(input+T(Index));
continueFunc(ToString(input+T(Index)));
}
template<typename ContinueFunctor>
void operator()(const std::string &input, const ContinueFunctor continueFunc) const
template<typename ContinueFunctor, vtkm::IdComponent Index>
void operator()(const std::string &input,
const ContinueFunctor continueFunc,
vtkm::internal::IndexTag<Index>) const
{
continueFunc(input);
}
@ -238,9 +242,9 @@ struct DynamicTransformFinish
void operator()(vtkm::internal::FunctionInterface<Signature> &funcInterface) const
{
g_DynamicTransformFinishCalls++;
VTKM_TEST_ASSERT(ToString(funcInterface.template GetParameter<1>()) == ToString(Arg1),
VTKM_TEST_ASSERT(ToString(funcInterface.template GetParameter<1>()) == ToString(Arg1+1),
"Arg 1 incorrect");
VTKM_TEST_ASSERT(ToString(funcInterface.template GetParameter<2>()) == ToString(Arg2),
VTKM_TEST_ASSERT(ToString(funcInterface.template GetParameter<2>()) == ToString(Arg2+2),
"Arg 2 incorrect");
VTKM_TEST_ASSERT(ToString(funcInterface.template GetParameter<3>()) == ToString(Arg3),
"Arg 3 incorrect");
@ -249,26 +253,16 @@ struct DynamicTransformFinish
struct ForEachFunctor
{
template<typename T>
void operator()(T &x) const { x = T(2)*x; }
template<typename T, vtkm::IdComponent Index>
void operator()(T &x, vtkm::internal::IndexTag<Index>) const {
x = T(Index)+x;
}
void operator()(std::string &x) const { x.append("*2"); }
};
struct ZipFunctor
{
void operator()(const vtkm::Pair<Type1,Type3> &a1,
const vtkm::Pair<Type2,Type4> &a2,
const vtkm::Pair<Type3,Type5> &a3) const
{
std::cout << "In functor for zipped functions." << std::endl;
VTKM_TEST_ASSERT(a1.first == Arg1, "Bad arg.");
VTKM_TEST_ASSERT(a1.second == Arg3, "Bad arg.");
VTKM_TEST_ASSERT(a2.first == Arg2, "Bad arg.");
VTKM_TEST_ASSERT(a2.second == Arg4, "Bad arg.");
VTKM_TEST_ASSERT(a3.first == Arg3, "Bad arg.");
VTKM_TEST_ASSERT(a3.second == Arg5, "Bad arg.");
template<vtkm::IdComponent Index>
void operator()(std::string &x, vtkm::internal::IndexTag<Index>) const {
std::stringstream message;
message << x << "+" << Index;
x = message.str();
}
};
@ -290,7 +284,7 @@ void TryFunctionInterface5(
std::cout << "Swizzling parameters with replace." << std::endl;
funcInterface.Replace<1>(Arg5)
.Replace<2>(Arg1)
.Replace(Arg1, vtkm::internal::IndexTag<2>())
.Replace<5>(Arg2)
.InvokeCont(FiveArgSwizzledFunctor());
}
@ -305,7 +299,7 @@ void TestBasicFunctionInterface()
VTKM_TEST_ASSERT(funcInterface.GetArity() == 3,
"Got wrong number of parameters.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter(vtkm::internal::IndexTag<2>()) == Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3, "Arg 3 incorrect.");
std::cout << "Checking invocation." << std::endl;
@ -314,7 +308,7 @@ void TestBasicFunctionInterface()
std::cout << "Checking invocation with argument modification." << std::endl;
funcInterface.SetParameter<1>(Type1());
funcInterface.SetParameter<2>(Type2());
funcInterface.SetParameter(Type2(), vtkm::internal::IndexTag<2>());
funcInterface.SetParameter<3>(Type3());
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() != Arg1, "Arg 1 not cleared.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() != Arg2, "Arg 2 not cleared.");
@ -457,28 +451,18 @@ void TestForEach()
VTKM_TEST_ASSERT(funcInterface.GetParameter<5>() == Arg5, "Arg 5 incorrect.");
funcInterface.ForEachCont(ForEachFunctor());
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == 2*Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == 2*Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3+"*2", "Arg 3 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == 2.0f*Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<5>() == 2*Arg5, "Arg 5 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == Type1(1)+Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == Type2(2)+Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3+"+3", "Arg 3 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == Type4(4)+Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<5>() == Type5(5)+Arg5, "Arg 5 incorrect.");
funcInterface.ForEachExec(ForEachFunctor());
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == 4*Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == 4*Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3+"*2*2", "Arg 3 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == 4.0f*Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<5>() == 4*Arg5, "Arg 5 incorrect.");
}
void TestZip()
{
std::cout << "Testing zipping function interfaces." << std::endl;
vtkm::internal::make_FunctionInterfaceZip(
vtkm::internal::make_FunctionInterface<void>(Arg1, Arg2, Arg3),
vtkm::internal::make_FunctionInterface<void>(Arg3, Arg4, Arg5)).
InvokeCont(ZipFunctor());
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == Type1(2)+Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == Type2(4)+Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3+"+3+3", "Arg 3 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == Type4(8)+Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<5>() == Type5(10)+Arg5, "Arg 5 incorrect.");
}
#ifdef TEST_INVOKE_TIME
@ -561,7 +545,6 @@ void TestFunctionInterface()
TestStaticTransform();
TestDynamicTransform();
TestForEach();
TestZip();
#ifdef TEST_INVOKE_TIME
TestInvokeTime();
#endif //TEST_INVOKE_TIME

@ -53,7 +53,7 @@ namespace detail {
// tag. Causes a compile error otherwise.
struct DispatcherBaseControlSignatureTagCheck
{
template<typename ControlSignatureTag>
template<typename ControlSignatureTag, vtkm::IdComponent Index>
struct ReturnType {
// If you get a compile error here, it means there is something that is
// not a valid control signature tag in a worklet's ControlSignature.
@ -66,7 +66,7 @@ struct DispatcherBaseControlSignatureTagCheck
// signature tag. Causes a compile error otherwise.
struct DispatcherBaseExecutionSignatureTagCheck
{
template<typename ExecutionSignatureTag>
template<typename ExecutionSignatureTag, vtkm::IdComponent Index>
struct ReturnType {
// If you get a compile error here, it means there is something that is not
// a valid execution signature tag in a worklet's ExecutionSignature.
@ -77,16 +77,16 @@ struct DispatcherBaseExecutionSignatureTagCheck
// Used in the dynamic cast to check to make sure that the type passed into
// the Invoke method matches the type accepted by the ControlSignature.
template<typename ContinueFunctor, typename TypeCheckTag>
template<typename ContinueFunctor,
typename TypeCheckTag,
vtkm::IdComponent Index>
struct DispatcherBaseTypeCheckFunctor
{
const ContinueFunctor &Continue;
vtkm::IdComponent ParameterIndex;
VTKM_CONT_EXPORT
DispatcherBaseTypeCheckFunctor(const ContinueFunctor &continueFunc,
vtkm::IdComponent parameterIndex)
: Continue(continueFunc), ParameterIndex(parameterIndex) { }
DispatcherBaseTypeCheckFunctor(const ContinueFunctor &continueFunc)
: Continue(continueFunc) { }
template<typename T>
VTKM_CONT_EXPORT
@ -111,7 +111,7 @@ struct DispatcherBaseTypeCheckFunctor
{
std::stringstream message;
message << "Encountered bad type for parameter "
<< this->ParameterIndex
<< Index
<< " when calling Invoke on a dispatcher.";
throw vtkm::cont::ErrorControlBadType(message.str());
}
@ -120,33 +120,27 @@ struct DispatcherBaseTypeCheckFunctor
// Uses vtkm::cont::internal::DynamicTransform and the DynamicTransformCont
// method of FunctionInterface to convert all DynamicArrayHandles and any
// other arguments declaring themselves as dynamic to static versions.
template<typename ControlInterface>
struct DispatcherBaseDynamicTransform
{
vtkm::cont::internal::DynamicTransform BasicDynamicTransform;
vtkm::IdComponent *ParameterCounter;
template<typename InputType,
typename ContinueFunctor,
vtkm::IdComponent Index>
VTKM_CONT_EXPORT
DispatcherBaseDynamicTransform(vtkm::IdComponent *parameterCounter)
: ParameterCounter(parameterCounter)
void operator()(const InputType &input,
const ContinueFunctor &continueFunc,
vtkm::internal::IndexTag<Index> indexTag) const
{
*this->ParameterCounter = 0;
}
template<typename ControlSignatureTag,
typename InputType,
typename ContinueFunctor>
VTKM_CONT_EXPORT
void operator()(const vtkm::Pair<ControlSignatureTag, InputType> &input,
const ContinueFunctor &continueFunc) const
{
(*this->ParameterCounter)++;
typedef typename ControlInterface::template ParameterType<Index>::type
ControlSignatureTag;
typedef DispatcherBaseTypeCheckFunctor<
ContinueFunctor, typename ControlSignatureTag::TypeCheckTag>
ContinueFunctor, typename ControlSignatureTag::TypeCheckTag, Index>
TypeCheckFunctor;
this->BasicDynamicTransform(input.second,
TypeCheckFunctor(continueFunc,
*this->ParameterCounter));
vtkm::cont::internal::DynamicTransform basicDynamicTransform;
basicDynamicTransform(input, TypeCheckFunctor(continueFunc), indexTag);
}
};
@ -170,7 +164,7 @@ struct DispatcherBaseDynamicTransformHelper
// A functor used in a StaticCast of a FunctionInterface to transport arguments
// from the control environment to the execution environment.
template<typename Device>
template<typename ControlInterface, typename Device>
struct DispatcherBaseTransportFunctor
{
vtkm::Id NumInstances;
@ -178,25 +172,28 @@ struct DispatcherBaseTransportFunctor
DispatcherBaseTransportFunctor(vtkm::Id numInstances)
: NumInstances(numInstances) { }
template<typename T>
template<typename ControlParameter, vtkm::IdComponent Index>
struct InvokeTypes {
typedef typename T::FirstType::TransportTag TransportTag;
typedef typename T::SecondType ControlParameter;
typedef typename ControlInterface::template ParameterType<Index>::type
ControlSignatureTag;
typedef typename ControlSignatureTag::TransportTag TransportTag;
typedef vtkm::cont::arg::Transport<TransportTag,ControlParameter,Device>
TransportType;
};
template<typename T>
template<typename ControlParameter, vtkm::IdComponent Index>
struct ReturnType {
typedef typename InvokeTypes<T>::TransportType::ExecObjectType type;
typedef typename InvokeTypes<ControlParameter, Index>::
TransportType::ExecObjectType type;
};
template<typename T>
template<typename ControlParameter, vtkm::IdComponent Index>
VTKM_CONT_EXPORT
typename ReturnType<T>::type
operator()(const T &invokeData) const {
typename InvokeTypes<T>::TransportType transport;
return transport(invokeData.second, this->NumInstances);
typename ReturnType<ControlParameter, Index>::type
operator()(const ControlParameter &invokeData,
vtkm::internal::IndexTag<Index>) const {
typename InvokeTypes<ControlParameter, Index>::TransportType transport;
return transport(invokeData, this->NumInstances);
}
};
@ -251,20 +248,13 @@ private:
// type against the TypeCheckTag in the ControlSignature tags. To do this,
// the check needs access to both the parameter (in the parameters
// argument) and the ControlSignature tags (in the ControlInterface type).
// To make this possible, we use the zip mechanism of FunctionInterface to
// combine these two separate function interfaces into a single
// FunctionInterface with each parameter being a Pair containing both
// the ControlSignature tag and the control object itself.
typedef typename vtkm::internal::FunctionInterfaceZipType<
ControlInterface, ParameterInterface>::type ZippedInterface;
ZippedInterface zippedInterface =
vtkm::internal::make_FunctionInterfaceZip(ControlInterface(),
parameters);
vtkm::IdComponent parameterIndexCounter;
zippedInterface.DynamicTransformCont(
detail::DispatcherBaseDynamicTransform(&parameterIndexCounter),
// To make this possible, we call DynamicTransform with a functor containing
// the control signature tags. It uses the index provided by the
// dynamic transform mechanism to get the right tag and make sure that
// the dynamic type is correct. (This prevents the compiler from expanding
// worklets with types that should not be.)
parameters.DynamicTransformCont(
detail::DispatcherBaseDynamicTransform<ControlInterface>(),
detail::DispatcherBaseDynamicTransformHelper<MyType>(this));
}
@ -308,38 +298,25 @@ private:
void InvokeTransportParameters(const Invocation &invocation,
vtkm::Id numInstances) const
{
// The first step in invoking a worklet is transport the arguments to the
// execution environment. The invocation object passed to this function
// The first step in invoking a worklet is to transport the arguments to
// the execution environment. The invocation object passed to this function
// contains the parameters passed to Invoke in the control environment. We
// will use the template magic in the FunctionInterface class to invoke the
// appropriate Transport class on each parameter to get a list of execution
// objects (corresponding to the arguments of the Invoke in the control
// environment) in a FunctionInterface.
// appropriate Transport class on each parameter and get a list of
// execution objects (corresponding to the arguments of the Invoke in the
// control environment) in a FunctionInterface. Specifically, we use a
// static transform of the FunctionInterface to call the transport on each
// argument and return the corresponding execution environment object.
typedef typename Invocation::ParameterInterface ParameterInterfaceType;
const ParameterInterfaceType &parameters = invocation.Parameters;
// The Transport relies on both the ControlSignature tag and the control
// object itself. To make it easier to work with each parameter, use the
// zip mechanism of FunctionInterface to combine the separate function
// interfaces of the ControlSignature and the parameters into one. This
// will make a FunctionInterface with each parameter being a Pair
// containing both the ControlSignature tag and the control object itself.
typedef typename vtkm::internal::FunctionInterfaceZipType<
typename Invocation::ControlInterface,
typename Invocation::ParameterInterface>::type ZippedInterface;
ZippedInterface zippedInterface =
vtkm::internal::make_FunctionInterfaceZip(
typename Invocation::ControlInterface(), invocation.Parameters);
typedef detail::DispatcherBaseTransportFunctor<
typename Invocation::ControlInterface, Device> TransportFunctorType;
typedef typename ParameterInterfaceType::template StaticTransformType<
TransportFunctorType>::type ExecObjectParameters;
// Use the StaticTransform mechanism to run the
// DispatcherBaseTransportFunctor on each parameter of the zipped
// interface. This functor will in turn run the appropriate Transform on
// the parameter and return the associated execution object. The end result
// of the transform is a FunctionInterface containing execution objects
// corresponding to each Invoke argument.
typedef detail::DispatcherBaseTransportFunctor<Device> TransportFunctor;
typedef typename ZippedInterface::template StaticTransformType<
TransportFunctor>::type ExecObjectParameters;
ExecObjectParameters execObjectParameters =
zippedInterface.StaticTransformCont(TransportFunctor(numInstances));
parameters.StaticTransformCont(TransportFunctorType(numInstances));
// Replace the parameters in the invocation with the execution object and
// pass to next step of Invoke.

@ -22,4 +22,10 @@ set(unit_tests
UnitTestWorkletMapField.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})
vtkm_save_worklet_unit_tests(${unit_tests})
vtkm_worklet_unit_tests( VTKM_DEVICE_ADAPTER_SERIAL )
if (VTKm_ENABLE_CUDA)
vtkm_worklet_unit_tests( VTKM_DEVICE_ADAPTER_CUDA )
endif()

@ -26,9 +26,7 @@
#include <vtkm/cont/testing/Testing.h>
namespace {
static const vtkm::Id ARRAY_SIZE = 10;
namespace worklets {
class TestWorklet : public vtkm::worklet::WorkletMapField
{
@ -73,6 +71,13 @@ public:
}
};
} // worklet namespace
namespace {
static const vtkm::Id ARRAY_SIZE = 10;
template<typename WorkletType>
struct DoTestWorklet
{
@ -111,18 +116,26 @@ struct DoTestWorklet
void TestWorkletMapField()
{
typedef vtkm::cont::internal::DeviceAdapterTraits<
VTKM_DEFAULT_DEVICE_ADAPTER_TAG> DeviceAdapterTraits;
std::cout << "Testing Map Field on device adapter: "
<< DeviceAdapterTraits::GetId() << std::endl;
std::cout << "--- Worklet accepting all types." << std::endl;
vtkm::testing::Testing::TryTypes(DoTestWorklet<TestWorklet>(),
vtkm::TypeListTagCommon());
vtkm::testing::Testing::TryTypes(
DoTestWorklet< ::worklets::TestWorklet >(),
vtkm::TypeListTagCommon());
std::cout << "--- Worklet accepting some types." << std::endl;
vtkm::testing::Testing::TryTypes(DoTestWorklet<TestWorkletLimitedTypes>(),
vtkm::TypeListTagFieldScalar());
vtkm::testing::Testing::TryTypes(
DoTestWorklet< ::worklets::TestWorkletLimitedTypes >(),
vtkm::TypeListTagFieldScalar());
std::cout << "--- Sending bad type to worklet." << std::endl;
try
{
DoTestWorklet<TestWorkletLimitedTypes>()(vtkm::Vec<vtkm::Float32,3>());
DoTestWorklet< ::worklets::TestWorkletLimitedTypes > badWorkletTest;
badWorkletTest( vtkm::Vec<vtkm::Float32,3>() );
VTKM_TEST_FAIL("Did not throw expected error.");
}
catch (vtkm::cont::ErrorControlBadType &error)