vtk-m/vtkm/VecAxisAlignedPointCoordinates.h
Sujin Philip e28309f09b Remove VTKM_EXEC_CONSTANT
If a global static array is declared with VTKM_EXEC_CONSTANT and the code
is compiled by nvcc (for multibackend code) then the array is only accesible
on the GPU. If for some reason a worklet fails on the cuda backend and it is
re-executed on any of the CPU backends, it will continue to fail.

We couldn't find a simple way to declare the array once and have it available
on both CPU and GPU. The approach we are using here is to declare the arrays
as static inside some "Get" function which is marked as VTKM_EXEC_CONT.
2017-12-05 13:49:55 -05:00

176 lines
5.6 KiB
C++

//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_VecAxisAlignedPointCoordinates_h
#define vtk_m_VecAxisAlignedPointCoordinates_h
#include <vtkm/Math.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/Types.h>
#include <vtkm/VecTraits.h>
namespace vtkm
{
namespace detail
{
/// Specifies the size of VecAxisAlignedPointCoordinates for the given
/// dimension.
///
template <vtkm::IdComponent NumDimensions>
struct VecAxisAlignedPointCoordinatesNumComponents;
template <>
struct VecAxisAlignedPointCoordinatesNumComponents<1>
{
static const vtkm::IdComponent NUM_COMPONENTS = 2;
};
template <>
struct VecAxisAlignedPointCoordinatesNumComponents<2>
{
static const vtkm::IdComponent NUM_COMPONENTS = 4;
};
template <>
struct VecAxisAlignedPointCoordinatesNumComponents<3>
{
static const vtkm::IdComponent NUM_COMPONENTS = 8;
};
} // namespace detail
/// \brief An implicit vector for point coordinates in axis aligned cells. For
/// internal use only.
///
/// The \c VecAxisAlignedPointCoordinates class is a Vec-like class that holds
/// the point coordinates for a axis aligned cell. The class is templated on the
/// dimensions of the cell, which can be 1 (for a line).
///
/// This is an internal class used to represent coordinates for uniform datasets
/// in an execution environment when executing a WorkletMapPointToCell. Users
/// should not directly construct this class under any circumstances. Use the
/// related ArrayPortalUniformPointCoordinates and
/// ArrayHandleUniformPointCoordinates classes instead.
///
template <vtkm::IdComponent NumDimensions>
class VecAxisAlignedPointCoordinates
{
public:
typedef vtkm::Vec<vtkm::FloatDefault, 3> ComponentType;
static const vtkm::IdComponent NUM_COMPONENTS =
detail::VecAxisAlignedPointCoordinatesNumComponents<NumDimensions>::NUM_COMPONENTS;
VTKM_EXEC_CONT
VecAxisAlignedPointCoordinates(ComponentType origin = ComponentType(0, 0, 0),
ComponentType spacing = ComponentType(1, 1, 1))
: Origin(origin)
, Spacing(spacing)
{
}
VTKM_EXEC_CONT
vtkm::IdComponent GetNumberOfComponents() const { return NUM_COMPONENTS; }
template <vtkm::IdComponent DestSize>
VTKM_EXEC_CONT void CopyInto(vtkm::Vec<ComponentType, DestSize>& dest) const
{
vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->GetNumberOfComponents());
for (vtkm::IdComponent index = 0; index < numComponents; index++)
{
dest[index] = (*this)[index];
}
}
VTKM_EXEC_CONT
ComponentType operator[](vtkm::IdComponent index) const
{
static const vtkm::FloatDefault VecAxisAlignedPointCoordinatesOffsetTable[8][3] = {
{ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }
};
const auto& offset = VecAxisAlignedPointCoordinatesOffsetTable[index];
return ComponentType(this->Origin[0] + offset[0] * this->Spacing[0],
this->Origin[1] + offset[1] * this->Spacing[1],
this->Origin[2] + offset[2] * this->Spacing[2]);
}
VTKM_EXEC_CONT
const ComponentType& GetOrigin() const { return this->Origin; }
VTKM_EXEC_CONT
const ComponentType& GetSpacing() const { return this->Spacing; }
private:
// Position of lower left point.
ComponentType Origin;
// Spacing in the x, y, and z directions.
ComponentType Spacing;
};
template <vtkm::IdComponent NumDimensions>
struct TypeTraits<vtkm::VecAxisAlignedPointCoordinates<NumDimensions>>
{
typedef vtkm::TypeTraitsRealTag NumericTag;
typedef TypeTraitsVectorTag DimensionalityTag;
VTKM_EXEC_CONT
static vtkm::VecAxisAlignedPointCoordinates<NumDimensions> ZeroInitialization()
{
return vtkm::VecAxisAlignedPointCoordinates<NumDimensions>(
vtkm::Vec<vtkm::FloatDefault, 3>(0, 0, 0), vtkm::Vec<vtkm::FloatDefault, 3>(0, 0, 0));
}
};
template <vtkm::IdComponent NumDimensions>
struct VecTraits<vtkm::VecAxisAlignedPointCoordinates<NumDimensions>>
{
typedef vtkm::VecAxisAlignedPointCoordinates<NumDimensions> VecType;
typedef vtkm::Vec<vtkm::FloatDefault, 3> ComponentType;
typedef vtkm::VecTraitsTagMultipleComponents HasMultipleComponents;
typedef vtkm::VecTraitsTagSizeStatic IsSizeStatic;
static const vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const VecType&) { return NUM_COMPONENTS; }
VTKM_EXEC_CONT
static ComponentType GetComponent(const VecType& vector, vtkm::IdComponent componentIndex)
{
return vector[componentIndex];
}
template <vtkm::IdComponent destSize>
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
{
src.CopyInto(dest);
}
};
} // namespace vtkm
#endif //vtk_m_VecAxisAlignedPointCoordinates_h