//============================================================================ // 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_Types_h #define vtk_m_Types_h #include #include /*! * \namespace vtkm * \brief VTKm Toolkit. * * vtkm is the namespace for the VTKm Toolkit. It contains other sub namespaces, * as well as basic data types and functions callable from all components in VTKm * toolkit. * * \namespace vtkm::cont * \brief VTKm Control Environment. * * vtkm::cont defines the publicly accessible API for the VTKm Control * Environment. Users of the VTKm Toolkit can use this namespace to access the * Control Environment. * * \namespace vtkm::cuda * \brief CUDA implementation. * * vtkm::cuda includes the code to implement the VTKm for CUDA-based platforms. * * \namespace vtkm::cuda::cont * \brief CUDA implementation for Control Environment. * * vtkm::cuda::cont includes the code to implement the VTKm Control Environment * for CUDA-based platforms. * * \namespace vtkm::cuda::exec * \brief CUDA implementation for Execution Environment. * * vtkm::cuda::exec includes the code to implement the VTKm Execution Environment * for CUDA-based platforms. * * \namespace vtkm::exec * \brief VTKm Execution Environment. * * vtkm::exec defines the publicly accessible API for the VTKm Execution * Environment. Worklets typically use classes/apis defined within this * namespace alone. * * \namespace vtkm::internal * \brief VTKm Internal Environment * * vtkm::internal defines API which is internal and subject to frequent * change. This should not be used for projects using VTKm. Instead it servers * are a reference for the developers of VTKm. * * \namespace vtkm::math * \brief Utility math functions * * vtkm::math defines the publicly accessible API for Utility Math functions. * * \namespace vtkm::testing * \brief Internal testing classes * */ namespace vtkm { //***************************************************************************** // Typedefs for basic types. //***************************************************************************** /// Alignment requirements are prescribed by CUDA on device (Table B-1 in NVIDIA /// CUDA C Programming Guide 4.0) namespace internal { #if VTKM_SIZE_INT == 4 typedef int Int32Type; typedef unsigned int UInt32Type; #else #error Could not find a 32-bit integer. #endif #if VTKM_SIZE_LONG == 8 typedef long Int64Type; typedef unsigned long UInt64Type; #elif VTKM_SIZE_LONG_LONG == 8 typedef long long Int64Type; typedef unsigned long long UInt64Type; #else #error Could not find a 64-bit integer. #endif //----------------------------------------------------------------------------- template struct equals { template VTKM_EXEC_CONT_EXPORT bool operator()(const T& a, const T& b) const { return equals()(a,b) && a[Size-1] == b[Size-1]; } }; template<> struct equals<1> { template VTKM_EXEC_CONT_EXPORT bool operator()(const T& a, const T& b) const { return a[0] == b[0]; } }; template<> struct equals<2> { template VTKM_EXEC_CONT_EXPORT bool operator()(const T& a, const T& b) const { return a[0] == b[0] && a[1] == b[1]; } }; template<> struct equals<3> { template VTKM_EXEC_CONT_EXPORT bool operator()(const T& a, const T& b) const { return a[0] == b[0] && a[1] == b[1] && a[2] == b[2]; } }; template struct assign_scalar_to_vector { template VTKM_EXEC_CONT_EXPORT void operator()(VectorType &dest, const ComponentType &src) { assign_scalar_to_vector()(dest, src); dest[Size-1] = src; } }; template<> struct assign_scalar_to_vector<1> { template VTKM_EXEC_CONT_EXPORT void operator()(VectorType &dest, const ComponentType &src) { dest[0] = src; } }; template<> struct assign_scalar_to_vector<2> { template VTKM_EXEC_CONT_EXPORT void operator()(VectorType &dest, const ComponentType &src) { dest[0] = src; dest[1] = src; } }; template<> struct assign_scalar_to_vector<3> { template VTKM_EXEC_CONT_EXPORT void operator()(VectorType &dest, const ComponentType &src) { dest[0] = src; dest[1] = src; dest[2] = src; } }; template struct copy_vector { template VTKM_EXEC_CONT_EXPORT void operator()(T1 &dest, const T2 &src) { copy_vector()(dest, src); dest[Size-1] = src[Size-1]; } }; template<> struct copy_vector<1> { template VTKM_EXEC_CONT_EXPORT void operator()(T1 &dest, const T2 &src) { dest[0] = src[0]; } }; template<> struct copy_vector<2> { template VTKM_EXEC_CONT_EXPORT void operator()(T1 &dest, const T2 &src) { dest[0] = src[0]; dest[1] = src[1]; } }; template<> struct copy_vector<3> { template VTKM_EXEC_CONT_EXPORT void operator()(T1 &dest, const T2 &src) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; } }; template struct sum_vector { template VTKM_EXEC_CONT_EXPORT typename T::ComponentType operator()(const T &x) { return sum_vector()(x) + x[Size-1]; } }; template<> struct sum_vector<1> { template VTKM_EXEC_CONT_EXPORT typename T::ComponentType operator()(const T &x) { return x[0]; } }; template<> struct sum_vector<2> { template VTKM_EXEC_CONT_EXPORT typename T::ComponentType operator()(const T &x) { return x[0] + x[1]; } }; template<> struct sum_vector<3> { template VTKM_EXEC_CONT_EXPORT typename T::ComponentType operator()(const T &x) { return x[0] + x[1] + x[2]; } }; template<> struct sum_vector<4> { template VTKM_EXEC_CONT_EXPORT typename T::ComponentType operator()(const T &x) { return x[0] + x[1] + x[2] + x[3]; } }; template struct product_vector { template VTKM_EXEC_CONT_EXPORT typename T::ComponentType operator()(const T &x) { return product_vector()(x) * x[Size-1]; } }; template<> struct product_vector<1> { template VTKM_EXEC_CONT_EXPORT typename T::ComponentType operator()(const T &x) { return x[0]; } }; template<> struct product_vector<2> { template VTKM_EXEC_CONT_EXPORT typename T::ComponentType operator()(const T &x) { return x[0] * x[1]; } }; template<> struct product_vector<3> { template VTKM_EXEC_CONT_EXPORT typename T::ComponentType operator()(const T &x) { return x[0] * x[1] * x[2]; } }; template<> struct product_vector<4> { template VTKM_EXEC_CONT_EXPORT typename T::ComponentType operator()(const T &x) { return x[0] * x[1] * x[2] * x[3]; } }; } // namespace internal //----------------------------------------------------------------------------- #if VTKM_SIZE_ID == 4 /// Represents an ID. typedef internal::Int32Type Id; #elif VTKM_SIZE_ID == 8 /// Represents an ID. typedef internal::Int64Type Id; #else #error Unknown Id Size #endif #ifdef VTKM_USE_DOUBLE_PRECISION /// Scalar corresponds to a floating point number. typedef double Scalar; #else //VTKM_USE_DOUBLE_PRECISION /// Scalar corresponds to a floating point number. typedef float Scalar; #endif //VTKM_USE_DOUBLE_PRECISION //----------------------------------------------------------------------------- /// Tuple corresponds to a Size-tuple of type T template class Tuple { public: typedef T ComponentType; static const int NUM_COMPONENTS=Size; VTKM_EXEC_CONT_EXPORT Tuple() {} VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType& value) { for(int i=0; i < NUM_COMPONENTS; ++i) { this->Components[i]=value; } } VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType* values) { for(int i=0; i < NUM_COMPONENTS; ++i) { this->Components[i]=values[i]; } } VTKM_EXEC_CONT_EXPORT Tuple(const Tuple &src) { for (int i = 0; i < NUM_COMPONENTS; i++) { this->Components[i] = src[i]; } } VTKM_EXEC_CONT_EXPORT Tuple &operator=(const Tuple &src) { for (int i = 0; i < NUM_COMPONENTS; i++) { this->Components[i] = src[i]; } return *this; } VTKM_EXEC_CONT_EXPORT const ComponentType &operator[](int idx) const { return this->Components[idx]; } VTKM_EXEC_CONT_EXPORT ComponentType &operator[](int idx) { return this->Components[idx]; } VTKM_EXEC_CONT_EXPORT bool operator==(const Tuple &other) const { bool same = true; for (int componentIndex=0; componentIndexComponents[componentIndex] == other[componentIndex]); } return same; } VTKM_EXEC_CONT_EXPORT bool operator<(const Tuple &other) const { for(vtkm::Id i=0; i < NUM_COMPONENTS; ++i) { //ignore equals as that represents check next value if(this->Components[i] < other[i]) { return true; } else if(other[i] < this->Components[i]) { return false; } } //if all same we are not less return false; } VTKM_EXEC_CONT_EXPORT bool operator!=(const Tuple &other) const { return !(this->operator==(other)); } protected: ComponentType Components[NUM_COMPONENTS]; }; //----------------------------------------------------------------------------- // Specializations for small tuples. These are not exactly common but can occur // with generalizations. We implement them a bit special. template class Tuple { public: typedef T ComponentType; static const int NUM_COMPONENTS = 1; VTKM_EXEC_CONT_EXPORT Tuple() {} VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType&) { } VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType*) { } VTKM_EXEC_CONT_EXPORT Tuple(const Tuple &) { } VTKM_EXEC_CONT_EXPORT Tuple & operator=(const Tuple &) { return *this; } VTKM_EXEC_CONT_EXPORT ComponentType operator[](int idx) const { return ComponentType(); } VTKM_EXEC_CONT_EXPORT bool operator==(const Tuple &other) const { return true; } VTKM_EXEC_CONT_EXPORT bool operator!=(const Tuple &other) const { return false; } }; template class Tuple { public: typedef T ComponentType; static const int NUM_COMPONENTS = 1; VTKM_EXEC_CONT_EXPORT Tuple() {} VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType& value) : Component(value) { } VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType* values) : Component(*values) { } VTKM_EXEC_CONT_EXPORT Tuple(const Tuple &src) : Component(src.Component) { } VTKM_EXEC_CONT_EXPORT Tuple & operator=(const Tuple &src) { this->Component = src.Component; return *this; } VTKM_EXEC_CONT_EXPORT const ComponentType &operator[](int idx) const { return this->Component; } VTKM_EXEC_CONT_EXPORT ComponentType &operator[](int idx) { return this->Component; } VTKM_EXEC_CONT_EXPORT bool operator==(const Tuple &other) const { return this->Component == other.Component; } VTKM_EXEC_CONT_EXPORT bool operator!=(const Tuple &other) const { return !(this->operator==(other)); } VTKM_EXEC_CONT_EXPORT bool operator<(const Tuple &other) const { return this->Component < other.Component; } protected: ComponentType Component; }; //----------------------------------------------------------------------------- // Specializations for common tuple sizes (with special names). template class Tuple { public: typedef T ComponentType; static const int NUM_COMPONENTS = 2; VTKM_EXEC_CONT_EXPORT Tuple() {} VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType& value) { internal::assign_scalar_to_vector()(this->Components,value); } VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType* values) { internal::copy_vector()(this->Components, values); } VTKM_EXEC_CONT_EXPORT Tuple(ComponentType x, ComponentType y) { this->Components[0] = x; this->Components[1] = y; } VTKM_EXEC_CONT_EXPORT Tuple(const Tuple &src) { internal::copy_vector()(this->Components, src.Components); } VTKM_EXEC_CONT_EXPORT Tuple & operator=(const Tuple &src) { internal::copy_vector()(this->Components, src.Components); return *this; } VTKM_EXEC_CONT_EXPORT const ComponentType &operator[](int idx) const { return this->Components[idx]; } VTKM_EXEC_CONT_EXPORT ComponentType &operator[](int idx) { return this->Components[idx]; } VTKM_EXEC_CONT_EXPORT bool operator==(const Tuple &other) const { return internal::equals()(*this, other); } VTKM_EXEC_CONT_EXPORT bool operator!=(const Tuple &other) const { return !(this->operator==(other)); } VTKM_EXEC_CONT_EXPORT bool operator<(const Tuple &other) const { return( (this->Components[0] < other[0]) || (!(other[0] < this->Components[0]) && (this->Components[1] < other[1])) ); } protected: ComponentType Components[NUM_COMPONENTS]; }; /// Vector2 corresponds to a 2-tuple typedef vtkm::Tuple Vector2; /// Id2 corresponds to a 2-dimensional index typedef vtkm::Tuple Id2; template class Tuple { public: typedef T ComponentType; static const int NUM_COMPONENTS = 3; VTKM_EXEC_CONT_EXPORT Tuple() {} VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType& value) { internal::assign_scalar_to_vector()(this->Components,value); } VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType* values) { internal::copy_vector()(this->Components, values); } VTKM_EXEC_CONT_EXPORT Tuple(ComponentType x, ComponentType y, ComponentType z) { this->Components[0] = x; this->Components[1] = y; this->Components[2] = z; } VTKM_EXEC_CONT_EXPORT Tuple(const Tuple &src) { internal::copy_vector()(this->Components, src.Components); } VTKM_EXEC_CONT_EXPORT Tuple & operator=(const Tuple &src) { internal::copy_vector()(this->Components, src.Components); return *this; } VTKM_EXEC_CONT_EXPORT const ComponentType &operator[](int idx) const { return this->Components[idx]; } VTKM_EXEC_CONT_EXPORT ComponentType &operator[](int idx) { return this->Components[idx]; } VTKM_EXEC_CONT_EXPORT bool operator==(const Tuple &other) const { return internal::equals()(*this, other); } VTKM_EXEC_CONT_EXPORT bool operator!=(const Tuple &other) const { return !(this->operator==(other)); } VTKM_EXEC_CONT_EXPORT bool operator<(const Tuple &other) const { return((this->Components[0] < other[0]) || ( !(other[0] < this->Components[0]) && (this->Components[1] < other[1])) || ( !(other[0] < this->Components[0]) && !(other[1] < this->Components[1]) && (this->Components[2] < other[2]) ) ); } protected: ComponentType Components[NUM_COMPONENTS]; }; /// Vector3 corresponds to a 3-tuple typedef vtkm::Tuple Vector3; /// Id3 corresponds to a 3-dimensional index for 3d arrays. Note that /// the precision of each index may be less than vtkm::Id. typedef vtkm::Tuple Id3; template class Tuple { public: typedef T ComponentType; static const int NUM_COMPONENTS = 4; VTKM_EXEC_CONT_EXPORT Tuple() {} VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType& value) { internal::assign_scalar_to_vector()(this->Components,value); } VTKM_EXEC_CONT_EXPORT explicit Tuple(const ComponentType* values) { internal::copy_vector()(this->Components, values); } VTKM_EXEC_CONT_EXPORT Tuple(ComponentType x, ComponentType y, ComponentType z, ComponentType w) { this->Components[0] = x; this->Components[1] = y; this->Components[2] = z; this->Components[3] = w; } VTKM_EXEC_CONT_EXPORT Tuple(const Tuple &src) { internal::copy_vector()(this->Components, src.Components); } VTKM_EXEC_CONT_EXPORT Tuple & operator=(const Tuple &src) { internal::copy_vector()(this->Components, src.Components); return *this; } VTKM_EXEC_CONT_EXPORT const ComponentType &operator[](int idx) const { return this->Components[idx]; } VTKM_EXEC_CONT_EXPORT ComponentType &operator[](int idx) { return this->Components[idx]; } VTKM_EXEC_CONT_EXPORT bool operator==(const Tuple &other) const { return internal::equals()(*this, other); } VTKM_EXEC_CONT_EXPORT bool operator!=(const Tuple &other) const { return !(this->operator==(other)); } VTKM_EXEC_CONT_EXPORT bool operator<(const Tuple &other) const { return((this->Components[0] < other[0]) || ( !(other[0] < this->Components[0]) && this->Components[1] < other[1]) || ( !(other[0] < this->Components[0]) && !(other[1] < this->Components[1]) && (this->Components[2] < other[2]) ) || ( !(other[0] < this->Components[0]) && !(other[1] < this->Components[1]) && !(other[2] < this->Components[2]) && (this->Components[3] < other[3])) ); } protected: ComponentType Components[NUM_COMPONENTS]; }; /// Vector4 corresponds to a 4-tuple typedef vtkm::Tuple Vector4; /// Initializes and returns a Vector2. VTKM_EXEC_CONT_EXPORT vtkm::Vector2 make_Vector2(vtkm::Scalar x, vtkm::Scalar y) { return vtkm::Vector2(x, y); } /// Initializes and returns a Vector3. VTKM_EXEC_CONT_EXPORT vtkm::Vector3 make_Vector3(vtkm::Scalar x, vtkm::Scalar y, vtkm::Scalar z) { return vtkm::Vector3(x, y, z); } /// Initializes and returns a Vector4. VTKM_EXEC_CONT_EXPORT vtkm::Vector4 make_Vector4(vtkm::Scalar x, vtkm::Scalar y, vtkm::Scalar z, vtkm::Scalar w) { return vtkm::Vector4(x, y, z, w); } /// Initializes and returns an Id3 VTKM_EXEC_CONT_EXPORT vtkm::Id3 make_Id3(vtkm::Id x, vtkm::Id y, vtkm::Id z) { return vtkm::Id3(x, y, z); } template VTKM_EXEC_CONT_EXPORT T dot(const vtkm::Tuple &a, const vtkm::Tuple &b) { T result = a[0]*b[0]; for (int componentIndex = 1; componentIndex < Size; componentIndex++) { result += a[componentIndex]*b[componentIndex]; } return result; } VTKM_EXEC_CONT_EXPORT vtkm::Id dot(vtkm::Id a, vtkm::Id b) { return a * b; } VTKM_EXEC_CONT_EXPORT vtkm::Scalar dot(vtkm::Scalar a, vtkm::Scalar b) { return a * b; } } // End of namespace vtkm template VTKM_EXEC_CONT_EXPORT vtkm::Tuple operator+(const vtkm::Tuple &a, const vtkm::Tuple &b) { vtkm::Tuple result; for (int componentIndex = 0; componentIndex < Size; componentIndex++) { result[componentIndex] = a[componentIndex] + b[componentIndex]; } return result; } template VTKM_EXEC_CONT_EXPORT vtkm::Tuple operator-(const vtkm::Tuple &a, const vtkm::Tuple &b) { vtkm::Tuple result; for (int componentIndex = 0; componentIndex < Size; componentIndex++) { result[componentIndex] = a[componentIndex] - b[componentIndex]; } return result; } template VTKM_EXEC_CONT_EXPORT vtkm::Tuple operator*(const vtkm::Tuple &a, const vtkm::Tuple &b) { vtkm::Tuple result; for (int componentIndex = 0; componentIndex < Size; componentIndex++) { result[componentIndex] = a[componentIndex] * b[componentIndex]; } return result; } template VTKM_EXEC_CONT_EXPORT vtkm::Tuple operator/(const vtkm::Tuple &a, const vtkm::Tuple &b) { vtkm::Tuple result; for (int componentIndex = 0; componentIndex < Size; componentIndex++) { result[componentIndex] = a[componentIndex] / b[componentIndex]; } return result; } template VTKM_EXEC_CONT_EXPORT vtkm::Tuple operator*(const vtkm::Tuple &a, const Tb &b) { vtkm::Tuple result; for (int componentIndex = 0; componentIndex < Size; componentIndex++) { result[componentIndex] = a[componentIndex] * b; } return result; } template VTKM_EXEC_CONT_EXPORT vtkm::Tuple operator*(const Ta &a, const vtkm::Tuple &b) { vtkm::Tuple result; for (int componentIndex = 0; componentIndex < Size; componentIndex++) { result[componentIndex] = a * b[componentIndex]; } return result; } #endif //vtkm_Types_h