Merge branch 'master' into cpu_parallel_radix_sort

This commit is contained in:
Thomas Otahal 2018-02-07 10:23:54 -07:00
commit 9cf12c48ce
140 changed files with 1862 additions and 897 deletions

@ -174,7 +174,7 @@ endif ()
# will never adequately match the user's setup, so there is no feasible way
# to detect the "best" version to use. The user will have to manually
# select the right files. (Chances are the distributions are shipping their
# custom version of tbb, anyway, so the problem is probably nonexistant.)
# custom version of tbb, anyway, so the problem is probably nonexistent.)
if (WIN32 AND MSVC)
set(COMPILER_PREFIX "vc7.1")
if (MSVC_VERSION EQUAL 1400)

@ -70,7 +70,7 @@ if(${diff_result})
# If diff returned non-zero, it failed and the two files are different.
get_filename_component(filename ${SOURCE_FILE} NAME)
message(SEND_ERROR
"The source file ${filename} does not match the generated file. If you have modified this file directly, then you have messed up. Modify the ${filename}.in file instead and then copy the pyexpander result to ${filename}. If you modified ${filename}.in, then you might just need to copy the pyresult back to the source directory. If you have not modifed either, then you have likely checked out an inappropriate change. Check the git logs to see what changes were made.
"The source file ${filename} does not match the generated file. If you have modified this file directly, then you have messed up. Modify the ${filename}.in file instead and then copy the pyexpander result to ${filename}. If you modified ${filename}.in, then you might just need to copy the pyresult back to the source directory. If you have not modified either, then you have likely checked out an inappropriate change. Check the git logs to see what changes were made.
If the changes have resulted from modifying ${filename}.in, then you can finish by moving ${GENERATED_FILE}.save over ${SOURCE_FILE}")
else()
# Now that we have done the comparison, remove the generated file so there is

@ -111,7 +111,7 @@ macro(vtkm_configure_component_Base)
endif()
endif()
# Check for the existance of the base vtkm target
# Check for the existence of the base vtkm target
if (TARGET vtkm)
set(VTKm_base_vtkm_target_FOUND True)
endif()
@ -179,7 +179,7 @@ macro(vtkm_configure_component_OpenGL)
#setting VTKm_OPENGL_INCLUDE_DIRS when both mesa and
#opengl are not present causes cmake to fail to configure
#becase of a percieved dependency in the rendering lib
#because of a perceived dependency in the rendering lib
if(VTKm_OSMesa_FOUND OR OPENGL_FOUND)
set(VTKm_OPENGL_INCLUDE_DIRS ${vtkm_opengl_includes})
set(VTKm_OPENGL_LIBRARIES ${vtkm_opengl_libraries})
@ -350,7 +350,7 @@ macro(vtkm_configure_component_CUDA)
set(VTKm_CUDA_Architecture "native" CACHE STRING "Which GPU Architecture(s) to compile for")
set_property(CACHE VTKm_CUDA_Architecture PROPERTY STRINGS native fermi kepler maxwell pascal volta all)
#detect what the propery is set too
#detect what the property is set too
if(VTKm_CUDA_Architecture STREQUAL "native")
if(VTKM_CUDA_NATIVE_EXE_PROCESS_RAN_OUTPUT)

@ -58,7 +58,7 @@ function(determine_version source_dir git_command var_prefix)
endif()
extract_version_components("${output}" tmp)
if(DEFINED tmp_VERSION)
message(STATUS "Determined Source Version : ${tmp_VERSION_FULL}")
message(STATUS "Determined ${PROJECT_NAME} Source Version: ${tmp_VERSION_FULL}")
if (NOT "${tmp_VERSION}" STREQUAL "${${var_prefix}_VERSION}")
message(WARNING
"Version from git (${tmp_VERSION}) disagrees with hard coded version (${${var_prefix}_VERSION}). Either update the git tags or version.txt.")

@ -186,7 +186,7 @@ function(vtkm_add_header_build_test name dir_prefix use_cuda)
vtkm_setup_msvc_properties(TestBuild_${name})
# Send the libraries created for test builds to their own directory so as to
# not polute the directory with useful libraries.
# not pollute the directory with useful libraries.
set_target_properties(TestBuild_${name} PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${VTKm_LIBRARY_OUTPUT_PATH}/testbuilds
LIBRARY_OUTPUT_DIRECTORY ${VTKm_LIBRARY_OUTPUT_PATH}/testbuilds

@ -157,6 +157,8 @@ EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = */testing/*
EXCLUDE_PATTERNS += */examples/*
EXCLUDE_PATTERNS += UnitTest*
EXCLUDE_PATTERNS += */vtkmdiy/fmt/*
EXCLUDE_PATTERNS += */vtkmdiy/thread/*
EXCLUDE_SYMBOLS = thrust
EXCLUDE_SYMBOLS += detail

@ -94,7 +94,7 @@ if(NOT VTKm_Base_FOUND)
endif()
#-----------------------------------------------------------------------------
# When using C++11 suport make sure you use the standard C++ extensions rather
# When using C++11 support make sure you use the standard C++ extensions rather
# than compiler-specific versions of the extensions (to preserve portability).
set(CMAKE_CXX_EXTENSIONS False)

@ -436,7 +436,7 @@ authorized developers may add a comment with a single *trailing* line:
Do: merge
to ask that the change be merged into the upstream repository. By
convention, only merge if you have recieved `+1` . Do not request a merge
convention, only merge if you have received `+1` . Do not request a merge
if any `-1` review comments have not been resolved.
### Merge Success ###

@ -20,7 +20,7 @@
list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
".*warning: ignoring loop annotation.*"
".*diy.include.diy.*WShadow.*" # exclude `diy` shadow warnings.
".*diy.include.diy.*note: shadowed.*" # exclude `diy` shadow warnings.
".*diy.include.diy.storage.hpp.*Wunused-result.*" # this is a TODO in DIY.
".*warning: Included by graph for.*not generated, too many nodes. Consider increasing DOT_GRAPH_MAX_NODES."
".*diy.include.*diy.mpi.io.hpp.*Wconversion.*"
".*diy.include.*diy.mpi.datatypes.hpp.*Wunused-parameter.*"
)

@ -142,7 +142,7 @@ struct Bounds
/// \b Expand bounds to include other bounds.
///
/// This version of \c Include expands these bounds just enough to include
/// that of another bounds. Esentially it is the union of the two bounds.
/// that of another bounds. Essentially it is the union of the two bounds.
///
VTKM_EXEC_CONT
void Include(const vtkm::Bounds& bounds)

@ -329,7 +329,7 @@ VTKM_EXEC_CONT void MatrixLUPFactorFindUpperTriangleElements(vtkm::Matrix<T, Siz
/// LU-factorization takes a matrix A and decomposes it into a lower triangular
/// matrix L and upper triangular matrix U such that A = LU. The
/// LUP-factorization also allows permutation of A, which makes the
/// decomposition always posible so long as A is not singular. In addition to
/// decomposition always possible so long as A is not singular. In addition to
/// matrices L and U, LUP also finds permutation matrix P containing all zeros
/// except one 1 per row and column such that PA = LU.
///

@ -139,7 +139,7 @@ struct Range
/// \b Expand range to include other range.
///
/// This version of \c Include expands this range just enough to include that
/// of another range. Esentially it is the union of the two ranges.
/// of another range. Essentially it is the union of the two ranges.
///
VTKM_EXEC_CONT
void Include(const vtkm::Range& range)

@ -102,7 +102,7 @@ struct RangeId
/// \b Expand range to include other range.
///
/// This version of \c Include expands this range just enough to include that
/// of another range. Esentially it is the union of the two ranges.
/// of another range. Essentially it is the union of the two ranges.
///
VTKM_EXEC_CONT
void Include(const vtkm::RangeId& range)

@ -131,7 +131,7 @@ struct RangeId3
/// \b Expand range to include other range.
///
/// This version of \c Include expands the range just enough to include
/// the other range. Esentially it is the union of the two ranges.
/// the other range. Essentially it is the union of the two ranges.
///
VTKM_EXEC_CONT
void Include(const vtkm::RangeId3& range)

@ -58,7 +58,7 @@ VTKM_EXEC_CONT vtkm::Vec<T, 3> Transform3DPoint(const vtkm::Matrix<T, 4, 4>& mat
/// transformed by the given matrix in homogeneous coordinates.
///
/// Unlike Transform3DPoint, this method honors the fourth component of the
/// transformed homogeneous coordiante. This makes it applicable for perspective
/// transformed homogeneous coordinate. This makes it applicable for perspective
/// transformations, but requires some more computations.
///
template <typename T>

@ -63,7 +63,7 @@ struct TypeTraitsVectorTag
};
/// The TypeTraits class provides helpful compile-time information about the
/// basic types used in VTKm (and a few others for convienience). The majority
/// basic types used in VTKm (and a few others for convenience). The majority
/// of TypeTraits contents are typedefs to tags that can be used to easily
/// override behavior of called functions.
///
@ -71,7 +71,7 @@ template <typename T>
class TypeTraits
{
public:
/// \brief A tag to determing whether the type is integer or real.
/// \brief A tag to determine whether the type is integer or real.
///
/// This tag is either TypeTraitsRealTag or TypeTraitsIntegerTag.
using NumericTag = vtkm::TypeTraitsUnknownTag;

@ -48,7 +48,7 @@
* \brief Transportation controls for Control Environment Objects.
*
* vtkm::cont::arg includes the classes that allows the vtkm::worklet::Dispatchers
* to request Control Environment Objects to be transfered to the Execution Environment.
* to request Control Environment Objects to be transferred to the Execution Environment.
*
* \namespace vtkm::cont::cuda
* \brief CUDA implementation for Control Environment.
@ -790,7 +790,7 @@ protected:
/// The \c Vec class is most often used to represent vectors in the
/// mathematical sense as a quantity with a magnitude and direction. Vectors
/// are, of course, used extensively in computational geometry as well as
/// phyiscal simulations. The \c Vec class can be (and is) repurposed for more
/// physical simulations. The \c Vec class can be (and is) repurposed for more
/// general usage of holding a fixed-length sequence of objects.
///
/// There is no real limit to the size of the sequence (other than the largest

@ -126,6 +126,14 @@ struct VecTraits<vtkm::VecFromPortalPermute<IndexVecType, PortalType>>
}
};
template <typename IndexVecType, typename PortalType>
inline VTKM_EXEC VecFromPortalPermute<IndexVecType, PortalType> make_VecFromPortalPermute(
const IndexVecType* index,
const PortalType& portal)
{
return VecFromPortalPermute<IndexVecType, PortalType>(index, portal);
}
} // namespace vtkm
#endif //vtk_m_VecFromPortalPermute_h

@ -367,7 +367,7 @@ struct VecTraitsBasic
/// \brief VecTraits for Pair types
///
/// Although a pair woudl seem better as a size-2 vector, we treat it as a
/// Although a pair would seem better as a size-2 vector, we treat it as a
/// scalar. This is because a \c Vec is assumed to have the same type for
/// every component, and a pair in general has a different type for each
/// component. Thus we treat a pair as a "scalar" unit.

@ -48,8 +48,8 @@ public:
{
}
template <vtkm::IdComponent SrcSize>
VTKM_EXEC_CONT VecVariable(const vtkm::VecVariable<ComponentType, SrcSize>& src)
template <typename SrcVecType>
VTKM_EXEC_CONT VecVariable(const SrcVecType& src)
: NumComponents(src.GetNumberOfComponents())
{
VTKM_ASSERT(this->NumComponents <= MaxSize);
@ -59,17 +59,6 @@ public:
}
}
template <vtkm::IdComponent SrcSize>
VTKM_EXEC_CONT VecVariable(const vtkm::Vec<ComponentType, SrcSize>& src)
: NumComponents(SrcSize)
{
VTKM_ASSERT(this->NumComponents <= MaxSize);
for (vtkm::IdComponent index = 0; index < this->NumComponents; index++)
{
this->Data[index] = src[index];
}
}
VTKM_EXEC_CONT
vtkm::IdComponent GetNumberOfComponents() const { return this->NumComponents; }

@ -22,7 +22,7 @@
#ifndef vtk_m_VectorAnalysis_h
#define vtk_m_VectorAnalysis_h
// This header file defines math functions that deal with linear albegra funcitons
// This header file defines math functions that deal with linear albegra functions
#include <vtkm/Math.h>
#include <vtkm/TypeTraits.h>

@ -418,7 +418,7 @@ private:
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
ValueArrayHandle InputHandle;
// We don't actually use this, but we need it to prevent sufficently
// We don't actually use this, but we need it to prevent sufficiently
// smart compilers from optimizing the Reduce call out.
Value Result;

@ -436,7 +436,7 @@ public:
{
throw vtkm::cont::ErrorInternal(
"ArrayHandleTransform read only. "
"There should be no occurance of the ArrayHandle trying to pull "
"There should be no occurrence of the ArrayHandle trying to pull "
"data from the execution environment.");
}

@ -441,7 +441,7 @@ public:
}
template <typename ArrayHandleType>
bool IsSameType() const
bool IsType() const
{
return this->GetArrayHandleWrapper<ArrayHandleType>() != nullptr;
}
@ -488,7 +488,7 @@ void CastAndCall(const vtkm::cont::ArrayHandleVirtualCoordinates& coords,
Functor&& f,
Args&&... args)
{
if (coords.IsSameType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
if (coords.IsType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
{
f(coords.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>(), std::forward<Args>(args)...);
}

@ -75,7 +75,7 @@ private:
PortalType Portal;
};
/// Convienience function for converting an ArrayPortal to a begin iterator.
/// Convenience function for converting an ArrayPortal to a begin iterator.
///
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename PortalType>
@ -86,7 +86,7 @@ ArrayPortalToIteratorBegin(const PortalType& portal)
return iterators.GetBegin();
}
/// Convienience function for converting an ArrayPortal to an end iterator.
/// Convenience function for converting an ArrayPortal to an end iterator.
///
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename PortalType>

@ -38,7 +38,7 @@ private:
VTKM_CONT static bool IsUniformGrid(const vtkm::cont::DynamicCellSet& cellset,
const vtkm::cont::CoordinateSystem& coordinates)
{
return coordinates.GetData().IsSameType<vtkm::cont::ArrayHandleUniformPointCoordinates>() &&
return coordinates.GetData().IsType<vtkm::cont::ArrayHandleUniformPointCoordinates>() &&
(cellset.IsType<vtkm::cont::CellSetStructured<1>>() ||
cellset.IsType<vtkm::cont::CellSetStructured<2>>() ||
cellset.IsType<vtkm::cont::CellSetStructured<3>>());
@ -97,7 +97,7 @@ public:
"expecting ArrayHandleUniformPointCoordinates for coordinates");
auto cellId3 = static_cast<vtkm::Id3>((point - coords.GetOrigin()) / coords.GetSpacing());
auto cellDim = coords.GetDimensions() - vtkm::Id3(1);
auto cellDim = vtkm::Max(vtkm::Id3(1), coords.GetDimensions() - vtkm::Id3(1));
if (cellId3[0] < 0 || cellId3[0] >= cellDim[0] || cellId3[1] < 0 ||
cellId3[1] >= cellDim[1] || cellId3[2] < 0 || cellId3[2] >= cellDim[2])
{

@ -631,7 +631,7 @@ class DeviceAdapterAtomicArrayImplementation;
/// \brief Class providing a device-specific support for selecting the optimal
/// Task type for a given worklet.
///
/// When worklets are launched inside the execution enviornment we need to
/// When worklets are launched inside the execution environment we need to
/// ask the device adapter what is the preferred execution style, be it
/// a tiled iteration pattern, or strided. This class
///

@ -67,7 +67,7 @@ struct VTKM_CONT_EXPORT PolymorphicArrayHandleContainerBase
///
/// The \c PolymorphicArrayHandleContainer is similar to the
/// \c SimplePolymorphicContainer in that it can contain an object of an
/// unkown type. However, this class specifically holds ArrayHandle objects
/// unknown type. However, this class specifically holds ArrayHandle objects
/// (with different template parameters) so that it can polymorphically answer
/// simple questions about the object.
///
@ -289,7 +289,7 @@ public:
return this->CastToTypeStorage<ValueType, StorageTag>();
}
/// Given a refernce to an ArrayHandle object, casts this array to the
/// Given a references to an ArrayHandle object, casts this array to the
/// ArrayHandle's type and sets the given ArrayHandle to this array. Throws
/// \c ErrorBadType if the cast does not work. Use \c
/// ArrayHandleType to check if the cast can happen.

@ -308,7 +308,7 @@ void CastAndCall(const vtkm::cont::Field& field, Functor&& f, Args&&... args)
}
//@{
/// Convinience functions to build fields from C style arrays and std::vector
/// Convenience functions to build fields from C style arrays and std::vector
template <typename T>
vtkm::cont::Field make_Field(std::string name,
Field::AssociationEnum association,

@ -36,16 +36,16 @@ namespace cont
class VTKM_CONT_EXPORT MultiBlock
{
public:
/// creat a new MultiBlcok containng a single DataSet "ds"
/// create a new MultiBlock containng a single DataSet "ds"
VTKM_CONT
MultiBlock(const vtkm::cont::DataSet& ds);
/// creat a new MultiBlcok with the exisiting one "src"
/// create a new MultiBlock with the existing one "src"
VTKM_CONT
MultiBlock(const vtkm::cont::MultiBlock& src);
/// creat a new MultiBlcok with a DataSet vector "mblocks"
/// create a new MultiBlock with a DataSet vector "mblocks"
VTKM_CONT
MultiBlock(const std::vector<vtkm::cont::DataSet>& mblocks);
/// creat a new MultiBlcok with the capacity set to be "size"
/// create a new MultiBlock with the capacity set to be "size"
VTKM_CONT
MultiBlock(vtkm::Id size);
@ -57,7 +57,7 @@ public:
VTKM_CONT
~MultiBlock();
/// get the field "field_name" from blcok "block_index"
/// get the field "field_name" from block "block_index"
VTKM_CONT
vtkm::cont::Field GetField(const std::string& field_name, const int& block_index);

@ -131,7 +131,7 @@ public:
///
/// If you want a \c RuntimeDeviceTracker with independent state, just create
/// one independently. If you want to start with the state of a source
/// \c RuntimeDeviceTracker but update the state indepenently, you can use
/// \c RuntimeDeviceTracker but update the state independently, you can use
/// \c DeepCopy method to get the initial state. Further changes will
/// not be shared.
///
@ -152,7 +152,7 @@ public:
///
/// If you want a \c RuntimeDeviceTracker with independent state, just create
/// one independently. If you want to start with the state of a source
/// \c RuntimeDeviceTracker but update the state indepenently, you can use
/// \c RuntimeDeviceTracker but update the state independently, you can use
/// \c DeepCopy method to get the initial state. Further changes will
/// not be shared.
///

@ -132,7 +132,7 @@ public:
VTKM_CONT
PortalConstType GetPortalConst() const;
/// Retuns the number of entries allocated in the array.
/// Returns the number of entries allocated in the array.
VTKM_CONT
vtkm::Id GetNumberOfValues() const;

@ -27,7 +27,7 @@ namespace vtkm
namespace cont
{
/// A class that can be used to time operations in VTK-m that might be occuring
/// A class that can be used to time operations in VTK-m that might be occurring
/// in parallel. You should make sure that the device adapter for the timer
/// matches that being used to execute algorithms to ensure that the thread
/// synchronization is correct.

@ -127,19 +127,13 @@ struct ExecutionPortalFactoryBasic<T, DeviceAdapterTagCuda>
VTKM_CONT
static PortalType CreatePortal(ValueType* start, ValueType* end)
{
using ThrustPointerT = thrust::system::cuda::pointer<ValueType>;
ThrustPointerT startThrust(start);
ThrustPointerT endThrust(end);
return PortalType(startThrust, endThrust);
return PortalType(start, end);
}
VTKM_CONT
static PortalConstType CreatePortalConst(const ValueType* start, const ValueType* end)
{
using ThrustPointerT = thrust::system::cuda::pointer<const ValueType>;
ThrustPointerT startThrust(start);
ThrustPointerT endThrust(end);
return PortalConstType(startThrust, endThrust);
return PortalConstType(start, end);
}
};

@ -24,21 +24,16 @@
#include <vtkm/cont/ErrorBadAllocation.h>
#include <vtkm/cont/Storage.h>
// Disable warnings we check vtkm for but Thrust does not.
VTKM_THIRDPARTY_PRE_INCLUDE
#include <thrust/copy.h>
#include <thrust/device_malloc_allocator.h>
#include <thrust/system/cuda/vector.h>
#include <thrust/system/cuda/execution_policy.h>
VTKM_THIRDPARTY_POST_INCLUDE
#include <vtkm/cont/cuda/ErrorCuda.h>
#include <vtkm/cont/cuda/internal/CudaAllocator.h>
#include <vtkm/cont/cuda/internal/ThrustExceptionHandler.h>
#include <vtkm/exec/cuda/internal/ArrayPortalFromThrust.h>
VTKM_THIRDPARTY_PRE_INCLUDE
#include <thrust/copy.h>
#include <thrust/device_ptr.h>
VTKM_THIRDPARTY_POST_INCLUDE
#include <limits>
namespace vtkm
@ -53,15 +48,13 @@ namespace internal
/// \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::pointer to contain the
/// data.
template <typename T, class StorageTag>
class ArrayManagerExecutionThrustDevice
{
public:
using ValueType = T;
using PointerType = typename thrust::system::cuda::pointer<ValueType>;
using difference_type = typename PointerType::difference_type;
using PointerType = T*;
using difference_type = std::ptrdiff_t;
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
@ -71,9 +64,9 @@ public:
VTKM_CONT
ArrayManagerExecutionThrustDevice(StorageType* storage)
: Storage(storage)
, Begin(static_cast<ValueType*>(nullptr))
, End(static_cast<ValueType*>(nullptr))
, Capacity(static_cast<ValueType*>(nullptr))
, Begin(nullptr)
, End(nullptr)
, Capacity(nullptr)
{
}
@ -83,10 +76,7 @@ public:
/// Returns the size of the array.
///
VTKM_CONT
vtkm::Id GetNumberOfValues() const
{
return static_cast<vtkm::Id>(this->End.get() - this->Begin.get());
}
vtkm::Id GetNumberOfValues() const { return static_cast<vtkm::Id>(this->End - this->Begin); }
/// Allocates the appropriate size of the array and copies the given data
/// into the array.
@ -144,14 +134,13 @@ public:
PortalType PrepareForOutput(vtkm::Id numberOfValues)
{
// Can we reuse the existing buffer?
vtkm::Id curCapacity = this->Begin.get() != nullptr
? static_cast<vtkm::Id>(this->Capacity.get() - this->Begin.get())
: 0;
vtkm::Id curCapacity =
this->Begin != nullptr ? static_cast<vtkm::Id>(this->Capacity - this->Begin) : 0;
// Just mark a new end if we don't need to increase the allocation:
if (curCapacity >= numberOfValues)
{
this->End = PointerType(this->Begin.get() + static_cast<difference_type>(numberOfValues));
this->End = this->Begin + static_cast<difference_type>(numberOfValues);
return PortalType(this->Begin, this->End);
}
@ -173,9 +162,8 @@ public:
// Attempt to allocate:
try
{
ValueType* tmp =
this->Begin =
static_cast<ValueType*>(vtkm::cont::cuda::internal::CudaAllocator::Allocate(bufferSize));
this->Begin = PointerType(tmp);
}
catch (const std::exception& error)
{
@ -184,7 +172,7 @@ public:
throw vtkm::cont::ErrorBadAllocation(err.str());
}
this->Capacity = PointerType(this->Begin.get() + static_cast<difference_type>(numberOfValues));
this->Capacity = this->Begin + static_cast<difference_type>(numberOfValues);
this->End = this->Capacity;
return PortalType(this->Begin, this->End);
@ -206,8 +194,9 @@ public:
storage->Allocate(this->GetNumberOfValues());
try
{
::thrust::copy(
this->Begin, this->End, vtkm::cont::ArrayPortalToIteratorBegin(storage->GetPortal()));
::thrust::copy(thrust::cuda::pointer<ValueType>(this->Begin),
thrust::cuda::pointer<ValueType>(this->End),
vtkm::cont::ArrayPortalToIteratorBegin(storage->GetPortal()));
}
catch (...)
{
@ -221,22 +210,21 @@ public:
{
// The operation will succeed even if this assertion fails, but this
// is still supposed to be a precondition to Shrink.
VTKM_ASSERT(this->Begin.get() != nullptr &&
this->Begin.get() + numberOfValues <= this->End.get());
VTKM_ASSERT(this->Begin != nullptr && this->Begin + numberOfValues <= this->End);
this->End = PointerType(this->Begin.get() + static_cast<difference_type>(numberOfValues));
this->End = this->Begin + static_cast<difference_type>(numberOfValues);
}
/// Frees all memory.
///
VTKM_CONT void ReleaseResources()
{
if (this->Begin.get() != nullptr)
if (this->Begin != nullptr)
{
vtkm::cont::cuda::internal::CudaAllocator::Free(this->Begin.get());
this->Begin = PointerType(static_cast<ValueType*>(nullptr));
this->End = PointerType(static_cast<ValueType*>(nullptr));
this->Capacity = PointerType(static_cast<ValueType*>(nullptr));
vtkm::cont::cuda::internal::CudaAllocator::Free(this->Begin);
this->Begin = nullptr;
this->End = nullptr;
this->Capacity = nullptr;
}
}
@ -258,7 +246,7 @@ private:
this->PrepareForOutput(this->Storage->GetNumberOfValues());
::thrust::copy(vtkm::cont::ArrayPortalToIteratorBegin(this->Storage->GetPortalConst()),
vtkm::cont::ArrayPortalToIteratorEnd(this->Storage->GetPortalConst()),
this->Begin);
thrust::cuda::pointer<ValueType>(this->Begin));
}
catch (...)
{

@ -42,7 +42,7 @@ struct VTKM_CONT_EXPORT CudaAllocator
/// that can be accessed concurrently by the CPU and GPUs.
static VTKM_CONT bool UsingManagedMemory();
/// Returns true if the pointer is accessable from a CUDA device.
/// Returns true if the pointer is accessible from a CUDA device.
static VTKM_CONT bool IsDevicePointer(const void* ptr);
/// Returns true if the pointer is a CUDA pointer allocated with

@ -258,8 +258,8 @@ class DeviceTaskTypes<vtkm::cont::DeviceAdapterTagCuda>
public:
template <typename WorkletType, typename InvocationType>
static vtkm::exec::internal::TaskSingular<WorkletType, InvocationType> MakeTask(
const WorkletType& worklet,
const InvocationType& invocation,
WorkletType& worklet,
InvocationType& invocation,
vtkm::Id,
vtkm::Id globalIndexOffset = 0)
{
@ -269,8 +269,8 @@ public:
template <typename WorkletType, typename InvocationType>
static vtkm::exec::internal::TaskSingular<WorkletType, InvocationType> MakeTask(
const WorkletType& worklet,
const InvocationType& invocation,
WorkletType& worklet,
InvocationType& invocation,
vtkm::Id3,
vtkm::Id globalIndexOffset = 0)
{

@ -53,14 +53,13 @@ VTKM_THIRDPARTY_PRE_INCLUDE
#include <thrust/binary_search.h>
#include <thrust/copy.h>
#include <thrust/count.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/scan.h>
#include <thrust/sort.h>
#include <thrust/system/cpp/memory.h>
#include <thrust/system/cuda/vector.h>
#include <thrust/unique.h>
#include <vtkm/exec/cuda/internal/ExecutionPolicy.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/system/cuda/execution_policy.h>
VTKM_THIRDPARTY_POST_INCLUDE
#include <atomic>
@ -218,8 +217,7 @@ private:
OutputPortal output,
UnaryPredicate unary_predicate)
{
using IteratorType = typename detail::IteratorTraits<OutputPortal>::IteratorType;
IteratorType outputBegin = IteratorBegin(output);
auto outputBegin = IteratorBegin(output);
using ValueType = typename StencilPortal::ValueType;
@ -356,7 +354,7 @@ private:
BinaryFunctor binary_functor,
std::false_type)
{
//The portal type and the initial value ARENT the same type so we have
//The portal type and the initial value AREN'T the same type so we have
//to a slower approach, where we wrap the input portal inside a cast
//portal
using CastFunctor = vtkm::cont::internal::Cast<typename InputPortal::ValueType, T>;
@ -497,12 +495,15 @@ private:
try
{
::thrust::system::cuda::vector<ValueType> result(1);
auto end = ::thrust::inclusive_scan(ThrustCudaPolicyPerThread,
IteratorBegin(input),
IteratorEnd(input),
IteratorBegin(output),
bop);
return *(end - 1);
::thrust::copy_n(ThrustCudaPolicyPerThread, end - 1, 1, result.begin());
return result[0];
}
catch (...)
{

@ -20,21 +20,8 @@
#ifndef vtk_m_cont_cuda_internal_MakeThrustIterator_h
#define vtk_m_cont_cuda_internal_MakeThrustIterator_h
#include <vtkm/Pair.h>
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/internal/ExportMacros.h>
#include <vtkm/exec/cuda/internal/ArrayPortalFromThrust.h>
#include <vtkm/exec/cuda/internal/WrappedOperators.h>
// Disable warnings we check vtkm for but Thrust does not.
VTKM_THIRDPARTY_PRE_INCLUDE
#include <thrust/functional.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/iterator/transform_iterator.h>
#include <thrust/system/cuda/memory.h>
VTKM_THIRDPARTY_POST_INCLUDE
#include <vtkm/exec/cuda/internal/IteratorFromArrayPortal.h>
namespace vtkm
{
@ -44,107 +31,46 @@ namespace cuda
{
namespace internal
{
namespace detail
{
// Tags to specify what type of thrust iterator to use.
struct ThrustIteratorFromArrayPortalTag
{
};
struct ThrustIteratorDevicePtrTag
{
};
// Traits to help classify what thrust iterators will be used.
template <typename IteratorType>
struct ThrustIteratorTag
{
using Type = ThrustIteratorFromArrayPortalTag;
};
template <typename T>
struct ThrustIteratorTag<thrust::system::cuda::pointer<T>>
{
using Type = ThrustIteratorDevicePtrTag;
};
template <typename T>
struct ThrustIteratorTag<thrust::system::cuda::pointer<const T>>
{
using Type = ThrustIteratorDevicePtrTag;
};
template <typename PortalType, typename Tag>
struct IteratorChooser;
template <typename PortalType>
struct IteratorChooser<PortalType, detail::ThrustIteratorFromArrayPortalTag>
{
using Type = vtkm::exec::cuda::internal::IteratorFromArrayPortal<PortalType>;
};
template <typename PortalType>
struct IteratorChooser<PortalType, detail::ThrustIteratorDevicePtrTag>
{
using PortalToIteratorType = vtkm::cont::ArrayPortalToIterators<PortalType>;
using Type = typename PortalToIteratorType::IteratorType;
};
template <typename PortalType>
struct IteratorTraits
{
using PortalToIteratorType = vtkm::cont::ArrayPortalToIterators<PortalType>;
using Tag = typename detail::ThrustIteratorTag<typename PortalToIteratorType::IteratorType>::Type;
using IteratorType = typename IteratorChooser<PortalType, Tag>::Type;
};
template <typename PortalType>
VTKM_CONT typename IteratorTraits<PortalType>::IteratorType MakeIteratorBegin(
PortalType portal,
detail::ThrustIteratorFromArrayPortalTag)
{
return vtkm::exec::cuda::internal::IteratorFromArrayPortal<PortalType>(portal);
}
template <typename PortalType>
VTKM_CONT typename IteratorTraits<PortalType>::IteratorType MakeIteratorBegin(
PortalType portal,
detail::ThrustIteratorDevicePtrTag)
{
vtkm::cont::ArrayPortalToIterators<PortalType> iterators(portal);
return iterators.GetBegin();
}
template <typename PortalType>
VTKM_CONT typename IteratorTraits<PortalType>::IteratorType MakeIteratorEnd(
PortalType portal,
detail::ThrustIteratorFromArrayPortalTag)
inline vtkm::exec::cuda::internal::IteratorFromArrayPortal<PortalType> IteratorBegin(
const PortalType& portal)
{
vtkm::exec::cuda::internal::IteratorFromArrayPortal<PortalType> iterator(portal);
::thrust::advance(iterator, static_cast<std::size_t>(portal.GetNumberOfValues()));
return iterator;
}
template <typename PortalType>
VTKM_CONT typename IteratorTraits<PortalType>::IteratorType MakeIteratorEnd(
PortalType portal,
detail::ThrustIteratorDevicePtrTag)
inline vtkm::exec::cuda::internal::IteratorFromArrayPortal<PortalType> IteratorEnd(
const PortalType& portal)
{
vtkm::cont::ArrayPortalToIterators<PortalType> iterators(portal);
return iterators.GetEnd();
vtkm::exec::cuda::internal::IteratorFromArrayPortal<PortalType> iterator(portal);
iterator += static_cast<std::size_t>(portal.GetNumberOfValues());
return iterator;
}
} // namespace detail
template <typename PortalType>
VTKM_CONT typename detail::IteratorTraits<PortalType>::IteratorType IteratorBegin(PortalType portal)
template <typename T>
inline T* IteratorBegin(const vtkm::exec::cuda::internal::ArrayPortalFromThrust<T>& portal)
{
using IteratorTag = typename detail::IteratorTraits<PortalType>::Tag;
return detail::MakeIteratorBegin(portal, IteratorTag());
return portal.GetIteratorBegin();
}
template <typename PortalType>
VTKM_CONT typename detail::IteratorTraits<PortalType>::IteratorType IteratorEnd(PortalType portal)
template <typename T>
inline T* IteratorEnd(const vtkm::exec::cuda::internal::ArrayPortalFromThrust<T>& portal)
{
using IteratorTag = typename detail::IteratorTraits<PortalType>::Tag;
return detail::MakeIteratorEnd(portal, IteratorTag());
return portal.GetIteratorEnd();
}
template <typename T>
inline const T* IteratorBegin(
const vtkm::exec::cuda::internal::ConstArrayPortalFromThrust<T>& portal)
{
return portal.GetIteratorBegin();
}
template <typename T>
inline const T* IteratorEnd(const vtkm::exec::cuda::internal::ConstArrayPortalFromThrust<T>& portal)
{
return portal.GetIteratorEnd();
}
}
}

@ -268,7 +268,7 @@ ArrayHandle<T, StorageTagBasic>::PrepareForInput(DeviceAdapterTag device) const
this->PrepareForDevice(device);
const vtkm::UInt64 numBytes = static_cast<vtkm::UInt64>(sizeof(ValueType)) *
static_cast<vtkm::UInt64>(this->GetStorage().GetNumberOfValues());
static_cast<vtkm::UInt64>(this->GetNumberOfValues());
if (!this->Internals->ExecutionArrayValid)
@ -348,7 +348,7 @@ ArrayHandle<T, StorageTagBasic>::PrepareForInPlace(DeviceAdapterTag device)
this->PrepareForDevice(device);
const vtkm::UInt64 numBytes = static_cast<vtkm::UInt64>(sizeof(ValueType)) *
static_cast<vtkm::UInt64>(this->GetStorage().GetNumberOfValues());
static_cast<vtkm::UInt64>(this->GetNumberOfValues());
if (!this->Internals->ExecutionArrayValid)
{

@ -40,7 +40,7 @@ namespace internal
/// any resources in its destructor.
///
/// This class typically takes on one of two forms. If the control and
/// execution environments have seperate memory spaces, then this class
/// execution environments have separate memory spaces, then this class
/// behaves how you would expect. It allocates/deallocates arrays and copies
/// data. However, if the control and execution environments share the same
/// memory space, this class should delegate all its operations to the

@ -1007,7 +1007,7 @@ private:
/// \brief Class providing a device-specific support for selecting the optimal
/// Task type for a given worklet.
///
/// When worklets are launched inside the execution enviornment we need to
/// When worklets are launched inside the execution environment we need to
/// ask the device adapter what is the preferred execution style, be it
/// a tiled iteration pattern, or strided. This class
///
@ -1020,8 +1020,8 @@ class DeviceTaskTypes
public:
template <typename WorkletType, typename InvocationType>
static vtkm::exec::internal::TaskSingular<WorkletType, InvocationType> MakeTask(
const WorkletType& worklet,
const InvocationType& invocation,
WorkletType& worklet,
InvocationType& invocation,
vtkm::Id,
vtkm::Id globalIndexOffset = 0)
{
@ -1031,8 +1031,8 @@ public:
template <typename WorkletType, typename InvocationType>
static vtkm::exec::internal::TaskSingular<WorkletType, InvocationType> MakeTask(
const WorkletType& worklet,
const InvocationType& invocation,
WorkletType& worklet,
InvocationType& invocation,
vtkm::Id3,
vtkm::Id globalIndexOffset = 0)
{

@ -119,7 +119,7 @@ struct TemplatedTests
VTKM_TEST_ASSERT(const_portal.GetNumberOfValues() == ARRAY_SIZE,
"Const portal array size wrong.");
std::cout << " Check inital value." << std::endl;
std::cout << " Check initial value." << std::endl;
VTKM_TEST_ASSERT(CheckPortal(portal, ORIGINAL_VALUE), "Portal iterator has bad value.");
VTKM_TEST_ASSERT(CheckPortal(const_portal, ORIGINAL_VALUE),
"Const portal iterator has bad value.");

@ -281,28 +281,6 @@ public:
values_output.Shrink(writePos + 1);
}
template <typename T, class CIn, class COut>
VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
vtkm::cont::ArrayHandle<T, COut>& output)
{
vtkm::Id numberOfValues = input.GetNumberOfValues();
auto inputPortal = input.PrepareForInput(Device());
auto outputPortal = output.PrepareForOutput(numberOfValues, Device());
if (numberOfValues <= 0)
{
return vtkm::TypeTraits<T>::ZeroInitialization();
}
std::partial_sum(vtkm::cont::ArrayPortalToIteratorBegin(inputPortal),
vtkm::cont::ArrayPortalToIteratorEnd(inputPortal),
vtkm::cont::ArrayPortalToIteratorBegin(outputPortal));
// Return the value at the last index in the array, which is the full sum.
return outputPortal.Get(numberOfValues - 1);
}
template <typename T, class CIn, class COut, class BinaryFunctor>
VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
vtkm::cont::ArrayHandle<T, COut>& output,
@ -329,6 +307,13 @@ public:
return outputPortal.Get(numberOfValues - 1);
}
template <typename T, class CIn, class COut>
VTKM_CONT static T ScanInclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
vtkm::cont::ArrayHandle<T, COut>& output)
{
return ScanInclusive(input, output, vtkm::Sum());
}
template <typename T, class CIn, class COut, class BinaryFunctor>
VTKM_CONT static T ScanExclusive(const vtkm::cont::ArrayHandle<T, CIn>& input,
vtkm::cont::ArrayHandle<T, COut>& output,
@ -513,8 +498,8 @@ class DeviceTaskTypes<vtkm::cont::DeviceAdapterTagSerial>
{
public:
template <typename WorkletType, typename InvocationType>
static vtkm::exec::serial::internal::TaskTiling1D MakeTask(const WorkletType& worklet,
const InvocationType& invocation,
static vtkm::exec::serial::internal::TaskTiling1D MakeTask(WorkletType& worklet,
InvocationType& invocation,
vtkm::Id,
vtkm::Id globalIndexOffset = 0)
{
@ -522,8 +507,8 @@ public:
}
template <typename WorkletType, typename InvocationType>
static vtkm::exec::serial::internal::TaskTiling3D MakeTask(const WorkletType& worklet,
const InvocationType& invocation,
static vtkm::exec::serial::internal::TaskTiling3D MakeTask(WorkletType& worklet,
InvocationType& invocation,
vtkm::Id3,
vtkm::Id globalIndexOffset = 0)
{

@ -414,8 +414,8 @@ class DeviceTaskTypes<vtkm::cont::DeviceAdapterTagTBB>
{
public:
template <typename WorkletType, typename InvocationType>
static vtkm::exec::serial::internal::TaskTiling1D MakeTask(const WorkletType& worklet,
const InvocationType& invocation,
static vtkm::exec::serial::internal::TaskTiling1D MakeTask(WorkletType& worklet,
InvocationType& invocation,
vtkm::Id,
vtkm::Id globalIndexOffset = 0)
{
@ -423,8 +423,8 @@ public:
}
template <typename WorkletType, typename InvocationType>
static vtkm::exec::serial::internal::TaskTiling3D MakeTask(const WorkletType& worklet,
const InvocationType& invocation,
static vtkm::exec::serial::internal::TaskTiling3D MakeTask(WorkletType& worklet,
InvocationType& invocation,
vtkm::Id3,
vtkm::Id globalIndexOffset = 0)
{

@ -128,7 +128,7 @@ vtkm::cont::DataSet MakeTestDataSet(const vtkm::Vec<vtkm::Id, DIMENSIONS>& dims,
VTKM_ASSERT(false);
}
// It is posible that the warping will result in invalid cells. So use a
// It is possible that the warping will result in invalid cells. So use a
// local random generator with a known seed that does not create invalid cells.
std::default_random_engine rgen;

@ -1070,7 +1070,6 @@ private:
std::cout << " Reduce with 0 values." << std::endl;
array.Shrink(0);
vtkm::Id reduce_sum_no_values = Algorithm::Reduce(array, vtkm::Id(0));
VTKM_TEST_ASSERT(reduce_sum == OFFSET * ARRAY_SIZE, "Got bad sum from Reduce");
VTKM_TEST_ASSERT(reduce_sum_with_intial_value == reduce_sum + ARRAY_SIZE,
"Got bad sum from Reduce with initial value");

@ -31,7 +31,6 @@ set(headers
ExecutionObjectBase.h
ExecutionWholeArray.h
FunctorBase.h
ImplicitFunction.h
Jacobian.h
ParametricCoordinates.h
TaskBase.h

@ -265,7 +265,7 @@ static inline VTKM_EXEC vtkm::VecCConst<vtkm::IdComponent> CellFaceLocalIndices(
numPointsInFace);
}
/// \brief Returns a canonical identifer for a cell face
/// \brief Returns a canonical identifier for a cell face
///
/// Given information about a cell face and the global point indices for that cell, returns a
/// vtkm::Id3 that contains values that are unique to that face. The values for two faces will be

@ -67,8 +67,8 @@ VTKM_EXEC typename WorldCoordVector::ComponentType ReverseInterpolateTriangle(
//
// In this diagram, the distance between p0 and the point marked x divided by
// the length of the edge it is on is equal, by proportionality, to the u
// parametric coordiante. (The v coordinate follows the other edge
// accordingly.) Thus, if we can find the interesection at x (or more
// parametric coordinate. (The v coordinate follows the other edge
// accordingly.) Thus, if we can find the intersection at x (or more
// specifically the distance between p0 and x), then we can find that
// parametric coordinate.
//
@ -94,13 +94,13 @@ VTKM_EXEC typename WorldCoordVector::ComponentType ReverseInterpolateTriangle(
// compute it, we are done. We can skip the part about finding the actual
// coordinates of the intersection.
//
// Solving for the interesection is as simple as substituting the line's
// Solving for the intersection is as simple as substituting the line's
// definition of p(d) into p for the plane equation. With some basic algebra
// you get:
//
// d = dot((wcoords - p0), planeNormal)/dot((p1-p0), planeNormal)
//
// From here, the u coordiante is simply d. The v coordinate follows
// From here, the u coordinate is simply d. The v coordinate follows
// similarly.
//

@ -1,145 +0,0 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_exec_ImplicitFunction_h
#define vtk_m_exec_ImplicitFunction_h
#include <vtkm/Types.h>
namespace vtkm
{
namespace exec
{
class VTKM_ALWAYS_EXPORT ImplicitFunction
{
public:
ImplicitFunction()
: Function(nullptr)
, ValueCaller(nullptr)
, GradientCaller(nullptr)
{
}
VTKM_EXEC
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->ValueCaller(this->Function, x, y, z);
}
VTKM_EXEC
FloatDefault Value(const vtkm::Vec<FloatDefault, 3>& x) const
{
return this->ValueCaller(this->Function, x[0], x[1], x[2]);
}
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->GradientCaller(this->Function, x, y, z);
}
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3>& x) const
{
return this->GradientCaller(this->Function, x[0], x[1], x[2]);
}
template <typename T>
VTKM_EXEC void Bind(const T* function)
{
this->Function = function;
this->ValueCaller = [](const void* t, FloatDefault x, FloatDefault y, FloatDefault z) {
return static_cast<const T*>(t)->Value(x, y, z);
};
this->GradientCaller = [](const void* t, FloatDefault x, FloatDefault y, FloatDefault z) {
return static_cast<const T*>(t)->Gradient(x, y, z);
};
}
private:
using ValueCallerSig = FloatDefault(const void*, FloatDefault, FloatDefault, FloatDefault);
using GradientCallerSig = vtkm::Vec<FloatDefault, 3>(const void*,
FloatDefault,
FloatDefault,
FloatDefault);
const void* Function;
ValueCallerSig* ValueCaller;
GradientCallerSig* GradientCaller;
};
/// \brief A function object that evaluates the contained implicit function
class VTKM_ALWAYS_EXPORT ImplicitFunctionValue
{
public:
ImplicitFunctionValue() = default;
explicit ImplicitFunctionValue(const vtkm::exec::ImplicitFunction& func)
: Function(func)
{
}
VTKM_EXEC
FloatDefault operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Value(x);
}
VTKM_EXEC
FloatDefault operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Value(x, y, z);
}
private:
vtkm::exec::ImplicitFunction Function;
};
/// \brief A function object that computes the gradient of the contained implicit
/// function and the specified point.
class VTKM_ALWAYS_EXPORT ImplicitFunctionGradient
{
public:
ImplicitFunctionGradient() = default;
explicit ImplicitFunctionGradient(const vtkm::exec::ImplicitFunction& func)
: Function(func)
{
}
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Gradient(x);
}
VTKM_EXEC
vtkm::Vec<FloatDefault, 3> operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Gradient(x, y, z);
}
private:
vtkm::exec::ImplicitFunction Function;
};
}
} // vtkm::exec
#endif // vtk_m_exec_ImplicitFunction_h

@ -28,6 +28,7 @@
#include <vtkm/exec/CellInterpolate.h>
#include <vtkm/exec/FunctorBase.h>
#include <vtkm/exec/Jacobian.h>
#include <vtkm/exec/internal/FastVec.h>
#include <vtkm/internal/Assume.h>
namespace vtkm
@ -586,7 +587,77 @@ ParametricCoordinatesToWorldCoordinates(const WorldCoordVector& pointWCoords,
}
//-----------------------------------------------------------------------------
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector&,
const typename WorldCoordVector::ComponentType&,
vtkm::CellShapeTagEmpty,
bool& success,
const vtkm::exec::FunctorBase& worklet)
{
worklet.RaiseError("Attempted to find point coordinates in empty cell.");
success = false;
return typename WorldCoordVector::ComponentType();
}
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType&,
vtkm::CellShapeTagVertex,
bool& success,
const vtkm::exec::FunctorBase& vtkmNotUsed(worklet))
{
(void)pointWCoords; // Silence compiler warnings.
VTKM_ASSERT(pointWCoords.GetNumberOfComponents() == 1);
success = true;
return typename WorldCoordVector::ComponentType(0, 0, 0);
}
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
vtkm::CellShapeTagLine,
bool& success,
const vtkm::exec::FunctorBase& vtkmNotUsed(worklet))
{
VTKM_ASSERT(pointWCoords.GetNumberOfComponents() == 2);
success = true;
// Because this is a line, there is only one valid parametric coordinate. Let
// vec be the vector from the first point to the second point
// (pointWCoords[1] - pointWCoords[0]), which is the direction of the line.
// dot(vec,wcoords-pointWCoords[0])/mag(vec) is the orthoginal projection of
// wcoords on the line and represents the distance between the orthoginal
// projection and pointWCoords[0]. The parametric coordinate is the fraction
// of this over the length of the segment, which is mag(vec). Thus, the
// parametric coordinate is dot(vec,wcoords-pointWCoords[0])/mag(vec)^2.
using Vector3 = typename WorldCoordVector::ComponentType;
using T = typename Vector3::ComponentType;
Vector3 vec = pointWCoords[1] - pointWCoords[0];
T numerator = vtkm::dot(vec, wcoords - pointWCoords[0]);
T denominator = vtkm::MagnitudeSquared(vec);
return Vector3(numerator / denominator, 0, 0);
}
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
vtkm::CellShapeTagTriangle,
bool& success,
const vtkm::exec::FunctorBase&)
{
success = true;
vtkm::exec::internal::FastVec<WorldCoordVector, 3> local(pointWCoords);
return vtkm::exec::internal::ReverseInterpolateTriangle(local.Get(), wcoords);
}
//-----------------------------------------------------------------------------
namespace detail
{
@ -655,160 +726,37 @@ public:
}
};
template <typename WorldCoordVector, typename CellShapeTag>
class JacobianFunctor3DCell
{
using T = typename WorldCoordVector::ComponentType::ComponentType;
using Vector3 = vtkm::Vec<T, 3>;
using Matrix3x3 = vtkm::Matrix<T, 3, 3>;
const WorldCoordVector* PointWCoords;
public:
VTKM_EXEC
JacobianFunctor3DCell(const WorldCoordVector* pointWCoords)
: PointWCoords(pointWCoords)
{
}
VTKM_EXEC
Matrix3x3 operator()(const Vector3& pcoords) const
{
Matrix3x3 jacobian;
vtkm::exec::JacobianFor3DCell(*this->PointWCoords, pcoords, jacobian, CellShapeTag());
return jacobian;
}
};
template <typename WorldCoordVector, typename CellShapeTag>
class CoordinatesFunctor3DCell
{
using T = typename WorldCoordVector::ComponentType::ComponentType;
using Vector3 = vtkm::Vec<T, 3>;
const WorldCoordVector* PointWCoords;
const vtkm::exec::FunctorBase* Worklet;
public:
VTKM_EXEC
CoordinatesFunctor3DCell(const WorldCoordVector* pointWCoords,
const vtkm::exec::FunctorBase* worklet)
: PointWCoords(pointWCoords)
, Worklet(worklet)
{
}
VTKM_EXEC
Vector3 operator()(Vector3 pcoords) const
{
return vtkm::exec::ParametricCoordinatesToWorldCoordinates(
*this->PointWCoords, pcoords, CellShapeTag(), *this->Worklet);
}
};
template <typename WorldCoordVector, typename CellShapeTag>
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates3D(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
CellShapeTag,
bool& success,
const vtkm::exec::FunctorBase& worklet)
WorldCoordinatesToParametricCoordinatesQuad(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
bool& success,
const vtkm::exec::FunctorBase& worklet)
{
auto result = vtkm::NewtonsMethod(
JacobianFunctor3DCell<WorldCoordVector, CellShapeTag>(&pointWCoords),
CoordinatesFunctor3DCell<WorldCoordVector, CellShapeTag>(&pointWCoords, &worklet),
wcoords,
typename WorldCoordVector::ComponentType(0.5f, 0.5f, 0.5f));
success = result.Valid;
return result.Solution;
}
using T = typename WorldCoordVector::ComponentType::ComponentType;
using Vector2 = vtkm::Vec<T, 2>;
using Vector3 = vtkm::Vec<T, 3>;
// We have an underdetermined system in 3D, so create a 2D space in the
// plane that the polygon sits.
vtkm::exec::internal::Space2D<T> space(pointWCoords[0], pointWCoords[1], pointWCoords[3]);
auto result = vtkm::NewtonsMethod(
JacobianFunctorQuad<WorldCoordVector, vtkm::CellShapeTagQuad>(&pointWCoords, &space),
CoordinatesFunctorQuad<WorldCoordVector, vtkm::CellShapeTagQuad>(
&pointWCoords, &space, &worklet),
space.ConvertCoordToSpace(wcoords),
Vector2(0.5f, 0.5f));
success = result.Valid;
return Vector3(result.Solution[0], result.Solution[1], 0);
}
} // namespace detail
//-----------------------------------------------------------------------------
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
vtkm::CellShapeTagGeneric shape,
bool& success,
const vtkm::exec::FunctorBase& worklet)
{
typename WorldCoordVector::ComponentType result;
switch (shape.Id)
{
vtkmGenericCellShapeMacro(result = WorldCoordinatesToParametricCoordinates(
pointWCoords, wcoords, CellShapeTag(), success, worklet));
default:
success = false;
worklet.RaiseError("Unknown cell shape sent to world 2 parametric.");
return typename WorldCoordVector::ComponentType();
}
return result;
}
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector&,
const typename WorldCoordVector::ComponentType&,
vtkm::CellShapeTagEmpty,
bool& success,
const vtkm::exec::FunctorBase& worklet)
{
worklet.RaiseError("Attempted to find point coordinates in empty cell.");
success = false;
return typename WorldCoordVector::ComponentType();
}
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType&,
vtkm::CellShapeTagVertex,
bool& success,
const vtkm::exec::FunctorBase& vtkmNotUsed(worklet))
{
(void)pointWCoords; // Silence compiler warnings.
VTKM_ASSERT(pointWCoords.GetNumberOfComponents() == 1);
success = true;
return typename WorldCoordVector::ComponentType(0, 0, 0);
}
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
vtkm::CellShapeTagLine,
bool& success,
const vtkm::exec::FunctorBase& vtkmNotUsed(worklet))
{
VTKM_ASSERT(pointWCoords.GetNumberOfComponents() == 2);
success = true;
// Because this is a line, there is only one vaild parametric coordinate. Let
// vec be the vector from the first point to the second point
// (pointWCoords[1] - pointWCoords[0]), which is the direction of the line.
// dot(vec,wcoords-pointWCoords[0])/mag(vec) is the orthoginal projection of
// wcoords on the line and represents the distance between the orthoginal
// projection and pointWCoords[0]. The parametric coordinate is the fraction
// of this over the length of the segment, which is mag(vec). Thus, the
// parametric coordinate is dot(vec,wcoords-pointWCoords[0])/mag(vec)^2.
using Vector3 = typename WorldCoordVector::ComponentType;
using T = typename Vector3::ComponentType;
Vector3 vec = pointWCoords[1] - pointWCoords[0];
T numerator = vtkm::dot(vec, wcoords - pointWCoords[0]);
T denominator = vtkm::MagnitudeSquared(vec);
return Vector3(numerator / denominator, 0, 0);
}
static inline VTKM_EXEC vtkm::Vec<vtkm::FloatDefault, 3> WorldCoordinatesToParametricCoordinates(
const vtkm::VecAxisAlignedPointCoordinates<1>& pointWCoords,
const vtkm::VecAxisAlignedPointCoordinates<2>& pointWCoords,
const vtkm::Vec<vtkm::FloatDefault, 3>& wcoords,
vtkm::CellShapeTagLine,
vtkm::CellShapeTagQuad,
bool& success,
const FunctorBase&)
{
@ -820,14 +768,16 @@ template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
vtkm::CellShapeTagTriangle,
vtkm::CellShapeTagQuad,
bool& success,
const vtkm::exec::FunctorBase& vtkmNotUsed(worklet))
const vtkm::exec::FunctorBase& worklet)
{
success = true;
return vtkm::exec::internal::ReverseInterpolateTriangle(pointWCoords, wcoords);
vtkm::exec::internal::FastVec<WorldCoordVector, 4> local(pointWCoords);
return detail::WorldCoordinatesToParametricCoordinatesQuad(
local.Get(), wcoords, success, worklet);
}
//-----------------------------------------------------------------------------
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
@ -951,57 +901,16 @@ WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
triangleWCoords, trianglePCoords, vtkm::CellShapeTagTriangle(), worklet);
}
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
vtkm::CellShapeTagQuad,
bool& success,
const vtkm::exec::FunctorBase& worklet)
//-----------------------------------------------------------------------------
namespace detail
{
VTKM_ASSERT(pointWCoords.GetNumberOfComponents() == 4);
using T = typename WorldCoordVector::ComponentType::ComponentType;
using Vector2 = vtkm::Vec<T, 2>;
using Vector3 = vtkm::Vec<T, 3>;
// We have an underdetermined system in 3D, so create a 2D space in the
// plane that the polygon sits.
vtkm::exec::internal::Space2D<T> space(pointWCoords[0], pointWCoords[1], pointWCoords[3]);
auto result = vtkm::NewtonsMethod(
detail::JacobianFunctorQuad<WorldCoordVector, vtkm::CellShapeTagQuad>(&pointWCoords, &space),
detail::CoordinatesFunctorQuad<WorldCoordVector, vtkm::CellShapeTagQuad>(
&pointWCoords, &space, &worklet),
space.ConvertCoordToSpace(wcoords),
Vector2(0.5f, 0.5f));
success = result.Valid;
return Vector3(result.Solution[0], result.Solution[1], 0);
}
static inline VTKM_EXEC vtkm::Vec<vtkm::FloatDefault, 3> WorldCoordinatesToParametricCoordinates(
const vtkm::VecAxisAlignedPointCoordinates<2>& pointWCoords,
const vtkm::Vec<vtkm::FloatDefault, 3>& wcoords,
vtkm::CellShapeTagQuad,
bool& success,
const FunctorBase&)
{
success = true;
return (wcoords - pointWCoords.GetOrigin()) / pointWCoords.GetSpacing();
}
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
vtkm::CellShapeTagTetra,
bool& success,
const vtkm::exec::FunctorBase& vtkmNotUsed(worklet))
WorldCoordinatesToParametricCoordinatesTetra(
const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords)
{
VTKM_ASSERT(pointWCoords.GetNumberOfComponents() == 4);
success = true;
// We solve the world to parametric coordinates problem for tetrahedra
// similarly to that for triangles. Before understanding this code, you
// should understand the triangle code (in ReverseInterpolateTriangle in
@ -1025,16 +934,13 @@ WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
// d = dot((wcoords - p0), planeNormal)/dot((p1-p0), planeNormal)
//
using Vector3 = typename WorldCoordVector::ComponentType;
const auto vec0 = pointWCoords[1] - pointWCoords[0];
const auto vec1 = pointWCoords[2] - pointWCoords[0];
const auto vec2 = pointWCoords[3] - pointWCoords[0];
const auto coordVec = wcoords - pointWCoords[0];
Vector3 pcoords;
const Vector3 vec0 = pointWCoords[1] - pointWCoords[0];
const Vector3 vec1 = pointWCoords[2] - pointWCoords[0];
const Vector3 vec2 = pointWCoords[3] - pointWCoords[0];
const Vector3 coordVec = wcoords - pointWCoords[0];
Vector3 planeNormal = vtkm::Cross(vec1, vec2);
typename WorldCoordVector::ComponentType pcoords;
auto planeNormal = vtkm::Cross(vec1, vec2);
pcoords[0] = vtkm::dot(coordVec, planeNormal) / vtkm::dot(vec0, planeNormal);
planeNormal = vtkm::Cross(vec0, vec2);
@ -1045,21 +951,94 @@ WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
return pcoords;
}
} // detail
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
vtkm::CellShapeTagHexahedron,
vtkm::CellShapeTagTetra,
bool& success,
const vtkm::exec::FunctorBase& worklet)
const vtkm::exec::FunctorBase&)
{
VTKM_ASSERT(pointWCoords.GetNumberOfComponents() == 8);
return detail::WorldCoordinatesToParametricCoordinates3D(
pointWCoords, wcoords, vtkm::CellShapeTagHexahedron(), success, worklet);
success = true;
vtkm::exec::internal::FastVec<WorldCoordVector, 4> local(pointWCoords);
return detail::WorldCoordinatesToParametricCoordinatesTetra(local.Get(), wcoords);
}
//-----------------------------------------------------------------------------
namespace detail
{
template <typename WorldCoordVector, typename CellShapeTag>
class JacobianFunctor3DCell
{
using T = typename WorldCoordVector::ComponentType::ComponentType;
using Vector3 = vtkm::Vec<T, 3>;
using Matrix3x3 = vtkm::Matrix<T, 3, 3>;
const WorldCoordVector* PointWCoords;
public:
VTKM_EXEC
JacobianFunctor3DCell(const WorldCoordVector* pointWCoords)
: PointWCoords(pointWCoords)
{
}
VTKM_EXEC
Matrix3x3 operator()(const Vector3& pcoords) const
{
Matrix3x3 jacobian;
vtkm::exec::JacobianFor3DCell(*this->PointWCoords, pcoords, jacobian, CellShapeTag());
return jacobian;
}
};
template <typename WorldCoordVector, typename CellShapeTag>
class CoordinatesFunctor3DCell
{
using T = typename WorldCoordVector::ComponentType::ComponentType;
using Vector3 = vtkm::Vec<T, 3>;
const WorldCoordVector* PointWCoords;
const vtkm::exec::FunctorBase* Worklet;
public:
VTKM_EXEC
CoordinatesFunctor3DCell(const WorldCoordVector* pointWCoords,
const vtkm::exec::FunctorBase* worklet)
: PointWCoords(pointWCoords)
, Worklet(worklet)
{
}
VTKM_EXEC
Vector3 operator()(Vector3 pcoords) const
{
return vtkm::exec::ParametricCoordinatesToWorldCoordinates(
*this->PointWCoords, pcoords, CellShapeTag(), *this->Worklet);
}
};
template <typename WorldCoordVector, typename CellShapeTag>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates3D(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
CellShapeTag,
bool& success,
const vtkm::exec::FunctorBase& worklet)
{
auto result = vtkm::NewtonsMethod(
JacobianFunctor3DCell<WorldCoordVector, CellShapeTag>(&pointWCoords),
CoordinatesFunctor3DCell<WorldCoordVector, CellShapeTag>(&pointWCoords, &worklet),
wcoords,
typename WorldCoordVector::ComponentType(0.5f, 0.5f, 0.5f));
success = result.Valid;
return result.Solution;
}
} // detail
static inline VTKM_EXEC vtkm::Vec<vtkm::FloatDefault, 3> WorldCoordinatesToParametricCoordinates(
const vtkm::VecAxisAlignedPointCoordinates<3>& pointWCoords,
const vtkm::Vec<vtkm::FloatDefault, 3>& wcoords,
@ -1071,6 +1050,19 @@ static inline VTKM_EXEC vtkm::Vec<vtkm::FloatDefault, 3> WorldCoordinatesToParam
return (wcoords - pointWCoords.GetOrigin()) / pointWCoords.GetSpacing();
}
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
vtkm::CellShapeTagHexahedron,
bool& success,
const vtkm::exec::FunctorBase& worklet)
{
vtkm::exec::internal::FastVec<WorldCoordVector, 8> local(pointWCoords);
return detail::WorldCoordinatesToParametricCoordinates3D(
local.Get(), wcoords, vtkm::CellShapeTagHexahedron(), success, worklet);
}
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
@ -1079,10 +1071,9 @@ WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
bool& success,
const vtkm::exec::FunctorBase& worklet)
{
VTKM_ASSERT(pointWCoords.GetNumberOfComponents() == 6);
vtkm::exec::internal::FastVec<WorldCoordVector, 6> local(pointWCoords);
return detail::WorldCoordinatesToParametricCoordinates3D(
pointWCoords, wcoords, vtkm::CellShapeTagWedge(), success, worklet);
local.Get(), wcoords, vtkm::CellShapeTagWedge(), success, worklet);
}
template <typename WorldCoordVector>
@ -1093,10 +1084,32 @@ WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
bool& success,
const vtkm::exec::FunctorBase& worklet)
{
VTKM_ASSERT(pointWCoords.GetNumberOfComponents() == 5);
vtkm::exec::internal::FastVec<WorldCoordVector, 5> local(pointWCoords);
return detail::WorldCoordinatesToParametricCoordinates3D(
pointWCoords, wcoords, vtkm::CellShapeTagPyramid(), success, worklet);
local.Get(), wcoords, vtkm::CellShapeTagPyramid(), success, worklet);
}
//-----------------------------------------------------------------------------
template <typename WorldCoordVector>
static inline VTKM_EXEC typename WorldCoordVector::ComponentType
WorldCoordinatesToParametricCoordinates(const WorldCoordVector& pointWCoords,
const typename WorldCoordVector::ComponentType& wcoords,
vtkm::CellShapeTagGeneric shape,
bool& success,
const vtkm::exec::FunctorBase& worklet)
{
typename WorldCoordVector::ComponentType result;
switch (shape.Id)
{
vtkmGenericCellShapeMacro(result = WorldCoordinatesToParametricCoordinates(
pointWCoords, wcoords, CellShapeTag(), success, worklet));
default:
success = false;
worklet.RaiseError("Unknown cell shape sent to world 2 parametric.");
return typename WorldCoordVector::ComponentType();
}
return result;
}
}
} // namespace vtkm::exec

@ -47,7 +47,7 @@ namespace arg
/// object associated where the fetch (nominally) gets its data from. This
/// execution object is the data provided by the transport.
///
/// There is no generic implementaiton of \c Fetch. There are partial
/// There is no generic implementation of \c Fetch. There are partial
/// specializations of \c Fetch for each mechanism (fetch-aspect tag
/// combination) supported. If you get a compiler error about an incomplete
/// type for \c Fetch, it means you used an invalid \c FetchTag - \c AspectTag

@ -32,7 +32,7 @@ namespace arg
/// \brief \c Fetch tag for getting array values with direct indexing.
///
/// \c FetchTagArrayDirectIn is a tag used with the \c Fetch class to retreive
/// \c FetchTagArrayDirectIn is a tag used with the \c Fetch class to retrieve
/// values from an array portal. The fetch uses direct indexing, so the thread
/// index given to \c Load is used as the index into the array.
///

@ -43,7 +43,7 @@ namespace arg
/// \brief \c Fetch tag for getting array values determined by topology connections.
///
/// \c FetchTagArrayTopologyMapIn is a tag used with the \c Fetch class to
/// retreive values from an array portal. The fetch uses indexing based on
/// retrieve values from an array portal. The fetch uses indexing based on
/// the topology structure used for the input domain.
///
struct FetchTagArrayTopologyMapIn

@ -33,7 +33,7 @@ namespace arg
/// \brief \c Fetch tag for getting topology information.
///
/// \c FetchTagCellSetIn is a tag used with the \c Fetch class to retreive
/// \c FetchTagCellSetIn is a tag used with the \c Fetch class to retrieve
/// values from a topology object. This default parameter returns
/// the basis topology type, i.e. cell type in a \c WorkletCellMap.
///

@ -36,7 +36,7 @@ namespace arg
/// \brief \c Fetch tag for execution objects.
///
/// \c FetchTagExecObject is a tag used with the \c Fetch class to retreive
/// \c FetchTagExecObject is a tag used with the \c Fetch class to retrieve
/// execution objects. For safety, execution objects are read-only. \c
/// FetchTagExecObject is almost always used in conjunction with \c
/// TransportTagExecObject and vice versa.

@ -198,21 +198,21 @@ struct BoundaryState
namespace detail
{
/// Given a \c Vec of (semi) aribtrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// Given a \c Vec of (semi) arbitrary size, inflate it to a vtkm::Id3 by padding with zeros.
///
inline VTKM_EXEC vtkm::Id3 To3D(vtkm::Id3 index)
{
return index;
}
/// Given a \c Vec of (semi) aribtrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// Given a \c Vec of (semi) arbitrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// \overload
inline VTKM_EXEC vtkm::Id3 To3D(vtkm::Id2 index)
{
return vtkm::Id3(index[0], index[1], 1);
}
/// Given a \c Vec of (semi) aribtrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// Given a \c Vec of (semi) arbitrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// \overload
inline VTKM_EXEC vtkm::Id3 To3D(vtkm::Vec<vtkm::Id, 1> index)
{

@ -36,7 +36,7 @@ namespace detail
{
/// Most cell shape tags have a default constructor, but the generic cell shape
/// tag does not to prevent accidently losing the Id, which, unlike the other
/// tag does not to prevent accidentally losing the Id, which, unlike the other
/// cell shapes, can vary.
///
template <typename CellShapeTag>
@ -158,42 +158,42 @@ private:
namespace detail
{
/// Given a \c Vec of (semi) aribtrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// Given a \c Vec of (semi) arbitrary size, inflate it to a vtkm::Id3 by padding with zeros.
///
static inline VTKM_EXEC vtkm::Id3 InflateTo3D(vtkm::Id3 index)
{
return index;
}
/// Given a \c Vec of (semi) aribtrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// Given a \c Vec of (semi) arbitrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// \overload
static inline VTKM_EXEC vtkm::Id3 InflateTo3D(vtkm::Id2 index)
{
return vtkm::Id3(index[0], index[1], 0);
}
/// Given a \c Vec of (semi) aribtrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// Given a \c Vec of (semi) arbitrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// \overload
static inline VTKM_EXEC vtkm::Id3 InflateTo3D(vtkm::Vec<vtkm::Id, 1> index)
{
return vtkm::Id3(index[0], 0, 0);
}
/// Given a \c Vec of (semi) aribtrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// Given a \c Vec of (semi) arbitrary size, inflate it to a vtkm::Id3 by padding with zeros.
/// \overload
static inline VTKM_EXEC vtkm::Id3 InflateTo3D(vtkm::Id index)
{
return vtkm::Id3(index, 0, 0);
}
/// Given a vtkm::Id3, reduce down to an identifer of choice.
/// Given a vtkm::Id3, reduce down to an identifier of choice.
///
static inline VTKM_EXEC vtkm::Id3 Deflate(const vtkm::Id3& index, vtkm::Id3)
{
return index;
}
/// Given a vtkm::Id3, reduce down to an identifer of choice.
/// Given a vtkm::Id3, reduce down to an identifier of choice.
/// \overload
static inline VTKM_EXEC vtkm::Id2 Deflate(const vtkm::Id3& index, vtkm::Id2)
{

@ -101,10 +101,7 @@ struct load_through_texture
{
static const vtkm::IdComponent WillUseTexture = 0;
__device__ static T get(const thrust::system::cuda::pointer<const T>& data)
{
return *(data.get());
}
__device__ static T get(const T* const data) { return *data; }
};
//only load through a texture if we have sm 35 support
@ -116,13 +113,13 @@ struct load_through_texture<T, typename std::enable_if<UseScalarTextureLoad<cons
static const vtkm::IdComponent WillUseTexture = 1;
__device__ static T get(const thrust::system::cuda::pointer<const T>& data)
__device__ static T get(const T* const data)
{
#if __CUDA_ARCH__ >= 350
// printf("__CUDA_ARCH__ UseScalarTextureLoad");
return __ldg(data.get());
return __ldg(data);
#else
return *(data.get());
return *data;
#endif
}
};
@ -133,62 +130,55 @@ struct load_through_texture<T, typename std::enable_if<UseVecTextureLoads<const
{
static const vtkm::IdComponent WillUseTexture = 1;
__device__ static T get(const thrust::system::cuda::pointer<const T>& data)
__device__ static T get(const T* const data)
{
#if __CUDA_ARCH__ >= 350
// printf("__CUDA_ARCH__ UseVecTextureLoads");
return getAs(data);
#else
return *(data.get());
return *data;
#endif
}
__device__ static vtkm::Vec<vtkm::Int32, 2> getAs(
const thrust::system::cuda::pointer<const vtkm::Vec<vtkm::Int32, 2>>& data)
__device__ static vtkm::Vec<vtkm::Int32, 2> getAs(const vtkm::Vec<vtkm::Int32, 2>* const data)
{
const int2 temp = __ldg((const int2*)data.get());
const int2 temp = __ldg((const int2*)data);
return vtkm::Vec<vtkm::Int32, 2>(temp.x, temp.y);
}
__device__ static vtkm::Vec<vtkm::UInt32, 2> getAs(
const thrust::system::cuda::pointer<const vtkm::Vec<vtkm::UInt32, 2>>& data)
__device__ static vtkm::Vec<vtkm::UInt32, 2> getAs(const vtkm::Vec<vtkm::UInt32, 2>* const data)
{
const uint2 temp = __ldg((const uint2*)data.get());
const uint2 temp = __ldg((const uint2*)data);
return vtkm::Vec<vtkm::UInt32, 2>(temp.x, temp.y);
}
__device__ static vtkm::Vec<vtkm::Int32, 4> getAs(
const thrust::system::cuda::pointer<const vtkm::Vec<vtkm::Int32, 4>>& data)
__device__ static vtkm::Vec<vtkm::Int32, 4> getAs(const vtkm::Vec<vtkm::Int32, 4>* const data)
{
const int4 temp = __ldg((const int4*)data.get());
const int4 temp = __ldg((const int4*)data);
return vtkm::Vec<vtkm::Int32, 4>(temp.x, temp.y, temp.z, temp.w);
}
__device__ static vtkm::Vec<vtkm::UInt32, 4> getAs(
const thrust::system::cuda::pointer<const vtkm::Vec<vtkm::UInt32, 4>>& data)
__device__ static vtkm::Vec<vtkm::UInt32, 4> getAs(const vtkm::Vec<vtkm::UInt32, 4>* const data)
{
const uint4 temp = __ldg((const uint4*)data.get());
const uint4 temp = __ldg((const uint4*)data);
return vtkm::Vec<vtkm::UInt32, 4>(temp.x, temp.y, temp.z, temp.w);
}
__device__ static vtkm::Vec<vtkm::Float32, 2> getAs(
const thrust::system::cuda::pointer<const vtkm::Vec<vtkm::Float32, 2>>& data)
__device__ static vtkm::Vec<vtkm::Float32, 2> getAs(const vtkm::Vec<vtkm::Float32, 2>* const data)
{
const float2 temp = __ldg((const float2*)data.get());
const float2 temp = __ldg((const float2*)data);
return vtkm::Vec<vtkm::Float32, 2>(temp.x, temp.y);
}
__device__ static vtkm::Vec<vtkm::Float32, 4> getAs(
const thrust::system::cuda::pointer<const vtkm::Vec<vtkm::Float32, 4>>& data)
__device__ static vtkm::Vec<vtkm::Float32, 4> getAs(const vtkm::Vec<vtkm::Float32, 4>* const data)
{
const float4 temp = __ldg((const float4*)data.get());
const float4 temp = __ldg((const float4*)data);
return vtkm::Vec<vtkm::Float32, 4>(temp.x, temp.y, temp.z, temp.w);
}
__device__ static vtkm::Vec<vtkm::Float64, 2> getAs(
const thrust::system::cuda::pointer<const vtkm::Vec<vtkm::Float64, 2>>& data)
__device__ static vtkm::Vec<vtkm::Float64, 2> getAs(const vtkm::Vec<vtkm::Float64, 2>* const data)
{
const double2 temp = __ldg((const double2*)data.get());
const double2 temp = __ldg((const double2*)data);
return vtkm::Vec<vtkm::Float64, 2>(temp.x, temp.y);
}
};
@ -203,22 +193,22 @@ struct load_through_texture<
using NonConstT = typename std::remove_const<T>::type;
__device__ static T get(const thrust::system::cuda::pointer<const T>& data)
__device__ static T get(const T* const data)
{
#if __CUDA_ARCH__ >= 350
// printf("__CUDA_ARCH__ UseMultipleScalarTextureLoads");
return getAs(data);
#else
return *(data.get());
return *data;
#endif
}
__device__ static T getAs(const thrust::system::cuda::pointer<const T>& data)
__device__ static T getAs(const T* const data)
{
//we need to fetch each component individually
const vtkm::IdComponent NUM_COMPONENTS = T::NUM_COMPONENTS;
using ComponentType = typename T::ComponentType;
const ComponentType* recasted_data = (const ComponentType*)(data.get());
const ComponentType* recasted_data = (const ComponentType*)(data);
NonConstT result;
#pragma unroll
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; ++i)
@ -241,13 +231,13 @@ class ArrayPortalFromThrust : public ArrayPortalFromThrustBase
{
public:
using ValueType = T;
using IteratorType = thrust::system::cuda::pointer<T>;
using IteratorType = T*;
using difference_type = std::ptrdiff_t;
VTKM_EXEC_CONT ArrayPortalFromThrust() {}
VTKM_CONT
ArrayPortalFromThrust(thrust::system::cuda::pointer<T> begin,
thrust::system::cuda::pointer<T> end)
ArrayPortalFromThrust(IteratorType begin, IteratorType end)
: BeginIterator(begin)
, EndIterator(end)
{
@ -274,15 +264,13 @@ public:
VTKM_EXEC_CONT
ValueType Get(vtkm::Id index) const
{
using SizeType = typename ::thrust::iterator_traits<IteratorType>::difference_type;
return *(this->BeginIterator + static_cast<SizeType>(index));
return *(this->BeginIterator + static_cast<difference_type>(index));
}
VTKM_EXEC_CONT
void Set(vtkm::Id index, ValueType value) const
{
using SizeType = typename ::thrust::iterator_traits<IteratorType>::difference_type;
*(this->BeginIterator + static_cast<SizeType>(index)) = value;
*(this->BeginIterator + static_cast<difference_type>(index)) = value;
}
VTKM_EXEC_CONT
@ -301,13 +289,17 @@ class ConstArrayPortalFromThrust : public ArrayPortalFromThrustBase
{
public:
using ValueType = T;
using IteratorType = thrust::system::cuda::pointer<const T>;
using IteratorType = const T*;
using difference_type = std::ptrdiff_t;
VTKM_EXEC_CONT ConstArrayPortalFromThrust() {}
VTKM_EXEC_CONT ConstArrayPortalFromThrust()
: BeginIterator(nullptr)
, EndIterator(nullptr)
{
}
VTKM_CONT
ConstArrayPortalFromThrust(const thrust::system::cuda::pointer<const T> begin,
const thrust::system::cuda::pointer<const T> end)
ConstArrayPortalFromThrust(IteratorType begin, IteratorType end)
: BeginIterator(begin)
, EndIterator(end)
{

@ -44,8 +44,8 @@ struct vtkm_cuda_policy : thrust::device_execution_policy<vtkm_cuda_policy>
template <typename T>
__host__ __device__ void sort(
const vtkm_cuda_policy& exec,
thrust::system::cuda::pointer<T> first,
thrust::system::cuda::pointer<T> last,
T* first,
T* last,
vtkm::exec::cuda::internal::WrappedBinaryPredicate<T, vtkm::SortLess> comp)
{ //sort for concrete pointers and less than op
//this makes sure that we invoke the thrust radix sort and not merge sort
@ -55,8 +55,8 @@ __host__ __device__ void sort(
template <typename T, typename RandomAccessIterator>
__host__ __device__ void sort_by_key(
const vtkm_cuda_policy& exec,
thrust::system::cuda::pointer<T> first,
thrust::system::cuda::pointer<T> last,
T* first,
T* last,
RandomAccessIterator values_first,
vtkm::exec::cuda::internal::WrappedBinaryPredicate<T, vtkm::SortLess> comp)
{ //sort for concrete pointers and less than op
@ -68,8 +68,8 @@ __host__ __device__ void sort_by_key(
template <typename T>
__host__ __device__ void sort(
const vtkm_cuda_policy& exec,
thrust::system::cuda::pointer<T> first,
thrust::system::cuda::pointer<T> last,
T* first,
T* last,
vtkm::exec::cuda::internal::WrappedBinaryPredicate<T, ::thrust::less<T>> comp)
{ //sort for concrete pointers and less than op
//this makes sure that we invoke the thrust radix sort and not merge sort
@ -79,8 +79,8 @@ __host__ __device__ void sort(
template <typename T, typename RandomAccessIterator>
__host__ __device__ void sort_by_key(
const vtkm_cuda_policy& exec,
thrust::system::cuda::pointer<T> first,
thrust::system::cuda::pointer<T> last,
T* first,
T* last,
RandomAccessIterator values_first,
vtkm::exec::cuda::internal::WrappedBinaryPredicate<T, ::thrust::less<T>> comp)
{ //sort for concrete pointers and less than op
@ -92,8 +92,8 @@ __host__ __device__ void sort_by_key(
template <typename T>
__host__ __device__ void sort(
const vtkm_cuda_policy& exec,
thrust::system::cuda::pointer<T> first,
thrust::system::cuda::pointer<T> last,
T* first,
T* last,
vtkm::exec::cuda::internal::WrappedBinaryPredicate<T, vtkm::SortGreater> comp)
{ //sort for concrete pointers and greater than op
//this makes sure that we invoke the thrust radix sort and not merge sort
@ -103,8 +103,8 @@ __host__ __device__ void sort(
template <typename T, typename RandomAccessIterator>
__host__ __device__ void sort_by_key(
const vtkm_cuda_policy& exec,
thrust::system::cuda::pointer<T> first,
thrust::system::cuda::pointer<T> last,
T* first,
T* last,
RandomAccessIterator values_first,
vtkm::exec::cuda::internal::WrappedBinaryPredicate<T, vtkm::SortGreater> comp)
{ //sort for concrete pointers and greater than op
@ -116,8 +116,8 @@ __host__ __device__ void sort_by_key(
template <typename T>
__host__ __device__ void sort(
const vtkm_cuda_policy& exec,
thrust::system::cuda::pointer<T> first,
thrust::system::cuda::pointer<T> last,
T* first,
T* last,
vtkm::exec::cuda::internal::WrappedBinaryPredicate<T, ::thrust::greater<T>> comp)
{ //sort for concrete pointers and greater than op
//this makes sure that we invoke the thrust radix sort and not merge sort
@ -127,8 +127,8 @@ __host__ __device__ void sort(
template <typename T, typename RandomAccessIterator>
__host__ __device__ void sort_by_key(
const vtkm_cuda_policy& exec,
thrust::system::cuda::pointer<T> first,
thrust::system::cuda::pointer<T> last,
T* first,
T* last,
RandomAccessIterator values_first,
vtkm::exec::cuda::internal::WrappedBinaryPredicate<T, ::thrust::greater<T>> comp)
{ //sort for concrete pointers and greater than op
@ -174,8 +174,8 @@ template <typename T,
typename BinaryFunction>
__host__ __device__::thrust::pair<OutputIterator1, OutputIterator2> reduce_by_key(
const vtkm_cuda_policy& exec,
thrust::system::cuda::pointer<T> keys_first,
thrust::system::cuda::pointer<T> keys_last,
T* keys_first,
T* keys_last,
InputIterator2 values_first,
OutputIterator1 keys_output,
OutputIterator2 values_output,

@ -75,7 +75,7 @@ struct WrappedUnaryPredicate
return m_f((T)x);
}
VTKM_EXEC bool operator()(const thrust::system::cuda::pointer<T> x) const { return m_f(*x); }
VTKM_EXEC bool operator()(const T* x) const { return m_f(*x); }
};
// Binary function object wrapper which can detect and handle calling the
@ -126,26 +126,11 @@ struct WrappedBinaryOperator
return m_f((T)x, (T)y);
}
VTKM_EXEC T operator()(const thrust::system::cuda::pointer<T> x, const T* y) const
{
return m_f(*x, *y);
}
VTKM_EXEC T operator()(const T* const x, const T& y) const { return m_f(*x, y); }
VTKM_EXEC T operator()(const thrust::system::cuda::pointer<T> x, const T& y) const
{
return m_f(*x, y);
}
VTKM_EXEC T operator()(const T& x, const T* const y) const { return m_f(x, *y); }
VTKM_EXEC T operator()(const T& x, const thrust::system::cuda::pointer<T> y) const
{
return m_f(x, *y);
}
VTKM_EXEC T operator()(const thrust::system::cuda::pointer<T> x,
const thrust::system::cuda::pointer<T> y) const
{
return m_f(*x, *y);
}
VTKM_EXEC T operator()(const T* const x, const T* const y) const { return m_f(*x, *y); }
};
template <typename T_, typename Function>
@ -192,26 +177,11 @@ struct WrappedBinaryPredicate
return m_f((T)x, (T)y);
}
VTKM_EXEC bool operator()(const thrust::system::cuda::pointer<T> x, const T* y) const
{
return m_f(*x, *y);
}
VTKM_EXEC bool operator()(const T* const x, const T& y) const { return m_f(*x, y); }
VTKM_EXEC bool operator()(const thrust::system::cuda::pointer<T> x, const T& y) const
{
return m_f(*x, y);
}
VTKM_EXEC bool operator()(const T& x, const T* const y) const { return m_f(x, *y); }
VTKM_EXEC bool operator()(const T& x, const thrust::system::cuda::pointer<T> y) const
{
return m_f(x, *y);
}
VTKM_EXEC bool operator()(const thrust::system::cuda::pointer<T> x,
const thrust::system::cuda::pointer<T> y) const
{
return m_f(*x, *y);
}
VTKM_EXEC bool operator()(const T* const x, const T* const y) const { return m_f(*x, *y); }
};
}
}

@ -20,6 +20,7 @@
set(headers
ErrorMessageBuffer.h
FastVec.h
ReduceByKeyLookup.h
TaskSingular.h
WorkletInvokeFunctorDetail.h

@ -0,0 +1,96 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_exec_internal_FastVec_h
#define vtk_m_exec_internal_FastVec_h
#include <vtkm/Types.h>
#include <vtkm/VecVariable.h>
namespace vtkm
{
namespace exec
{
namespace internal
{
/// Use this class to convert Vecs of any type to an efficient stack based Vec
/// type. The template parameters are the input Vec type and the maximum
/// number of components it may have. Specializations exist to optimize
/// the copy and stack usage away for already efficient types.
/// This class is useful when several accesses will be performed on
/// potentially inefficient Vec types such as VecFromPortalPermute.
///
template <typename VecType, vtkm::IdComponent MaxSize>
class FastVec
{
public:
using Type = vtkm::VecVariable<typename VecType::ComponentType, MaxSize>;
explicit VTKM_EXEC FastVec(const VecType& vec)
: Vec(vec)
{
}
VTKM_EXEC const Type& Get() const { return this->Vec; }
private:
Type Vec;
};
template <typename ComponentType, vtkm::IdComponent NumComponents, vtkm::IdComponent MaxSize>
class FastVec<vtkm::Vec<ComponentType, NumComponents>, MaxSize>
{
public:
using Type = vtkm::Vec<ComponentType, NumComponents>;
explicit VTKM_EXEC FastVec(const Type& vec)
: Vec(vec)
{
VTKM_ASSERT(vec.GetNumberOfComponents() <= MaxSize);
}
VTKM_EXEC const Type& Get() const { return this->Vec; }
private:
const Type& Vec;
};
template <typename ComponentType, vtkm::IdComponent MaxSize1, vtkm::IdComponent MaxSize2>
class FastVec<vtkm::VecVariable<ComponentType, MaxSize1>, MaxSize2>
{
public:
using Type = vtkm::VecVariable<ComponentType, MaxSize1>;
explicit VTKM_EXEC FastVec(const Type& vec)
: Vec(vec)
{
VTKM_ASSERT(vec.GetNumberOfComponents() <= MaxSize2);
}
VTKM_EXEC const Type& Get() const { return this->Vec; }
private:
const Type& Vec;
};
}
}
} // vtkm::exec::internal
#endif // vtk_m_exec_internal_FastVec_h

@ -75,7 +75,7 @@ public:
}
private:
WorkletType Worklet;
typename std::remove_const<WorkletType>::type Worklet;
// This is held by by value so that when we transfer the invocation object
// over to CUDA it gets properly copied to the device. While we want to
// hold by reference to reduce the number of copies, it is not possible

@ -173,7 +173,7 @@ public:
/// parameters that go along with it
template <typename WorkletType, typename InvocationType>
TaskTiling1D(WorkletType& worklet,
const InvocationType& invocation,
InvocationType& invocation,
const vtkm::Id& globalIndexOffset = 0)
: Worklet(nullptr)
, Invocation(nullptr)
@ -263,7 +263,7 @@ public:
template <typename WorkletType, typename InvocationType>
TaskTiling3D(WorkletType& worklet,
const InvocationType& invocation,
InvocationType& invocation,
const vtkm::Id& globalIndexOffset = 0)
: Worklet(nullptr)
, Invocation(nullptr)

@ -50,7 +50,7 @@ vtkm::Vec<T, 3> WorldToParametric(const vtkm::Vec<T, 3>& wcoord)
return T(0.5) * (wcoord + vtkm::Vec<T, 3>(0.25f));
}
/// Simple structure describing a linear field. Has a convienience class
/// Simple structure describing a linear field. Has a convenience class
/// for getting values.
template <typename FieldType>
struct LinearField

@ -46,6 +46,7 @@ set(headers
PointElevation.h
PolicyBase.h
PolicyDefault.h
Probe.h
Result.h
Streamline.h
SurfaceNormals.h
@ -81,6 +82,7 @@ set(header_template_sources
NDHistogram.hxx
PointAverage.hxx
PointElevation.hxx
Probe.hxx
Streamline.hxx
SurfaceNormals.hxx
Tetrahedralize.hxx

60
vtkm/filter/Probe.h Normal file

@ -0,0 +1,60 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_filter_Probe_h
#define vtk_m_filter_Probe_h
#include <vtkm/filter/FilterDataSet.h>
#include <vtkm/worklet/Probe.h>
namespace vtkm
{
namespace filter
{
class Probe : public vtkm::filter::FilterDataSet<Probe>
{
public:
VTKM_CONT
void SetGeometry(const vtkm::cont::DataSet& geometry);
template <typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT vtkm::filter::Result DoExecute(const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& device);
//Map a new field onto the resulting dataset after running the filter
//this call is only valid
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT bool DoMapField(vtkm::filter::Result& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& device);
private:
vtkm::cont::DataSet Geometry;
vtkm::worklet::Probe Worklet;
};
}
} // vtkm::filter
#include <vtkm/filter/Probe.hxx>
#endif // vtk_m_filter_Probe_h

86
vtkm/filter/Probe.hxx Normal file

@ -0,0 +1,86 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_filter_Probe_hxx
#define vtk_m_filter_Probe_hxx
namespace vtkm
{
namespace filter
{
VTKM_CONT
inline void Probe::SetGeometry(const vtkm::cont::DataSet& geometry)
{
this->Geometry = vtkm::cont::DataSet();
this->Geometry.AddCellSet(geometry.GetCellSet());
this->Geometry.AddCoordinateSystem(geometry.GetCoordinateSystem());
}
template <typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT inline vtkm::filter::Result Probe::DoExecute(
const vtkm::cont::DataSet& input,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& device)
{
this->Worklet.Run(
vtkm::filter::ApplyPolicy(input.GetCellSet(this->GetActiveCellSetIndex()), policy),
input.GetCoordinateSystem(this->GetActiveCoordinateSystemIndex()),
this->Geometry.GetCoordinateSystem().GetData(),
device);
auto output = this->Geometry;
auto hpf = this->Worklet.GetHiddenPointsField(device);
auto hcf = this->Worklet.GetHiddenCellsField(
vtkm::filter::ApplyPolicy(output.GetCellSet(), policy), device);
output.AddField(vtkm::cont::Field("HIDDEN", vtkm::cont::Field::ASSOC_POINTS, hpf));
output.AddField(vtkm::cont::Field(
"HIDDEN", vtkm::cont::Field::ASSOC_CELL_SET, output.GetCellSet().GetName(), hcf));
return vtkm::filter::Result(output);
}
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT inline bool Probe::DoMapField(vtkm::filter::Result& result,
const vtkm::cont::ArrayHandle<T, StorageType>& input,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter& device)
{
if (fieldMeta.IsPointField())
{
auto fieldArray =
this->Worklet.ProcessPointField(input, device, typename DerivedPolicy::AllCellSetList());
result.GetDataSet().AddField(fieldMeta.AsField(fieldArray));
return true;
}
else if (fieldMeta.IsCellField())
{
auto fieldArray = this->Worklet.ProcessCellField(input, device);
result.GetDataSet().AddField(fieldMeta.AsField(fieldArray));
return true;
}
return false;
}
}
} // vtkm::filter
#endif // vtk_m_filter_Probe_hxx

@ -40,6 +40,7 @@ set(unit_tests
UnitTestNDHistogramFilter.cxx
UnitTestPointAverageFilter.cxx
UnitTestPointElevationFilter.cxx
UnitTestProbe.cxx
UnitTestStreamlineFilter.cxx
UnitTestSurfaceNormalsFilter.cxx
UnitTestTetrahedralizeFilter.cxx

@ -93,8 +93,8 @@ void TestExternalFacesExplicitGrid(const vtkm::cont::DataSet& ds,
VTKM_TEST_ASSERT(numOutputExtFaces == numExpectedExtFaces, "Number of External Faces mismatch");
// verify fields
VTKM_TEST_ASSERT(resultds.HasField("pointvar"), "Point field not mapped succesfully");
VTKM_TEST_ASSERT(resultds.HasField("cellvar"), "Cell field not mapped succesfully");
VTKM_TEST_ASSERT(resultds.HasField("pointvar"), "Point field not mapped successfully");
VTKM_TEST_ASSERT(resultds.HasField("cellvar"), "Cell field not mapped successfully");
// verify CompactPoints
if (compactPoints)

@ -37,8 +37,8 @@ void TestCellGradientUniform3D()
vtkm::filter::Gradient gradient;
gradient.SetOutputFieldName("Gradient");
gradient.SetComputeVorticity(true); //this wont work as we have a scalar field
gradient.SetComputeQCriterion(true); //this wont work as we have a scalar field
gradient.SetComputeVorticity(true); //this won't work as we have a scalar field
gradient.SetComputeQCriterion(true); //this won't work as we have a scalar field
result = gradient.Execute(dataSet, dataSet.GetField("pointvar"));

@ -0,0 +1,246 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/filter/Probe.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/cont/DataSetFieldAdd.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/worklet/CellDeepCopy.h>
namespace
{
vtkm::cont::DataSet MakeInputDataSet()
{
std::vector<vtkm::Float32> pvec(16), cvec(9);
for (std::size_t i = 0; i < 16; ++i)
{
pvec[i] = static_cast<vtkm::Float32>(i) * 0.3f;
}
for (std::size_t i = 0; i < 9; ++i)
{
cvec[i] = static_cast<vtkm::Float32>(i) * 0.7f;
}
auto input = vtkm::cont::DataSetBuilderUniform::Create(
vtkm::Id2(4, 4), vtkm::make_Vec(0.0f, 0.0f), vtkm::make_Vec(1.0f, 1.0f));
vtkm::cont::DataSetFieldAdd::AddPointField(input, "pointdata", pvec);
vtkm::cont::DataSetFieldAdd::AddCellField(input, "celldata", cvec);
return input;
}
vtkm::cont::DataSet MakeGeometryDataSet()
{
auto geometry = vtkm::cont::DataSetBuilderUniform::Create(
vtkm::Id2(9, 9), vtkm::make_Vec(0.7f, 0.7f), vtkm::make_Vec(0.35f, 0.35f));
return geometry;
}
struct ConvertImpl
{
template <typename DeviceAdapter>
bool operator()(DeviceAdapter device,
const vtkm::cont::DataSet& uds,
vtkm::cont::DataSet& eds) const
{
vtkm::cont::CellSetExplicit<> cs(uds.GetCellSet().GetName());
vtkm::worklet::CellDeepCopy::Run(uds.GetCellSet(), cs, device);
eds.AddCellSet(cs);
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>> points;
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>::Copy(uds.GetCoordinateSystem().GetData(),
points);
eds.AddCoordinateSystem(
vtkm::cont::CoordinateSystem(uds.GetCoordinateSystem().GetName(), points));
for (vtkm::IdComponent i = 0; i < uds.GetNumberOfFields(); ++i)
{
eds.AddField(uds.GetField(i));
}
return true;
}
};
vtkm::cont::DataSet ConvertDataSetUniformToExplicit(const vtkm::cont::DataSet& uds)
{
vtkm::cont::DataSet eds;
vtkm::cont::TryExecute(ConvertImpl(), uds, eds);
return eds;
}
const std::vector<vtkm::Float32>& GetExpectedPointData()
{
static std::vector<vtkm::Float32> expected = {
1.05f, 1.155f, 1.26f, 1.365f, 1.47f, 1.575f, 1.68f, 0.0f, 0.0f, 1.47f, 1.575f, 1.68f,
1.785f, 1.89f, 1.995f, 2.1f, 0.0f, 0.0f, 1.89f, 1.995f, 2.1f, 2.205f, 2.31f, 2.415f,
2.52f, 0.0f, 0.0f, 2.31f, 2.415f, 2.52f, 2.625f, 2.73f, 2.835f, 2.94f, 0.0f, 0.0f,
2.73f, 2.835f, 2.94f, 3.045f, 3.15f, 3.255f, 3.36f, 0.0f, 0.0f, 3.15f, 3.255f, 3.36f,
3.465f, 3.57f, 3.675f, 3.78f, 0.0f, 0.0f, 3.57f, 3.675f, 3.78f, 3.885f, 3.99f, 4.095f,
4.2f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
};
return expected;
}
const std::vector<vtkm::Float32>& GetExpectedCellData()
{
static std::vector<vtkm::Float32> expected = {
0.0f, 0.7f, 0.7f, 0.7f, 1.4f, 1.4f, 1.4f, 0.0f, 0.0f, 2.1f, 2.8f, 2.8f, 2.8f, 3.5f,
3.5f, 3.5f, 0.0f, 0.0f, 2.1f, 2.8f, 2.8f, 2.8f, 3.5f, 3.5f, 3.5f, 0.0f, 0.0f, 2.1f,
2.8f, 2.8f, 2.8f, 3.5f, 3.5f, 3.5f, 0.0f, 0.0f, 4.2f, 4.9f, 4.9f, 4.9f, 5.6f, 5.6f,
5.6f, 0.0f, 0.0f, 4.2f, 4.9f, 4.9f, 4.9f, 5.6f, 5.6f, 5.6f, 0.0f, 0.0f, 4.2f, 4.9f,
4.9f, 4.9f, 5.6f, 5.6f, 5.6f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
};
return expected;
}
const std::vector<vtkm::UInt8>& GetExpectedHiddenPoints()
{
static std::vector<vtkm::UInt8> expected = { 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2,
2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0,
2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,
0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
return expected;
}
const std::vector<vtkm::UInt8>& GetExpectedHiddenCells()
{
static std::vector<vtkm::UInt8> expected = { 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2,
0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2,
0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
return expected;
}
template <typename T>
void TestResultArray(const vtkm::cont::ArrayHandle<T>& result, const std::vector<T>& expected)
{
VTKM_TEST_ASSERT(result.GetNumberOfValues() == static_cast<vtkm::Id>(expected.size()),
"Incorrect field size");
auto portal = result.GetPortalConstControl();
vtkm::Id size = portal.GetNumberOfValues();
for (vtkm::Id i = 0; i < size; ++i)
{
VTKM_TEST_ASSERT(test_equal(portal.Get(i), expected[static_cast<std::size_t>(i)]),
"Incorrect field value");
}
}
class TestProbe
{
private:
using FieldArrayType = vtkm::cont::ArrayHandle<vtkm::Float32>;
using HiddenArrayType = vtkm::cont::ArrayHandle<vtkm::UInt8>;
static void ExplicitToUnifrom()
{
std::cout << "Testing Probe Explicit to Uniform:\n";
auto input = ConvertDataSetUniformToExplicit(MakeInputDataSet());
auto geometry = MakeGeometryDataSet();
vtkm::filter::Probe probe;
probe.SetGeometry(geometry);
auto result = probe.Execute(input);
probe.MapFieldOntoOutput(result, input.GetField("pointdata"));
probe.MapFieldOntoOutput(result, input.GetField("celldata"));
auto output = result.GetDataSet();
TestResultArray(output.GetField("pointdata").GetData().template Cast<FieldArrayType>(),
GetExpectedPointData());
TestResultArray(output.GetField("celldata").GetData().template Cast<FieldArrayType>(),
GetExpectedCellData());
TestResultArray(output.GetPointField("HIDDEN").GetData().template Cast<HiddenArrayType>(),
GetExpectedHiddenPoints());
TestResultArray(output.GetCellField("HIDDEN").GetData().template Cast<HiddenArrayType>(),
GetExpectedHiddenCells());
}
static void UniformToExplict()
{
std::cout << "Testing Probe Uniform to Explicit:\n";
auto input = MakeInputDataSet();
auto geometry = ConvertDataSetUniformToExplicit(MakeGeometryDataSet());
vtkm::filter::Probe probe;
probe.SetGeometry(geometry);
auto result = probe.Execute(input);
probe.MapFieldOntoOutput(result, input.GetField("pointdata"));
probe.MapFieldOntoOutput(result, input.GetField("celldata"));
auto output = result.GetDataSet();
TestResultArray(output.GetField("pointdata").GetData().template Cast<FieldArrayType>(),
GetExpectedPointData());
TestResultArray(output.GetField("celldata").GetData().template Cast<FieldArrayType>(),
GetExpectedCellData());
TestResultArray(output.GetPointField("HIDDEN").GetData().template Cast<HiddenArrayType>(),
GetExpectedHiddenPoints());
TestResultArray(output.GetCellField("HIDDEN").GetData().template Cast<HiddenArrayType>(),
GetExpectedHiddenCells());
}
static void ExplicitToExplict()
{
std::cout << "Testing Probe Explicit to Explicit:\n";
auto input = ConvertDataSetUniformToExplicit(MakeInputDataSet());
auto geometry = ConvertDataSetUniformToExplicit(MakeGeometryDataSet());
vtkm::filter::Probe probe;
probe.SetGeometry(geometry);
auto result = probe.Execute(input);
probe.MapFieldOntoOutput(result, input.GetField("pointdata"));
probe.MapFieldOntoOutput(result, input.GetField("celldata"));
auto output = result.GetDataSet();
TestResultArray(output.GetField("pointdata").GetData().template Cast<FieldArrayType>(),
GetExpectedPointData());
TestResultArray(output.GetField("celldata").GetData().template Cast<FieldArrayType>(),
GetExpectedCellData());
TestResultArray(output.GetPointField("HIDDEN").GetData().template Cast<HiddenArrayType>(),
GetExpectedHiddenPoints());
TestResultArray(output.GetCellField("HIDDEN").GetData().template Cast<HiddenArrayType>(),
GetExpectedHiddenCells());
}
public:
static void Run()
{
ExplicitToUnifrom();
UniformToExplict();
ExplicitToExplict();
}
};
} // anonymous namespace
int UnitTestProbe(int, char* [])
{
return vtkm::cont::testing::Testing::Run(TestProbe::Run);
}

@ -32,7 +32,7 @@ namespace internal
/// \brief A value class for returning setable values of an ArrayPortal
///
/// \c ArrayPortal classes have a pair of \c Get and \c Set methods that
/// retreive and store values in the array. This is to make it easy to
/// retrieve and store values in the array. This is to make it easy to
/// implement the \c ArrayPortal even it is not really an array. However, there
/// are some cases where the code structure expects a reference to a value that
/// can be set. For example, the \c IteratorFromArrayPortal class must return

@ -307,7 +307,7 @@
#ifdef VTKM_MSVC
//With MSVC the types that we generate cause warning C4503 (long symbol names)
//this doesn't affect the resulting binary so we just supress that warning
//this doesn't affect the resulting binary so we just suppress that warning
//
#pragma warning(disable:4503)
@ -317,7 +317,7 @@
//a valid use is MSVC-specific. Even less fortunate is the fact that if
//another header violates the warning, it is impossible to suppress it
//because it happens in a system header file (xutility), which was included
//far before the actual offending code occured. Even less fortunate than
//far before the actual offending code occurred. Even less fortunate than
//that, a boost header we (indirectly) use sets off this warning, cannot
//be suppressed, and is not going to be fixed
//(https://svn.boost.org/trac/boost/ticket/11426). The best solution is to

@ -102,7 +102,7 @@ class FunctionInterfaceDynamicTransformContContinue;
/// series of transformations and operations can occur.
///
/// Supporting arbitrary function and template arguments is difficult and
/// really requires seperate implementations for ANSI and C++11 versions of
/// really requires separate implementations for ANSI and C++11 versions of
/// compilers. Thus, variatic template arguments are, at this point in time,
/// something to be avoided when possible. The intention of \c
/// FunctionInterface is to collect most of the variatic template code into one

@ -500,7 +500,7 @@ void TestInvokeTime()
vtkm::Float64 invokeCallTime = timer.GetElapsedTime();
std::cout << "Time for invoking function interface: " << invokeCallTime << " seconds"
<< std::endl;
std::cout << "Pointless result (makeing sure compiler computes it) " << f.Field << std::endl;
std::cout << "Pointless result (making sure compiler computes it) " << f.Field << std::endl;
#if !defined(NDEBUG) && defined(VTKM_MSVC)
// We expect function calls through the FunctionInterface class to take

@ -214,7 +214,7 @@ public:
//to openGL this works for all storage types.
//
//Second option is to call PrepareForInput and get a PortalConst in the
//exection environment.
//execution environment.
//if we are StorageTagBasic this would allow us the ability to grab
//the raw memory value and copy those, which we know are valid and remove
//a unneeded copy.

@ -40,7 +40,7 @@
// 1. Some Linux distributions default linker implicitly enables the as-needed
// linking flag. This means that your shared library or executable will only
// link to libraries from which they use symbols. So if you explicitly link to
// pthread but don't use any symbols you wont have a 'DT_NEEDED' entry for
// pthread but don't use any symbols you won't have a 'DT_NEEDED' entry for
// pthread.
//
// 2. NVidia libGL (driver version 352 ) uses pthread but doesn't have

@ -42,7 +42,7 @@
// 1. Some Linux distributions default linker implicitly enables the as-needed
// linking flag. This means that your shared library or executable will only
// link to libraries from which they use symbols. So if you explicitly link to
// pthread but don't use any symbols you wont have a 'DT_NEEDED' entry for
// pthread but don't use any symbols you won't have a 'DT_NEEDED' entry for
// pthread.
//
// 2. NVidia libGL (driver version 352 ) uses pthread but doesn't have

@ -98,7 +98,7 @@ private:
std::stringstream strStream(options);
//Format supports both space and "_" seperated tokens...
//Format supports both space and "_" separated tokens...
if (token.find("DATA") != std::string::npos && token.find("FILE") != std::string::npos)
{
strStream >> bovFile >> std::ws;

@ -159,6 +159,9 @@ void AxisAnnotation3D::Render(const Camera& camera,
this->Labels[i]->SetPosition(vtkm::Float32(tickPos[0] - tickSize[0]),
vtkm::Float32(tickPos[1] - tickSize[1]),
vtkm::Float32(tickPos[2] - tickSize[2]));
vtkm::Vec<vtkm::Float32, 3> pp(vtkm::Float32(tickPos[0] - tickSize[0]),
vtkm::Float32(tickPos[1] - tickSize[1]),
vtkm::Float32(tickPos[2] - tickSize[2]));
this->Labels[i]->SetAlignment(TextAnnotation::HCenter, TextAnnotation::VCenter);
}

@ -172,7 +172,7 @@ vtkm_library(
WRAP_FOR_CUDA ${device_sources}
)
# EGL Libs are added here to ensure propper linking when statically compiling.
# EGL Libs are added here to ensure proper linking when statically compiling.
# This is safe to do even when not using EGL as the values will then be empty.
target_link_libraries(vtkm_rendering
PUBLIC vtkm_cont
@ -181,7 +181,7 @@ target_link_libraries(vtkm_rendering
${EGL_LIBRARIES}
)
# EGL Dirs are added here to ensure propper linking when statically compiling.
# EGL Dirs are added here to ensure proper linking when statically compiling.
# This is safe to do even when not using EGL as the values will then be empty.
target_include_directories(vtkm_rendering
PRIVATE ${VTKm_OPENGL_INCLUDE_DIRS}

@ -438,7 +438,7 @@ public:
/// \brief Rotate the camera about the view up vector centered at the focal point.
///
/// Note that the view up vector is whatever was set via SetViewUp, and is
/// not necesarily perpendicular to the direction of projection. The angle is
/// not necessarily perpendicular to the direction of projection. The angle is
/// given in degrees.
///
/// Azimuth only makes sense for 3D cameras, so the camera mode will be set

@ -57,7 +57,7 @@ struct ClearBuffers : public vtkm::worklet::WorkletMapField
color[3] = 0.f;
// The depth is set to slightly larger than 1.0f, ensuring this color value always fails a
// depth check
depth = 1.001f;
depth = VTKM_DEFAULT_CANVAS_DEPTH;
}
}; // struct ClearBuffers
@ -207,10 +207,12 @@ struct DrawColorBar : public vtkm::worklet::WorkletMapField
{
// local bar coord
vtkm::Id x = index % BarWidth;
vtkm::Id y = index / BarWidth, yLocal = y;
vtkm::Id y = index / BarWidth;
vtkm::Id sample = Horizontal ? x : y;
vtkm::Vec<vtkm::Float32, 4> color = colorMap.Get(sample);
vtkm::Float32 normalizedHeight =
Horizontal ? vtkm::Float32(y) / BarHeight : vtkm::Float32(x) / BarWidth;
// offset to global image coord
x += BarBottomLeft[0];
y += BarBottomLeft[1];
@ -218,7 +220,6 @@ struct DrawColorBar : public vtkm::worklet::WorkletMapField
vtkm::Id offset = y * ImageWidth + x;
// If the colortable has alpha values, we blend each color sample with translucent white.
// The height of the resultant translucent bar indicates the opacity.
vtkm::Float32 normalizedHeight = static_cast<vtkm::Float32>(yLocal) / BarHeight;
if (color[3] < 1.0f && normalizedHeight <= color[3])
{
vtkm::Float32 intensity = 0.4f;
@ -234,6 +235,8 @@ struct DrawColorBar : public vtkm::worklet::WorkletMapField
}
else
{
// make sure this is opaque
color[3] = 1.f;
frameBuffer.Set(offset, color);
}
}
@ -578,7 +581,8 @@ void Canvas::AddText(const vtkm::Matrix<vtkm::Float32, 4, 4>& transform,
vtkm::Float32 scale,
const vtkm::Vec<vtkm::Float32, 2>& anchor,
const vtkm::rendering::Color& color,
const std::string& text) const
const std::string& text,
const vtkm::Float32& depth) const
{
if (!Internals->FontTexture.IsValid())
{
@ -590,7 +594,7 @@ void Canvas::AddText(const vtkm::Matrix<vtkm::Float32, 4, 4>& transform,
vtkm::rendering::Canvas* self = const_cast<vtkm::rendering::Canvas*>(this);
TextRenderer fontRenderer(self, Internals->Font, Internals->FontTexture);
fontRenderer.RenderText(transform, scale, anchor, color, text);
fontRenderer.RenderText(transform, scale, anchor, color, text, depth);
}
void Canvas::AddText(const vtkm::Vec<vtkm::Float32, 2>& position,
@ -609,7 +613,7 @@ void Canvas::AddText(const vtkm::Vec<vtkm::Float32, 2>& position,
vtkm::Matrix<vtkm::Float32, 4, 4> transform =
vtkm::MatrixMultiply(translationMatrix, vtkm::MatrixMultiply(scaleMatrix, rotationMatrix));
this->AddText(transform, scale, anchor, color, text);
this->AddText(transform, scale, anchor, color, text, 0.f);
}
void Canvas::AddText(vtkm::Float32 x,

@ -31,6 +31,8 @@
#include <vtkm/rendering/ColorTable.h>
#include <vtkm/rendering/Texture2D.h>
#define VTKM_DEFAULT_CANVAS_DEPTH 1.001f
namespace vtkm
{
namespace rendering
@ -188,7 +190,8 @@ public:
vtkm::Float32 scale,
const vtkm::Vec<vtkm::Float32, 2>& anchor,
const vtkm::rendering::Color& color,
const std::string& text) const;
const std::string& text,
const vtkm::Float32& depth = 0) const;
friend class AxisAnnotation2D;

@ -68,7 +68,6 @@ public:
{
vtkm::Vec<Precision, 3> intersection = origin + inDepth * dir;
vtkm::Vec<vtkm::Float32, 4> point;
point[0] = static_cast<vtkm::Float32>(intersection[0]);
point[1] = static_cast<vtkm::Float32>(intersection[1]);
point[2] = static_cast<vtkm::Float32>(intersection[2]);
@ -91,18 +90,19 @@ public:
// blend the mapped color with existing canvas color
vtkm::Vec<vtkm::Float32, 4> inColor = colorBuffer.Get(pixelIndex);
vtkm::Float32 alpha = inColor[3] * (1.f - color[3]);
// if transparency exists, all alphas have been pre-multiplied
vtkm::Float32 alpha = (1.f - color[3]);
color[0] = color[0] + inColor[0] * alpha;
color[1] = color[1] + inColor[1] * alpha;
color[2] = color[2] + inColor[2] * alpha;
color[3] = alpha + color[3];
color[3] = inColor[3] * alpha + color[3];
// clamp
for (vtkm::Int32 i = 0; i < 4; ++i)
{
color[i] = vtkm::Min(1.f, vtkm::Max(color[i], 0.f));
}
// The existng depth should already been feed into thge ray mapper
// The existing depth should already been feed into the ray mapper
// so no color contribution will exist past the existing depth.
depthBuffer.Set(pixelIndex, depth);

@ -19,6 +19,7 @@
//============================================================================
#include <vtkm/rendering/ColorBarAnnotation.h>
#include <vtkm/rendering/TextAnnotationScreen.h>
namespace vtkm
{
@ -27,12 +28,32 @@ namespace rendering
ColorBarAnnotation::ColorBarAnnotation()
{
vtkm::Bounds bounds(vtkm::Range(-0.88, +0.88), vtkm::Range(+0.87, +0.92), vtkm::Range(0, 0));
Position = bounds;
Horizontal = true;
FieldName = "";
}
ColorBarAnnotation::~ColorBarAnnotation()
{
}
void ColorBarAnnotation::SetFieldName(const std::string& fieldName)
{
FieldName = fieldName;
}
void ColorBarAnnotation::SetPosition(const vtkm::Bounds& position)
{
Position = position;
vtkm::Float64 x = Position.X.Length();
vtkm::Float64 y = Position.Y.Length();
if (x > y)
Horizontal = true;
else
Horizontal = false;
}
void ColorBarAnnotation::SetRange(const vtkm::Range& range, vtkm::IdComponent numTicks)
{
std::vector<vtkm::Float64> positions, proportions;
@ -52,17 +73,50 @@ void ColorBarAnnotation::Render(const vtkm::rendering::Camera& camera,
const vtkm::rendering::WorldAnnotator& worldAnnotator,
vtkm::rendering::Canvas& canvas)
{
vtkm::Bounds bounds(vtkm::Range(-0.88, +0.88), vtkm::Range(+0.87, +0.92), vtkm::Range(0, 0));
canvas.AddColorBar(bounds, this->ColorTable, true);
canvas.AddColorBar(Position, this->ColorTable, Horizontal);
this->Axis.SetColor(canvas.GetForegroundColor());
this->Axis.SetLineWidth(1);
this->Axis.SetScreenPosition(bounds.X.Min, bounds.Y.Min, bounds.X.Max, bounds.Y.Min);
this->Axis.SetMajorTickSize(0, .02, 1.0);
if (Horizontal)
{
this->Axis.SetScreenPosition(Position.X.Min, Position.Y.Min, Position.X.Max, Position.Y.Min);
this->Axis.SetLabelAlignment(TextAnnotation::HCenter, TextAnnotation::Top);
this->Axis.SetMajorTickSize(0, .02, 1.0);
}
else
{
this->Axis.SetScreenPosition(Position.X.Min, Position.Y.Min, Position.X.Min, Position.Y.Max);
this->Axis.SetLabelAlignment(TextAnnotation::Right, TextAnnotation::VCenter);
this->Axis.SetMajorTickSize(.02, 0.0, 1.0);
}
this->Axis.SetMinorTickSize(0, 0, 0); // no minor ticks
this->Axis.SetLabelAlignment(TextAnnotation::HCenter, TextAnnotation::Top);
this->Axis.Render(camera, worldAnnotator, canvas);
if (FieldName != "")
{
vtkm::Vec<vtkm::Float32, 2> labelPos;
if (Horizontal)
{
labelPos[0] = vtkm::Float32(Position.X.Min);
labelPos[1] = vtkm::Float32(Position.Y.Max);
}
else
{
labelPos[0] = vtkm::Float32(Position.X.Min - 0.07);
labelPos[1] = vtkm::Float32(Position.Y.Max + 0.03);
}
vtkm::rendering::TextAnnotationScreen var(FieldName,
canvas.GetForegroundColor(),
.045f, // font scale
labelPos,
0.f); // rotation
var.Render(camera, worldAnnotator, canvas);
}
}
}
} // namespace vtkm::rendering

@ -38,6 +38,9 @@ class VTKM_RENDERING_EXPORT ColorBarAnnotation
protected:
vtkm::rendering::ColorTable ColorTable;
vtkm::rendering::AxisAnnotation2D Axis;
vtkm::Bounds Position;
bool Horizontal;
std::string FieldName;
public:
ColorBarAnnotation();
@ -50,14 +53,22 @@ public:
this->ColorTable = colorTable;
}
VTKM_CONT
void SetRange(const vtkm::Range& range, vtkm::IdComponent numTicks);
VTKM_CONT
void SetFieldName(const std::string& fieldName);
VTKM_CONT
void SetRange(vtkm::Float64 l, vtkm::Float64 h, vtkm::IdComponent numTicks)
{
this->SetRange(vtkm::Range(l, h), numTicks);
}
VTKM_CONT
void SetPosition(const vtkm::Bounds& position);
virtual void Render(const vtkm::rendering::Camera& camera,
const vtkm::rendering::WorldAnnotator& worldAnnotator,
vtkm::rendering::Canvas& canvas);

@ -41,7 +41,7 @@ struct ColorTableInternals;
///
/// This class provides the basic representation of a color table. This class was
/// Ported from EAVL. Originally created by Jeremy Meredith, Dave Pugmire,
/// and Sean Ahern. This class uses seperate RGB and alpha control points and can
/// and Sean Ahern. This class uses separate RGB and alpha control points and can
/// be used as a transfer function.
///
class VTKM_RENDERING_EXPORT ColorTable

@ -202,7 +202,7 @@ public:
}
else
{
throw vtkm::cont::ErrorBadValue("ENGERY MODE Not implemented for this use case\n");
throw vtkm::cont::ErrorBadValue("ENERGY MODE Not implemented for this use case\n");
}
Tracer->Trace(rays);

@ -59,13 +59,13 @@ in_size: size of the input PNG file in bytes.
convert_to_rgba32: optional parameter, true by default.
Set to true to get the output in RGBA 32-bit (8 bit per channel) color format
no matter what color type the original PNG image had. This gives predictable,
useable data from any random input PNG.
usable data from any random input PNG.
Set to false to do no color conversion at all. The result then has the same data
type as the PNG image, which can range from 1 bit to 64 bits per pixel.
Information about the color type or palette colors are not provided. You need
to know this information yourself to be able to use the data so this only
works for trusted PNG files. Use LodePNG instead of picoPNG if you need this information.
return: 0 if success, not 0 if some error occured.
return: 0 if success, not 0 if some error occurred.
*/
int DecodePNG(std::vector<unsigned char>& out_image,
unsigned long& image_width,

@ -65,21 +65,43 @@ void LineRenderer::RenderLine(const vtkm::Vec<vtkm::Float64, 3>& point0,
vtkm::Id dx = vtkm::Abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
vtkm::Id dy = -vtkm::Abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
vtkm::Id err = dx + dy, err2 = 0;
vtkm::rendering::Canvas::ColorBufferType::PortalControl colorPortal =
auto colorPortal =
vtkm::rendering::Canvas::ColorBufferType(Canvas->GetColorBuffer()).GetPortalControl();
vtkm::rendering::Canvas::DepthBufferType::PortalControl depthPortal =
auto depthPortal =
vtkm::rendering::Canvas::DepthBufferType(Canvas->GetDepthBuffer()).GetPortalControl();
vtkm::Vec<vtkm::Float32, 4> colorC = color.Components;
while (x0 >= 0 && x0 < Canvas->GetWidth() && y0 >= 0 && y0 < Canvas->GetHeight())
{
vtkm::Float32 t = (dx == 0) ? 1.0f : (static_cast<vtkm::Float32>(x0) - p0[0]) / (p1[0] - p0[0]);
t = vtkm::Min(1.f, vtkm::Max(0.f, t));
vtkm::Float32 z = vtkm::Lerp(z0, z1, t);
vtkm::Id index = y0 * Canvas->GetWidth() + x0;
if (depthPortal.Get(index) > z)
vtkm::Vec<vtkm::Float32, 4> currentColor = colorPortal.Get(index);
vtkm::Float32 currentZ = depthPortal.Get(index);
bool blend = currentColor[3] < 1.f && z > currentZ;
if (currentZ > z || blend)
{
depthPortal.Set(index, z);
colorPortal.Set(index, colorC);
vtkm::Vec<vtkm::Float32, 4> writeColor = colorC;
vtkm::Float32 depth = z;
if (blend)
{
// If there is any transparency, all alphas
// have been pre-mulitplied
vtkm::Float32 alpha = (1.f - currentColor[3]);
writeColor[0] = currentColor[0] + colorC[0] * alpha;
writeColor[1] = currentColor[1] + colorC[1] * alpha;
writeColor[2] = currentColor[2] + colorC[2] * alpha;
writeColor[3] = 1.f * alpha + currentColor[3]; // we are always drawing opaque lines
// keep the current z. Line z interpolation is not accurate
depth = currentZ;
}
depthPortal.Set(index, depth);
colorPortal.Set(index, writeColor);
}
if (x0 == x1 && y0 == y1)
{
break;

@ -459,17 +459,17 @@ void MapperGL::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
vtkm::cont::ArrayHandleUniformPointCoordinates uVerts;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> eVerts;
if (dcoords.IsSameType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
if (dcoords.IsType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
{
uVerts = dcoords.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>();
RenderTriangles(*this, numTri, uVerts, indices, sf, colorTable, scalarRange, camera);
}
else if (dcoords.IsSameType<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>>())
else if (dcoords.IsType<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>>())
{
eVerts = dcoords.Cast<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>>();
RenderTriangles(*this, numTri, eVerts, indices, sf, colorTable, scalarRange, camera);
}
else if (dcoords.IsSameType<vtkm::cont::ArrayHandleCartesianProduct<
else if (dcoords.IsType<vtkm::cont::ArrayHandleCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>>())

@ -69,7 +69,6 @@ void TextAnnotationBillboard::Render(const vtkm::rendering::Camera& camera,
vtkm::MatrixMultiply(projectionMatrix, viewMatrix), this->Position);
canvas.SetViewToScreenSpace(camera, true);
MatrixType translateMatrix =
vtkm::Transform3DTranslate(screenPos[0], screenPos[1], -screenPos[2]);
@ -98,7 +97,10 @@ void TextAnnotationBillboard::Render(const vtkm::rendering::Camera& camera,
VectorType right = vtkm::Transform3DVector(fullTransformMatrix, VectorType(1, 0, 0));
VectorType up = vtkm::Transform3DVector(fullTransformMatrix, VectorType(0, 1, 0));
worldAnnotator.AddText(origin, right, up, this->Scale, this->Anchor, this->TextColor, this->Text);
// scale depth from (1, -1) to (0, 1);
vtkm::Float32 depth = screenPos[2] * .5f + .5f;
worldAnnotator.AddText(
origin, right, up, this->Scale, this->Anchor, this->TextColor, this->Text, depth);
canvas.SetViewToWorldSpace(camera, true);
}

@ -35,34 +35,43 @@ namespace internal
struct RenderBitmapFont : public vtkm::worklet::WorkletMapField
{
using ColorBufferType = vtkm::rendering::Canvas::ColorBufferType;
using DepthBufferType = vtkm::rendering::Canvas::DepthBufferType;
using FontTextureType = vtkm::rendering::Canvas::FontTextureType;
typedef void ControlSignature(FieldIn<>, FieldIn<>, ExecObject, WholeArrayInOut<>);
typedef void ExecutionSignature(_1, _2, _3, _4);
typedef void ControlSignature(FieldIn<>,
FieldIn<>,
ExecObject,
WholeArrayInOut<>,
WholeArrayInOut<>);
typedef void ExecutionSignature(_1, _2, _3, _4, _5);
using InputDomain = _1;
VTKM_CONT
RenderBitmapFont() {}
VTKM_CONT
RenderBitmapFont(const vtkm::Vec<vtkm::Float32, 4>& color, vtkm::Id width, vtkm::Id height)
RenderBitmapFont(const vtkm::Vec<vtkm::Float32, 4>& color,
vtkm::Id width,
vtkm::Id height,
vtkm::Float32 depth)
: Color(color)
, Width(width)
, Height(height)
, Depth(depth)
{
}
template <typename ColorBufferPortal, typename FontTexture>
template <typename ColorBufferPortal, typename FontTexture, typename DepthBufferPortal>
VTKM_EXEC void operator()(const vtkm::Vec<vtkm::Float32, 4>& screenCoords,
const vtkm::Vec<vtkm::Float32, 4>& textureCoords,
const FontTexture& fontTexture,
ColorBufferPortal& colorBuffer) const
ColorBufferPortal& colorBuffer,
DepthBufferPortal& depthBuffer) const
{
vtkm::Float32 x0 = Clamp(screenCoords[0], 0.0f, static_cast<vtkm::Float32>(Width - 1));
vtkm::Float32 x1 = Clamp(screenCoords[2], 0.0f, static_cast<vtkm::Float32>(Width - 1));
vtkm::Float32 y0 = Clamp(screenCoords[1], 0.0f, static_cast<vtkm::Float32>(Height - 1));
vtkm::Float32 y1 = Clamp(screenCoords[3], 0.0f, static_cast<vtkm::Float32>(Height - 1));
// For crisp text rendering, we sample the font texture at points smaller than the pixel
// sizes. Here we sample at increments of 0.25f, and scale the reported intensities accordingly
vtkm::Float32 dx = x1 - x0, dy = y1 - y0;
@ -75,28 +84,43 @@ struct RenderBitmapFont : public vtkm::worklet::WorkletMapField
vtkm::Float32 u = vtkm::Lerp(textureCoords[0], textureCoords[2], tu);
vtkm::Float32 v = vtkm::Lerp(textureCoords[1], textureCoords[3], tv);
vtkm::Float32 intensity = fontTexture.GetColor(u, v)[0] * 0.25f;
Plot(x, y, intensity, colorBuffer);
Plot(x, y, intensity, colorBuffer, depthBuffer);
}
}
}
template <typename ColorBufferPortal>
template <typename ColorBufferPortal, typename DepthBufferPortal>
void Plot(vtkm::Float32 x,
vtkm::Float32 y,
vtkm::Float32 intensity,
ColorBufferPortal& colorBuffer) const
ColorBufferPortal& colorBuffer,
DepthBufferPortal& depthBuffer) const
{
vtkm::Id index =
static_cast<vtkm::Id>(vtkm::Round(y)) * Width + static_cast<vtkm::Id>(vtkm::Round(x));
vtkm::Vec<vtkm::Float32, 4> srcColor = colorBuffer.Get(index);
vtkm::Float32 currentDepth = depthBuffer.Get(index);
bool swap = Depth > currentDepth;
intensity = intensity * Color[3];
vtkm::Float32 inverseIntensity = 1.0f - intensity;
vtkm::Float32 alpha = srcColor[3] * inverseIntensity;
vtkm::Vec<vtkm::Float32, 4> color = intensity * Color;
color[3] = intensity;
vtkm::Vec<vtkm::Float32, 4> front = color;
vtkm::Vec<vtkm::Float32, 4> back = srcColor;
if (swap)
{
front = srcColor;
back = color;
}
vtkm::Vec<vtkm::Float32, 4> blendedColor;
blendedColor[0] = Color[0] * intensity + srcColor[0] * alpha;
blendedColor[1] = Color[1] * intensity + srcColor[1] * alpha;
blendedColor[2] = Color[2] * intensity + srcColor[2] * alpha;
blendedColor[3] = alpha + intensity;
vtkm::Float32 alpha = (1.f - front[3]);
blendedColor[0] = front[0] + back[0] * alpha;
blendedColor[1] = front[1] + back[1] * alpha;
blendedColor[2] = front[2] + back[2] * alpha;
blendedColor[3] = back[3] * alpha + front[3];
colorBuffer.Set(index, blendedColor);
}
@ -109,11 +133,13 @@ struct RenderBitmapFont : public vtkm::worklet::WorkletMapField
vtkm::Vec<vtkm::Float32, 4> Color;
vtkm::Id Width;
vtkm::Id Height;
vtkm::Float32 Depth;
}; // struct RenderBitmapFont
struct RenderBitmapFontExecutor
{
using ColorBufferType = vtkm::rendering::Canvas::ColorBufferType;
using DepthBufferType = vtkm::rendering::Canvas::DepthBufferType;
using FontTextureType = vtkm::rendering::Canvas::FontTextureType;
using ScreenCoordsArrayHandle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>>;
using TextureCoordsArrayHandle = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 4>>;
@ -124,13 +150,16 @@ struct RenderBitmapFontExecutor
const FontTextureType& fontTexture,
const vtkm::Vec<vtkm::Float32, 4>& color,
const ColorBufferType& colorBuffer,
const DepthBufferType& depthBuffer,
vtkm::Id width,
vtkm::Id height)
vtkm::Id height,
vtkm::Float32 depth)
: ScreenCoords(screenCoords)
, TextureCoords(textureCoords)
, FontTexture(fontTexture)
, ColorBuffer(colorBuffer)
, Worklet(color, width, height)
, DepthBuffer(depthBuffer)
, Worklet(color, width, height, depth)
{
}
@ -141,7 +170,7 @@ struct RenderBitmapFontExecutor
vtkm::worklet::DispatcherMapField<RenderBitmapFont, Device> dispatcher(Worklet);
dispatcher.Invoke(
ScreenCoords, TextureCoords, FontTexture.GetExecObject<Device>(), ColorBuffer);
ScreenCoords, TextureCoords, FontTexture.GetExecObject<Device>(), ColorBuffer, DepthBuffer);
return true;
}
@ -149,6 +178,7 @@ struct RenderBitmapFontExecutor
TextureCoordsArrayHandle TextureCoords;
FontTextureType FontTexture;
ColorBufferType ColorBuffer;
DepthBufferType DepthBuffer;
RenderBitmapFont Worklet;
}; // struct RenderBitmapFontExecutor
} // namespace internal
@ -201,7 +231,8 @@ void TextRenderer::RenderText(const vtkm::Matrix<vtkm::Float32, 4, 4>& transform
vtkm::Float32 scale,
const vtkm::Vec<vtkm::Float32, 2>& anchor,
const vtkm::rendering::Color& color,
const std::string& text)
const std::string& text,
const vtkm::Float32& depth)
{
vtkm::Float32 textWidth = this->Font.GetTextWidth(text);
vtkm::Float32 fx = -(0.5f + 0.5f * anchor[0]) * textWidth;
@ -246,8 +277,10 @@ void TextRenderer::RenderText(const vtkm::Matrix<vtkm::Float32, 4, 4>& transform
FontTexture,
color.Components,
Canvas->GetColorBuffer(),
Canvas->GetDepthBuffer(),
Canvas->GetWidth(),
Canvas->GetHeight()));
Canvas->GetHeight(),
depth));
}
}
} // namespace vtkm::rendering

@ -64,7 +64,8 @@ public:
vtkm::Float32 scale,
const vtkm::Vec<vtkm::Float32, 2>& anchor,
const vtkm::rendering::Color& color,
const std::string& text);
const std::string& text,
const vtkm::Float32& depth = 0.f);
private:
const vtkm::rendering::Canvas* Canvas;

@ -293,7 +293,7 @@ public:
{
if (index == 0)
return;
//if we are a shared face, mark ourself and neighbor for desctruction
//if we are a shared face, mark ourself and neighbor for destruction
if (IsTwin(indices.Get(index), indices.Get(index - 1)))
{
outputFlags.Set(index, 0);

@ -102,6 +102,7 @@ void View2D::RenderScreenAnnotations()
if (scene.GetNumberOfActors() > 0)
{
//this->ColorBarAnnotation.SetAxisColor(vtkm::rendering::Color(1,1,1));
this->ColorBarAnnotation.SetFieldName(scene.GetActor(0).GetScalarField().GetName());
this->ColorBarAnnotation.SetRange(
scene.GetActor(0).GetScalarRange().Min, scene.GetActor(0).GetScalarRange().Max, 5);
this->ColorBarAnnotation.SetColorTable(scene.GetActor(0).GetColorTable());

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