Merge branch 'dynamic-point-coordinates'

This commit is contained in:
Kenneth Moreland 2014-06-09 11:13:17 -06:00
commit da68debbf3
39 changed files with 6498 additions and 5 deletions

@ -21,6 +21,9 @@
include_directories(${Boost_INCLUDE_DIRS})
set(headers
Extent.h
ListTag.h
TypeListTag.h
Types.h
TypeTraits.h
VectorTraits.h

319
vtkm/Extent.h Normal file

@ -0,0 +1,319 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_Extent_h
#define vtk_m_Extent_h
#include <vtkm/Types.h>
namespace vtkm {
/// Extent stores the values for the index ranges for a structured grid array.
/// It does this through the minimum indices and the maximum indices.
///
template<int Dimensions>
struct Extent
{
vtkm::Tuple<vtkm::Id,Dimensions> Min;
vtkm::Tuple<vtkm::Id,Dimensions> Max;
VTKM_EXEC_CONT_EXPORT
Extent() : Min(0), Max(0) { }
VTKM_EXEC_CONT_EXPORT
Extent(const vtkm::Tuple<vtkm::Id,Dimensions> &min,
const vtkm::Tuple<vtkm::Id,Dimensions> &max)
: Min(min), Max(max) { }
VTKM_EXEC_CONT_EXPORT
Extent(const Extent<Dimensions> &other)
: Min(other.Min), Max(other.Max) { }
VTKM_EXEC_CONT_EXPORT
Extent<Dimensions> &operator=(const Extent<Dimensions> &rhs)
{
this->Min = rhs.Min;
this->Max = rhs.Max;
return *this;
}
} __attribute__ ((aligned(VTKM_SIZE_ID)));
/// This is the Extent to use for structured grids with 3 topological
/// dimensions.
///
typedef vtkm::Extent<3> Extent3 __attribute__ ((aligned(VTKM_SIZE_ID)));
/// This is the Extent to use for structured grids with 2 topological
/// dimensions.
///
typedef vtkm::Extent<2> Extent2 __attribute__ ((aligned(VTKM_SIZE_ID)));
/// Given an extent, returns the array dimensions for the points.
///
template<int Dimensions>
VTKM_EXEC_CONT_EXPORT
vtkm::Tuple<vtkm::Id,Dimensions>
ExtentPointDimensions(const vtkm::Extent<Dimensions> &extent)
{
return extent.Max - extent.Min + vtkm::Tuple<vtkm::Id,Dimensions>(1);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Id3 ExtentPointDimensions(const vtkm::Extent3 &extent)
{
// Efficient implementation that uses no temporary Id3 to create dimensions.
return vtkm::Id3(extent.Max[0] - extent.Min[0] + 1,
extent.Max[1] - extent.Min[1] + 1,
extent.Max[2] - extent.Min[2] + 1);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Id2 ExtentPointDimensions(const vtkm::Extent2 &extent)
{
// Efficient implementation that uses no temporary Id2 to create dimensions.
return vtkm::Id2(extent.Max[0] - extent.Min[0] + 1,
extent.Max[1] - extent.Min[1] + 1);
}
/// Given an extent, returns the array dimensions for the cells.
///
template<int Dimensions>
VTKM_EXEC_CONT_EXPORT
vtkm::Tuple<vtkm::Id,Dimensions>
ExtentCellDimensions(const vtkm::Extent<Dimensions> &extent)
{
return extent.Max - extent.Min;
}
/// Given an extent, returns the number of points in the structured mesh.
///
template<int Dimensions>
VTKM_EXEC_CONT_EXPORT
vtkm::Id ExtentNumberOfPoints(const vtkm::Extent<Dimensions> &extent)
{
return internal::product_vector<Dimensions>()(
vtkm::ExtentPointDimensions(extent));
}
template<>
VTKM_EXEC_CONT_EXPORT
vtkm::Id ExtentNumberOfPoints(const vtkm::Extent3 &extent)
{
// Efficient implementation that uses no temporary Id3.
return (
(extent.Max[0] - extent.Min[0] + 1)
* (extent.Max[1] - extent.Min[1] + 1)
* (extent.Max[2] - extent.Min[2] + 1));
}
template<>
VTKM_EXEC_CONT_EXPORT
vtkm::Id ExtentNumberOfPoints(const vtkm::Extent2 &extent)
{
// Efficient implementation that uses no temporary Id2.
return (
(extent.Max[0] - extent.Min[0] + 1)
* (extent.Max[1] - extent.Min[1] + 1));
}
/// Given an extent, returns the number of cells in the structured mesh.
///
template<int Dimensions>
VTKM_EXEC_CONT_EXPORT
vtkm::Id ExtentNumberOfCells(const vtkm::Extent<Dimensions> &extent)
{
return internal::product_vector<Dimensions>()(
vtkm::ExtentCellDimensions(extent));
}
template<>
VTKM_EXEC_CONT_EXPORT
vtkm::Id ExtentNumberOfCells(const vtkm::Extent3 &extent)
{
// Efficient implementation that uses no temporary Id3.
return (
(extent.Max[0] - extent.Min[0])
* (extent.Max[1] - extent.Min[1])
* (extent.Max[2] - extent.Min[2]));
}
template<>
VTKM_EXEC_CONT_EXPORT
vtkm::Id ExtentNumberOfCells(const vtkm::Extent2 &extent)
{
// Efficient implementation that uses no temporary Id2.
return (
(extent.Max[0] - extent.Min[0])
* (extent.Max[1] - extent.Min[1]));
}
/// Elements in structured grids have a single index with 0 being the entry at
/// the minimum extent in every direction and then increasing first in the r
/// then the s direction and so on. This method converts a flat index to the
/// topological coordinates (e.g. r,s,t for 3d topologies).
///
template<int Dimensions>
VTKM_EXEC_CONT_EXPORT
vtkm::Tuple<vtkm::Id,Dimensions>
ExtentPointFlatIndexToTopologyIndex(vtkm::Id index,
const vtkm::Extent<Dimensions> &extent)
{
const vtkm::Tuple<vtkm::Id,Dimensions> dims =
vtkm::ExtentPointDimensions(extent);
vtkm::Tuple<vtkm::Id,Dimensions> ijkIndex;
vtkm::Id indexOnDim = index;
for (int dimIndex = 0; dimIndex < Dimensions-1; dimIndex++)
{
ijkIndex[dimIndex] = indexOnDim % dims[dimIndex] + extent.Min[dimIndex];
indexOnDim /= dims[dimIndex];
}
// Special case for last dimension to remove some unneeded operations
ijkIndex[Dimensions-1] = indexOnDim + extent.Min[Dimensions-1];
return ijkIndex;
}
VTKM_EXEC_CONT_EXPORT
vtkm::Id3 ExtentPointFlatIndexToTopologyIndex(vtkm::Id index,
const vtkm::Extent3 &extent)
{
// Efficient implementation that tries to reduce the number of temporary
// variables.
const vtkm::Id3 dims = vtkm::ExtentPointDimensions(extent);
return vtkm::Id3((index % dims[0]) + extent.Min[0],
((index / dims[0]) % dims[1]) + extent.Min[1],
((index / (dims[0]*dims[1]))) + extent.Min[2]);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Id2 ExtentPointFlatIndexToTopologyIndex(vtkm::Id index,
const vtkm::Extent2 &extent)
{
// Efficient implementation that tries to reduce the number of temporary
// variables.
const vtkm::Id2 dims = vtkm::ExtentPointDimensions(extent);
return vtkm::Id2((index % dims[0]) + extent.Min[0],
(index / dims[0]) + extent.Min[1]);
}
/// Elements in structured grids have a single index with 0 being the entry at
/// the minimum extent in every direction and then increasing first in the r
/// then the s direction and so on. This method converts a flat index to the
/// topological coordinates (e.g. r,s,t for 3d topologies).
///
template<int Dimensions>
VTKM_EXEC_CONT_EXPORT
vtkm::Tuple<vtkm::Id,Dimensions>
ExtentCellFlatIndexToTopologyIndex(vtkm::Id index,
const vtkm::Extent<Dimensions> &extent)
{
const vtkm::Tuple<vtkm::Id,Dimensions> dims =
vtkm::ExtentCellDimensions(extent);
vtkm::Tuple<vtkm::Id,Dimensions> ijkIndex;
vtkm::Id indexOnDim = index;
for (int dimIndex = 0; dimIndex < Dimensions-1; dimIndex++)
{
ijkIndex[dimIndex] = indexOnDim % dims[dimIndex] + extent.Min[dimIndex];
indexOnDim /= dims[dimIndex];
}
// Special case for last dimension to remove some unneeded operations
ijkIndex[Dimensions-1] = indexOnDim + extent.Min[Dimensions-1];
return ijkIndex;
}
VTKM_EXEC_CONT_EXPORT
vtkm::Id3 ExtentCellFlatIndexToTopologyIndex(vtkm::Id index,
const vtkm::Extent3 &extent)
{
// Efficient implementation that tries to reduce the number of temporary
// variables.
const vtkm::Id3 dims = vtkm::ExtentCellDimensions(extent);
return vtkm::Id3((index % dims[0]) + extent.Min[0],
((index / dims[0]) % dims[1]) + extent.Min[1],
((index / (dims[0]*dims[1]))) + extent.Min[2]);
}
VTKM_EXEC_CONT_EXPORT
vtkm::Id2 ExtentCellFlatIndexToTopologyIndex(vtkm::Id index,
const vtkm::Extent2 &extent)
{
// Efficient implementation that tries to reduce the number of temporary
// variables.
const vtkm::Id2 dims = vtkm::ExtentCellDimensions(extent);
return vtkm::Id2((index % dims[0]) + extent.Min[0],
(index / dims[0]) + extent.Min[1]);
}
/// Elements in structured grids have a single index with 0 being the entry at
/// the minimum extent in every direction and then increasing first in the r
/// then the s direction and so on. This method converts topological
/// coordinates to a flat index.
///
template<int Dimensions>
VTKM_EXEC_CONT_EXPORT
vtkm::Id
ExtentPointTopologyIndexToFlatIndex(const vtkm::Tuple<vtkm::Id,Dimensions> &ijk,
const vtkm::Extent<Dimensions> &extent)
{
const vtkm::Tuple<vtkm::Id,Dimensions> dims = ExtentPointDimensions(extent);
const vtkm::Tuple<vtkm::Id,Dimensions> deltas = ijk - extent.Min;
vtkm::Id flatIndex = deltas[Dimensions-1];
for (int dimIndex = Dimensions-2; dimIndex >= 0; dimIndex--)
{
flatIndex = flatIndex*dims[dimIndex] + deltas[dimIndex];
}
return flatIndex;
}
/// Elements in structured grids have a single index with 0 being the entry at
/// the minimum extent in every direction and then increasing first in the r
/// then the s direction and so on. This method converts topological
/// coordinates to a flat index.
///
template<int Dimensions>
VTKM_EXEC_CONT_EXPORT
vtkm::Id
ExtentCellTopologyIndexToFlatIndex(const vtkm::Tuple<vtkm::Id,Dimensions> &ijk,
const vtkm::Extent<Dimensions> &extent)
{
const vtkm::Tuple<vtkm::Id,Dimensions> dims = ExtentCellDimensions(extent);
const vtkm::Tuple<vtkm::Id,Dimensions> deltas = ijk - extent.Min;
vtkm::Id flatIndex = deltas[Dimensions-1];
for (int dimIndex = Dimensions-2; dimIndex >= 0; dimIndex--)
{
flatIndex = flatIndex*dims[dimIndex] + deltas[dimIndex];
}
return flatIndex;
}
/// Given a cell index, returns the index to the first point incident on that
/// cell.
///
template<int Dimensions>
VTKM_EXEC_CONT_EXPORT
vtkm::Id ExtentFirstPointOnCell(vtkm::Id cellIndex,
const Extent<Dimensions> &extent)
{
return ExtentPointTopologyIndexToFlatIndex(
ExtentCellFlatIndexToTopologyIndex(cellIndex,extent),
extent);
}
} // namespace vtkm
#endif //vtk_m_Extent_h

216
vtkm/ListTag.h Normal file

@ -0,0 +1,216 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_ListTag_h
#define vtk_m_ListTag_h
#include <vtkm/internal/ExportMacros.h>
namespace vtkm {
namespace detail {
struct ListEmpty { };
template<typename T>
struct ListBase { };
template<typename T1, typename T2>
struct ListBase2 { };
template<typename T1, typename T2, typename T3>
struct ListBase3 { };
template<typename T1, typename T2, typename T3, typename T4>
struct ListBase4 { };
template<typename ListTag1, typename ListTag2>
struct ListJoin { };
} // namespace detail
template<typename T> struct ListTagBase;
/// A special tag for an empty list.
///
struct ListTagEmpty {
typedef detail::ListEmpty List;
};
/// A basic tag for a list of one typename. This struct can be subclassed
/// and still behave like a list tag.
template<typename T>
struct ListTagBase {
typedef detail::ListBase<T> List;
};
/// A basic tag for a list of two typenames. This struct can be subclassed
/// and still behave like a list tag.
template<typename T1, typename T2>
struct ListTagBase2 {
typedef detail::ListBase2<T1, T2> List;
};
/// A basic tag for a list of three typenames. This struct can be subclassed
/// and still behave like a list tag.
template<typename T1, typename T2, typename T3>
struct ListTagBase3 {
typedef detail::ListBase3<T1, T2, T3> List;
};
/// A basic tag for a list of four typenames. This struct can be subclassed
/// and still behave like a list tag.
template<typename T1, typename T2, typename T3, typename T4>
struct ListTagBase4 {
typedef detail::ListBase4<T1, T2, T3, T4> List;
};
/// A tag that is a construction of two other tags joined together. This struct
/// can be subclassed and still behave like a list tag.
template<typename ListTag1, typename ListTag2>
struct ListTagJoin {
typedef detail::ListJoin<ListTag1, ListTag2> List;
};
template<typename Functor, typename ListTag>
VTKM_CONT_EXPORT
void ListForEach(Functor &f, ListTag);
template<typename Functor, typename ListTag>
VTKM_CONT_EXPORT
void ListForEach(const Functor &f, ListTag);
namespace detail {
template<typename Functor>
VTKM_CONT_EXPORT
void ListForEachImpl(Functor, ListEmpty)
{
// Nothing to do for empty list
}
template<typename Functor, typename T>
VTKM_CONT_EXPORT
void ListForEachImpl(Functor &f, ListBase<T>)
{
f(T());
}
template<typename Functor, typename T1, typename T2>
VTKM_CONT_EXPORT
void ListForEachImpl(Functor &f, ListBase2<T1,T2>)
{
f(T1());
f(T2());
}
template<typename Functor, typename T1, typename T2, typename T3>
VTKM_CONT_EXPORT
void ListForEachImpl(Functor &f, ListBase3<T1,T2,T3>)
{
f(T1());
f(T2());
f(T3());
}
template<typename Functor, typename T1, typename T2, typename T3, typename T4>
VTKM_CONT_EXPORT
void ListForEachImpl(Functor &f, ListBase4<T1,T2,T3,T4>)
{
f(T1());
f(T2());
f(T3());
f(T4());
}
template<typename Functor, typename ListTag1, typename ListTag2>
VTKM_CONT_EXPORT
void ListForEachImpl(Functor &f, ListJoin<ListTag1, ListTag2>)
{
vtkm::ListForEach(f, ListTag1());
vtkm::ListForEach(f, ListTag2());
}
template<typename Functor, typename T>
VTKM_CONT_EXPORT
void ListForEachImpl(const Functor &f, ListBase<T>)
{
f(T());
}
template<typename Functor, typename T1, typename T2>
VTKM_CONT_EXPORT
void ListForEachImpl(const Functor &f, ListBase2<T1,T2>)
{
f(T1());
f(T2());
}
template<typename Functor, typename T1, typename T2, typename T3>
VTKM_CONT_EXPORT
void ListForEachImpl(const Functor &f, ListBase3<T1,T2,T3>)
{
f(T1());
f(T2());
f(T3());
}
template<typename Functor, typename T1, typename T2, typename T3, typename T4>
VTKM_CONT_EXPORT
void ListForEachImpl(const Functor &f, ListBase4<T1,T2,T3,T4>)
{
f(T1());
f(T2());
f(T3());
f(T4());
}
template<typename Functor, typename ListTag1, typename ListTag2>
VTKM_CONT_EXPORT
void ListForEachImpl(const Functor &f, ListJoin<ListTag1, ListTag2>)
{
vtkm::ListForEach(f, ListTag1());
vtkm::ListForEach(f, ListTag2());
}
} // namespace detail
/// For each typename represented by the list tag, call the functor with a
/// default instance of that type.
///
template<typename Functor, typename ListTag>
VTKM_CONT_EXPORT
void ListForEach(Functor &f, ListTag)
{
detail::ListForEachImpl(f, typename ListTag::List());
}
/// For each typename represented by the list tag, call the functor with a
/// default instance of that type.
///
template<typename Functor, typename ListTag>
VTKM_CONT_EXPORT
void ListForEach(const Functor &f, ListTag)
{
detail::ListForEachImpl(f, typename ListTag::List());
}
} // namespace vtkm
#endif //vtk_m_ListTag_h

64
vtkm/TypeListTag.h Normal file

@ -0,0 +1,64 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_TypeListTag_h
#define vtk_m_TypeListTag_h
#ifndef VTKM_DEFAULT_TYPE_LIST_TAG
#define VTKM_DEFAULT_TYPE_LIST_TAG ::vtkm::TypeListTagCommon
#endif
#include <vtkm/ListTag.h>
#include <vtkm/Types.h>
namespace vtkm {
struct TypeListTagId : vtkm::ListTagBase<vtkm::Id> { };
struct TypeListTagId2 : vtkm::ListTagBase<vtkm::Id2> { };
struct TypeListTagId3 : vtkm::ListTagBase<vtkm::Id3> { };
struct TypeListTagScalar : vtkm::ListTagBase<vtkm::Scalar> { };
struct TypeListTagVector2 : vtkm::ListTagBase<vtkm::Vector2> { };
struct TypeListTagVector3 : vtkm::ListTagBase<vtkm::Vector3> { };
struct TypeListTagVector4 : vtkm::ListTagBase<vtkm::Vector4> { };
struct TypeListTagIndex
: vtkm::ListTagBase3<vtkm::Id,vtkm::Id2,vtkm::Id3> { };
struct TypeListTagReal
: vtkm::ListTagBase4<vtkm::Scalar,vtkm::Vector2,vtkm::Vector3,vtkm::Vector4>
{ };
/// A list of all basic types listed in vtkm/Types.h. Does not include all
/// possible VTK-m types like arbitrarily typed and sized tuples or math
/// types like matrices.
///
struct TypeListTagAll
: vtkm::ListTagJoin<vtkm::TypeListTagIndex, vtkm::TypeListTagReal>
{ };
/// A list of the most commonly used types across multiple domains. Includes
/// Id, Scalar, and Vector3.
///
struct TypeListTagCommon
: vtkm::ListTagBase3<vtkm::Id, vtkm::Scalar, vtkm::Vector3>
{ };
} // namespace vtkm
#endif //vtk_m_TypeListTag_h

@ -241,6 +241,116 @@ struct copy_vector<3>
}
};
template<int Size>
struct sum_vector
{
template<typename T>
VTKM_EXEC_CONT_EXPORT
typename T::ComponentType operator()(const T &x)
{
return sum_vector<Size-1>()(x) + x[Size-1];
}
};
template<>
struct sum_vector<1>
{
template<typename T>
VTKM_EXEC_CONT_EXPORT
typename T::ComponentType operator()(const T &x)
{
return x[0];
}
};
template<>
struct sum_vector<2>
{
template<typename T>
VTKM_EXEC_CONT_EXPORT
typename T::ComponentType operator()(const T &x)
{
return x[0] + x[1];
}
};
template<>
struct sum_vector<3>
{
template<typename T>
VTKM_EXEC_CONT_EXPORT
typename T::ComponentType operator()(const T &x)
{
return x[0] + x[1] + x[2];
}
};
template<>
struct sum_vector<4>
{
template<typename T>
VTKM_EXEC_CONT_EXPORT
typename T::ComponentType operator()(const T &x)
{
return x[0] + x[1] + x[2] + x[3];
}
};
template<int Size>
struct product_vector
{
template<typename T>
VTKM_EXEC_CONT_EXPORT
typename T::ComponentType operator()(const T &x)
{
return product_vector<Size-1>()(x) * x[Size-1];
}
};
template<>
struct product_vector<1>
{
template<typename T>
VTKM_EXEC_CONT_EXPORT
typename T::ComponentType operator()(const T &x)
{
return x[0];
}
};
template<>
struct product_vector<2>
{
template<typename T>
VTKM_EXEC_CONT_EXPORT
typename T::ComponentType operator()(const T &x)
{
return x[0] * x[1];
}
};
template<>
struct product_vector<3>
{
template<typename T>
VTKM_EXEC_CONT_EXPORT
typename T::ComponentType operator()(const T &x)
{
return x[0] * x[1] * x[2];
}
};
template<>
struct product_vector<4>
{
template<typename T>
VTKM_EXEC_CONT_EXPORT
typename T::ComponentType operator()(const T &x)
{
return x[0] * x[1] * x[2] * x[3];
}
};
} // namespace internal

@ -28,6 +28,8 @@
#define VTKM_ARRAY_CONTAINER_CONTROL VTKM_ARRAY_CONTAINER_CONTROL_BASIC
#endif
#include <boost/static_assert.hpp>
namespace vtkm {
namespace cont {
@ -62,13 +64,35 @@ struct ArrayContainerControlTag___ { };
namespace internal {
struct UndefinedArrayContainerControl { };
namespace detail {
// This class should never be used. It is used as a placeholder for undefined
// ArrayContainerControl objects. If you get a compiler error involving this
// object, then it probably comes from trying to use an ArrayHandle with bad
// template arguments.
template<typename T>
struct UndefinedArrayPortal {
BOOST_STATIC_ASSERT(sizeof(T) == -1);
};
} // namespace detail
/// This templated class must be partially specialized for each
/// ArrayContainerControlTag created, which will define the implementation for
/// that tag.
///
template<typename T, class ArrayContainerControlTag>
class ArrayContainerControl
#ifdef VTKM_DOXYGEN_ONLY
#ifndef VTKM_DOXYGEN_ONLY
: public vtkm::cont::internal::UndefinedArrayContainerControl
{
public:
typedef vtkm::cont::internal::detail::UndefinedArrayPortal<T> PortalType;
typedef vtkm::cont::internal::detail::UndefinedArrayPortal<T> PortalConstType;
};
#else //VTKM_DOXYGEN_ONLY
{
public:
@ -133,8 +157,6 @@ public:
VTKM_CONT_EXPORT
void ReleaseResources();
};
#else // VTKM_DOXYGEN_ONLY
;
#endif // VTKM_DOXYGEN_ONLY
} // namespace internal

@ -105,6 +105,28 @@ public:
}
};
//// If you are using this specalization of ArrayContainerControl, it means the
//// type of an ArrayHandle does not match the type of the array portal for the
//// array portal in an implicit array. Currently this use is invalid, but there
//// could be a case for implementing casting where appropriate.
//template<typename T, typename ArrayPortalType>
//class ArrayContainerControl<T, ArrayContainerControlTagImplicit<ArrayPortalType> >
//{
//public:
// // This is meant to be invalid because this class should not actually be used.
// struct PortalType
// {
// typedef void *ValueType;
// typedef void *IteratorType;
// };
// // This is meant to be invalid because this class should not actually be used.
// struct PortalConstType
// {
// typedef void *ValueType;
// typedef void *IteratorType;
// };
//};
template<typename T, class ArrayPortalType, class DeviceAdapterTag>
class ArrayTransfer<
T, ArrayContainerControlTagImplicit<ArrayPortalType>, DeviceAdapterTag>

@ -30,16 +30,35 @@
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <boost/concept_check.hpp>
#include <boost/mpl/not.hpp>
#include <boost/smart_ptr/scoped_ptr.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <vector>
namespace vtkm {
namespace cont {
// Forward declaration
namespace internal { class ArrayHandleAccess; }
namespace internal {
/// Checks to see if the given type and container can form a valid array handle
/// (some containers cannot support all types). This check is compatable with
/// the Boost meta-template programming library (MPL). It contains a typedef
/// named type that is either boost::mpl::true_ or boost::mpl::false_. Both of
/// these have a typedef named value with the respective boolean value.
///
template<typename T, typename ArrayContainerControlTag>
struct IsValidArrayHandle {
typedef typename boost::mpl::not_<
typename boost::is_base_of<
vtkm::cont::internal::UndefinedArrayContainerControl,
vtkm::cont::internal::ArrayContainerControl<T,ArrayContainerControlTag>
>::type
>::type type;
};
} // namespace internal
/// \brief Manages an array-worth of data.
///

@ -0,0 +1,775 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_ArrayHandleCompositeVector_h
#define vtk_m_ArrayHandleCompositeVector_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ErrorControlBadValue.h>
#include <vtkm/cont/ErrorControlInternal.h>
#include <vtkm/VectorTraits.h>
#include <vtkm/internal/FunctionInterface.h>
#include <boost/static_assert.hpp>
namespace vtkm {
namespace cont {
namespace internal {
namespace detail {
template<typename ValueType>
struct CompositeVectorSwizzleFunctor
{
static const int NUM_COMPONENTS =
vtkm::VectorTraits<ValueType>::NUM_COMPONENTS;
typedef vtkm::Tuple<int, NUM_COMPONENTS> ComponentMapType;
// Caution! This is a reference.
const ComponentMapType &SourceComponents;
VTKM_EXEC_CONT_EXPORT
CompositeVectorSwizzleFunctor(const ComponentMapType &sourceComponents)
: SourceComponents(sourceComponents) { }
// Currently only supporting 1-4 components.
template<typename T1>
VTKM_EXEC_CONT_EXPORT
ValueType operator()(const T1 &p1) const {
return ValueType(
vtkm::VectorTraits<T1>::GetComponent(p1, this->SourceComponents[0]));
}
template<typename T1, typename T2>
VTKM_EXEC_CONT_EXPORT
ValueType operator()(const T1 &p1, const T2 &p2) const {
return ValueType(
vtkm::VectorTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VectorTraits<T2>::GetComponent(p2, this->SourceComponents[1]));
}
template<typename T1, typename T2, typename T3>
VTKM_EXEC_CONT_EXPORT
ValueType operator()(const T1 &p1, const T2 &p2, const T3 &p3) const {
return ValueType(
vtkm::VectorTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VectorTraits<T2>::GetComponent(p2, this->SourceComponents[1]),
vtkm::VectorTraits<T3>::GetComponent(p3, this->SourceComponents[2]));
}
template<typename T1, typename T2, typename T3, typename T4>
VTKM_EXEC_CONT_EXPORT
ValueType operator()(const T1 &p1,
const T2 &p2,
const T3 &p3,
const T4 &p4) const {
return ValueType(
vtkm::VectorTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VectorTraits<T2>::GetComponent(p2, this->SourceComponents[1]),
vtkm::VectorTraits<T3>::GetComponent(p3, this->SourceComponents[2]),
vtkm::VectorTraits<T4>::GetComponent(p4, this->SourceComponents[3]));
}
};
template<typename ReturnValueType>
struct CompositeVectorPullValueFunctor
{
vtkm::Id Index;
VTKM_EXEC_EXPORT
CompositeVectorPullValueFunctor(vtkm::Id index) : Index(index) { }
// This form is to pull values out of array arguments.
template<typename PortalType>
VTKM_EXEC_EXPORT
typename PortalType::ValueType operator()(const PortalType &portal) const {
return portal.Get(this->Index);
}
// This form is an identity to pass the return value back.
VTKM_EXEC_EXPORT
const ReturnValueType &operator()(const ReturnValueType &value) const {
return value;
}
};
struct CompositeVectorArrayToPortalCont {
template<typename ArrayHandleType>
struct ReturnType {
typedef typename ArrayHandleType::PortalConstControl type;
};
template<typename ArrayHandleType>
VTKM_CONT_EXPORT
typename ReturnType<ArrayHandleType>::type
operator()(const ArrayHandleType &array) const {
return array.GetPortalConstControl();
}
};
template<typename DeviceAdapterTag>
struct CompositeVectorArrayToPortalExec {
template<typename ArrayHandleType>
struct ReturnType {
typedef typename ArrayHandleType::template ExecutionTypes<
DeviceAdapterTag>::PortalConst type;
};
template<typename ArrayHandleType>
VTKM_CONT_EXPORT
typename ReturnType<ArrayHandleType>::type
operator()(const ArrayHandleType &array) const {
return array.PrepareForInput(DeviceAdapterTag());
}
};
struct CheckArraySizeFunctor {
vtkm::Id ExpectedSize;
CheckArraySizeFunctor(vtkm::Id expectedSize) : ExpectedSize(expectedSize) { }
template<typename T>
void operator()(const T &a) const {
if (a.GetNumberOfValues() != this->ExpectedSize)
{
throw vtkm::cont::ErrorControlBadValue(
"All input arrays to ArrayHandleCompositeVector must be the same size.");
}
}
};
} // namespace detail
/// \brief A portal that gets values from components of other portals.
///
/// This is the portal used within ArrayHandleCompositeVector.
///
template<typename SignatureWithPortals>
class ArrayPortalCompositeVector
{
typedef vtkm::internal::FunctionInterface<SignatureWithPortals> PortalTypes;
typedef vtkm::Tuple<int, PortalTypes::ARITY> ComponentMapType;
public:
typedef typename PortalTypes::ResultType ValueType;
static const int NUM_COMPONENTS =
vtkm::VectorTraits<ValueType>::NUM_COMPONENTS;
BOOST_STATIC_ASSERT(NUM_COMPONENTS == PortalTypes::ARITY);
VTKM_EXEC_CONT_EXPORT
ArrayPortalCompositeVector() { }
VTKM_CONT_EXPORT
ArrayPortalCompositeVector(
const PortalTypes portals,
vtkm::Tuple<int, NUM_COMPONENTS> sourceComponents)
: Portals(portals), SourceComponents(sourceComponents) { }
VTKM_EXEC_EXPORT
vtkm::Id GetNumberOfValues() const {
return this->Portals.template GetParameter<1>().GetNumberOfValues();
}
VTKM_EXEC_EXPORT
ValueType Get(vtkm::Id index) const {
// This might be inefficient because we are copying all the portals only
// because they are coupled with the return value.
PortalTypes localPortals = this->Portals;
localPortals.InvokeExec(
detail::CompositeVectorSwizzleFunctor<ValueType>(this->SourceComponents),
detail::CompositeVectorPullValueFunctor<ValueType>(index));
return localPortals.GetReturnValue();
}
private:
PortalTypes Portals;
ComponentMapType SourceComponents;
};
/// \brief A "portal" that holds arrays to get components from.
///
/// This class takes place as the control-side portal within an
/// ArrayHandleCompositeVector. This is an incomplete implementation, so you
/// really can't use it to get values. However, between this and the
/// specialization ArrayTransfer, it's enough to get values to the execution
/// environment.
///
template<typename SignatureWithArrays>
class ArrayPortalCompositeVectorCont
{
typedef vtkm::internal::FunctionInterface<SignatureWithArrays>
FunctionInterfaceArrays;
public:
typedef typename FunctionInterfaceArrays::ResultType ValueType;
static const int NUM_COMPONENTS =
vtkm::VectorTraits<ValueType>::NUM_COMPONENTS;
typedef vtkm::Tuple<int, NUM_COMPONENTS> ComponentMapType;
// If you get a compile error here, it means you probably tried to create
// an ArrayHandleCompositeVector with a return type of a vector with a
// different number of components than the number of arrays given.
BOOST_STATIC_ASSERT(NUM_COMPONENTS == FunctionInterfaceArrays::ARITY);
VTKM_CONT_EXPORT
ArrayPortalCompositeVectorCont() : NumberOfValues(0) { }
VTKM_CONT_EXPORT
ArrayPortalCompositeVectorCont(
const FunctionInterfaceArrays &arrays,
const ComponentMapType &vtkmNotUsed(sourceComponents))
: NumberOfValues(arrays.template GetParameter<1>().GetNumberOfValues()) { }
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfValues() const {
return this->NumberOfValues;
}
VTKM_CONT_EXPORT
ValueType Get(vtkm::Id vtkmNotUsed(index)) const {
throw vtkm::cont::ErrorControlInternal("Not implemented.");
}
VTKM_CONT_EXPORT
void Set(vtkm::Id vtkmNotUsed(index), ValueType vtkmNotUsed(value)) {
throw vtkm::cont::ErrorControlInternal("Not implemented.");
}
// Not a viable type, but there is no implementation.
typedef ValueType *IteratorType;
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const {
throw vtkm::cont::ErrorControlInternal("Not implemented.");
}
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const {
throw vtkm::cont::ErrorControlInternal("Not implemented.");
}
private:
vtkm::Id NumberOfValues;
};
template<typename SignatureWithArrays>
struct ArrayContainerControlTagCompositeVector { };
/// A convenience class that provides a typedef to the appropriate tag for
/// a counting array container.
template<typename SignatureWithArrays>
struct ArrayHandleCompositeVectorTraits
{
typedef vtkm::cont::internal::ArrayContainerControlTagCompositeVector<
SignatureWithArrays> Tag;
typedef typename vtkm::internal::FunctionInterface<SignatureWithArrays>::ResultType
ValueType;
typedef vtkm::cont::internal::ArrayContainerControl<
ValueType, Tag> ContainerType;
};
// It may seem weird that this specialization throws an exception for
// everything, but that is because all the functionality is handled in the
// ArrayTransfer class.
template<typename SignatureWithArrays>
class ArrayContainerControl<
typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType,
vtkm::cont::internal::ArrayContainerControlTagCompositeVector<SignatureWithArrays> >
{
typedef vtkm::internal::FunctionInterface<SignatureWithArrays>
FunctionInterfaceWithArrays;
static const int NUM_COMPONENTS = FunctionInterfaceWithArrays::ARITY;
typedef vtkm::Tuple<int, NUM_COMPONENTS> ComponentMapType;
public:
typedef ArrayPortalCompositeVectorCont<SignatureWithArrays> PortalType;
typedef PortalType PortalConstType;
typedef typename PortalType::ValueType ValueType;
VTKM_CONT_EXPORT
ArrayContainerControl() : Valid(false) { }
VTKM_CONT_EXPORT
ArrayContainerControl(const FunctionInterfaceWithArrays &arrays,
const ComponentMapType &sourceComponents)
: Arrays(arrays), SourceComponents(sourceComponents), Valid(true)
{
arrays.ForEachCont(
detail::CheckArraySizeFunctor(this->GetNumberOfValues()));
}
VTKM_CONT_EXPORT
PortalType GetPortal() {
throw vtkm::cont::ErrorControlBadValue(
"Composite vector arrays are read only.");
}
VTKM_CONT_EXPORT
PortalConstType GetPortalConst() const {
if (!this->Valid)
{
throw vtkm::cont::ErrorControlBadValue(
"Tried to use an ArrayHandleCompositeHandle without dependent arrays.");
}
return PortalConstType(this->Arrays, this->SourceComponents);
}
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfValues() const {
if (!this->Valid)
{
throw vtkm::cont::ErrorControlBadValue(
"Tried to use an ArrayHandleCompositeHandle without dependent arrays.");
}
return this->Arrays.template GetParameter<1>().GetNumberOfValues();
}
VTKM_CONT_EXPORT
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues)) {
throw vtkm::cont::ErrorControlInternal(
"The allocate method for the composite vector control array "
"container should never have been called. The allocate is generally "
"only called by the execution array manager, and the array transfer "
"for the transform container should prevent the execution array "
"manager from being directly used.");
}
VTKM_CONT_EXPORT
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues)) {
throw vtkm::cont::ErrorControlBadValue(
"Composite vector arrays are read-only.");
}
VTKM_CONT_EXPORT
void ReleaseResources() {
if (this->Valid)
{
// TODO: Implement this.
}
}
VTKM_CONT_EXPORT
const FunctionInterfaceWithArrays &GetArrays() const {
VTKM_ASSERT_CONT(this->Valid);
return this->Arrays;
}
VTKM_CONT_EXPORT
const ComponentMapType &GetSourceComponents() const {
VTKM_ASSERT_CONT(this->Valid);
return this->SourceComponents;
}
private:
FunctionInterfaceWithArrays Arrays;
ComponentMapType SourceComponents;
bool Valid;
};
template<typename SignatureWithArrays, typename DeviceAdapterTag>
class ArrayTransfer<
typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType,
vtkm::cont::internal::ArrayContainerControlTagCompositeVector<SignatureWithArrays>,
DeviceAdapterTag>
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
typedef typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ContainerType
ContainerType;
typedef vtkm::internal::FunctionInterface<SignatureWithArrays>
FunctionWithArrays;
typedef typename FunctionWithArrays::template StaticTransformType<
detail::CompositeVectorArrayToPortalExec<DeviceAdapterTag> >::type
FunctionWithPortals;
typedef typename FunctionWithPortals::Signature SignatureWithPortals;
public:
typedef typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType
ValueType;
// These are not currently fully implemented.
typedef typename ContainerType::PortalType PortalControl;
typedef typename ContainerType::PortalConstType PortalConstControl;
typedef ArrayPortalCompositeVector<SignatureWithPortals> PortalExecution;
typedef ArrayPortalCompositeVector<SignatureWithPortals> PortalConstExecution;
VTKM_CONT_EXPORT
ArrayTransfer() : ContainerValid(false) { }
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfValues() const {
VTKM_ASSERT_CONT(this->ContainerValid);
return this->Container.GetNumberOfValues();
}
VTKM_CONT_EXPORT
void LoadDataForInput(PortalConstControl vtkmNotUsed(contPortal))
{
throw vtkm::cont::ErrorControlInternal(
"ArrayHandleCompositeVector in a bad state. "
"There must be a UserArray set, but how did that happen?");
}
VTKM_CONT_EXPORT
void LoadDataForInput(const ContainerType &controlArray)
{
this->Container = controlArray;
this->ContainerValid = true;
}
VTKM_CONT_EXPORT
void LoadDataForInPlace(ContainerType &vtkmNotUsed(controlArray))
{
throw vtkm::cont::ErrorControlBadValue(
"Composite vector arrays cannot be used for output or in place.");
}
VTKM_CONT_EXPORT
void AllocateArrayForOutput(ContainerType &vtkmNotUsed(controlArray),
vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorControlBadValue(
"Composite vector arrays cannot be used for output.");
}
VTKM_CONT_EXPORT
void RetrieveOutputData(ContainerType &vtkmNotUsed(controlArray)) const
{
throw vtkm::cont::ErrorControlBadValue(
"Composite vector arrays cannot be used for output.");
}
template<typename IteratorTypeControl>
VTKM_CONT_EXPORT
void CopyInto(IteratorTypeControl vtkmNotUsed(dest)) const
{
throw vtkm::cont::ErrorControlInternal(
"CopyInto not implemented for composite vector arrays.");
}
VTKM_CONT_EXPORT
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorControlBadValue(
"Composite vector arrays cannot be resized.");
}
VTKM_CONT_EXPORT
PortalExecution GetPortalExecution()
{
throw vtkm::cont::ErrorControlBadValue(
"Composite vector arrays are read-only. (Get the const portal.)");
}
VTKM_CONT_EXPORT
PortalConstExecution GetPortalConstExecution() const
{
VTKM_ASSERT_CONT(this->ContainerValid);
return
PortalConstExecution(
this->Container.GetArrays().StaticTransformCont(
detail::CompositeVectorArrayToPortalExec<DeviceAdapterTag>()),
this->Container.GetSourceComponents());
}
VTKM_CONT_EXPORT
void ReleaseResources() {
this->Container.ReleaseResources();
}
private:
bool ContainerValid;
ContainerType Container;
};
} // namespace internal
/// \brief An \c ArrayHandle that combines components from other arrays.
///
/// \c ArrayHandleCompositeVector is a specialization of \c ArrayHandle that
/// derives its content from other arrays. It takes up to 4 other \c
/// ArrayHandle objects and mimics an array that contains vectors with
/// components that come from these delegate arrays.
///
/// The easiest way to create and type an \c ArrayHandleCompositeVector is
/// to use the \c make_ArrayHandleCompositeVector functions.
///
template<typename Signature>
class ArrayHandleCompositeVector
: public vtkm::cont::ArrayHandle<
typename internal::ArrayHandleCompositeVectorTraits<Signature>::ValueType,
typename internal::ArrayHandleCompositeVectorTraits<Signature>::Tag>
{
typedef typename internal::ArrayHandleCompositeVectorTraits<Signature>::ContainerType
ArrayContainerControlType;
typedef typename internal::ArrayPortalCompositeVectorCont<Signature>::ComponentMapType
ComponentMapType;
public:
typedef vtkm::cont::ArrayHandle<
typename internal::ArrayHandleCompositeVectorTraits<Signature>::ValueType,
typename internal::ArrayHandleCompositeVectorTraits<Signature>::Tag>
Superclass;
typedef typename Superclass::ValueType ValueType;
VTKM_CONT_EXPORT
ArrayHandleCompositeVector() : Superclass() { }
VTKM_CONT_EXPORT
ArrayHandleCompositeVector(
const vtkm::internal::FunctionInterface<Signature> &arrays,
const ComponentMapType &sourceComponents)
: Superclass(ArrayContainerControlType(arrays, sourceComponents))
{ }
/// Template constructors for passing in types. You'll get weird compile
/// errors if the argument types do not actually match the types in the
/// signature.
///
template<typename ArrayHandleType1>
VTKM_CONT_EXPORT
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
int sourceComponent1)
: Superclass(ArrayContainerControlType(
vtkm::internal::make_FunctionInterface<ValueType>(array1),
ComponentMapType(sourceComponent1)))
{ }
template<typename ArrayHandleType1,
typename ArrayHandleType2>
VTKM_CONT_EXPORT
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
int sourceComponent1,
const ArrayHandleType2 &array2,
int sourceComponent2)
: Superclass(ArrayContainerControlType(
vtkm::internal::make_FunctionInterface<ValueType>(
array1, array2),
ComponentMapType(sourceComponent1,
sourceComponent2)))
{ }
template<typename ArrayHandleType1,
typename ArrayHandleType2,
typename ArrayHandleType3>
VTKM_CONT_EXPORT
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
int sourceComponent1,
const ArrayHandleType2 &array2,
int sourceComponent2,
const ArrayHandleType3 &array3,
int sourceComponent3)
: Superclass(ArrayContainerControlType(
vtkm::internal::make_FunctionInterface<ValueType>(
array1, array2, array3),
ComponentMapType(sourceComponent1,
sourceComponent2,
sourceComponent3)))
{ }
template<typename ArrayHandleType1,
typename ArrayHandleType2,
typename ArrayHandleType3,
typename ArrayHandleType4>
VTKM_CONT_EXPORT
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
int sourceComponent1,
const ArrayHandleType2 &array2,
int sourceComponent2,
const ArrayHandleType3 &array3,
int sourceComponent3,
const ArrayHandleType4 &array4,
int sourceComponent4)
: Superclass(ArrayContainerControlType(
vtkm::internal::make_FunctionInterface<ValueType>(
array1, array2, array3, array4),
ComponentMapType(sourceComponent1,
sourceComponent2,
sourceComponent3,
sourceComponent4)))
{ }
};
/// \brief Get the type for an ArrayHandleCompositeVector
///
/// The ArrayHandleCompositeVector has a difficult template specification.
/// Use this helper template to covert a list of array handle types to a
/// composite vector of these array handles. Here is a simple example.
///
/// \code{.cpp}
/// typedef vtkm::cont::ArrayHandleCompositeVector<
/// vtkm::cont::ArrayHandle<vtkm::Scalar>,
/// vtkm::cont::ArrayHandle<vtkm::Scalar> >::type OutArrayType;
/// OutArrayType outArray = vtkm::cont::make_ArrayHandleCompositeVector(a1,a2);
/// \endcode
///
template<typename ArrayHandleType1,
typename ArrayHandleType2 = void,
typename ArrayHandleType3 = void,
typename ArrayHandleType4 = void>
struct ArrayHandleCompositeVectorType
{
private:
typedef typename vtkm::VectorTraits<typename ArrayHandleType1::ValueType>::ComponentType
ComponentType;
typedef vtkm::Tuple<ComponentType,4> Signature(
ArrayHandleType1,ArrayHandleType2,ArrayHandleType3,ArrayHandleType4);
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
template<typename ArrayHandleType1,
typename ArrayHandleType2,
typename ArrayHandleType3>
struct ArrayHandleCompositeVectorType<
ArrayHandleType1,ArrayHandleType2,ArrayHandleType3>
{
private:
typedef typename vtkm::VectorTraits<typename ArrayHandleType1::ValueType>::ComponentType
ComponentType;
typedef vtkm::Tuple<ComponentType,3> Signature(
ArrayHandleType1,ArrayHandleType2,ArrayHandleType3);
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
template<typename ArrayHandleType1,
typename ArrayHandleType2>
struct ArrayHandleCompositeVectorType<ArrayHandleType1,ArrayHandleType2>
{
private:
typedef typename vtkm::VectorTraits<typename ArrayHandleType1::ValueType>::ComponentType
ComponentType;
typedef vtkm::Tuple<ComponentType,2> Signature(
ArrayHandleType1,ArrayHandleType2);
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
template<typename ArrayHandleType1>
struct ArrayHandleCompositeVectorType<ArrayHandleType1>
{
private:
typedef typename vtkm::VectorTraits<typename ArrayHandleType1::ValueType>::ComponentType
ComponentType;
typedef ComponentType Signature(ArrayHandleType1);
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
/// Create a composite vector array from other arrays.
///
template<typename ValueType1, typename Container1>
VTKM_CONT_EXPORT
typename ArrayHandleCompositeVectorType<
vtkm::cont::ArrayHandle<ValueType1,Container1> >::type
make_ArrayHandleCompositeVector(
const vtkm::cont::ArrayHandle<ValueType1,Container1> &array1,
int sourceComponent1)
{
return typename ArrayHandleCompositeVectorType<
vtkm::cont::ArrayHandle<ValueType1,Container1> >::type(array1,
sourceComponent1);
}
template<typename ValueType1, typename Container1,
typename ValueType2, typename Container2>
VTKM_CONT_EXPORT
typename ArrayHandleCompositeVectorType<
vtkm::cont::ArrayHandle<ValueType1,Container1>,
vtkm::cont::ArrayHandle<ValueType2,Container2> >::type
make_ArrayHandleCompositeVector(
const vtkm::cont::ArrayHandle<ValueType1,Container1> &array1,
int sourceComponent1,
const vtkm::cont::ArrayHandle<ValueType2,Container2> &array2,
int sourceComponent2)
{
return typename ArrayHandleCompositeVectorType<
vtkm::cont::ArrayHandle<ValueType1,Container1>,
vtkm::cont::ArrayHandle<ValueType2,Container2> >::type(array1,
sourceComponent1,
array2,
sourceComponent2);
}
template<typename ValueType1, typename Container1,
typename ValueType2, typename Container2,
typename ValueType3, typename Container3>
VTKM_CONT_EXPORT
typename ArrayHandleCompositeVectorType<
vtkm::cont::ArrayHandle<ValueType1,Container1>,
vtkm::cont::ArrayHandle<ValueType2,Container2>,
vtkm::cont::ArrayHandle<ValueType3,Container3> >::type
make_ArrayHandleCompositeVector(
const vtkm::cont::ArrayHandle<ValueType1,Container1> &array1,
int sourceComponent1,
const vtkm::cont::ArrayHandle<ValueType2,Container2> &array2,
int sourceComponent2,
const vtkm::cont::ArrayHandle<ValueType3,Container3> &array3,
int sourceComponent3)
{
return typename ArrayHandleCompositeVectorType<
vtkm::cont::ArrayHandle<ValueType1,Container1>,
vtkm::cont::ArrayHandle<ValueType2,Container2>,
vtkm::cont::ArrayHandle<ValueType3,Container3> >::type(array1,
sourceComponent1,
array2,
sourceComponent2,
array3,
sourceComponent3);
}
template<typename ValueType1, typename Container1,
typename ValueType2, typename Container2,
typename ValueType3, typename Container3,
typename ValueType4, typename Container4>
VTKM_CONT_EXPORT
typename ArrayHandleCompositeVectorType<
vtkm::cont::ArrayHandle<ValueType1,Container1>,
vtkm::cont::ArrayHandle<ValueType2,Container2>,
vtkm::cont::ArrayHandle<ValueType3,Container3>,
vtkm::cont::ArrayHandle<ValueType4,Container4> >::type
make_ArrayHandleCompositeVector(
const vtkm::cont::ArrayHandle<ValueType1,Container1> &array1,
int sourceComponent1,
const vtkm::cont::ArrayHandle<ValueType2,Container2> &array2,
int sourceComponent2,
const vtkm::cont::ArrayHandle<ValueType3,Container3> &array3,
int sourceComponent3,
const vtkm::cont::ArrayHandle<ValueType4,Container4> &array4,
int sourceComponent4)
{
return typename ArrayHandleCompositeVectorType<
vtkm::cont::ArrayHandle<ValueType1,Container1>,
vtkm::cont::ArrayHandle<ValueType2,Container2>,
vtkm::cont::ArrayHandle<ValueType3,Container3>,
vtkm::cont::ArrayHandle<ValueType4,Container4> >::type(array1,
sourceComponent1,
array2,
sourceComponent2,
array3,
sourceComponent3,
array4,
sourceComponent4);
}
}
} // namespace vtkm::cont
#endif //vtk_m_ArrayHandleCompositeVector_h

@ -118,11 +118,13 @@ class ArrayHandleCounting
> Superclass;
public:
VTKM_CONT_EXPORT
ArrayHandleCounting(CountingValueType startingValue, vtkm::Id length)
:Superclass(typename Superclass::PortalConstControl(startingValue, length))
{
}
VTKM_CONT_EXPORT
ArrayHandleCounting():Superclass() {}
};

@ -0,0 +1,158 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_ArrayHandleUniformPointCoordinates_h
#define vtk_m_cont_ArrayHandleUniformPointCoordinates_h
#include <vtkm/Extent.h>
#include <vtkm/cont/ArrayContainerControlImplicit.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/internal/IteratorFromArrayPortal.h>
namespace vtkm {
namespace cont {
namespace internal {
/// \brief An implicit array port that computes point coordinates for a uniform
/// grid.
///
class ArrayPortalUniformPointCoordinates
{
public:
typedef vtkm::Vector3 ValueType;
VTKM_EXEC_CONT_EXPORT
ArrayPortalUniformPointCoordinates() : NumberOfValues(0) { }
VTKM_EXEC_CONT_EXPORT
ArrayPortalUniformPointCoordinates(vtkm::Extent3 extent,
vtkm::Vector3 origin,
vtkm::Vector3 spacing)
: Extent(extent),
Dimensions(vtkm::ExtentPointDimensions(extent)),
NumberOfValues(vtkm::ExtentNumberOfPoints(extent)),
Origin(origin),
Spacing(spacing)
{ }
VTKM_EXEC_CONT_EXPORT
ArrayPortalUniformPointCoordinates(
const ArrayPortalUniformPointCoordinates &src)
: Extent(src.Extent),
Dimensions(src.Dimensions),
NumberOfValues(src.NumberOfValues),
Origin(src.Origin),
Spacing(src.Spacing)
{ }
VTKM_EXEC_CONT_EXPORT
ArrayPortalUniformPointCoordinates &
operator=(const ArrayPortalUniformPointCoordinates &src)
{
this->Extent = src.Extent;
this->Dimensions = src.Dimensions;
this->NumberOfValues = src.NumberOfValues;
this->Origin = src.Origin;
this->Spacing = src.Spacing;
return *this;
}
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
VTKM_EXEC_CONT_EXPORT
vtkm::Vector3 Get(vtkm::Id index) const {
return this->GetCoordinatesForTopologyIndex(
vtkm::ExtentPointFlatIndexToTopologyIndex(index, this->Extent));
}
VTKM_EXEC_CONT_EXPORT
vtkm::Id3 GetRange3() const { return this->Dimensions; }
VTKM_EXEC_CONT_EXPORT
vtkm::Vector3 Get(vtkm::Id3 index) const {
return this->GetCoordinatesForTopologyIndex(index + this->Extent.Min);
}
typedef vtkm::cont::internal::IteratorFromArrayPortal<
ArrayPortalUniformPointCoordinates> IteratorType;
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const {
return IteratorType(*this);
}
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const {
return IteratorType(*this, this->NumberOfValues);
}
private:
vtkm::Extent3 Extent;
vtkm::Id3 Dimensions;
vtkm::Id NumberOfValues;
vtkm::Vector3 Origin;
vtkm::Vector3 Spacing;
VTKM_EXEC_CONT_EXPORT
vtkm::Vector3 GetCoordinatesForTopologyIndex(vtkm::Id3 ijk) const {
return vtkm::Vector3(this->Origin[0] + this->Spacing[0]*ijk[0],
this->Origin[1] + this->Spacing[1]*ijk[1],
this->Origin[2] + this->Spacing[2]*ijk[2]);
}
};
} // namespace internal
/// ArrayHandleUniformPointCoordinates is a specialization of ArrayHandle. It
/// contains the information necessary to compute the point coordinates in a
/// uniform orthogonal grid (extent, origin, and spacing) and implicitly
/// computes these coordinates in its array portal.
///
class ArrayHandleUniformPointCoordinates
: public vtkm::cont::ArrayHandle<
vtkm::Vector3,
vtkm::cont::ArrayContainerControlTagImplicit<
internal::ArrayPortalUniformPointCoordinates> >
{
typedef vtkm::cont::ArrayHandle<
vtkm::Vector3,
vtkm::cont::ArrayContainerControlTagImplicit<
internal::ArrayPortalUniformPointCoordinates> > Superclass;
public:
VTKM_CONT_EXPORT
ArrayHandleUniformPointCoordinates() : Superclass() { }
VTKM_CONT_EXPORT
ArrayHandleUniformPointCoordinates(vtkm::Extent3 extent,
vtkm::Vector3 origin,
vtkm::Vector3 spacing)
: Superclass(
internal::ArrayPortalUniformPointCoordinates(extent, origin, spacing))
{ }
};
}
} // namespace vtkm::cont
#endif //vtk_+m_cont_ArrayHandleUniformPointCoordinates_h

@ -25,10 +25,16 @@ set(headers
ArrayContainerControlBasic.h
ArrayContainerControlImplicit.h
ArrayHandle.h
ArrayHandleCompositeVector.h
ArrayHandleCounting.h
ArrayHandleUniformPointCoordinates.h
ArrayPortal.h
Assert.h
ContainerListTag.h
DeviceAdapter.h
DeviceAdapterSerial.h
DynamicArrayHandle.h
DynamicPointCoordinates.h
Error.h
ErrorControl.h
ErrorControlAssert.h
@ -36,6 +42,9 @@ set(headers
ErrorControlInternal.h
ErrorControlOutOfMemory.h
ErrorExecution.h
PointCoordinatesArray.h
PointCoordinatesListTag.h
PointCoordinatesUniform.h
)
#-----------------------------------------------------------------------------

@ -0,0 +1,41 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_ContainerListTag_h
#define vtk_m_ContainerListTag_h
#ifndef VTKM_DEFAULT_CONTAINER_LIST_TAG
#define VTKM_DEFAULT_CONTAINER_LIST_TAG ::vtkm::cont::ContainerListTagBasic
#endif
#include <vtkm/ListTag.h>
#include <vtkm/cont/ArrayContainerControl.h>
#include <vtkm/cont/ArrayContainerControlBasic.h>
namespace vtkm {
namespace cont {
struct ContainerListTagBasic
: vtkm::ListTagBase<vtkm::cont::ArrayContainerControlTagBasic> { };
}
} // namespace vtkm::cont
#endif //vtk_m_ContainerListTag_h

@ -0,0 +1,336 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_DynamicArrayHandle_h
#define vtk_m_cont_DynamicArrayHandle_h
#include <vtkm/TypeListTag.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ContainerListTag.h>
#include <vtkm/cont/ErrorControlBadValue.h>
#include <vtkm/cont/internal/DynamicTransform.h>
#include <vtkm/cont/internal/SimplePolymorphicContainer.h>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/utility/enable_if.hpp>
namespace vtkm {
namespace cont {
namespace internal {
/// Behaves like (and is interchangable with) a DynamicArrayHandle. The
/// difference is that the list of types and list of containers to try when
/// calling CastAndCall is set to the class template arguments.
///
template<typename TypeList, typename ContainerList>
class DynamicArrayHandleCast;
} // namespace internal
/// \brief Holds an array handle without having to specify template parameters.
///
/// \c DynamicArrayHandle holds an \c ArrayHandle object using runtime
/// polymorphism to manage different value types and storage rather than
/// compile-time templates. This adds a programming convienience that helps
/// avoid a proliferation of templates. It also provides the management
/// necessary to interface VTK-m with data sources where types will not be
/// known until runtime.
///
/// To interface between the runtime polymorphism and the templated algorithms
/// in VTK-m, \c DynamicArrayHandle contains a method named \c CastAndCall that
/// will determine the correct type from some known list of types and
/// containers. This mechanism is used internally by VTK-m's worklet invocation
/// mechanism to determine the type when running algorithms.
///
/// By default, \c DynamicArrayHandle will assume that the value type in the
/// array matches one of the types specified by \c VTKM_DEFAULT_TYPE_LIST_TAG
/// and the container matches one of the tags specified by \c
/// VTKM_DEFAULT_CONTAINER_LIST_TAG. These lists can be changed by using the \c
/// ResetTypeList and \c ResetContainerList methods, respectively. It is
/// worthwhile to match these lists closely to the possible types that might be
/// used. If a type is missing you will get a runtime error. If there are more
/// types than necessary, then the template mechanism will create a lot of
/// object code that is never used, and keep in mind that the number of
/// combinations grows exponentally when using multiple \c DynamicArrayHandle
/// objects.
///
class DynamicArrayHandle
{
public:
VTKM_CONT_EXPORT
DynamicArrayHandle() { }
template<typename Type, typename Container>
VTKM_CONT_EXPORT
DynamicArrayHandle(const vtkm::cont::ArrayHandle<Type,Container> &array)
: ArrayContainer(new vtkm::cont::internal::SimplePolymorphicContainer<
vtkm::cont::ArrayHandle<Type,Container> >(array))
{ }
template<typename TypeList, typename ContainerList>
VTKM_CONT_EXPORT
DynamicArrayHandle(
const internal::DynamicArrayHandleCast<TypeList,ContainerList> &dynamicArray)
: ArrayContainer(dynamicArray.ArrayContainer) { }
/// Returns true if this array is of the provided type and uses the provided
/// container.
///
template<typename Type, typename Container>
VTKM_CONT_EXPORT
bool IsTypeAndContainer(Type = Type(), Container = Container()) const {
return (this->TryCastArrayContainer<Type,Container>() != NULL);
}
/// Returns this array cast to an ArrayHandle object of the given type and
/// container. Throws ErrorControlBadValue if the cast does not work. Use
/// IsTypeAndContainer to check if the cast can happen.
///
template<typename Type, typename Container>
VTKM_CONT_EXPORT
vtkm::cont::ArrayHandle<Type, Container>
CastToArrayHandle(Type = Type(), Container = Container()) const {
vtkm::cont::internal::SimplePolymorphicContainer<
vtkm::cont::ArrayHandle<Type,Container> > *container =
this->TryCastArrayContainer<Type,Container>();
if (container == NULL)
{
throw vtkm::cont::ErrorControlBadValue("Bad cast of dynamic array.");
}
return container->Item;
}
/// Changes the types to try casting to when resolving this dynamic array,
/// which is specified with a list tag like those in TypeListTag.h. Since C++
/// does not allow you to actually change the template arguments, this method
/// returns a new dynamic array object. This method is particularly useful to
/// narrow down (or expand) the types when using an array of particular
/// constraints.
///
template<typename NewTypeList>
VTKM_CONT_EXPORT
internal::DynamicArrayHandleCast<NewTypeList,VTKM_DEFAULT_CONTAINER_LIST_TAG>
ResetTypeList(NewTypeList = NewTypeList()) const {
return internal::DynamicArrayHandleCast<
NewTypeList,VTKM_DEFAULT_CONTAINER_LIST_TAG>(*this);
}
/// Changes the array containers to try casting to when resolving this
/// dynamic array, which is specified with a list tag like those in
/// ContainerListTag.h. Since C++ does not allow you to actually change the
/// template arguments, this method returns a new dynamic array object. This
/// method is particularly useful to narrow down (or expand) the types when
/// using an array of particular constraints.
///
template<typename NewContainerList>
VTKM_CONT_EXPORT
internal::DynamicArrayHandleCast<VTKM_DEFAULT_TYPE_LIST_TAG,NewContainerList>
ResetContainerList(NewContainerList = NewContainerList()) const {
return internal::DynamicArrayHandleCast<
VTKM_DEFAULT_TYPE_LIST_TAG,NewContainerList>(*this);
}
/// Attempts to cast the held array to a specific value type and container,
/// then call the given functor with the cast array. The types and containers
/// tried in the cast are those in the lists defined by
/// VTKM_DEFAULT_TYPE_LIST_TAG and VTKM_DEFAULT_CONTAINER_LIST_TAG,
/// respectively, unless they have been changed with a previous call to
/// ResetTypeList or ResetContainerList.
///
template<typename Functor>
VTKM_CONT_EXPORT
void CastAndCall(const Functor &f) const
{
this->CastAndCall(
f, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_CONTAINER_LIST_TAG());
}
/// A version of CastAndCall that tries specified lists of types and
/// containers.
///
template<typename Functor, typename TypeList, typename ContainerList>
VTKM_CONT_EXPORT
void CastAndCall(const Functor &f, TypeList, ContainerList) const;
private:
boost::shared_ptr<vtkm::cont::internal::SimplePolymorphicContainerBase>
ArrayContainer;
template<typename Type, typename Container>
VTKM_CONT_EXPORT
vtkm::cont::internal::SimplePolymorphicContainer<
vtkm::cont::ArrayHandle<Type,Container> > *
TryCastArrayContainer() const {
return
dynamic_cast<
vtkm::cont::internal::SimplePolymorphicContainer<
vtkm::cont::ArrayHandle<Type,Container> > *>(
this->ArrayContainer.get());
}
};
namespace detail {
template<typename Functor, typename Type>
struct DynamicArrayHandleTryContainer {
const DynamicArrayHandle Array;
const Functor &Function;
bool FoundCast;
VTKM_CONT_EXPORT
DynamicArrayHandleTryContainer(const DynamicArrayHandle &array,
const Functor &f)
: Array(array), Function(f), FoundCast(false) { }
template<typename Container>
VTKM_CONT_EXPORT
typename boost::enable_if<
typename vtkm::cont::internal::IsValidArrayHandle<Type,Container>::type
>::type
operator()(Container) {
if (!this->FoundCast &&
this->Array.IsTypeAndContainer(Type(), Container()))
{
this->Function(this->Array.CastToArrayHandle(Type(), Container()));
this->FoundCast = true;
}
}
template<typename Container>
VTKM_CONT_EXPORT
typename boost::disable_if<
typename vtkm::cont::internal::IsValidArrayHandle<Type,Container>::type
>::type
operator()(Container) {
// This type of array handle cannot exist, so do nothing.
}
};
template<typename Functor, typename ContainerList>
struct DynamicArrayHandleTryType {
const DynamicArrayHandle Array;
const Functor &Function;
bool FoundCast;
VTKM_CONT_EXPORT
DynamicArrayHandleTryType(const DynamicArrayHandle &array, const Functor &f)
: Array(array), Function(f), FoundCast(false) { }
template<typename Type>
VTKM_CONT_EXPORT
void operator()(Type) {
if (this->FoundCast) { return; }
typedef DynamicArrayHandleTryContainer<Functor, Type> TryContainerType;
TryContainerType tryContainer =
TryContainerType(this->Array, this->Function);
vtkm::ListForEach(tryContainer, ContainerList());
if (tryContainer.FoundCast)
{
this->FoundCast = true;
}
}
};
} // namespace detail
template<typename Functor, typename TypeList, typename ContainerList>
VTKM_CONT_EXPORT
void DynamicArrayHandle::CastAndCall(const Functor &f,
TypeList,
ContainerList) const
{
typedef detail::DynamicArrayHandleTryType<Functor, ContainerList> TryTypeType;
TryTypeType tryType = TryTypeType(*this, f);
vtkm::ListForEach(tryType, TypeList());
if (!tryType.FoundCast)
{
throw vtkm::cont::ErrorControlBadValue(
"Could not find appropriate cast for array in CastAndCall.");
}
}
namespace internal {
template<typename TypeList, typename ContainerList>
class DynamicArrayHandleCast : public vtkm::cont::DynamicArrayHandle
{
public:
VTKM_CONT_EXPORT
DynamicArrayHandleCast() : DynamicArrayHandle() { }
VTKM_CONT_EXPORT
DynamicArrayHandleCast(const vtkm::cont::DynamicArrayHandle &array)
: DynamicArrayHandle(array) { }
template<typename SrcTypeList, typename SrcContainerList>
VTKM_CONT_EXPORT
DynamicArrayHandleCast(
const DynamicArrayHandleCast<SrcTypeList,SrcContainerList> &array)
: DynamicArrayHandle(array) { }
template<typename NewTypeList>
VTKM_CONT_EXPORT
DynamicArrayHandleCast<NewTypeList,ContainerList>
ResetTypeList(NewTypeList = NewTypeList()) const {
return DynamicArrayHandleCast<NewTypeList,ContainerList>(*this);
}
template<typename NewContainerList>
VTKM_CONT_EXPORT
internal::DynamicArrayHandleCast<TypeList,NewContainerList>
ResetContainerList(NewContainerList = NewContainerList()) const {
return internal::DynamicArrayHandleCast<TypeList,NewContainerList>(*this);
}
template<typename Functor>
VTKM_CONT_EXPORT
void CastAndCall(const Functor &f) const
{
this->CastAndCall(f, TypeList(), ContainerList());
}
template<typename Functor, typename TL, typename CL>
VTKM_CONT_EXPORT
void CastAndCall(const Functor &f, TL, CL) const
{
this->DynamicArrayHandle::CastAndCall(f, TL(), CL());
}
};
template<>
struct DynamicTransformTraits<vtkm::cont::DynamicArrayHandle> {
typedef vtkm::cont::internal::DynamicTransformTagCastAndCall DynamicTag;
};
template<typename TypeList, typename ContainerList>
struct DynamicTransformTraits<
vtkm::cont::internal::DynamicArrayHandleCast<TypeList,ContainerList> >
{
typedef vtkm::cont::internal::DynamicTransformTagCastAndCall DynamicTag;
};
} // namespace internal
}
} // namespace vtkm::cont
#endif //vtk_m_cont_DynamicArrayHandle_h

@ -0,0 +1,388 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_DynamicPointCoordinates_h
#define vtk_m_cont_DynamicPointCoordinates_h
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/ErrorControlBadValue.h>
#include <vtkm/cont/PointCoordinatesArray.h>
#include <vtkm/cont/PointCoordinatesListTag.h>
#include <vtkm/cont/internal/DynamicTransform.h>
#include <boost/shared_ptr.hpp>
namespace vtkm {
namespace cont {
namespace internal {
/// Behaves like (and is interchangable with) a \c DynamicPointCoordinates. The
/// difference is that the lists of point coordinates, base types, and
/// containers to try when calling \c CastAndCall is set to the class template
/// arguments.
///
template<typename PointCoordinatesList,
typename TypeList,
typename ContainerList>
class DynamicPointCoordinatesCast;
} // namespace internal
/// \brief Holds point coordinates polymorphically.
///
/// The \c DynamicPointCoordinates holds a point coordinate field for a mesh.
/// Like a \c DynamicArrayHandle it contains a \c CastAndCall method that
/// allows it to interface with templated functions and will automatically be
/// converted on a worklet invoke.
///
/// \c DynamicPointCoordinates differes from \c DynamicArrayHandle in the type
/// of arrays it will check. Point coordinates are often defined as implicit
/// (uniform), semi-implicit (structured), unstructured, or some combination
/// thereof. Methods for defining point coordinates are captured in \c
/// PointCoordinates classes, and \c DynamicPointCoordinates polymorphically
/// stores one of these \c PointCoordinates objects.
///
/// By default, \c DynamicPointCoordinates will assume that the stored point
/// coordinates are of a type specified by \c
/// VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG. This can be overriden by using the
/// \c ResetPointCoordinatesList method.
///
/// Internally, some \c PointCoordinates objects will reference dynamic arrays.
/// Thus, \c DynamicPointCoordinates also maintains lists of types and
/// containers that these subarrays might use. These default to \c
/// VTKM_DEFAULT_TYPE_LIST_TAG and \c VTKM_DEFAULT_CONTAINER_LIST_TAG and can
/// be changed with the \c ResetTypeList and \c ResetContainerList methods.
///
class DynamicPointCoordinates
{
public:
VTKM_CONT_EXPORT
DynamicPointCoordinates() { }
/// Special constructor for the common case of using a basic array to store
/// point coordinates.
///
VTKM_CONT_EXPORT
DynamicPointCoordinates(const vtkm::cont::DynamicArrayHandle &array)
: PointCoordinatesContainer(new vtkm::cont::PointCoordinatesArray(array))
{ }
/// Special constructor for the common case of using a basic array to store
/// point coordinates.
///
template<typename Container>
VTKM_CONT_EXPORT
DynamicPointCoordinates(
const vtkm::cont::ArrayHandle<vtkm::Vector3,Container> &array)
: PointCoordinatesContainer(new vtkm::cont::PointCoordinatesArray(array))
{ }
/// Takes a concrete point coordinates class and stores it polymorphically.
/// Although the template will match any possible type, there is a check
/// to make sure that the type is a valid point coordinates class. If you get
/// a compile error in the check, follow the instantiation list to where the
/// constructor is called.
///
template<typename PointCoordinatesType>
VTKM_CONT_EXPORT
DynamicPointCoordinates(const PointCoordinatesType &pointCoordinates)
: PointCoordinatesContainer(new PointCoordinatesType(pointCoordinates))
{
VTKM_IS_POINT_COORDINATES(PointCoordinatesType);
}
/// Returns true if these point coordinates are stored in a \c
/// PointCoordinates class of the given type.
///
template<typename PointCoordinatesType>
VTKM_CONT_EXPORT
bool IsPointCoordinateType(PointCoordinatesType = PointCoordinatesType()) const
{
VTKM_IS_POINT_COORDINATES(PointCoordinatesType);
return (this->TryCastPointCoordinatesType<PointCoordinatesType>() != NULL);
}
/// Returns these point coordinates in a \c PointCoordinates class of the
/// given type. Throws \c ErrorControlBadValue if the cast does not work. Use
/// \c IsPointCoordinateType to check if the cast can happen.
///
template<typename PointCoordinatesType>
VTKM_CONT_EXPORT
const PointCoordinatesType &
CastToPointCoordinates(PointCoordinatesType = PointCoordinatesType()) const {
VTKM_IS_POINT_COORDINATES(PointCoordinatesType);
PointCoordinatesType *pointCoordinates =
this->TryCastPointCoordinatesType<PointCoordinatesType>();
if (pointCoordinates == NULL)
{
throw vtkm::cont::ErrorControlBadValue(
"Bad cast of dynamic point coordinates.");
}
return *pointCoordinates;
}
/// Changes the point coordinates objects to try casting to when resolving
/// dynamic arrays within the point coordinates container, which is specified
/// with a list tag like those in PointCoordinatesListTag.h. Since C++ does
/// not allow you to actually change the template arguments, this method
/// returns a new dynamic array object. This method is particularly useful to
/// narrow down (or expand) the types when using an array of particular
/// constraints.
///
template<typename NewPointCoordinatesList>
VTKM_CONT_EXPORT
internal::DynamicPointCoordinatesCast<
NewPointCoordinatesList,
VTKM_DEFAULT_TYPE_LIST_TAG,
VTKM_DEFAULT_CONTAINER_LIST_TAG>
ResetPointCoordinatesList(
NewPointCoordinatesList = NewPointCoordinatesList()) const {
return internal::DynamicPointCoordinatesCast<
NewPointCoordinatesList,
VTKM_DEFAULT_TYPE_LIST_TAG,
VTKM_DEFAULT_CONTAINER_LIST_TAG>(*this);
}
/// Changes the types to try casting to when resolving dynamic arrays within
/// the point coordinates container, which is specified with a list tag like
/// those in TypeListTag.h. Since C++ does not allow you to actually change
/// the template arguments, this method returns a new dynamic array object.
/// This method is particularly useful to narrow down (or expand) the types
/// when using an array of particular constraints.
///
template<typename NewTypeList>
VTKM_CONT_EXPORT
internal::DynamicPointCoordinatesCast<
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG,
NewTypeList,
VTKM_DEFAULT_CONTAINER_LIST_TAG>
ResetTypeList(NewTypeList = NewTypeList()) const {
return internal::DynamicPointCoordinatesCast<
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG,
NewTypeList,
VTKM_DEFAULT_CONTAINER_LIST_TAG>(*this);
}
/// Changes the array containers to try casting to when resolving dynamic
/// arrays within the point coordinates container, which is specified with a
/// list tag like those in ContainerListTag.h. Since C++ does not allow you
/// to actually change the template arguments, this method returns a new
/// dynamic array object. This method is particularly useful to narrow down
/// (or expand) the types when using an array of particular constraints.
///
template<typename NewContainerList>
VTKM_CONT_EXPORT
internal::DynamicPointCoordinatesCast<
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG,
VTKM_DEFAULT_TYPE_LIST_TAG,
NewContainerList>
ResetContainerList(NewContainerList = NewContainerList()) const {
return internal::DynamicPointCoordinatesCast<
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG,
VTKM_DEFAULT_TYPE_LIST_TAG,
NewContainerList>(*this);
}
/// Attempts to cast the held point coordinates to a specific array
/// representation and then call the given functor with the cast array. This
/// is generally done in two parts. The first part finds the concrete type of
/// \c PointCoordinates object by trying all those in \c
/// VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG.
///
/// The second part then asks the concrete \c PointCoordinates object to cast
/// and call to a concrete array. This second cast might rely on \c
/// VTKM_DEFAULT_TYPE_LIST_TAG and \c VTKM_DEFAULT_CONTAINER_LIST_TAG.
///
template<typename Functor>
VTKM_CONT_EXPORT
void CastAndCall(const Functor &f) const
{
this->CastAndCall(f,
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG(),
VTKM_DEFAULT_TYPE_LIST_TAG(),
VTKM_DEFAULT_CONTAINER_LIST_TAG());
}
/// A version of \c CastAndCall that tries specified lists of point
/// coordinates, types, and containers.
///
template<typename Functor,
typename PointCoordinatesList,
typename TypeList,
typename ContainerList>
VTKM_CONT_EXPORT
void CastAndCall(const Functor &f,
PointCoordinatesList,
TypeList,
ContainerList) const;
private:
boost::shared_ptr<vtkm::cont::internal::PointCoordinatesBase>
PointCoordinatesContainer;
template<typename PointCoordinatesType>
VTKM_CONT_EXPORT
PointCoordinatesType *
TryCastPointCoordinatesType() const {
VTKM_IS_POINT_COORDINATES(PointCoordinatesType);
return dynamic_cast<PointCoordinatesType *>(
this->PointCoordinatesContainer.get());
}
};
namespace detail {
template<typename Functor, typename TypeList, typename ContainerList>
struct DynamicPointCoordinatesTryContainer
{
const DynamicPointCoordinates PointCoordinates;
const Functor &Function;
bool FoundCast;
VTKM_CONT_EXPORT
DynamicPointCoordinatesTryContainer(
const DynamicPointCoordinates &pointCoordinates,
const Functor &f)
: PointCoordinates(pointCoordinates), Function(f), FoundCast(false)
{ }
template<typename PointCoordinatesType>
VTKM_CONT_EXPORT
void operator()(PointCoordinatesType) {
if (!this->FoundCast &&
this->PointCoordinates.IsPointCoordinateType(PointCoordinatesType()))
{
PointCoordinatesType pointCoordinates =
this->PointCoordinates.CastToPointCoordinates(PointCoordinatesType());
pointCoordinates.CastAndCall(this->Function, TypeList(), ContainerList());
this->FoundCast = true;
}
}
};
} // namespace detail
template<typename Functor,
typename PointCoordinatesList,
typename TypeList,
typename ContainerList>
VTKM_CONT_EXPORT
void DynamicPointCoordinates::CastAndCall(const Functor &f,
PointCoordinatesList,
TypeList,
ContainerList) const
{
typedef detail::DynamicPointCoordinatesTryContainer<
Functor, TypeList, ContainerList> TryTypeType;
TryTypeType tryType = TryTypeType(*this, f);
vtkm::ListForEach(tryType, PointCoordinatesList());
if (!tryType.FoundCast)
{
throw vtkm::cont::ErrorControlBadValue(
"Could not find appropriate cast for point coordinates in CastAndCall.");
}
}
namespace internal {
template<typename PointCoordinatesList,
typename TypeList,
typename ContainerList>
class DynamicPointCoordinatesCast : public vtkm::cont::DynamicPointCoordinates
{
public:
VTKM_CONT_EXPORT
DynamicPointCoordinatesCast() : DynamicPointCoordinates() { }
VTKM_CONT_EXPORT
DynamicPointCoordinatesCast(const vtkm::cont::DynamicPointCoordinates &coords)
: DynamicPointCoordinates(coords) { }
template<typename SrcPointCoordinatesList,
typename SrcTypeList,
typename SrcContainerList>
VTKM_CONT_EXPORT
DynamicPointCoordinatesCast(
const DynamicPointCoordinatesCast<SrcPointCoordinatesList,SrcTypeList,SrcContainerList> &coords)
: DynamicPointCoordinates(coords)
{ }
template<typename NewPointCoordinatesList>
VTKM_CONT_EXPORT
DynamicPointCoordinatesCast<NewPointCoordinatesList,TypeList,ContainerList>
ResetPointCoordinatesList(
NewPointCoordinatesList = NewPointCoordinatesList()) const {
return DynamicPointCoordinatesCast<
NewPointCoordinatesList,TypeList,ContainerList>(*this);
}
template<typename NewTypeList>
VTKM_CONT_EXPORT
DynamicPointCoordinatesCast<PointCoordinatesList,NewTypeList,ContainerList>
ResetTypeList(NewTypeList = NewTypeList()) const {
return DynamicPointCoordinatesCast<
PointCoordinatesList,NewTypeList,ContainerList>(*this);
}
template<typename NewContainerList>
VTKM_CONT_EXPORT
DynamicPointCoordinatesCast<PointCoordinatesList,TypeList,NewContainerList>
ResetContainerList(NewContainerList = NewContainerList()) const {
return DynamicPointCoordinatesCast<
PointCoordinatesList,TypeList,NewContainerList>(*this);
}
template<typename Functor>
VTKM_CONT_EXPORT
void CastAndCall(const Functor &f) const
{
this->CastAndCall(f, PointCoordinatesList(), TypeList(), ContainerList());
}
template<typename Functor, typename PCL, typename TL, typename CL>
VTKM_CONT_EXPORT
void CastAndCall(const Functor &f, PCL, TL, CL) const
{
this->DynamicPointCoordinates::CastAndCall(f, PCL(), TL(), CL());
}
};
template<>
struct DynamicTransformTraits<vtkm::cont::DynamicPointCoordinates> {
typedef vtkm::cont::internal::DynamicTransformTagCastAndCall DynamicTag;
};
template<typename PointCoordinatesList,
typename TypeList,
typename ContainerList>
struct DynamicTransformTraits<
vtkm::cont::internal::DynamicPointCoordinatesCast<
PointCoordinatesList,TypeList,ContainerList> >
{
typedef vtkm::cont::internal::DynamicTransformTagCastAndCall DynamicTag;
};
} // namespace internal
}
} // namespace vtkm::cont
#endif //vtk_m_cont_DynamicPointCoordinates_h

@ -0,0 +1,75 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_PointCoordinatesArray_h
#define vtk_m_cont_PointCoordinatesArray_h
#include <vtkm/TypeListTag.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/internal/PointCoordinatesBase.h>
namespace vtkm {
namespace cont {
/// \brief Point coordinates stored in a \c Vector3 array.
///
/// The \c PointCoordinatesArray class is a simple PointCoordinates class
/// that stores the point coordinates in a single array. The array is managed
/// by a \c DynamicArrayHandle.
///
/// Like other PointCoordinates classes, \c PointCoordinatesArray is intended
/// to be used in conjunction with \c DynamicPointCoordinates.
///
class PointCoordinatesArray : public internal::PointCoordinatesBase
{
public:
VTKM_CONT_EXPORT
PointCoordinatesArray() { }
VTKM_CONT_EXPORT
PointCoordinatesArray(const vtkm::cont::DynamicArrayHandle &array)
: Array(array) { }
template<typename Container>
VTKM_CONT_EXPORT
PointCoordinatesArray(
const vtkm::cont::ArrayHandle<vtkm::Vector3,Container> &array)
: Array(array) { }
/// In this \c CastAndCall, \c TypeList is ignored. All point coordinates are
/// expressed as Vector3, so that must be how the array is represented.
///
template<typename Functor, typename TypeList, typename ContainerList>
VTKM_CONT_EXPORT
void CastAndCall(const Functor &f, TypeList, ContainerList) const
{
this->Array.CastAndCall(f, vtkm::TypeListTagVector3(), ContainerList());
}
private:
vtkm::cont::DynamicArrayHandle Array;
};
}
} // namespace vtkm::cont
#endif //vtk_m_cont_PointCoordinatesArray_h

@ -0,0 +1,52 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_PointCoordinatesListTag_h
#define vtk_m_cont_PointCoordinatesListTag_h
#ifndef VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG
#define VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG \
::vtkm::cont::PointCoordinatesListTagCommon
#endif
#include <vtkm/ListTag.h>
#include <vtkm/cont/PointCoordinatesArray.h>
#include <vtkm/cont/PointCoordinatesUniform.h>
namespace vtkm {
namespace cont {
struct PointCoordinatesListTagArray :
vtkm::ListTagBase<vtkm::cont::PointCoordinatesArray> { };
struct PointCoordinatesListTagUniform :
vtkm::ListTagBase<vtkm::cont::PointCoordinatesUniform> { };
/// A list of the most commonly used point coordinate types. Includes \c
/// PointCoordinatesArray.
///
struct PointCoordinatesListTagCommon
: vtkm::ListTagBase2<
vtkm::cont::PointCoordinatesArray,
vtkm::cont::PointCoordinatesUniform>
{ };
}
} // namespace vtkm::cont
#endif //vtk_m_cont_PointCoordinatesListTag_h

@ -0,0 +1,70 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_PointCoordinatesUniform_h
#define vtk_m_cont_PointCoordinatesUniform_h
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/internal/PointCoordinatesBase.h>
namespace vtkm {
namespace cont {
/// \brief Implicitly defined uniform point coordinates.
///
/// The \c PointCoordinatesUniform class is a PointCoordinates class that
/// implicitly defines the points for a uniform rectilinear grid of data
/// (defined by an extent, an origin, and spacing in each dimension).
///
/// Like other PointCoordinates classes, \c PointCoordinatesArray is intended
/// to be used in conjunction with \c DynamicPointCoordinates.
///
class PointCoordinatesUniform : public internal::PointCoordinatesBase
{
public:
VTKM_CONT_EXPORT
PointCoordinatesUniform() { }
VTKM_CONT_EXPORT
PointCoordinatesUniform(const vtkm::Extent3 &extent,
const vtkm::Vector3 &origin,
const vtkm::Vector3 &spacing)
: Array(extent, origin, spacing)
{ }
/// In this \c CastAndCall, both \c TypeList and \c ContainerList are
/// ignored. All point coordinates are expressed as Vector3, so that must be
/// how the array is represented.
///
template<typename Functor, typename TypeList, typename ContainerList>
VTKM_CONT_EXPORT
void CastAndCall(const Functor &f, TypeList, ContainerList) const
{
f(this->Array);
}
private:
vtkm::cont::ArrayHandleUniformPointCoordinates Array;
};
}
} // namespace vtkm::cont
#endif //vtk_m_cont_PointCoordinatesUniform_h

@ -32,7 +32,10 @@ set(headers
DeviceAdapterError.h
DeviceAdapterTag.h
DeviceAdapterTagSerial.h
DynamicTransform.h
IteratorFromArrayPortal.h
PointCoordinatesBase.h
SimplePolymorphicContainer.h
)
vtkm_declare_headers(${headers})

@ -0,0 +1,121 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_internal_DynamicTransform_h
#define vtk_m_cont_internal_DynamicTransform_h
#include "vtkm/internal/ExportMacros.h"
namespace vtkm {
namespace cont {
namespace internal {
namespace detail {
template<typename ContinueFunctor>
struct DynamicArrayTransformCastAndCall
{
const ContinueFunctor &Continue;
VTKM_CONT_EXPORT
DynamicArrayTransformCastAndCall(const ContinueFunctor &continueFunc)
: Continue(continueFunc) { }
template<typename T>
VTKM_CONT_EXPORT
void operator()(const T &x) const {
this->Continue(x);
}
};
} // namespace detail
/// Tag used to identify an object that is a dynamic object that contains a
/// CastAndCall method that iterates over all possible dynamic choices to run
/// templated code.
///
struct DynamicTransformTagCastAndCall { };
/// Tag used to identify an object that is a static object that, when used with
/// a \c DynamicTransform should just pass itself as a concrete object.
///
struct DynamicTransformTagStatic { };
/// A traits class that identifies whether an object used in a \c
/// DynamicTransform should use a \c CastAndCall functionality or treated as a
/// static object. The default implementation identifies the object as static
/// (as most objects are bound to be). Dynamic objects that implement
/// \c CastAndCall should specialize (or partially specialize) this traits class
/// to identify the object as dynamic. VTK-m classes like \c DynamicArray are
/// already specialized.
///
template<typename T>
struct DynamicTransformTraits {
/// A type set to either \c DynamicTransformTagStatic or \c
/// DynamicTransformTagCastAndCall. The default implementation is set to \c
/// DynamicTransformTagStatic. Dynamic objects that implement \c CastAndCall
/// should specialize this class redefine it to \c
/// DynamicTransformTagCastAndCall.
///
typedef vtkm::cont::internal::DynamicTransformTagStatic DynamicTag;
};
/// This functor can be used as the transform in the \c DynamicTransformCont
/// method of \c FunctionInterface. It will allow dynamic objects like
/// \c DynamicArray to be cast to their concrete types for templated operation.
///
struct DynamicTransform
{
template<typename InputType, typename ContinueFunctor>
VTKM_CONT_EXPORT
void operator()(const InputType &input,
const ContinueFunctor &continueFunc) const
{
this->DoTransform(
input,
continueFunc,
typename vtkm::cont::internal::DynamicTransformTraits<InputType>::DynamicTag());
}
private:
template<typename InputType, typename ContinueFunctor>
VTKM_CONT_EXPORT
void DoTransform(const InputType &input,
const ContinueFunctor &continueFunc,
vtkm::cont::internal::DynamicTransformTagStatic) const
{
continueFunc(input);
}
template<typename InputType, typename ContinueFunctor>
VTKM_CONT_EXPORT
void DoTransform(const InputType &dynamicInput,
const ContinueFunctor &continueFunc,
vtkm::cont::internal::DynamicTransformTagCastAndCall) const
{
dynamicInput.CastAndCall(
detail::DynamicArrayTransformCastAndCall<ContinueFunctor>(continueFunc));
}
};
}
}
} // namespace vtkm::cont::internal
#endif //vtk_m_cont_internal_DynamicTransform_h

@ -0,0 +1,78 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_internal_PointCoordinatesBase_h
#define vtk_m_cont_internal_PointCoordinatesBase_h
#include <vtkm/Types.h>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_base_of.hpp>
/// Checks that the argument is a proper \c PointCoordinates class. This is a
/// handy concept check for functions and classes to make sure that a template
/// argument is actually point coordinates. (You can get weird errors elsewhere
/// in the code when a mistake is made.)
#define VTKM_IS_POINT_COORDINATES(pctype) \
BOOST_STATIC_ASSERT_MSG( \
::vtkm::cont::internal::IsValidPointCoordinates<pctype>::type::value, \
"Provided type is not a valid VTK-m PointCoordinates type.")
namespace vtkm {
namespace cont {
namespace internal {
/// \brief Superclass for point coordinates classes.
///
/// \c PointCoordinatesBase is a simple superclass for all point coordinates
/// classes (by convention named \c PointCoordinates___).
///
/// The most important feature of this base class is to provide a common class
/// to perform a compile-time check to make sure a templated class is in fact
/// supposed to be a point coordinate class. (It is assumed that the subclass
/// will implement the expected methods.)
///
/// The second feature of this base class is to provide a type to perform safe
/// up and down casts, although this is easy to get around.
///
class PointCoordinatesBase
{
public:
// It is important to declare the destructor virtual so that subclasses will
// be properly destroyed.
virtual ~PointCoordinatesBase() { }
};
/// Checks to see if the given type is a valid point coordinates class. This
/// check is compatable with the Boost meta-template programming library (MPL).
/// It contains a typedef named type that is either boost::mpl::true_ or
/// boost::mpl::false_. Both of these have a typedef named value with the
/// respective boolean value.
///
template<typename Type>
struct IsValidPointCoordinates {
typedef typename boost::is_base_of<
vtkm::cont::internal::PointCoordinatesBase,Type>::type type;
};
}
}
} // namespace vtkm::cont::internal
#endif //vtk_m_cont_internal_PointCoordinatesBase_h

@ -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 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_internal_SimplePolymorphicContainer_h
#define vtk_m_cont_internal_SimplePolymorphicContainer_h
#include <vtkm/Types.h>
namespace vtkm {
namespace cont {
namespace internal {
/// \brief Base class for SimplePolymorphicContainer
///
struct SimplePolymorphicContainerBase {
virtual ~SimplePolymorphicContainerBase() { }
};
/// \brief Simple object container that can use C++ run-time type information.
///
/// The SimplePolymorphicContainer is a trivial structure that contains a
/// single object. The intention is to be able to pass around a pointer to the
/// superclass SimplePolymorphicContainerBase to methods that cannot know the
/// full type of the object at run-time. This is roughly equivalent to passing
/// around a void* except that C++ will capture run-time type information that
/// allows for safer dynamic downcasts.
///
template<typename T>
struct SimplePolymorphicContainer : public SimplePolymorphicContainerBase
{
T Item;
VTKM_CONT_EXPORT
SimplePolymorphicContainer() : Item() { }
VTKM_CONT_EXPORT
SimplePolymorphicContainer(const T &src) : Item(src) { }
};
}
}
} // namespace vtkm::cont::internal
#endif //vtk_m_cont_internal_SimplePolymorphicContainer_h

@ -22,6 +22,7 @@
set(unit_tests
UnitTestArrayManagerExecutionShareWithControl.cxx
UnitTestArrayPortalFromIterators.cxx
UnitTestDynamicTransform.cxx
UnitTestIteratorFromArrayPortal.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})

@ -0,0 +1,145 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include "vtkm/cont/internal/DynamicTransform.h"
#include "vtkm/cont/ArrayHandle.h"
#include "vtkm/cont/DynamicArrayHandle.h"
#include "vtkm/cont/DynamicPointCoordinates.h"
#include "vtkm/internal/FunctionInterface.h"
#include "vtkm/cont/testing/Testing.h"
namespace {
static int g_FunctionCalls;
#define TRY_TRANSFORM(expr) \
g_FunctionCalls = 0; \
expr; \
VTKM_TEST_ASSERT(g_FunctionCalls == 1, "Functor not called correctly.")
struct TypeListTagString : vtkm::ListTagBase<std::string> { };
struct ScalarFunctor {
void operator()(vtkm::Scalar) const {
std::cout << " In Scalar functor." << std::endl;
g_FunctionCalls++;
}
};
struct ArrayHandleScalarFunctor {
template<typename T>
void operator()(const vtkm::cont::ArrayHandle<T> &) const {
VTKM_TEST_FAIL("Called wrong form of functor operator.");
}
void operator()(const vtkm::cont::ArrayHandle<vtkm::Scalar> &) const {
std::cout << " In ArrayHandle<Scalar> functor." << std::endl;
g_FunctionCalls++;
}
};
struct ArrayHandleStringFunctor {
void operator()(const vtkm::cont::ArrayHandle<std::string> &) const {
std::cout << " In ArrayHandle<string> functor." << std::endl;
g_FunctionCalls++;
}
};
struct FunctionInterfaceFunctor {
template<typename Signature>
void operator()(const vtkm::internal::FunctionInterface<Signature> &) const {
VTKM_TEST_FAIL("Called wrong form of functor operator.");
}
void operator()(
const vtkm::internal::FunctionInterface<
void(vtkm::cont::ArrayHandle<vtkm::Scalar>,
vtkm::cont::ArrayHandle<vtkm::Scalar>,
vtkm::cont::ArrayHandle<std::string>,
vtkm::cont::ArrayHandleUniformPointCoordinates)> &) const {
std::cout << " In FunctionInterface<...> functor." << std::endl;
g_FunctionCalls++;
}
};
void TestBasicTransform()
{
std::cout << "Testing basic transform." << std::endl;
vtkm::cont::internal::DynamicTransform transform;
std::cout << " Trying with simple scalar." << std::endl;
TRY_TRANSFORM(transform(vtkm::Scalar(5), ScalarFunctor()));
std::cout << " Trying with basic scalar array." << std::endl;
vtkm::cont::ArrayHandle<vtkm::Scalar> concreteArray;
TRY_TRANSFORM(transform(concreteArray, ArrayHandleScalarFunctor()));
std::cout << " Trying scalar dynamic array." << std::endl;
vtkm::cont::DynamicArrayHandle dynamicArray = concreteArray;
TRY_TRANSFORM(transform(dynamicArray, ArrayHandleScalarFunctor()));
std::cout << " Trying with unusual (string) dynamic array." << std::endl;
dynamicArray = vtkm::cont::ArrayHandle<std::string>();
TRY_TRANSFORM(transform(dynamicArray.ResetTypeList(TypeListTagString()),
ArrayHandleStringFunctor()));
}
void TestFunctionTransform()
{
std::cout << "Testing transforms in FunctionInterface." << std::endl;
vtkm::cont::ArrayHandle<vtkm::Scalar> scalarArray;
vtkm::cont::ArrayHandle<std::string> stringArray;
vtkm::cont::ArrayHandleUniformPointCoordinates pointCoordinatesArray;
std::cout << " Trying basic functor call w/o transform (make sure it works)."
<< std::endl;
TRY_TRANSFORM(FunctionInterfaceFunctor()(
vtkm::internal::make_FunctionInterface<void>(
scalarArray,
scalarArray,
stringArray,
pointCoordinatesArray)));
std::cout << " Trying dynamic cast" << std::endl;
TRY_TRANSFORM(
vtkm::internal::make_FunctionInterface<void>(
scalarArray,
vtkm::cont::DynamicArrayHandle(scalarArray),
vtkm::cont::DynamicArrayHandle(stringArray).ResetTypeList(TypeListTagString()),
vtkm::cont::DynamicPointCoordinates(vtkm::cont::PointCoordinatesUniform()))
.DynamicTransformCont(vtkm::cont::internal::DynamicTransform(),
FunctionInterfaceFunctor()));
}
void TestDynamicTransform()
{
TestBasicTransform();
TestFunctionTransform();
}
} // anonymous namespace
int UnitTestDynamicTransform(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestDynamicTransform);
}

@ -29,11 +29,17 @@ set(unit_tests
UnitTestArrayContainerControlBasic.cxx
UnitTestArrayContainerControlImplicit.cxx
UnitTestArrayHandle.cxx
UnitTestArrayHandleCompositeVector.cxx
UnitTestArrayHandleCounting.cxx
UnitTestArrayHandleUniformPointCoordinates.cxx
UnitTestContainerListTag.cxx
UnitTestContTesting.cxx
UnitTestDeviceAdapterAlgorithmDependency.cxx
UnitTestDeviceAdapterAlgorithmGeneral.cxx
UnitTestDeviceAdapterSerial.cxx
UnitTestDynamicArrayHandle.cxx
UnitTestDynamicPointCoordinates.cxx
UnitTestPointCoordinates.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})

@ -0,0 +1,313 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
// Make sure ArrayHandleCompositeVector does not rely on default container or
// device adapter.
#define VTKM_ARRAY_CONTAINER_CONTROL VTKM_ARRAY_CONTAINER_CONTROL_ERROR
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_ERROR
#include <vtkm/cont/ArrayHandleCompositeVector.h>
#include <vtkm/VectorTraits.h>
#include <vtkm/cont/ArrayContainerControlBasic.h>
#include <vtkm/cont/DeviceAdapterSerial.h>
#include <vtkm/cont/testing/Testing.h>
#include <vector>
namespace {
const vtkm::Id ARRAY_SIZE = 10;
typedef vtkm::cont::ArrayContainerControlTagBasic Container;
vtkm::Scalar TestValue(vtkm::Id index, int inComponentIndex, int inArrayId)
{
return index + vtkm::Scalar(0.1)*inComponentIndex + vtkm::Scalar(0.01)*inArrayId;
}
template<typename ValueType>
vtkm::cont::ArrayHandle<ValueType, Container>
MakeInputArray(int arrayId)
{
typedef vtkm::VectorTraits<ValueType> VTraits;
// Create a buffer with valid test values.
ValueType buffer[ARRAY_SIZE];
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
for (int componentIndex = 0;
componentIndex < VTraits::NUM_COMPONENTS;
componentIndex++)
{
VTraits::SetComponent(buffer[index],
componentIndex,
TestValue(index, componentIndex, arrayId));
}
}
// Make an array handle that points to this buffer.
typedef vtkm::cont::ArrayHandle<ValueType, Container> ArrayHandleType;
ArrayHandleType bufferHandle =
vtkm::cont::make_ArrayHandle(buffer, ARRAY_SIZE, Container());
// When this function returns, the array is going to go out of scope, which
// will invalidate the array handle we just created. So copy to a new buffer
// that will stick around after we return.
ArrayHandleType copyHandle;
vtkm::cont::DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagSerial>::Copy(
bufferHandle, copyHandle);
return copyHandle;
}
template<typename ValueType, typename C>
void CheckArray(const vtkm::cont::ArrayHandle<ValueType,C> &outArray,
const int *inComponents,
const int *inArrayIds)
{
// ArrayHandleCompositeVector currently does not implement the ability to
// get to values on the control side, so copy to an array that is accessible.
typedef vtkm::cont::ArrayHandle<ValueType, Container> ArrayHandleType;
ArrayHandleType arrayCopy;
vtkm::cont::DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagSerial>::Copy(
outArray, arrayCopy);
typename ArrayHandleType::PortalConstControl portal =
arrayCopy.GetPortalConstControl();
typedef vtkm::VectorTraits<ValueType> VTraits;
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
ValueType retreivedValue = portal.Get(index);
for (int componentIndex = 0;
componentIndex < VTraits::NUM_COMPONENTS;
componentIndex++)
{
vtkm::Scalar retrievedComponent =
VTraits::GetComponent(retreivedValue, componentIndex);
vtkm::Scalar expectedComponent = TestValue(index,
inComponents[componentIndex],
inArrayIds[componentIndex]);
VTKM_TEST_ASSERT(retrievedComponent == expectedComponent,
"Got bad value.");
}
}
}
template<int inComponents>
void TryScalarArray()
{
std::cout << "Creating a scalar array from one of "
<< inComponents << " components." << std::endl;
typedef vtkm::Tuple<vtkm::Scalar,inComponents> InValueType;
typedef vtkm::cont::ArrayHandle<InValueType, Container> InArrayType;
int inArrayId = 0;
InArrayType inArray = MakeInputArray<InValueType>(inArrayId);
typedef typename vtkm::cont::ArrayHandleCompositeVectorType<InArrayType>::type
OutArrayType;
for (int inComponentIndex = 0;
inComponentIndex < inComponents;
inComponentIndex++)
{
OutArrayType outArray =
vtkm::cont::make_ArrayHandleCompositeVector(inArray, inComponentIndex);
CheckArray(outArray, &inComponentIndex, &inArrayId);
}
}
template<typename T1, typename T2, typename T3, typename T4>
void TryVector4(vtkm::cont::ArrayHandle<T1,Container> array1,
vtkm::cont::ArrayHandle<T2,Container> array2,
vtkm::cont::ArrayHandle<T3,Container> array3,
vtkm::cont::ArrayHandle<T4,Container> array4)
{
int arrayIds[4] = {0, 1, 2, 3};
int inComponents[4];
for (inComponents[0] = 0;
inComponents[0] < vtkm::VectorTraits<T1>::NUM_COMPONENTS;
inComponents[0]++)
{
for (inComponents[1] = 0;
inComponents[1] < vtkm::VectorTraits<T2>::NUM_COMPONENTS;
inComponents[1]++)
{
for (inComponents[2] = 0;
inComponents[2] < vtkm::VectorTraits<T3>::NUM_COMPONENTS;
inComponents[2]++)
{
for (inComponents[3] = 0;
inComponents[3] < vtkm::VectorTraits<T4>::NUM_COMPONENTS;
inComponents[3]++)
{
CheckArray(
vtkm::cont::make_ArrayHandleCompositeVector(
array1, inComponents[0],
array2, inComponents[1],
array3, inComponents[2],
array4, inComponents[3]),
inComponents,
arrayIds);
}
}
}
}
}
template<typename T1, typename T2, typename T3>
void TryVector3(vtkm::cont::ArrayHandle<T1,Container> array1,
vtkm::cont::ArrayHandle<T2,Container> array2,
vtkm::cont::ArrayHandle<T3,Container> array3)
{
int arrayIds[3] = {0, 1, 2};
int inComponents[3];
for (inComponents[0] = 0;
inComponents[0] < vtkm::VectorTraits<T1>::NUM_COMPONENTS;
inComponents[0]++)
{
for (inComponents[1] = 0;
inComponents[1] < vtkm::VectorTraits<T2>::NUM_COMPONENTS;
inComponents[1]++)
{
for (inComponents[2] = 0;
inComponents[2] < vtkm::VectorTraits<T3>::NUM_COMPONENTS;
inComponents[2]++)
{
CheckArray(
vtkm::cont::make_ArrayHandleCompositeVector(
array1, inComponents[0],
array2, inComponents[1],
array3, inComponents[2]),
inComponents,
arrayIds);
}
}
}
std::cout << " Fourth component from Scalar." << std::endl;
TryVector4(array1, array2, array3, MakeInputArray<vtkm::Scalar>(3));
std::cout << " Fourth component from Vector4." << std::endl;
TryVector4(array1, array2, array3, MakeInputArray<vtkm::Vector4>(3));
}
template<typename T1, typename T2>
void TryVector2(vtkm::cont::ArrayHandle<T1,Container> array1,
vtkm::cont::ArrayHandle<T2,Container> array2)
{
int arrayIds[2] = {0, 1};
int inComponents[2];
for (inComponents[0] = 0;
inComponents[0] < vtkm::VectorTraits<T1>::NUM_COMPONENTS;
inComponents[0]++)
{
for (inComponents[1] = 0;
inComponents[1] < vtkm::VectorTraits<T2>::NUM_COMPONENTS;
inComponents[1]++)
{
CheckArray(
vtkm::cont::make_ArrayHandleCompositeVector(
array1, inComponents[0],
array2, inComponents[1]),
inComponents,
arrayIds);
}
}
std::cout << " Third component from Scalar." << std::endl;
TryVector3(array1, array2, MakeInputArray<vtkm::Scalar>(2));
std::cout << " Third component from Vector2." << std::endl;
TryVector3(array1, array2, MakeInputArray<vtkm::Vector2>(2));
}
template<typename T1>
void TryVector1(vtkm::cont::ArrayHandle<T1,Container> array1)
{
int arrayIds[1] = {0};
int inComponents[1];
for (inComponents[0] = 0;
inComponents[0] < vtkm::VectorTraits<T1>::NUM_COMPONENTS;
inComponents[0]++)
{
CheckArray(
vtkm::cont::make_ArrayHandleCompositeVector(array1, inComponents[0]),
inComponents,
arrayIds);
}
std::cout << " Second component from Scalar." << std::endl;
TryVector2(array1, MakeInputArray<vtkm::Scalar>(1));
std::cout << " Second component from Vector4." << std::endl;
TryVector2(array1, MakeInputArray<vtkm::Vector4>(1));
}
void TryVector()
{
std::cout << "Trying many permutations of composite vectors." << std::endl;
std::cout << " First component from Scalar." << std::endl;
TryVector1(MakeInputArray<vtkm::Scalar>(0));
std::cout << " First component from Vector3." << std::endl;
TryVector1(MakeInputArray<vtkm::Vector3>(0));
}
void TestBadArrayLengths() {
std::cout << "Checking behavior when size of input arrays do not agree."
<< std::endl;
typedef vtkm::cont::ArrayHandle<vtkm::Id, Container> InArrayType;
InArrayType longInArray = MakeInputArray<vtkm::Id>(0);
InArrayType shortInArray = MakeInputArray<vtkm::Id>(1);
shortInArray.Shrink(ARRAY_SIZE/2);
try
{
vtkm::cont::make_ArrayHandleCompositeVector(longInArray,0, shortInArray,0);
VTKM_TEST_FAIL("Did not get exception like expected.");
}
catch (vtkm::cont::ErrorControlBadValue error)
{
std::cout << "Got expected error: " << std::endl
<< error.GetMessage() << std::endl;
}
}
void TestCompositeVector() {
TryScalarArray<2>();
TryScalarArray<3>();
TryScalarArray<4>();
TryVector();
TestBadArrayLengths();
}
} // anonymous namespace
int UnitTestArrayHandleCompositeVector(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestCompositeVector);
}

@ -0,0 +1,87 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/testing/Testing.h>
namespace {
const vtkm::Id3 MIN_VALUES(-5, 8, 40);
const vtkm::Id3 MAX_VALUES(10, 25, 44);
const vtkm::Id3 POINT_DIMS(16, 18, 5);
const vtkm::Id NUM_POINTS = 1440;
const vtkm::Vector3 ORIGIN(30, -3, -14);
const vtkm::Vector3 SPACING(10, 1, 0.1);
const vtkm::Vector3 LOWER_LEFT(-20, 5, -10); // MIN_VALUES*SPACING + ORIGIN
void TestArrayHandleUniformPointCoordinates()
{
std::cout << "Creating ArrayHandleUniformPointCoordinates" << std::endl;
vtkm::cont::ArrayHandleUniformPointCoordinates arrayHandle(
vtkm::Extent3(MIN_VALUES, MAX_VALUES), ORIGIN, SPACING);
VTKM_TEST_ASSERT(arrayHandle.GetNumberOfValues() == NUM_POINTS,
"Array computed wrong number of points.");
std::cout << "Getting array portal." << std::endl;
vtkm::cont::internal::ArrayPortalUniformPointCoordinates portal =
arrayHandle.GetPortalConstControl();
VTKM_TEST_ASSERT(portal.GetNumberOfValues() == NUM_POINTS,
"Portal has wrong number of points.");
VTKM_TEST_ASSERT(portal.GetRange3() == POINT_DIMS,
"Portal range is wrong.");
std::cout << "Checking computed values of portal." << std::endl;
vtkm::Vector3 expectedValue;
vtkm::Id flatIndex = 0;
vtkm::Id3 blockIndex;
expectedValue[2] = LOWER_LEFT[2];
for (blockIndex[2] = 0; blockIndex[2] < POINT_DIMS[2]; blockIndex[2]++)
{
expectedValue[1] = LOWER_LEFT[1];
for (blockIndex[1] = 0; blockIndex[1] < POINT_DIMS[1]; blockIndex[1]++)
{
expectedValue[0] = LOWER_LEFT[0];
for (blockIndex[0] = 0; blockIndex[0] < POINT_DIMS[0]; blockIndex[0]++)
{
VTKM_TEST_ASSERT(test_equal(expectedValue, portal.Get(flatIndex)),
"Got wrong value for flat index.");
VTKM_TEST_ASSERT(test_equal(expectedValue, portal.Get(blockIndex)),
"Got wrong value for block index.");
flatIndex++;
expectedValue[0] += SPACING[0];
}
expectedValue[1] += SPACING[1];
}
expectedValue[2] += SPACING[2];
}
}
} // anonymous namespace
int UnitTestArrayHandleUniformPointCoordinates(int, char *[])
{
return vtkm::cont::testing::Testing::Run(
TestArrayHandleUniformPointCoordinates);
}

@ -0,0 +1,79 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/ContainerListTag.h>
#include <vtkm/cont/testing/Testing.h>
#include <vector>
namespace {
enum TypeId {
BASIC
};
TypeId GetTypeId(vtkm::cont::ArrayContainerControlTagBasic) { return BASIC; }
struct TestFunctor
{
std::vector<TypeId> FoundTypes;
template<typename T>
VTKM_CONT_EXPORT
void operator()(T) {
this->FoundTypes.push_back(GetTypeId(T()));
}
};
template<int N>
void CheckSame(const vtkm::Tuple<TypeId,N> &expected,
const std::vector<TypeId> &found)
{
VTKM_TEST_ASSERT(static_cast<int>(found.size()) == N,
"Got wrong number of items.");
for (int index = 0; index < N; index++)
{
VTKM_TEST_ASSERT(expected[index] == found[index],
"Got wrong type.");
}
}
template<int N, typename ListTag>
void TryList(const vtkm::Tuple<TypeId,N> &expected, ListTag)
{
TestFunctor functor;
vtkm::ListForEach(functor, ListTag());
CheckSame(expected, functor.FoundTypes);
}
void TestLists()
{
std::cout << "ContainerListTagBasic" << std::endl;
TryList(vtkm::Tuple<TypeId,1>(BASIC), vtkm::cont::ContainerListTagBasic());
}
} // anonymous namespace
int UnitTestContainerListTag(int, char *[])
{
return vtkm::testing::Testing::Run(TestLists);
}

@ -0,0 +1,294 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/ArrayContainerControlImplicit.h>
#include <vtkm/cont/internal/IteratorFromArrayPortal.h>
#include <vtkm/cont/testing/Testing.h>
#include <sstream>
#include <string>
namespace {
const vtkm::Id ARRAY_SIZE = 10;
vtkm::Id TestValue(vtkm::Id index, vtkm::Id) {
return index*100;
}
vtkm::Scalar TestValue(vtkm::Id index, vtkm::Scalar) {
return static_cast<vtkm::Scalar>(index)/100;
}
template<typename T, int N>
vtkm::Tuple<T,N> TestValue(vtkm::Id index, vtkm::Tuple<T,N>) {
vtkm::Tuple<T,N> value;
for (int i = 0; i < N; i++)
{
value[i] = TestValue(index, T()) + (i + 1);
}
return value;
}
std::string TestValue(vtkm::Id index, std::string) {
std::stringstream stream;
stream << index;
return stream.str();
}
struct TypeListTagString : vtkm::ListTagBase<std::string> { };
template<typename T>
struct UnusualPortal
{
typedef T ValueType;
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfValues() const { return ARRAY_SIZE; }
VTKM_EXEC_CONT_EXPORT
ValueType Get(vtkm::Id index) const { return TestValue(index, ValueType()); }
typedef vtkm::cont::internal::IteratorFromArrayPortal<UnusualPortal<T> >
IteratorType;
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const {
return IteratorType(*this);
}
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const {
return IteratorType(*this, this->GetNumberOfValues());
}
};
template<typename T>
class ArrayHandleWithUnusualContainer
: public vtkm::cont::ArrayHandle<T, vtkm::cont::ArrayContainerControlTagImplicit<UnusualPortal<T> > >
{
typedef vtkm::cont::ArrayHandle<T, vtkm::cont::ArrayContainerControlTagImplicit<UnusualPortal<T> > >
Superclass;
public:
VTKM_CONT_EXPORT
ArrayHandleWithUnusualContainer()
: Superclass(typename Superclass::PortalConstControl()) { }
};
struct ContainerListTagUnusual :
vtkm::ListTagBase2<
ArrayHandleWithUnusualContainer<vtkm::Id>::ArrayContainerControlTag,
ArrayHandleWithUnusualContainer<std::string>::ArrayContainerControlTag>
{ };
bool CheckCalled;
struct CheckFunctor
{
template<typename T, typename Container>
void operator()(vtkm::cont::ArrayHandle<T, Container> array) const {
CheckCalled = true;
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE,
"Unexpected array size.");
typename vtkm::cont::ArrayHandle<T,Container>::PortalConstControl portal =
array.GetPortalConstControl();
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
VTKM_TEST_ASSERT(portal.Get(index) == TestValue(index, T()),
"Got bad value in array. Perhaps a bad cast?");
}
}
};
template<typename T>
vtkm::cont::DynamicArrayHandle CreateDynamicArray(T)
{
// Declared static to prevent going out of scope.
static T buffer[ARRAY_SIZE];
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
buffer[index] = TestValue(index, T());
}
return vtkm::cont::DynamicArrayHandle(
vtkm::cont::make_ArrayHandle(buffer, ARRAY_SIZE));
}
template<typename T>
void TryDefaultType(T)
{
CheckCalled = false;
vtkm::cont::DynamicArrayHandle array = CreateDynamicArray(T());
array.CastAndCall(CheckFunctor());
VTKM_TEST_ASSERT(CheckCalled,
"The functor was never called (and apparently a bad value exception not thrown).");
}
struct TryBasicVTKmType
{
template<typename T>
void operator()(T) {
CheckCalled = false;
vtkm::cont::DynamicArrayHandle array = CreateDynamicArray(T());
array.ResetTypeList(vtkm::TypeListTagAll()).CastAndCall(CheckFunctor());
VTKM_TEST_ASSERT(CheckCalled,
"The functor was never called (and apparently a bad value exception not thrown).");
}
};
void TryUnusualType()
{
// A string is an unlikely type to be declared elsewhere in VTK-m.
vtkm::cont::DynamicArrayHandle array = CreateDynamicArray(std::string());
try
{
array.CastAndCall(CheckFunctor());
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized type.");
}
catch (vtkm::cont::ErrorControlBadValue)
{
std::cout << " Caught exception for unrecognized type." << std::endl;
}
CheckCalled = false;
array.ResetTypeList(TypeListTagString()).CastAndCall(CheckFunctor());
VTKM_TEST_ASSERT(CheckCalled,
"The functor was never called (and apparently a bad value exception not thrown).");
std::cout << " Found type when type list was reset." << std:: endl;
}
void TryUnusualContainer()
{
vtkm::cont::DynamicArrayHandle array =
ArrayHandleWithUnusualContainer<vtkm::Id>();
try
{
array.CastAndCall(CheckFunctor());
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized container.");
}
catch (vtkm::cont::ErrorControlBadValue)
{
std::cout << " Caught exception for unrecognized container." << std::endl;
}
CheckCalled = false;
array.ResetContainerList(ContainerListTagUnusual()).CastAndCall(CheckFunctor());
VTKM_TEST_ASSERT(CheckCalled,
"The functor was never called (and apparently a bad value exception not thrown).");
std::cout << " Found instance when container list was reset." << std:: endl;
}
void TryUnusualTypeAndContainer()
{
vtkm::cont::DynamicArrayHandle array =
ArrayHandleWithUnusualContainer<std::string>();
try
{
array.CastAndCall(CheckFunctor());
VTKM_TEST_FAIL(
"CastAndCall failed to error for unrecognized type/container.");
}
catch (vtkm::cont::ErrorControlBadValue)
{
std::cout << " Caught exception for unrecognized type/container."
<< std::endl;
}
try
{
array.ResetTypeList(TypeListTagString()).CastAndCall(CheckFunctor());
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized container.");
}
catch (vtkm::cont::ErrorControlBadValue)
{
std::cout << " Caught exception for unrecognized container." << std::endl;
}
try
{
array.ResetContainerList(ContainerListTagUnusual()).
CastAndCall(CheckFunctor());
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized type.");
}
catch (vtkm::cont::ErrorControlBadValue)
{
std::cout << " Caught exception for unrecognized type." << std::endl;
}
CheckCalled = false;
array
.ResetTypeList(TypeListTagString())
.ResetContainerList(ContainerListTagUnusual())
.CastAndCall(CheckFunctor());
VTKM_TEST_ASSERT(CheckCalled,
"The functor was never called (and apparently a bad value exception not thrown).");
std::cout << " Found instance when type and container lists were reset." << std:: endl;
CheckCalled = false;
array
.ResetContainerList(ContainerListTagUnusual())
.ResetTypeList(TypeListTagString())
.CastAndCall(CheckFunctor());
VTKM_TEST_ASSERT(CheckCalled,
"The functor was never called (and apparently a bad value exception not thrown).");
std::cout << " Found instance when container and type lists were reset." << std:: endl;
}
void TestDynamicArrayHandle()
{
std::cout << "Try common types with default type lists." << std::endl;
TryDefaultType(vtkm::Id());
TryDefaultType(vtkm::Scalar());
TryDefaultType(vtkm::Vector3());
std::cout << "Try all VTK-m types." << std::endl;
vtkm::testing::Testing::TryAllTypes(TryBasicVTKmType());
std::cout << "Try unusual type." << std::endl;
TryUnusualType();
std::cout << "Try unusual container." << std::endl;
TryUnusualContainer();
std::cout << "Try unusual type in unusual container." << std::endl;
TryUnusualTypeAndContainer();
}
} // anonymous namespace
int UnitTestDynamicArrayHandle(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestDynamicArrayHandle);
}

@ -0,0 +1,231 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/cont/DynamicPointCoordinates.h>
#include <vtkm/cont/ArrayContainerControlImplicit.h>
#include <vtkm/cont/ContainerListTag.h>
#include <vtkm/cont/internal/IteratorFromArrayPortal.h>
#include <vtkm/cont/testing/Testing.h>
#include <vector>
namespace {
const vtkm::Extent3 EXTENT = vtkm::Extent3(vtkm::Id3(0,0,0), vtkm::Id3(9,9,9));
const vtkm::Vector3 ORIGIN = vtkm::Vector3(0, 0, 0);
const vtkm::Vector3 SPACING = vtkm::Vector3(1, 1, 1);
const vtkm::Id3 DIMENSION = vtkm::ExtentPointDimensions(EXTENT);
const vtkm::Id ARRAY_SIZE = DIMENSION[0]*DIMENSION[1]*DIMENSION[2];
vtkm::Vector3 TestValue(vtkm::Id index)
{
vtkm::Id3 index3d = vtkm::ExtentPointFlatIndexToTopologyIndex(index, EXTENT);
return vtkm::Vector3(index3d[0], index3d[1], index3d[2]);
}
int g_CheckArrayInvocations;
struct CheckArray
{
CheckArray() {
g_CheckArrayInvocations = 0;
}
template<typename Container>
void operator()(
const vtkm::cont::ArrayHandle<vtkm::Vector3,Container> &array) const
{
std::cout << " In CastAndCall functor" << std::endl;
g_CheckArrayInvocations++;
typename vtkm::cont::ArrayHandle<vtkm::Vector3,Container>::PortalConstControl portal =
array.GetPortalConstControl();
VTKM_TEST_ASSERT(portal.GetNumberOfValues() == ARRAY_SIZE,
"Array has wrong number of values.");
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
const vtkm::Vector3 receivedValue = portal.Get(index);
const vtkm::Vector3 expectedValue = TestValue(index);
VTKM_TEST_ASSERT(receivedValue == expectedValue,
"Got bad value in array.");
}
}
};
struct UnusualPortal
{
typedef vtkm::Vector3 ValueType;
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfValues() const { return ARRAY_SIZE; }
VTKM_EXEC_CONT_EXPORT
ValueType Get(vtkm::Id index) const { return TestValue(index); }
typedef vtkm::cont::internal::IteratorFromArrayPortal<UnusualPortal>
IteratorType;
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const {
return IteratorType(*this);
}
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const {
return IteratorType(*this, this->GetNumberOfValues());
}
};
class ArrayHandleWithUnusualContainer
: public vtkm::cont::ArrayHandle<vtkm::Vector3, vtkm::cont::ArrayContainerControlTagImplicit<UnusualPortal> >
{
typedef vtkm::cont::ArrayHandle<vtkm::Vector3, vtkm::cont::ArrayContainerControlTagImplicit<UnusualPortal> >
Superclass;
public:
VTKM_CONT_EXPORT
ArrayHandleWithUnusualContainer()
: Superclass(Superclass::PortalConstControl()) { }
};
struct ContainerListTagUnusual :
vtkm::ListTagBase<ArrayHandleWithUnusualContainer::ArrayContainerControlTag>
{ };
struct PointCoordinatesUnusual : vtkm::cont::internal::PointCoordinatesBase
{
template<typename Functor, typename TypeList, typename ContainerList>
void CastAndCall(const Functor &f, TypeList, ContainerList) const
{
f(ArrayHandleWithUnusualContainer());
}
};
struct PointCoordinatesListUnusual
: vtkm::ListTagBase<PointCoordinatesUnusual> { };
void TryDefaultArray()
{
std::cout << "Trying a basic point coordinates array with a default container."
<< std::endl;
std::vector<vtkm::Vector3> buffer(ARRAY_SIZE);
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
buffer[index] = TestValue(index);
}
vtkm::cont::DynamicPointCoordinates pointCoordinates =
vtkm::cont::DynamicPointCoordinates(
vtkm::cont::make_ArrayHandle(buffer));
pointCoordinates.CastAndCall(CheckArray());
VTKM_TEST_ASSERT(g_CheckArrayInvocations == 1,
"CastAndCall functor not called expected number of times.");
}
void TryUnusualContainer()
{
std::cout << "Trying a basic point coordinates array with an unusual container."
<< std::endl;
vtkm::cont::DynamicPointCoordinates pointCoordinates =
vtkm::cont::DynamicPointCoordinates(
vtkm::cont::PointCoordinatesArray(ArrayHandleWithUnusualContainer()));
std::cout << " Make sure we get an exception when we can't find the type."
<< std::endl;
try
{
pointCoordinates.CastAndCall(CheckArray());
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized container.");
}
catch (vtkm::cont::ErrorControlBadValue error)
{
std::cout << " Caught expected exception for unrecognized container: "
<< std::endl << " " << error.GetMessage() << std::endl;
}
std::cout << " Recast containers and try again." << std::endl;
pointCoordinates.ResetContainerList(ContainerListTagUnusual())
.CastAndCall(CheckArray());
VTKM_TEST_ASSERT(g_CheckArrayInvocations == 1,
"CastAndCall functor not called expected number of times.");
}
void TryUniformPointCoordinates()
{
std::cout << "Trying uniform point coordinates." << std::endl;
vtkm::cont::DynamicPointCoordinates pointCoordinates =
vtkm::cont::DynamicPointCoordinates(
vtkm::cont::PointCoordinatesUniform(EXTENT, ORIGIN, SPACING));
pointCoordinates.CastAndCall(CheckArray());
VTKM_TEST_ASSERT(g_CheckArrayInvocations == 1,
"CastAndCall functor not called expected number of times.");
}
void TryUnusualPointCoordinates()
{
std::cout << "Trying an unusual point coordinates object." << std::endl;
vtkm::cont::DynamicPointCoordinates pointCoordinates =
vtkm::cont::DynamicPointCoordinates(PointCoordinatesUnusual());
std::cout << " Make sure we get an exception when we can't find the type."
<< std::endl;
try
{
pointCoordinates.CastAndCall(CheckArray());
VTKM_TEST_FAIL("CastAndCall failed to error for unrecognized container.");
}
catch (vtkm::cont::ErrorControlBadValue error)
{
std::cout << " Caught expected exception for unrecognized point coordinates: "
<< std::endl << " " << error.GetMessage() << std::endl;
}
std::cout << " Recast containers and try again." << std::endl;
pointCoordinates.ResetPointCoordinatesList(PointCoordinatesListUnusual())
.CastAndCall(CheckArray());
VTKM_TEST_ASSERT(g_CheckArrayInvocations == 1,
"CastAndCall functor not called expected number of times.");
}
void DynamicPointCoordiantesTest()
{
TryDefaultArray();
TryUnusualContainer();
TryUniformPointCoordinates();
TryUnusualPointCoordinates();
}
} // anonymous namespace
int UnitTestDynamicPointCoordinates(int, char *[])
{
return vtkm::cont::testing::Testing::Run(DynamicPointCoordiantesTest);
}

@ -0,0 +1,132 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
// Make sure nothing relies on default container or device adapter.
#define VTKM_ARRAY_CONTAINER_CONTROL VTKM_ARRAY_CONTAINER_CONTROL_ERROR
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_ERROR
// Make sure nothing relies on default lists.
#define VTKM_DEFAULT_TYPE_LIST_TAG ::vtkm::ListTagEmpty
#define VTKM_DEFAULT_CONTAINER_LIST_TAG ::vtkm::ListTagEmpty
#include <vtkm/cont/PointCoordinatesArray.h>
#include <vtkm/cont/PointCoordinatesUniform.h>
#include <vtkm/Extent.h>
#include <vtkm/TypeListTag.h>
#include <vtkm/cont/ArrayContainerControlBasic.h>
#include <vtkm/cont/DeviceAdapterSerial.h>
#include <vtkm/cont/testing/Testing.h>
#include <vector>
namespace {
const vtkm::Extent3 EXTENT = vtkm::Extent3(vtkm::Id3(0,0,0), vtkm::Id3(9,9,9));
const vtkm::Vector3 ORIGIN = vtkm::Vector3(0, 0, 0);
const vtkm::Vector3 SPACING = vtkm::Vector3(1, 1, 1);
const vtkm::Id3 DIMENSION = vtkm::ExtentPointDimensions(EXTENT);
const vtkm::Id ARRAY_SIZE = DIMENSION[0]*DIMENSION[1]*DIMENSION[2];
typedef vtkm::cont::ArrayContainerControlTagBasic Container;
struct ContainerListTag : vtkm::cont::ContainerListTagBasic { };
vtkm::Vector3 TestValue(vtkm::Id index)
{
vtkm::Id3 index3d = vtkm::ExtentPointFlatIndexToTopologyIndex(index, EXTENT);
return vtkm::Vector3(index3d[0], index3d[1], index3d[2]);
}
struct CheckArray
{
template<typename C>
void operator()(
const vtkm::cont::ArrayHandle<vtkm::Vector3,C> &array) const
{
std::cout << " In CastAndCall functor" << std::endl;
typename vtkm::cont::ArrayHandle<vtkm::Vector3,C>::PortalConstControl portal =
array.GetPortalConstControl();
VTKM_TEST_ASSERT(portal.GetNumberOfValues() == ARRAY_SIZE,
"Array has wrong number of values.");
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
const vtkm::Vector3 receivedValue = portal.Get(index);
const vtkm::Vector3 expectedValue = TestValue(index);
VTKM_TEST_ASSERT(receivedValue == expectedValue,
"Got bad value in array.");
}
}
};
void TestPointCoordinatesArray()
{
std::cout << "Testing PointCoordinatesArray" << std::endl;
std::cout << " Creating buffer of data values" << std::endl;
std::vector<vtkm::Vector3> buffer(ARRAY_SIZE);
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
buffer[index] = TestValue(index);
}
std::cout << " Creating and checking array handle" << std::endl;
vtkm::cont::ArrayHandle<vtkm::Vector3,Container> array =
vtkm::cont::make_ArrayHandle(buffer, Container());
CheckArray()(array);
std::cout << " Creating and checking PointCoordinatesArray" << std::endl;
vtkm::cont::PointCoordinatesArray pointCoordinates =
vtkm::cont::PointCoordinatesArray(array);
pointCoordinates.CastAndCall(
CheckArray(),
vtkm::ListTagEmpty(), // Internally sets to Vector3
vtkm::cont::ContainerListTagBasic());
}
void TestPointCoordinatesUniform()
{
std::cout << "Testing PointCoordinatesUniform" << std::endl;
vtkm::cont::PointCoordinatesUniform pointCoordinates =
vtkm::cont::PointCoordinatesUniform(EXTENT, ORIGIN, SPACING);
pointCoordinates.CastAndCall(
CheckArray(),
vtkm::ListTagEmpty(), // Not used
vtkm::ListTagEmpty()); // Not used
}
void PointCoordinatesTests()
{
TestPointCoordinatesArray();
TestPointCoordinatesUniform();
}
} // anonymous namespace
int UnitTestPointCoordinates(int, char *[])
{
return vtkm::cont::testing::Testing::Run(PointCoordinatesTests);
}

@ -22,6 +22,7 @@ set(headers
ConfigureFor32.h
ConfigureFor64.h
ExportMacros.h
FunctionInterface.h
)
vtkm_declare_headers(${headers})

File diff suppressed because it is too large Load Diff

@ -21,5 +21,6 @@
set(unit_tests
UnitTestConfigureFor32.cxx
UnitTestConfigureFor64.cxx
UnitTestFunctionInterface.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})

@ -0,0 +1,577 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/internal/FunctionInterface.h>
#include <vtkm/testing/Testing.h>
#include <sstream>
#include <string>
#ifndef _WIN32
#include <limits.h>
#include <sys/time.h>
#include <unistd.h>
#endif
namespace {
// TODO: Once device adapters are implemented and contain timers, this class
// should be removed and replaced with that. Also remove the inclusion of
// limits.h, sys/time.h, and unistd.h.
class Timer
{
public:
VTKM_CONT_EXPORT Timer()
{
this->Reset();
}
VTKM_CONT_EXPORT void Reset()
{
this->StartTime = this->GetCurrentTime();
}
VTKM_CONT_EXPORT vtkm::Scalar GetElapsedTime()
{
TimeStamp currentTime = this->GetCurrentTime();
vtkm::Scalar elapsedTime;
elapsedTime = currentTime.Seconds - this->StartTime.Seconds;
elapsedTime += ((currentTime.Microseconds - this->StartTime.Microseconds)
/vtkm::Scalar(1000000));
return elapsedTime;
}
private:
struct TimeStamp {
vtkm::internal::Int64Type Seconds;
vtkm::internal::Int64Type Microseconds;
};
TimeStamp StartTime;
VTKM_CONT_EXPORT
TimeStamp GetCurrentTime()
{
TimeStamp retval;
#ifdef _WIN32
timeb currentTime;
::ftime(&currentTime);
retval.Seconds = currentTime.time;
retval.Microseconds = 1000*currentTime.millitm;
#else
timeval currentTime;
gettimeofday(&currentTime, NULL);
retval.Seconds = currentTime.tv_sec;
retval.Microseconds = currentTime.tv_usec;
#endif
return retval;
}
};
typedef vtkm::Id Type1;
const Type1 Arg1 = 1234;
typedef vtkm::Scalar Type2;
const Type2 Arg2 = 5678.125;
typedef std::string Type3;
const Type3 Arg3("Third argument");
typedef vtkm::Vector3 Type4;
const Type4 Arg4(1.2, 3.4, 5.6);
typedef vtkm::Id3 Type5;
const Type5 Arg5(4, 5, 6);
struct ThreeArgFunctor {
void operator()(const Type1 &a1, const Type2 &a2, const Type3 &a3) const
{
std::cout << "In 3 arg functor." << std::endl;
VTKM_TEST_ASSERT(a1 == Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(a2 == Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(a3 == Arg3, "Arg 3 incorrect.");
}
};
struct ThreeArgModifyFunctor {
void operator()(Type1 &a1, Type2 &a2, Type3 &a3) const
{
std::cout << "In 3 arg modify functor." << std::endl;
a1 = Arg1;
a2 = Arg2;
a3 = Arg3;
}
};
struct GetReferenceFunctor
{
template<typename T>
struct ReturnType {
typedef const typename boost::remove_reference<T>::type *type;
};
template<typename T>
const T *operator()(const T &x) const { return &x; }
};
struct PointerTransform {
template<typename T>
struct ReturnType {
typedef const T *type;
};
template<typename T>
const T *operator()(const T &x) const {
return &x;
}
};
struct ThreePointerArgFunctor {
void operator()(const Type1 *a1, const Type2 *a2, const Type3 *a3) const
{
std::cout << "In 3 point arg functor." << std::endl;
VTKM_TEST_ASSERT(*a1 == Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(*a2 == Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(*a3 == Arg3, "Arg 3 incorrect.");
}
};
struct ThreeArgFunctorWithReturn {
std::string operator()(const Type1 &a1,
const Type2 &a2,
const Type3 &a3) const
{
std::cout << "In 3 arg functor with return." << std::endl;
std::stringstream buffer;
buffer.precision(10);
buffer << a1 << " " << a2 << " " << a3;
return buffer.str();
}
};
struct FiveArgFunctor {
void operator()(const Type1 &a1,
const Type2 &a2,
const Type3 &a3,
const Type4 &a4,
const Type5 &a5) const
{
std::cout << "In 5 arg functor." << std::endl;
VTKM_TEST_ASSERT(a1 == Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(a2 == Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(a3 == Arg3, "Arg 3 incorrect.");
VTKM_TEST_ASSERT(a4 == Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(a5 == Arg5, "Arg 5 incorrect.");
}
};
struct FiveArgSwizzledFunctor {
void operator()(const Type5 &a5,
const Type1 &a1,
const Type3 &a3,
const Type4 &a4,
const Type2 &a2) const
{
std::cout << "In 5 arg functor." << std::endl;
VTKM_TEST_ASSERT(a1 == Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(a2 == Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(a3 == Arg3, "Arg 3 incorrect.");
VTKM_TEST_ASSERT(a4 == Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(a5 == Arg5, "Arg 5 incorrect.");
}
};
struct LotsOfArgsFunctor {
LotsOfArgsFunctor() : Field(0) { }
void operator()(vtkm::Scalar arg1,
vtkm::Scalar arg2,
vtkm::Scalar arg3,
vtkm::Scalar arg4,
vtkm::Scalar arg5,
vtkm::Scalar arg6,
vtkm::Scalar arg7,
vtkm::Scalar arg8,
vtkm::Scalar arg9,
vtkm::Scalar arg10) {
VTKM_TEST_ASSERT(arg1 == 1.0, "Got bad argument");
VTKM_TEST_ASSERT(arg2 == 2.0, "Got bad argument");
VTKM_TEST_ASSERT(arg3 == 3.0, "Got bad argument");
VTKM_TEST_ASSERT(arg4 == 4.0, "Got bad argument");
VTKM_TEST_ASSERT(arg5 == 5.0, "Got bad argument");
VTKM_TEST_ASSERT(arg6 == 6.0, "Got bad argument");
VTKM_TEST_ASSERT(arg7 == 7.0, "Got bad argument");
VTKM_TEST_ASSERT(arg8 == 8.0, "Got bad argument");
VTKM_TEST_ASSERT(arg9 == 9.0, "Got bad argument");
VTKM_TEST_ASSERT(arg10 == 10.0, "Got bad argument");
this->Field +=
arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9 + arg10;
}
vtkm::Scalar Field;
};
template<typename T>
std::string ToString(const T &value)
{
std::stringstream stream;
stream.precision(10);
stream << value;
return stream.str();
}
std::string ToString(const std::string &value)
{
return value;
}
struct StringTransform
{
template<typename T>
std::string operator()(const T &input) const { return ToString(input); }
};
struct ThreeArgStringFunctorWithReturn
{
std::string operator()(std::string arg1,
std::string arg2,
std::string arg3) const
{
return arg1 + " " + arg2 + " " + arg3;
}
};
struct DynamicTransformFunctor
{
template<typename T, typename ContinueFunctor>
void operator()(const T &input, const ContinueFunctor continueFunc) const
{
continueFunc(input);
continueFunc(ToString(input));
}
template<typename ContinueFunctor>
void operator()(const std::string &input, const ContinueFunctor continueFunc) const
{
continueFunc(input);
}
};
vtkm::Id g_DynamicTransformFinishCalls;
struct DynamicTransformFinish
{
template<typename Signature>
void operator()(vtkm::internal::FunctionInterface<Signature> &funcInterface) const
{
g_DynamicTransformFinishCalls++;
VTKM_TEST_ASSERT(ToString(funcInterface.template GetParameter<1>()) == ToString(Arg1),
"Arg 1 incorrect");
VTKM_TEST_ASSERT(ToString(funcInterface.template GetParameter<2>()) == ToString(Arg2),
"Arg 2 incorrect");
VTKM_TEST_ASSERT(ToString(funcInterface.template GetParameter<3>()) == ToString(Arg3),
"Arg 3 incorrect");
}
};
struct ForEachFunctor
{
template<typename T>
void operator()(T &x) const { x = 2*x; }
void operator()(std::string &x) const { x.append("*2"); }
};
void TryFunctionInterface5(
vtkm::internal::FunctionInterface<void(Type1,Type2,Type3,Type4,Type5)> funcInterface)
{
std::cout << "Checking 5 parameter function interface." << std::endl;
VTKM_TEST_ASSERT(funcInterface.GetArity() == 5,
"Got wrong number of parameters.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3, "Arg 3 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<5>() == Arg5, "Arg 5 incorrect.");
std::cout << "Checking invocation." << std::endl;
funcInterface.InvokeCont(FiveArgFunctor());
funcInterface.InvokeExec(FiveArgFunctor());
std::cout << "Swizzling parameters with replace." << std::endl;
funcInterface.Replace<1>(Arg5)
.Replace<2>(Arg1)
.Replace<5>(Arg2)
.InvokeCont(FiveArgSwizzledFunctor());
}
void TestBasicFunctionInterface()
{
std::cout << "Creating basic function interface." << std::endl;
vtkm::internal::FunctionInterface<void(Type1,Type2,Type3)> funcInterface =
vtkm::internal::make_FunctionInterface<void>(Arg1, Arg2, Arg3);
std::cout << "Checking parameters." << std::endl;
VTKM_TEST_ASSERT(funcInterface.GetArity() == 3,
"Got wrong number of parameters.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3, "Arg 3 incorrect.");
std::cout << "Checking invocation." << std::endl;
funcInterface.InvokeCont(ThreeArgFunctor());
funcInterface.InvokeExec(ThreeArgFunctor());
std::cout << "Checking invocation with argument modification." << std::endl;
funcInterface.SetParameter<1>(Type1());
funcInterface.SetParameter<2>(Type2());
funcInterface.SetParameter<3>(Type3());
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() != Arg1, "Arg 1 not cleared.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() != Arg2, "Arg 2 not cleared.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() != Arg3, "Arg 3 not cleared.");
funcInterface.InvokeCont(ThreeArgModifyFunctor());
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3, "Arg 3 incorrect.");
TryFunctionInterface5(
vtkm::internal::make_FunctionInterface<void>(Arg1,Arg2,Arg3,Arg4,Arg5));
}
void TestInvokeResult()
{
std::cout << "Checking invocation with return." << std::endl;
vtkm::internal::FunctionInterface<std::string(Type1,Type2,Type3)> funcInterface
= vtkm::internal::make_FunctionInterface<std::string>(Arg1, Arg2, Arg3);
funcInterface.InvokeCont(ThreeArgFunctorWithReturn());
std::string result = funcInterface.GetReturnValue();
std::cout << "Got result: " << result << std::endl;
VTKM_TEST_ASSERT(result == "1234 5678.125 Third argument",
"Got bad result from invoke.");
}
void TestAppend()
{
std::cout << "Appending interface with return value." << std::endl;
vtkm::internal::FunctionInterface<std::string(Type1,Type2)>
funcInterface2ArgWRet =
vtkm::internal::make_FunctionInterface<std::string>(Arg1,Arg2);
vtkm::internal::FunctionInterface<std::string(Type1,Type2,Type3)>
funcInterface3ArgWRet = funcInterface2ArgWRet.Append(Arg3);
VTKM_TEST_ASSERT(funcInterface3ArgWRet.GetParameter<1>() == Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface3ArgWRet.GetParameter<2>() == Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface3ArgWRet.GetParameter<3>() == Arg3, "Arg 3 incorrect.");
std::cout << "Invoking appended function interface." << std::endl;
funcInterface3ArgWRet.InvokeExec(ThreeArgFunctorWithReturn());
std::string result = funcInterface3ArgWRet.GetReturnValue();
std::cout << "Got result: " << result << std::endl;
VTKM_TEST_ASSERT(result == "1234 5678.125 Third argument",
"Got bad result from invoke.");
std::cout << "Appending another value." << std::endl;
vtkm::internal::FunctionInterface<std::string(Type1,Type2,Type3,Type4)>
funcInterface4ArgWRet = funcInterface3ArgWRet.Append(Arg4);
VTKM_TEST_ASSERT(funcInterface4ArgWRet.GetParameter<4>() == Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface4ArgWRet.GetReturnValue() == "1234 5678.125 Third argument",
"Got bad result from copy.");
std::cout << "Checking double append." << std::endl;
vtkm::internal::FunctionInterface<void(Type1,Type2,Type3)> funcInterface3 =
vtkm::internal::make_FunctionInterface<void>(Arg1,Arg2,Arg3);
TryFunctionInterface5(funcInterface3
.Append(Arg4)
.Append(Arg5));
}
void TestTransformInvoke()
{
std::cout << "Trying transform invoke." << std::endl;
vtkm::internal::FunctionInterface<std::string(Type1,Type2,Type3)>
funcInterface =
vtkm::internal::make_FunctionInterface<std::string>(Arg1, Arg2, Arg3);
funcInterface.InvokeCont(ThreeArgStringFunctorWithReturn(),
StringTransform());
std::string result = funcInterface.GetReturnValue();
std::cout << "Got result: " << result << std::endl;
VTKM_TEST_ASSERT(result == "1234 5678.125 Third argument",
"Got bad result from invoke.");
}
void TestStaticTransform()
{
std::cout << "Trying static transform." << std::endl;
typedef vtkm::internal::FunctionInterface<void(Type1,Type2,Type3)>
OriginalType;
OriginalType funcInterface =
vtkm::internal::make_FunctionInterface<void>(Arg1, Arg2, Arg3);
std::cout << "Transform with reported type." << std::endl;
typedef OriginalType::StaticTransformType<PointerTransform>::type
ReportedType;
ReportedType funcInterfaceTransform1 =
funcInterface.StaticTransformCont(PointerTransform());
funcInterfaceTransform1.InvokeCont(ThreePointerArgFunctor());
funcInterfaceTransform1 =
funcInterface.StaticTransformExec(PointerTransform());
funcInterfaceTransform1.InvokeExec(ThreePointerArgFunctor());
std::cout << "Transform with expected type." << std::endl;
typedef vtkm::internal::FunctionInterface<void(Type1*,Type2*,Type3*)>
ExpectedType;
ReportedType funcInterfaceTransform2 =
funcInterface.StaticTransformCont(PointerTransform());
funcInterfaceTransform2.InvokeCont(ThreePointerArgFunctor());
funcInterfaceTransform2 =
funcInterface.StaticTransformExec(PointerTransform());
funcInterfaceTransform2.InvokeExec(ThreePointerArgFunctor());
}
void TestDynamicTransform()
{
std::cout << "Trying dynamic transform." << std::endl;
vtkm::internal::FunctionInterface<void(Type1,Type2,Type3)> funcInterface =
vtkm::internal::make_FunctionInterface<void>(Arg1, Arg2, Arg3);
g_DynamicTransformFinishCalls = 0;
funcInterface.DynamicTransformCont(DynamicTransformFunctor(),
DynamicTransformFinish());
// We use an idiosyncrasy of DynamicTransform to call finish with two
// permutations for every non string argument and one permutation for every
// string argument. Thus, we expect it to be called 4 times.
std::cout << "Number of finish calls: " << g_DynamicTransformFinishCalls
<< std::endl;
VTKM_TEST_ASSERT(g_DynamicTransformFinishCalls == 4,
"DynamicTransform did not call finish the right number of times.");
}
void TestForEach()
{
std::cout << "Checking running a function on each parameter." << std::endl;
vtkm::internal::FunctionInterface<void(Type1,Type2,Type3,Type4,Type5)>
funcInterface = vtkm::internal::make_FunctionInterface<void>(
Arg1, Arg2, Arg3, Arg4, Arg5);
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3, "Arg 3 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<5>() == Arg5, "Arg 5 incorrect.");
funcInterface.ForEachCont(ForEachFunctor());
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == 2*Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == 2*Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3+"*2", "Arg 3 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == 2*Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<5>() == 2*Arg5, "Arg 5 incorrect.");
funcInterface.ForEachExec(ForEachFunctor());
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == 4*Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == 4*Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3+"*2*2", "Arg 3 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == 4*Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<5>() == 4*Arg5, "Arg 5 incorrect.");
}
void TestInvokeTime()
{
std::cout << "Checking time to call lots of args lots of times." << std::endl;
static vtkm::Id NUM_TRIALS = 50000;
LotsOfArgsFunctor f;
Timer timer;
for (vtkm::Id trial = 0; trial < NUM_TRIALS; trial++)
{
f(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f);
}
vtkm::Scalar directCallTime = timer.GetElapsedTime();
std::cout << "Time for direct call: " << directCallTime << " seconds"
<< std::endl;
vtkm::internal::FunctionInterface<void(vtkm::Scalar,
vtkm::Scalar,
vtkm::Scalar,
vtkm::Scalar,
vtkm::Scalar,
vtkm::Scalar,
vtkm::Scalar,
vtkm::Scalar,
vtkm::Scalar,
vtkm::Scalar)> funcInterface =
vtkm::internal::make_FunctionInterface<void>(vtkm::Scalar(1),
vtkm::Scalar(2),
vtkm::Scalar(3),
vtkm::Scalar(4),
vtkm::Scalar(5),
vtkm::Scalar(6),
vtkm::Scalar(7),
vtkm::Scalar(8),
vtkm::Scalar(9),
vtkm::Scalar(10));
timer.Reset();
for (vtkm::Id trial = 0; trial < NUM_TRIALS; trial++)
{
funcInterface.InvokeCont(f);
}
vtkm::Scalar 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;
// Might need to disable this for non-release builds.
VTKM_TEST_ASSERT(invokeCallTime < 1.05*directCallTime,
"Function interface invoke took longer than expected.");
}
void TestFunctionInterface()
{
TestBasicFunctionInterface();
TestInvokeResult();
TestAppend();
TestTransformInvoke();
TestStaticTransform();
TestDynamicTransform();
TestForEach();
TestInvokeTime();
}
} // anonymous namespace
int UnitTestFunctionInterface(int, char *[])
{
return vtkm::testing::Testing::Run(TestFunctionInterface);
}

@ -26,7 +26,10 @@ set(headers
VTKM_declare_headers(${headers})
set(unit_tests
UnitTestExtent.cxx
UnitTestListTag.cxx
UnitTestTesting.cxx
UnitTestTypeListTag.cxx
UnitTestTypes.cxx
UnitTestTypeTraits.cxx
UnitTestVectorTraits.cxx

@ -0,0 +1,197 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/Extent.h>
#include <vtkm/testing/Testing.h>
namespace {
const int MIN_VALUES[] = { -5, 8, 40, -8, -3 };
const int MAX_VALUES[] = { 10, 25, 44, -2, 1 };
const int POINT_DIMS[] = { 16, 18, 5, 7, 5 };
const int CELL_DIMS[] = { 15, 17, 4, 6, 4 };
const int NUM_POINTS[] = { 0, 16, 288, 1440, 10080, 50400 };
const int NUM_CELLS[] = { 0, 15, 255, 1020, 6120, 24480 };
template<int Dimensions>
void TestDimensions(vtkm::Extent<Dimensions>)
{
std::cout << "Testing Dimension sizes for " << Dimensions << " dimensions"
<< std::endl;
vtkm::Extent<Dimensions> extent;
vtkm::Tuple<vtkm::Id,Dimensions> pointDims;
vtkm::Tuple<vtkm::Id,Dimensions> cellDims;
vtkm::Id numPoints;
vtkm::Id numCells;
for (int dimIndex = 0; dimIndex < Dimensions; dimIndex++)
{
extent.Min[dimIndex] = 0; extent.Max[dimIndex] = 10;
}
pointDims = vtkm::ExtentPointDimensions(extent);
cellDims = vtkm::ExtentCellDimensions(extent);
for (int dimIndex = 0; dimIndex < Dimensions; dimIndex++)
{
VTKM_TEST_ASSERT(pointDims[dimIndex] == 11,
"Got incorrect point dimensions for extent.");
VTKM_TEST_ASSERT(cellDims[dimIndex] == 10,
"Got incorrect point dimensions for extent.");
}
for (int dimIndex = 0; dimIndex < Dimensions; dimIndex++)
{
extent.Min[dimIndex] = MIN_VALUES[dimIndex];
extent.Max[dimIndex] = MAX_VALUES[dimIndex];
}
pointDims = vtkm::ExtentPointDimensions(extent);
cellDims = vtkm::ExtentCellDimensions(extent);
for (int dimIndex = 0; dimIndex < Dimensions; dimIndex++)
{
VTKM_TEST_ASSERT(pointDims[dimIndex] == POINT_DIMS[dimIndex],
"Got incorrect point dimensions for extent.");
VTKM_TEST_ASSERT(cellDims[dimIndex] == CELL_DIMS[dimIndex],
"Got incorrect point dimensions for extent.");
}
numPoints = vtkm::ExtentNumberOfPoints(extent);
numCells = vtkm::ExtentNumberOfCells(extent);
VTKM_TEST_ASSERT(numPoints == NUM_POINTS[Dimensions],
"Got wrong number of points.");
VTKM_TEST_ASSERT(numCells == NUM_CELLS[Dimensions],
"Got wrong number of cells.");
}
template<int Dimensions>
void TryIndexConversion(const vtkm::Extent<Dimensions> &extent)
{
typedef vtkm::Tuple<vtkm::Id,Dimensions> IdX;
vtkm::Id lastFlatIndex;
IdX correctTopologyIndex;
std::cout << " Testing point index conversion" << std::endl;
correctTopologyIndex = IdX(100000);
lastFlatIndex = vtkm::ExtentNumberOfPoints(extent);
for (vtkm::Id correctFlatIndex = 0;
correctFlatIndex < lastFlatIndex;
correctFlatIndex++)
{
// Increment topology index
for (int dimIndex = 0; dimIndex < Dimensions; dimIndex++)
{
correctTopologyIndex[dimIndex]++;
if (correctTopologyIndex[dimIndex] <= extent.Max[dimIndex]) { break; }
correctTopologyIndex[dimIndex] = extent.Min[dimIndex];
// Iterate to increment the next index.
}
vtkm::Id computedFlatIndex =
vtkm::ExtentPointTopologyIndexToFlatIndex(correctTopologyIndex, extent);
VTKM_TEST_ASSERT(computedFlatIndex == correctFlatIndex,
"Got incorrect flat index.");
IdX computedTopologyIndex =
vtkm::ExtentPointFlatIndexToTopologyIndex(correctFlatIndex, extent);
VTKM_TEST_ASSERT(computedTopologyIndex == correctTopologyIndex,
"Got incorrect topology index.");
}
// Sanity check to make sure we got to the last topology index.
VTKM_TEST_ASSERT(correctTopologyIndex == extent.Max,
"Test code error. Indexing problem.");
std::cout << " Testing cell index conversion" << std::endl;
correctTopologyIndex = IdX(100000);
lastFlatIndex = vtkm::ExtentNumberOfCells(extent);
for (vtkm::Id correctFlatIndex = 0;
correctFlatIndex < lastFlatIndex;
correctFlatIndex++)
{
// Increment topology index
for (int dimIndex = 0; dimIndex < Dimensions; dimIndex++)
{
correctTopologyIndex[dimIndex]++;
if (correctTopologyIndex[dimIndex] < extent.Max[dimIndex]) { break; }
correctTopologyIndex[dimIndex] = extent.Min[dimIndex];
// Iterate to increment the next index.
}
vtkm::Id computedFlatIndex =
vtkm::ExtentCellTopologyIndexToFlatIndex(correctTopologyIndex, extent);
VTKM_TEST_ASSERT(computedFlatIndex == correctFlatIndex,
"Got incorrect flat index.");
IdX computedTopologyIndex =
vtkm::ExtentCellFlatIndexToTopologyIndex(correctFlatIndex, extent);
VTKM_TEST_ASSERT(computedTopologyIndex == correctTopologyIndex,
"Got incorrect topology index.");
vtkm::Id expectedFirstPointIndex =
vtkm::ExtentPointTopologyIndexToFlatIndex(correctTopologyIndex, extent);
vtkm::Id computedFirstPointIndex =
vtkm::ExtentFirstPointOnCell(correctFlatIndex, extent);
VTKM_TEST_ASSERT(computedFirstPointIndex == expectedFirstPointIndex,
"Got wrong first point index.");
}
// Sanity check to make sure we got to the last topology index.
VTKM_TEST_ASSERT(correctTopologyIndex == extent.Max - IdX(1),
"Test code error. Indexing problem.");
}
template<int Dimensions>
void TestIndexConversion(vtkm::Extent<Dimensions>)
{
std::cout << "Testing index conversion for " << Dimensions << " dimensions."
<< std::endl;
vtkm::Extent<Dimensions> extent;
for (int dimIndex = 0; dimIndex < Dimensions; dimIndex++)
{
extent.Min[dimIndex] = 0; extent.Max[dimIndex] = 10;
}
TryIndexConversion(extent);
for (int dimIndex = 0; dimIndex < Dimensions; dimIndex++)
{
extent.Min[dimIndex] = MIN_VALUES[dimIndex];
extent.Max[dimIndex] = MAX_VALUES[dimIndex];
}
TryIndexConversion(extent);
}
void ExtentTests()
{
TestDimensions(vtkm::Extent<1>());
TestDimensions(vtkm::Extent2());
TestDimensions(vtkm::Extent3());
TestDimensions(vtkm::Extent<5>());
TestIndexConversion(vtkm::Extent<1>());
TestIndexConversion(vtkm::Extent2());
TestIndexConversion(vtkm::Extent3());
TestIndexConversion(vtkm::Extent<5>());
}
} // anonymous namespace
int UnitTestExtent(int, char *[])
{
return vtkm::testing::Testing::Run(ExtentTests);
}

@ -0,0 +1,136 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/ListTag.h>
#include <vtkm/Types.h>
#include <vtkm/testing/Testing.h>
#include <vector>
namespace {
template<int N>
struct TestClass
{
enum { NUMBER = N };
};
struct TestListTag1
: vtkm::ListTagBase<TestClass<11> >
{ };
struct TestListTag2
: vtkm::ListTagBase2<TestClass<21>,TestClass<22> >
{ };
struct TestListTag3
: vtkm::ListTagBase3<TestClass<31>,TestClass<32>,TestClass<33> >
{ };
struct TestListTag4
: vtkm::ListTagBase4<TestClass<41>,TestClass<42>,TestClass<43>,TestClass<44> >
{ };
struct TestListTagJoin
: vtkm::ListTagJoin<TestListTag3, TestListTag1>
{ };
struct MutableFunctor
{
std::vector<int> FoundTypes;
template<typename T>
VTKM_CONT_EXPORT
void operator()(T) {
this->FoundTypes.push_back(T::NUMBER);
}
};
std::vector<int> g_FoundType;
struct ConstantFunctor
{
ConstantFunctor() {
g_FoundType.erase(g_FoundType.begin(), g_FoundType.end());
}
template<typename T>
VTKM_CONT_EXPORT
void operator()(T) const {
g_FoundType.push_back(T::NUMBER);
}
};
template<int N>
void CheckSame(const vtkm::Tuple<int,N> &expected,
const std::vector<int> &found)
{
VTKM_TEST_ASSERT(static_cast<int>(found.size()) == N,
"Got wrong number of items.");
for (int index = 0; index < N; index++)
{
VTKM_TEST_ASSERT(expected[index] == found[index],
"Got wrong type.");
}
}
template<int N, typename ListTag>
void TryList(const vtkm::Tuple<int,N> &expected, ListTag)
{
std::cout << " Try mutable for each" << std::endl;
MutableFunctor functor;
vtkm::ListForEach(functor, ListTag());
CheckSame(expected, functor.FoundTypes);
std::cout << " Try constant for each" << std::endl;
vtkm::ListForEach(ConstantFunctor(), ListTag());
CheckSame(expected, g_FoundType);
}
void TestLists()
{
std::cout << "ListTagEmpty" << std::endl;
TryList(vtkm::Tuple<int,0>(), vtkm::ListTagEmpty());
std::cout << "ListTagBase" << std::endl;
TryList(vtkm::Tuple<int,1>(11), TestListTag1());
std::cout << "ListTagBase2" << std::endl;
TryList(vtkm::Tuple<int,2>(21,22), TestListTag2());
std::cout << "ListTagBase3" << std::endl;
TryList(vtkm::Tuple<int,3>(31,32,33), TestListTag3());
std::cout << "ListTagBase4" << std::endl;
TryList(vtkm::Tuple<int,4>(41,42,43,44), TestListTag4());
std::cout << "ListTagJoin" << std::endl;
TryList(vtkm::Tuple<int,4>(31,32,33,11), TestListTagJoin());
}
} // anonymous namespace
int UnitTestListTag(int, char *[])
{
return vtkm::testing::Testing::Run(TestLists);
}

@ -0,0 +1,132 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014. Los Alamos National Security
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/TypeListTag.h>
#include <vtkm/Types.h>
#include <vtkm/testing/Testing.h>
#include <vector>
namespace {
enum TypeId {
ID,
ID2,
ID3,
SCALAR,
VECTOR2,
VECTOR3,
VECTOR4
};
TypeId GetTypeId(vtkm::Id) { return ID; }
TypeId GetTypeId(vtkm::Id2) { return ID2; }
TypeId GetTypeId(vtkm::Id3) { return ID3; }
TypeId GetTypeId(vtkm::Scalar) { return SCALAR; }
TypeId GetTypeId(vtkm::Vector2) { return VECTOR2; }
TypeId GetTypeId(vtkm::Vector3) { return VECTOR3; }
TypeId GetTypeId(vtkm::Vector4) { return VECTOR4; }
struct TestFunctor
{
std::vector<TypeId> FoundTypes;
template<typename T>
VTKM_CONT_EXPORT
void operator()(T) {
this->FoundTypes.push_back(GetTypeId(T()));
}
};
template<int N>
void CheckSame(const vtkm::Tuple<TypeId,N> &expected,
const std::vector<TypeId> &found)
{
VTKM_TEST_ASSERT(static_cast<int>(found.size()) == N,
"Got wrong number of items.");
for (int index = 0; index < N; index++)
{
VTKM_TEST_ASSERT(expected[index] == found[index],
"Got wrong type.");
}
}
template<int N, typename ListTag>
void TryList(const vtkm::Tuple<TypeId,N> &expected, ListTag)
{
TestFunctor functor;
vtkm::ListForEach(functor, ListTag());
CheckSame(expected, functor.FoundTypes);
}
void TestLists()
{
std::cout << "TypeListTagId" << std::endl;
TryList(vtkm::Tuple<TypeId,1>(ID), vtkm::TypeListTagId());
std::cout << "TypeListTagId2" << std::endl;
TryList(vtkm::Tuple<TypeId,1>(ID2), vtkm::TypeListTagId2());
std::cout << "TypeListTagId3" << std::endl;
TryList(vtkm::Tuple<TypeId,1>(ID3), vtkm::TypeListTagId3());
std::cout << "TypeListTagScalar" << std::endl;
TryList(vtkm::Tuple<TypeId,1>(SCALAR), vtkm::TypeListTagScalar());
std::cout << "TypeListTagVector2" << std::endl;
TryList(vtkm::Tuple<TypeId,1>(VECTOR2), vtkm::TypeListTagVector2());
std::cout << "TypeListTagVector3" << std::endl;
TryList(vtkm::Tuple<TypeId,1>(VECTOR3), vtkm::TypeListTagVector3());
std::cout << "TypeListTagVector4" << std::endl;
TryList(vtkm::Tuple<TypeId,1>(VECTOR4), vtkm::TypeListTagVector4());
std::cout << "TypeListTagIndex" << std::endl;
TryList(vtkm::Tuple<TypeId,3>(ID,ID2,ID3), vtkm::TypeListTagIndex());
std::cout << "TypeListTagReal" << std::endl;
TryList(vtkm::Tuple<TypeId,4>(SCALAR,VECTOR2,VECTOR3,VECTOR4),
vtkm::TypeListTagReal());
std::cout << "TypeListTagCommon" << std::endl;
TryList(vtkm::Tuple<TypeId,3>(ID,SCALAR,VECTOR3), vtkm::TypeListTagCommon());
std::cout << "TypeListTagAll" << std::endl;
vtkm::Tuple<TypeId,7> allTags;
allTags[0] = ID;
allTags[1] = ID2;
allTags[2] = ID3;
allTags[3] = SCALAR;
allTags[4] = VECTOR2;
allTags[5] = VECTOR3;
allTags[6] = VECTOR4;
TryList(allTags, vtkm::TypeListTagAll());
}
} // anonymous namespace
int UnitTestTypeListTag(int, char *[])
{
return vtkm::testing::Testing::Run(TestLists);
}