1 //---------------------------------------------------------------------------// 2 // Copyright (c) 2013-2014 Kyle Lutz <kyle.r.lutz@gmail.com> 3 // 4 // Distributed under the Boost Software License, Version 1.0 5 // See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt 7 // 8 // See http://boostorg.github.com/compute for more information. 9 //---------------------------------------------------------------------------// 10 11 #ifndef BOOST_COMPUTE_TYPES_FUNDAMENTAL_HPP 12 #define BOOST_COMPUTE_TYPES_FUNDAMENTAL_HPP 13 14 #include <cstring> 15 #include <ostream> 16 17 #include <boost/preprocessor/cat.hpp> 18 #include <boost/preprocessor/comma.hpp> 19 #include <boost/preprocessor/repetition.hpp> 20 #include <boost/preprocessor/stringize.hpp> 21 22 #include <boost/compute/cl.hpp> 23 24 namespace boost { 25 namespace compute { 26 27 // scalar data types 28 typedef cl_char char_; 29 typedef cl_uchar uchar_; 30 typedef cl_short short_; 31 typedef cl_ushort ushort_; 32 typedef cl_int int_; 33 typedef cl_uint uint_; 34 typedef cl_long long_; 35 typedef cl_ulong ulong_; 36 typedef cl_float float_; 37 typedef cl_double double_; 38 39 // converts uchar to ::boost::compute::uchar_ 40 #define BOOST_COMPUTE_MAKE_SCALAR_TYPE(scalar) \ 41 BOOST_PP_CAT(::boost::compute::scalar, _) 42 43 // converts float, 4 to ::boost::compute::float4_ 44 #define BOOST_COMPUTE_MAKE_VECTOR_TYPE(scalar, size) \ 45 BOOST_PP_CAT(BOOST_PP_CAT(::boost::compute::scalar, size), _) 46 47 namespace detail { 48 49 // specialized vector_type base classes that provide the 50 // (x,y), (x,y,z,w), (s0..s7), (s0..sf) accessors 51 template<class Scalar, size_t N> class vector_type_desc; 52 53 template<class Scalar> 54 class vector_type_desc<Scalar, 2> 55 { 56 public: 57 Scalar x, y; 58 operator [](size_t i)59 Scalar& operator[](size_t i) 60 { 61 return (&x)[i]; 62 } 63 operator [](size_t i) const64 const Scalar operator[](size_t i) const 65 { 66 return (&x)[i]; 67 } 68 }; 69 70 template<class Scalar> 71 class vector_type_desc<Scalar, 4> : public vector_type_desc<Scalar, 2> 72 { 73 public: 74 Scalar z, w; 75 }; 76 77 template<class Scalar> 78 class vector_type_desc<Scalar, 8> 79 { 80 public: 81 Scalar s0, s1, s2, s3, s4, s5, s6, s7; 82 operator [](size_t i)83 Scalar& operator[](size_t i) 84 { 85 return (&s0)[i]; 86 } 87 operator [](size_t i) const88 const Scalar operator[](size_t i) const 89 { 90 return (&s0)[i]; 91 } 92 }; 93 94 template<class Scalar> 95 class vector_type_desc<Scalar, 16> : public vector_type_desc<Scalar, 8> 96 { 97 public: 98 Scalar s8, s9, sa, sb, sc, sd, se, sf; 99 }; 100 101 } // end detail namespace 102 103 // vector data types 104 template<class Scalar, size_t N> 105 class vector_type : public detail::vector_type_desc<Scalar, N> 106 { 107 typedef detail::vector_type_desc<Scalar, N> base_type; 108 public: 109 typedef Scalar scalar_type; 110 vector_type()111 vector_type() 112 : base_type() 113 { 114 BOOST_STATIC_ASSERT(sizeof(Scalar) * N == sizeof(vector_type<Scalar, N>)); 115 } 116 vector_type(const Scalar scalar)117 explicit vector_type(const Scalar scalar) 118 { 119 for(size_t i = 0; i < N; i++) 120 (*this)[i] = scalar; 121 } 122 vector_type(const vector_type<Scalar,N> & other)123 vector_type(const vector_type<Scalar, N> &other) 124 { 125 std::memcpy(this, &other, sizeof(Scalar) * N); 126 } 127 128 vector_type<Scalar, N>& operator =(const vector_type<Scalar,N> & other)129 operator=(const vector_type<Scalar, N> &other) 130 { 131 std::memcpy(this, &other, sizeof(Scalar) * N); 132 return *this; 133 } 134 size() const135 size_t size() const 136 { 137 return N; 138 } 139 operator ==(const vector_type<Scalar,N> & other) const140 bool operator==(const vector_type<Scalar, N> &other) const 141 { 142 return std::memcmp(this, &other, sizeof(Scalar) * N) == 0; 143 } 144 operator !=(const vector_type<Scalar,N> & other) const145 bool operator!=(const vector_type<Scalar, N> &other) const 146 { 147 return !(*this == other); 148 } 149 }; 150 151 #define BOOST_COMPUTE_VECTOR_TYPE_CTOR_ARG_FUNCTION(z, i, _) \ 152 BOOST_PP_COMMA_IF(i) scalar_type BOOST_PP_CAT(arg, i) 153 #define BOOST_COMPUTE_VECTOR_TYPE_DECLARE_CTOR_ARGS(scalar, size) \ 154 BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_CTOR_ARG_FUNCTION, _) 155 #define BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_ARG(z, i, _) \ 156 (*this)[i] = BOOST_PP_CAT(arg, i); 157 #define BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_SINGLE_ARG(z, i, _) \ 158 (*this)[i] = arg; 159 160 #define BOOST_COMPUTE_DECLARE_VECTOR_TYPE_CLASS(cl_scalar, size, class_name) \ 161 class class_name : public vector_type<cl_scalar, size> \ 162 { \ 163 public: \ 164 class_name() { } \ 165 explicit class_name( scalar_type arg ) \ 166 { \ 167 BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_SINGLE_ARG, _) \ 168 } \ 169 class_name( \ 170 BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_CTOR_ARG_FUNCTION, _) \ 171 ) \ 172 { \ 173 BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_ARG, _) \ 174 } \ 175 }; 176 177 #define BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, size) \ 178 BOOST_COMPUTE_DECLARE_VECTOR_TYPE_CLASS(BOOST_PP_CAT(cl_, scalar), \ 179 size, \ 180 BOOST_PP_CAT(BOOST_PP_CAT(scalar, size), _)) \ 181 \ 182 inline std::ostream& operator<<( \ 183 std::ostream &s, \ 184 const BOOST_COMPUTE_MAKE_VECTOR_TYPE(scalar, size) &v) \ 185 { \ 186 s << BOOST_PP_STRINGIZE(BOOST_PP_CAT(scalar, size)) << "("; \ 187 for(size_t i = 0; i < size; i++){\ 188 s << v[i]; \ 189 if(i != size - 1){\ 190 s << ", "; \ 191 } \ 192 } \ 193 s << ")"; \ 194 return s; \ 195 } 196 197 #define BOOST_COMPUTE_DECLARE_VECTOR_TYPES(scalar) \ 198 BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 2) \ 199 BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 4) \ 200 BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 8) \ 201 BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 16) \ 202 203 BOOST_COMPUTE_DECLARE_VECTOR_TYPES(char) 204 BOOST_COMPUTE_DECLARE_VECTOR_TYPES(uchar) 205 BOOST_COMPUTE_DECLARE_VECTOR_TYPES(short) 206 BOOST_COMPUTE_DECLARE_VECTOR_TYPES(ushort) 207 BOOST_COMPUTE_DECLARE_VECTOR_TYPES(int) 208 BOOST_COMPUTE_DECLARE_VECTOR_TYPES(uint) 209 BOOST_COMPUTE_DECLARE_VECTOR_TYPES(long) 210 BOOST_COMPUTE_DECLARE_VECTOR_TYPES(ulong) 211 BOOST_COMPUTE_DECLARE_VECTOR_TYPES(float) 212 BOOST_COMPUTE_DECLARE_VECTOR_TYPES(double) 213 214 } // end compute namespace 215 } // end boost namespace 216 217 #endif // BOOST_COMPUTE_TYPES_FUNDAMENTAL_HPP 218