mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +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})
|
include_directories(${Boost_INCLUDE_DIRS})
|
||||||
|
|
||||||
set(headers
|
set(headers
|
||||||
|
Extent.h
|
||||||
ListTag.h
|
ListTag.h
|
||||||
TypeListTag.h
|
TypeListTag.h
|
||||||
Types.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
|
} // 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;
|
> Superclass;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
ArrayHandleCounting(CountingValueType startingValue, vtkm::Id length)
|
ArrayHandleCounting(CountingValueType startingValue, vtkm::Id length)
|
||||||
:Superclass(typename Superclass::PortalConstControl(startingValue, length))
|
:Superclass(typename Superclass::PortalConstControl(startingValue, length))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
ArrayHandleCounting():Superclass() {}
|
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
|
ArrayContainerControlBasic.h
|
||||||
ArrayContainerControlImplicit.h
|
ArrayContainerControlImplicit.h
|
||||||
ArrayHandle.h
|
ArrayHandle.h
|
||||||
|
ArrayHandleCompositeVector.h
|
||||||
ArrayHandleCounting.h
|
ArrayHandleCounting.h
|
||||||
|
ArrayHandleUniformPointCoordinates.h
|
||||||
ArrayPortal.h
|
ArrayPortal.h
|
||||||
Assert.h
|
Assert.h
|
||||||
ContainerListTag.h
|
ContainerListTag.h
|
||||||
|
@ -29,7 +29,9 @@ set(unit_tests
|
|||||||
UnitTestArrayContainerControlBasic.cxx
|
UnitTestArrayContainerControlBasic.cxx
|
||||||
UnitTestArrayContainerControlImplicit.cxx
|
UnitTestArrayContainerControlImplicit.cxx
|
||||||
UnitTestArrayHandle.cxx
|
UnitTestArrayHandle.cxx
|
||||||
|
UnitTestArrayHandleCompositeVector.cxx
|
||||||
UnitTestArrayHandleCounting.cxx
|
UnitTestArrayHandleCounting.cxx
|
||||||
|
UnitTestArrayHandleUniformPointCoordinates.cxx
|
||||||
UnitTestContainerListTag.cxx
|
UnitTestContainerListTag.cxx
|
||||||
UnitTestContTesting.cxx
|
UnitTestContTesting.cxx
|
||||||
UnitTestDeviceAdapterAlgorithmDependency.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.
|
// definitions of DoInvoke functions for all supported number of arguments.
|
||||||
// The created functions are conceptually defined as follows:
|
// 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
|
// VTKM_CONT_EXPORT
|
||||||
// void DoInvokeCont(const Function &f,
|
// void DoInvokeCont(const Function &f,
|
||||||
// ParameterContainer<Signature> ¶meters,
|
// ParameterContainer<P0(P1,P2,...)> ¶meters,
|
||||||
// FunctionInterfaceReturnContainer<R> &result,
|
// FunctionInterfaceReturnContainer<P0> &result,
|
||||||
// const TransformFunctor &transform)
|
// const TransformFunctor &transform)
|
||||||
// {
|
// {
|
||||||
// result.Value = transform(f(transform(parameters.Parameter1),...));
|
// result.Value = transform(f(transform(parameters.Parameter1),...));
|
||||||
@ -247,7 +251,7 @@ struct IdentityFunctor {
|
|||||||
f(BOOST_PP_ENUM_SHIFTED(NumParamsPlusOne, VTK_M_DO_INVOKE_TPARAM, )); \
|
f(BOOST_PP_ENUM_SHIFTED(NumParamsPlusOne, VTK_M_DO_INVOKE_TPARAM, )); \
|
||||||
}
|
}
|
||||||
#define VTK_M_DO_INVOKE_REPEAT(z, NumParams, data) \
|
#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_NAME DoInvokeCont
|
||||||
#define VTK_M_DO_INVOKE_EXPORT VTKM_CONT_EXPORT
|
#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,
|
template<typename OriginalFunction,
|
||||||
typename NewFunction,
|
typename NewFunction,
|
||||||
typename TransformFunctor,
|
typename TransformFunctor,
|
||||||
typename FinishFunctor>
|
typename FinishFunctor>
|
||||||
class FunctionInterfaceDynamicTransformContContinue;
|
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
|
} // namespace detail
|
||||||
|
|
||||||
template<typename FunctionSignature>
|
template<typename FunctionSignature>
|
||||||
@ -398,7 +549,7 @@ public:
|
|||||||
template<int ParameterIndex>
|
template<int ParameterIndex>
|
||||||
VTKM_EXEC_CONT_EXPORT
|
VTKM_EXEC_CONT_EXPORT
|
||||||
typename ParameterType<ParameterIndex>::type
|
typename ParameterType<ParameterIndex>::type
|
||||||
GetParameter() {
|
GetParameter() const {
|
||||||
return detail::GetParameter<ParameterIndex>(this->Parameters);
|
return detail::GetParameter<ParameterIndex>(this->Parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,6 +710,79 @@ public:
|
|||||||
return replacedFuncInterface;
|
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.
|
/// \brief Transforms the \c FunctionInterface based on run-time information.
|
||||||
///
|
///
|
||||||
/// The \c DynamicTransform method transforms all the parameters of this \c
|
/// The \c DynamicTransform method transforms all the parameters of this \c
|
||||||
@ -631,9 +855,8 @@ public:
|
|||||||
///
|
///
|
||||||
template<typename TransformFunctor, typename FinishFunctor>
|
template<typename TransformFunctor, typename FinishFunctor>
|
||||||
VTKM_CONT_EXPORT
|
VTKM_CONT_EXPORT
|
||||||
void
|
void DynamicTransformCont(const TransformFunctor &transform,
|
||||||
DynamicTransformCont(const TransformFunctor &transform,
|
const FinishFunctor &finish) {
|
||||||
const FinishFunctor &finish) {
|
|
||||||
typedef detail::FunctionInterfaceDynamicTransformContContinue<
|
typedef detail::FunctionInterfaceDynamicTransformContContinue<
|
||||||
FunctionSignature,
|
FunctionSignature,
|
||||||
ResultType(),
|
ResultType(),
|
||||||
@ -648,6 +871,33 @@ public:
|
|||||||
this->Result = emptyInterface.GetReturnValueSafe();
|
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:
|
private:
|
||||||
vtkm::internal::FunctionInterfaceReturnContainer<ResultType> Result;
|
vtkm::internal::FunctionInterfaceReturnContainer<ResultType> Result;
|
||||||
detail::ParameterContainer<FunctionSignature> Parameters;
|
detail::ParameterContainer<FunctionSignature> Parameters;
|
||||||
@ -655,6 +905,46 @@ private:
|
|||||||
|
|
||||||
namespace detail {
|
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,
|
template<typename OriginalFunction,
|
||||||
typename NewFunction,
|
typename NewFunction,
|
||||||
typename TransformFunctor,
|
typename TransformFunctor,
|
||||||
|
@ -135,10 +135,22 @@ struct GetReferenceFunctor
|
|||||||
const T *operator()(const T &x) const { return &x; }
|
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 {
|
struct ThreePointerArgFunctor {
|
||||||
void operator()(const Type1 *a1, const Type2 *a2, const Type3 *a3) const
|
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(*a1 == Arg1, "Arg 1 incorrect.");
|
||||||
VTKM_TEST_ASSERT(*a2 == Arg2, "Arg 2 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(
|
void TryFunctionInterface5(
|
||||||
vtkm::internal::FunctionInterface<void(Type1,Type2,Type3,Type4,Type5)> funcInterface)
|
vtkm::internal::FunctionInterface<void(Type1,Type2,Type3,Type4,Type5)> funcInterface)
|
||||||
{
|
{
|
||||||
@ -409,6 +429,35 @@ void TestTransformInvoke()
|
|||||||
"Got bad result from invoke.");
|
"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()
|
void TestDynamicTransform()
|
||||||
{
|
{
|
||||||
std::cout << "Trying dynamic transform." << std::endl;
|
std::cout << "Trying dynamic transform." << std::endl;
|
||||||
@ -429,6 +478,33 @@ void TestDynamicTransform()
|
|||||||
"DynamicTransform did not call finish the right number of times.");
|
"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()
|
void TestInvokeTime()
|
||||||
{
|
{
|
||||||
std::cout << "Checking time to call lots of args lots of times." << std::endl;
|
std::cout << "Checking time to call lots of args lots of times." << std::endl;
|
||||||
@ -487,7 +563,9 @@ void TestFunctionInterface()
|
|||||||
TestInvokeResult();
|
TestInvokeResult();
|
||||||
TestAppend();
|
TestAppend();
|
||||||
TestTransformInvoke();
|
TestTransformInvoke();
|
||||||
|
TestStaticTransform();
|
||||||
TestDynamicTransform();
|
TestDynamicTransform();
|
||||||
|
TestForEach();
|
||||||
TestInvokeTime();
|
TestInvokeTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ set(headers
|
|||||||
VTKM_declare_headers(${headers})
|
VTKM_declare_headers(${headers})
|
||||||
|
|
||||||
set(unit_tests
|
set(unit_tests
|
||||||
|
UnitTestExtent.cxx
|
||||||
UnitTestListTag.cxx
|
UnitTestListTag.cxx
|
||||||
UnitTestTesting.cxx
|
UnitTestTesting.cxx
|
||||||
UnitTestTypeListTag.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