mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Merge branch 'composite-vector-array' into dynamic-point-coordinates
This commit is contained in:
commit
ff31afca3e
@ -21,6 +21,7 @@
|
||||
include_directories(${Boost_INCLUDE_DIRS})
|
||||
|
||||
set(headers
|
||||
Extent.h
|
||||
ListTag.h
|
||||
TypeListTag.h
|
||||
Types.h
|
||||
|
319
vtkm/Extent.h
Normal file
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
|
110
vtkm/Types.h
110
vtkm/Types.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
|
||||
|
||||
|
716
vtkm/cont/ArrayHandleCompositeVector.h
Normal file
716
vtkm/cont/ArrayHandleCompositeVector.h
Normal file
@ -0,0 +1,716 @@
|
||||
//============================================================================
|
||||
// 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)))
|
||||
{ }
|
||||
};
|
||||
|
||||
/// Create a composite vector array from other arrays.
|
||||
///
|
||||
template<typename ValueType1, typename Container1>
|
||||
VTKM_CONT_EXPORT
|
||||
ArrayHandleCompositeVector<
|
||||
typename vtkm::VectorTraits<ValueType1>::ComponentType(
|
||||
vtkm::cont::ArrayHandle<ValueType1,Container1>)>
|
||||
make_ArrayHandleCompositeVector(
|
||||
const vtkm::cont::ArrayHandle<ValueType1,Container1> &array1,
|
||||
int sourceComponent1)
|
||||
{
|
||||
return ArrayHandleCompositeVector<
|
||||
typename vtkm::VectorTraits<ValueType1>::ComponentType(
|
||||
vtkm::cont::ArrayHandle<ValueType1,Container1>)>(array1,
|
||||
sourceComponent1);
|
||||
}
|
||||
template<typename ValueType1, typename Container1,
|
||||
typename ValueType2, typename Container2>
|
||||
VTKM_CONT_EXPORT
|
||||
ArrayHandleCompositeVector<
|
||||
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,2>(
|
||||
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||
vtkm::cont::ArrayHandle<ValueType2,Container2>)>
|
||||
make_ArrayHandleCompositeVector(
|
||||
const vtkm::cont::ArrayHandle<ValueType1,Container1> &array1,
|
||||
int sourceComponent1,
|
||||
const vtkm::cont::ArrayHandle<ValueType2,Container2> &array2,
|
||||
int sourceComponent2)
|
||||
{
|
||||
return ArrayHandleCompositeVector<
|
||||
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,2>(
|
||||
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||
vtkm::cont::ArrayHandle<ValueType2,Container2>)>(array1,
|
||||
sourceComponent1,
|
||||
array2,
|
||||
sourceComponent2);
|
||||
}
|
||||
template<typename ValueType1, typename Container1,
|
||||
typename ValueType2, typename Container2,
|
||||
typename ValueType3, typename Container3>
|
||||
VTKM_CONT_EXPORT
|
||||
ArrayHandleCompositeVector<
|
||||
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,3>(
|
||||
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||
vtkm::cont::ArrayHandle<ValueType2,Container2>,
|
||||
vtkm::cont::ArrayHandle<ValueType3,Container3>)>
|
||||
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 ArrayHandleCompositeVector<
|
||||
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,3>(
|
||||
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||
vtkm::cont::ArrayHandle<ValueType2,Container2>,
|
||||
vtkm::cont::ArrayHandle<ValueType3,Container3>)>(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
|
||||
ArrayHandleCompositeVector<
|
||||
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,4>(
|
||||
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||
vtkm::cont::ArrayHandle<ValueType2,Container2>,
|
||||
vtkm::cont::ArrayHandle<ValueType3,Container3>,
|
||||
vtkm::cont::ArrayHandle<ValueType4,Container4>)>
|
||||
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 ArrayHandleCompositeVector<
|
||||
vtkm::Tuple<typename vtkm::VectorTraits<ValueType1>::ComponentType,4>(
|
||||
vtkm::cont::ArrayHandle<ValueType1,Container1>,
|
||||
vtkm::cont::ArrayHandle<ValueType2,Container2>,
|
||||
vtkm::cont::ArrayHandle<ValueType3,Container3>,
|
||||
vtkm::cont::ArrayHandle<ValueType4,Container4>)>(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() {}
|
||||
};
|
||||
|
||||
|
158
vtkm/cont/ArrayHandleUniformPointCoordinates.h
Normal file
158
vtkm/cont/ArrayHandleUniformPointCoordinates.h
Normal file
@ -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,7 +25,9 @@ set(headers
|
||||
ArrayContainerControlBasic.h
|
||||
ArrayContainerControlImplicit.h
|
||||
ArrayHandle.h
|
||||
ArrayHandleCompositeVector.h
|
||||
ArrayHandleCounting.h
|
||||
ArrayHandleUniformPointCoordinates.h
|
||||
ArrayPortal.h
|
||||
Assert.h
|
||||
ContainerListTag.h
|
||||
|
@ -29,7 +29,9 @@ set(unit_tests
|
||||
UnitTestArrayContainerControlBasic.cxx
|
||||
UnitTestArrayContainerControlImplicit.cxx
|
||||
UnitTestArrayHandle.cxx
|
||||
UnitTestArrayHandleCompositeVector.cxx
|
||||
UnitTestArrayHandleCounting.cxx
|
||||
UnitTestArrayHandleUniformPointCoordinates.cxx
|
||||
UnitTestContainerListTag.cxx
|
||||
UnitTestContTesting.cxx
|
||||
UnitTestDeviceAdapterAlgorithmDependency.cxx
|
||||
|
313
vtkm/cont/testing/UnitTestArrayHandleCompositeVector.cxx
Normal file
313
vtkm/cont/testing/UnitTestArrayHandleCompositeVector.cxx
Normal file
@ -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 vtkm::cont::ArrayHandleCompositeVector<vtkm::Scalar(InArrayType)>
|
||||
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);
|
||||
}
|
@ -192,11 +192,15 @@ struct IdentityFunctor {
|
||||
// definitions of DoInvoke functions for all supported number of arguments.
|
||||
// The created functions are conceptually defined as follows:
|
||||
//
|
||||
// template<typename Function, typename Signature, typename TransformFunctor>
|
||||
// template<typename Function,
|
||||
// typename TransformFunctor,
|
||||
// typename P0,
|
||||
// typename P1,
|
||||
// typename P2,...>
|
||||
// VTKM_CONT_EXPORT
|
||||
// void DoInvokeCont(const Function &f,
|
||||
// ParameterContainer<Signature> ¶meters,
|
||||
// FunctionInterfaceReturnContainer<R> &result,
|
||||
// ParameterContainer<P0(P1,P2,...)> ¶meters,
|
||||
// FunctionInterfaceReturnContainer<P0> &result,
|
||||
// const TransformFunctor &transform)
|
||||
// {
|
||||
// result.Value = transform(f(transform(parameters.Parameter1),...));
|
||||
@ -247,7 +251,7 @@ struct IdentityFunctor {
|
||||
f(BOOST_PP_ENUM_SHIFTED(NumParamsPlusOne, VTK_M_DO_INVOKE_TPARAM, )); \
|
||||
}
|
||||
#define VTK_M_DO_INVOKE_REPEAT(z, NumParams, data) \
|
||||
VTK_M_DO_INVOKE(BOOST_PP_INC(NumParams));
|
||||
VTK_M_DO_INVOKE(BOOST_PP_INC(NumParams))
|
||||
|
||||
#define VTK_M_DO_INVOKE_NAME DoInvokeCont
|
||||
#define VTK_M_DO_INVOKE_EXPORT VTKM_CONT_EXPORT
|
||||
@ -318,12 +322,159 @@ struct FunctionInterfaceCopyParameters<0, ParameterIndex> {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename OriginalSignature, typename Transform>
|
||||
struct FunctionInterfaceStaticTransformType;
|
||||
|
||||
// The following code uses the Boost preprocessor utilities to create
|
||||
// definitions of DoStaticTransform functions for all supported number of
|
||||
// arguments. The created functions are conceptually defined as follows:
|
||||
//
|
||||
// template<typename Transform,
|
||||
// typename OriginalSignature,
|
||||
// typename TransformedSignature>
|
||||
// VTKM_CONT_EXPORT
|
||||
// void DoStaticTransformCont(
|
||||
// const Transform &transform,
|
||||
// const ParameterContainer<OriginalSignature> &originalParameters,
|
||||
// ParameterContainer<TransformedSignature> &transformedParameters)
|
||||
// {
|
||||
// transformedParameters.Parameter1 = transform(originalParameters.Parameter1);
|
||||
// transformedParameters.Parameter2 = transform(originalParameters.Parameter2);
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// We define multiple DoStaticTransformCont and DoStaticTransformExec that do
|
||||
// identical things with different exports. It is important to have these
|
||||
// separate definitions instead of a single version with VTKM_EXEC_CONT_EXPORT
|
||||
// because the transform to be invoked may only be viable in one or the other.
|
||||
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_ASSIGN(z, count, data) \
|
||||
BOOST_PP_IF(count, \
|
||||
BOOST_PP_CAT(transformedParameters.Parameter, count) = \
|
||||
transform(BOOST_PP_CAT(originalParameters.Parameter, count));,)
|
||||
|
||||
#define VTK_M_DO_STATIC_TRANSFORM(NumParamsPlusOne) \
|
||||
template<typename Transform, \
|
||||
BOOST_PP_ENUM_PARAMS(NumParamsPlusOne, typename OriginalP), \
|
||||
BOOST_PP_ENUM_PARAMS(NumParamsPlusOne, typename TransformedP)> \
|
||||
VTK_M_DO_STATIC_TRANSFORM_EXPORT \
|
||||
void VTK_M_DO_STATIC_TRANSFORM_NAME( \
|
||||
const Transform &transform, \
|
||||
const ParameterContainer<OriginalP0(BOOST_PP_ENUM_SHIFTED_PARAMS(NumParamsPlusOne, OriginalP))> &originalParameters, \
|
||||
ParameterContainer<TransformedP0(BOOST_PP_ENUM_SHIFTED_PARAMS(NumParamsPlusOne, TransformedP))> &transformedParameters) \
|
||||
{ \
|
||||
(void)transform; \
|
||||
(void)originalParameters; \
|
||||
(void)transformedParameters; \
|
||||
BOOST_PP_REPEAT(NumParamsPlusOne, VTK_M_DO_STATIC_TRANSFORM_ASSIGN,) \
|
||||
}
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_REPEAT(z, NumParams, data) \
|
||||
VTK_M_DO_STATIC_TRANSFORM(BOOST_PP_INC(NumParams))
|
||||
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_NAME DoStaticTransformCont
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_EXPORT VTKM_CONT_EXPORT
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(VTKM_MAX_FUNCTION_PARAMETERS),
|
||||
VTK_M_DO_STATIC_TRANSFORM_REPEAT,)
|
||||
#undef VTK_M_DO_STATIC_TRANSFORM_EXPORT
|
||||
#undef VTK_M_DO_STATIC_TRANSFORM_NAME
|
||||
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_NAME DoStaticTransformExec
|
||||
#define VTK_M_DO_STATIC_TRANSFORM_EXPORT VTKM_EXEC_EXPORT
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(VTKM_MAX_FUNCTION_PARAMETERS),
|
||||
VTK_M_DO_STATIC_TRANSFORM_REPEAT,)
|
||||
#undef VTK_M_DO_STATIC_TRANSFORM_EXPORT
|
||||
#undef VTK_M_DO_STATIC_TRANSFORM_NAME
|
||||
|
||||
#undef VTK_M_DO_STATIC_TRANSFORM_REPEAT
|
||||
#undef VTK_M_DO_STATIC_TRANSFORM
|
||||
#undef VTK_M_DO_STATIC_TRANSFORM_ASSIGN
|
||||
|
||||
template<typename OriginalFunction,
|
||||
typename NewFunction,
|
||||
typename TransformFunctor,
|
||||
typename FinishFunctor>
|
||||
class FunctionInterfaceDynamicTransformContContinue;
|
||||
|
||||
// The following code uses the Boost preprocessor utilities to create
|
||||
// definitions of DoForEach functions for all supported number of arguments.
|
||||
// The created functions are conceptually defined as follows:
|
||||
//
|
||||
// template<typename Functor, typename P0, typename P1, typename P2,...>
|
||||
// VTKM_CONT_EXPORT
|
||||
// void DoForEachCont(const Functor &f,
|
||||
// ParameterContainer<P0(P1,P2,...)> ¶meters)
|
||||
//
|
||||
// {
|
||||
// f(parameters.Parameter1);
|
||||
// f(parameters.Parameter2);
|
||||
// ...
|
||||
// }
|
||||
//
|
||||
// We define multiple DoForEachCont and DoForEachExec that do identical things
|
||||
// with different exports. It is important to have these separate definitions
|
||||
// instead of a single version with VTKM_EXEC_CONT_EXPORT because the functor
|
||||
// to be invoked on each parameter may only be viable in one or the other.
|
||||
// There are also separate versions that support a const FunctionInterface and
|
||||
// a non-const FunctionInterface.
|
||||
|
||||
#define VTK_M_DO_FOR_EACH_CALL_PARAM(z, count, data) \
|
||||
BOOST_PP_IF(count, f(BOOST_PP_CAT(parameters.Parameter, count));,)
|
||||
|
||||
#define VTK_M_DO_FOR_EACH(NumParamsPlusOne) \
|
||||
template<typename Functor, \
|
||||
BOOST_PP_ENUM_PARAMS(NumParamsPlusOne, typename P)> \
|
||||
VTK_M_DO_FOR_EACH_EXPORT \
|
||||
void VTK_M_DO_FOR_EACH_NAME( \
|
||||
const Functor &f, \
|
||||
VTK_M_DO_FOR_EACH_FI_CONST ParameterContainer<P0(BOOST_PP_ENUM_SHIFTED_PARAMS(NumParamsPlusOne, P))> ¶meters) \
|
||||
{ \
|
||||
(void)f; \
|
||||
(void)parameters; \
|
||||
BOOST_PP_REPEAT(NumParamsPlusOne, VTK_M_DO_FOR_EACH_CALL_PARAM,) \
|
||||
}
|
||||
#define VTK_M_DO_FOR_EACH_REPEAT(z, NumParams, data) \
|
||||
VTK_M_DO_FOR_EACH(BOOST_PP_INC(NumParams))
|
||||
|
||||
#define VTK_M_DO_FOR_EACH_EXPORT VTKM_CONT_EXPORT
|
||||
#define VTK_M_DO_FOR_EACH_NAME DoForEachCont
|
||||
#define VTK_M_DO_FOR_EACH_FI_CONST const
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(VTKM_MAX_FUNCTION_PARAMETERS),
|
||||
VTK_M_DO_FOR_EACH_REPEAT,)
|
||||
#undef VTK_M_DO_FOR_EACH_FI_CONST
|
||||
#undef VTK_M_DO_FOR_EACH_NAME
|
||||
#undef VTK_M_DO_FOR_EACH_EXPORT
|
||||
|
||||
#define VTK_M_DO_FOR_EACH_EXPORT VTKM_CONT_EXPORT
|
||||
#define VTK_M_DO_FOR_EACH_NAME DoForEachCont
|
||||
#define VTK_M_DO_FOR_EACH_FI_CONST
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(VTKM_MAX_FUNCTION_PARAMETERS),
|
||||
VTK_M_DO_FOR_EACH_REPEAT,)
|
||||
#undef VTK_M_DO_FOR_EACH_FI_CONST
|
||||
#undef VTK_M_DO_FOR_EACH_NAME
|
||||
#undef VTK_M_DO_FOR_EACH_EXPORT
|
||||
|
||||
#define VTK_M_DO_FOR_EACH_EXPORT VTKM_EXEC_EXPORT
|
||||
#define VTK_M_DO_FOR_EACH_NAME DoForEachExec
|
||||
#define VTK_M_DO_FOR_EACH_FI_CONST const
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(VTKM_MAX_FUNCTION_PARAMETERS),
|
||||
VTK_M_DO_FOR_EACH_REPEAT,)
|
||||
#undef VTK_M_DO_FOR_EACH_FI_CONST
|
||||
#undef VTK_M_DO_FOR_EACH_NAME
|
||||
#undef VTK_M_DO_FOR_EACH_EXPORT
|
||||
|
||||
#define VTK_M_DO_FOR_EACH_EXPORT VTKM_EXEC_EXPORT
|
||||
#define VTK_M_DO_FOR_EACH_NAME DoForEachExec
|
||||
#define VTK_M_DO_FOR_EACH_FI_CONST
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(VTKM_MAX_FUNCTION_PARAMETERS),
|
||||
VTK_M_DO_FOR_EACH_REPEAT,)
|
||||
#undef VTK_M_DO_FOR_EACH_FI_CONST
|
||||
#undef VTK_M_DO_FOR_EACH_NAME
|
||||
#undef VTK_M_DO_FOR_EACH_EXPORT
|
||||
|
||||
#undef VTK_M_DO_FOR_EACH_REPEAT
|
||||
#undef VTK_M_DO_FOR_EACH
|
||||
#undef VTK_M_DO_FOR_EACH_CALL_PARAM
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename FunctionSignature>
|
||||
@ -398,7 +549,7 @@ public:
|
||||
template<int ParameterIndex>
|
||||
VTKM_EXEC_CONT_EXPORT
|
||||
typename ParameterType<ParameterIndex>::type
|
||||
GetParameter() {
|
||||
GetParameter() const {
|
||||
return detail::GetParameter<ParameterIndex>(this->Parameters);
|
||||
}
|
||||
|
||||
@ -559,6 +710,79 @@ public:
|
||||
return replacedFuncInterface;
|
||||
}
|
||||
|
||||
template<typename Transform>
|
||||
struct StaticTransformType {
|
||||
typedef FunctionInterface<
|
||||
typename detail::FunctionInterfaceStaticTransformType<
|
||||
FunctionSignature,Transform>::type> type;
|
||||
};
|
||||
|
||||
/// \brief Transforms the \c FunctionInterface based on compile-time
|
||||
/// information.
|
||||
///
|
||||
/// The \c StaticTransform methods transform all the parameters of this \c
|
||||
/// FunctionInterface to different types and values based on compile-time
|
||||
/// information. It operates by accepting a functor that defines a unary
|
||||
/// function whose argument is the parameter to transform and the return
|
||||
/// value is the transformed value. The functor must also contain a templated
|
||||
/// struct name ReturnType with an internal type named \c type that defines
|
||||
/// the return type of the transform for a given input type.
|
||||
///
|
||||
/// The transformation is only applied to the parameters of the function. The
|
||||
/// return argument is uneffected.
|
||||
///
|
||||
/// The return type can be determined with the \c StaticTransformType
|
||||
/// template.
|
||||
///
|
||||
/// Here is an example of a transformation that converts a \c
|
||||
/// FunctionInterface to another \c FunctionInterface containing pointers to
|
||||
/// all of the parameters.
|
||||
///
|
||||
/// \code
|
||||
/// struct MyTransformFunctor {
|
||||
/// template<typename T>
|
||||
/// struct ReturnType {
|
||||
/// typedef const T *type;
|
||||
/// };
|
||||
///
|
||||
/// template<typename T>
|
||||
/// DAX_CONT_EXPORT
|
||||
/// const T *operator()(const T &x) const {
|
||||
/// return &x;
|
||||
/// }
|
||||
/// };
|
||||
///
|
||||
/// template<typename FunctionSignature>
|
||||
/// typename vtkm::internal::FunctionInterface<FunctionSignature>::template StaticTransformType<MyTransformFunctor>::type
|
||||
/// ImportantStuff(const vtkm::internal::FunctionInterface<FunctionSignature> &funcInterface)
|
||||
/// {
|
||||
/// return funcInterface.StaticTransformCont(MyTransformFunctor());
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
template<typename Transform>
|
||||
VTKM_CONT_EXPORT
|
||||
typename StaticTransformType<Transform>::type
|
||||
StaticTransformCont(const Transform &transform) const
|
||||
{
|
||||
typename StaticTransformType<Transform>::type newFuncInterface;
|
||||
detail::DoStaticTransformCont(transform,
|
||||
this->Parameters,
|
||||
newFuncInterface.Parameters);
|
||||
return newFuncInterface;
|
||||
}
|
||||
template<typename Transform>
|
||||
VTKM_EXEC_EXPORT
|
||||
typename StaticTransformType<Transform>::type
|
||||
StaticTransformExec(const Transform &transform) const
|
||||
{
|
||||
typename StaticTransformType<Transform>::type newFuncInterface;
|
||||
detail::DoStaticTransformExec(transform,
|
||||
this->Parameters,
|
||||
newFuncInterface.Parameters);
|
||||
return newFuncInterface;
|
||||
}
|
||||
|
||||
/// \brief Transforms the \c FunctionInterface based on run-time information.
|
||||
///
|
||||
/// The \c DynamicTransform method transforms all the parameters of this \c
|
||||
@ -631,9 +855,8 @@ public:
|
||||
///
|
||||
template<typename TransformFunctor, typename FinishFunctor>
|
||||
VTKM_CONT_EXPORT
|
||||
void
|
||||
DynamicTransformCont(const TransformFunctor &transform,
|
||||
const FinishFunctor &finish) {
|
||||
void DynamicTransformCont(const TransformFunctor &transform,
|
||||
const FinishFunctor &finish) {
|
||||
typedef detail::FunctionInterfaceDynamicTransformContContinue<
|
||||
FunctionSignature,
|
||||
ResultType(),
|
||||
@ -648,6 +871,33 @@ public:
|
||||
this->Result = emptyInterface.GetReturnValueSafe();
|
||||
}
|
||||
|
||||
/// \brief Applies a function to all the parameters.
|
||||
///
|
||||
/// The \c ForEach methods take a function and apply that function to each
|
||||
/// of the parameters in the \c FunctionInterface. (Return values are not
|
||||
/// effected.)
|
||||
///
|
||||
template<typename Functor>
|
||||
VTKM_CONT_EXPORT
|
||||
void ForEachCont(const Functor &f) const {
|
||||
detail::DoForEachCont(f, this->Parameters);
|
||||
}
|
||||
template<typename Functor>
|
||||
VTKM_CONT_EXPORT
|
||||
void ForEachCont(const Functor &f) {
|
||||
detail::DoForEachCont(f, this->Parameters);
|
||||
}
|
||||
template<typename Functor>
|
||||
VTKM_EXEC_EXPORT
|
||||
void ForEachExec(const Functor &f) const {
|
||||
detail::DoForEachExec(f, this->Parameters);
|
||||
}
|
||||
template<typename Functor>
|
||||
VTKM_EXEC_EXPORT
|
||||
void ForEachExec(const Functor &f) {
|
||||
detail::DoForEachExec(f, this->Parameters);
|
||||
}
|
||||
|
||||
private:
|
||||
vtkm::internal::FunctionInterfaceReturnContainer<ResultType> Result;
|
||||
detail::ParameterContainer<FunctionSignature> Parameters;
|
||||
@ -655,6 +905,46 @@ private:
|
||||
|
||||
namespace detail {
|
||||
|
||||
// The following code uses the Boost preprocessor utilities to create
|
||||
// definitions of FunctionInterfaceStaticTransformType for all supported number
|
||||
// of arguments. The created classes are conceptually defined as follows:
|
||||
//
|
||||
// template<typename Transform,
|
||||
// typename P0, // Return type
|
||||
// typename P1,
|
||||
// typename P2, ...>
|
||||
// struct FunctionInterfaceStaticTransformType<P0(P1,P2,...), Transform> {
|
||||
// typedef P0(type)(typename Transform::template ReturnType<P1>::type,
|
||||
// typename Transform::template ReturnType<P2>::type, ...);
|
||||
// };
|
||||
|
||||
#define VTK_M_STATIC_TRANSFORM_TPARAM(z, ParamIndex, data) \
|
||||
BOOST_PP_IF( \
|
||||
ParamIndex, \
|
||||
typename Transform::template ReturnType<BOOST_PP_CAT(P,ParamIndex)>::type,)
|
||||
|
||||
#define VTK_M_STATIC_TRANSFORM_TYPE(NumParamsPlusOne) \
|
||||
template<typename Transform, \
|
||||
BOOST_PP_ENUM_PARAMS(NumParamsPlusOne, typename P)> \
|
||||
struct FunctionInterfaceStaticTransformType< \
|
||||
P0(BOOST_PP_ENUM_SHIFTED_PARAMS(NumParamsPlusOne, P)), \
|
||||
Transform> \
|
||||
{ \
|
||||
typedef P0(type)( \
|
||||
BOOST_PP_ENUM_SHIFTED(NumParamsPlusOne, VTK_M_STATIC_TRANSFORM_TPARAM,) \
|
||||
); \
|
||||
};
|
||||
#define VTK_M_STATIC_TRANSFORM_TYPE_REPEAT(z, NumParams, data) \
|
||||
VTK_M_STATIC_TRANSFORM_TYPE(BOOST_PP_INC(NumParams))
|
||||
|
||||
BOOST_PP_REPEAT(BOOST_PP_INC(VTKM_MAX_FUNCTION_PARAMETERS),
|
||||
VTK_M_STATIC_TRANSFORM_TYPE_REPEAT,)
|
||||
|
||||
#undef VTK_M_STATIC_TRANSFORM_TYPE_REPEAT
|
||||
#undef VTK_M_STATIC_TRANSFORM_TYPE
|
||||
#undef VTK_M_STATIC_TRANSFORM_TPARAM
|
||||
|
||||
|
||||
template<typename OriginalFunction,
|
||||
typename NewFunction,
|
||||
typename TransformFunctor,
|
||||
|
@ -135,10 +135,22 @@ struct GetReferenceFunctor
|
||||
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 arg functor." << std::endl;
|
||||
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.");
|
||||
@ -286,6 +298,14 @@ struct DynamicTransformFinish
|
||||
}
|
||||
};
|
||||
|
||||
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)
|
||||
{
|
||||
@ -409,6 +429,35 @@ void TestTransformInvoke()
|
||||
"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;
|
||||
@ -429,6 +478,33 @@ void TestDynamicTransform()
|
||||
"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;
|
||||
@ -487,7 +563,9 @@ void TestFunctionInterface()
|
||||
TestInvokeResult();
|
||||
TestAppend();
|
||||
TestTransformInvoke();
|
||||
TestStaticTransform();
|
||||
TestDynamicTransform();
|
||||
TestForEach();
|
||||
TestInvokeTime();
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ set(headers
|
||||
VTKM_declare_headers(${headers})
|
||||
|
||||
set(unit_tests
|
||||
UnitTestExtent.cxx
|
||||
UnitTestListTag.cxx
|
||||
UnitTestTesting.cxx
|
||||
UnitTestTypeListTag.cxx
|
||||
|
197
vtkm/testing/UnitTestExtent.cxx
Normal file
197
vtkm/testing/UnitTestExtent.cxx
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user