fundamental.hpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  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. #ifndef BOOST_COMPUTE_TYPES_FUNDAMENTAL_HPP
  11. #define BOOST_COMPUTE_TYPES_FUNDAMENTAL_HPP
  12. #include <cstring>
  13. #include <ostream>
  14. #include <boost/preprocessor/cat.hpp>
  15. #include <boost/preprocessor/comma.hpp>
  16. #include <boost/preprocessor/repetition.hpp>
  17. #include <boost/preprocessor/stringize.hpp>
  18. #include <boost/compute/cl.hpp>
  19. namespace boost {
  20. namespace compute {
  21. // scalar data types
  22. typedef cl_char char_;
  23. typedef cl_uchar uchar_;
  24. typedef cl_short short_;
  25. typedef cl_ushort ushort_;
  26. typedef cl_int int_;
  27. typedef cl_uint uint_;
  28. typedef cl_long long_;
  29. typedef cl_ulong ulong_;
  30. typedef cl_float float_;
  31. typedef cl_double double_;
  32. // converts uchar to ::boost::compute::uchar_
  33. #define BOOST_COMPUTE_MAKE_SCALAR_TYPE(scalar) \
  34. BOOST_PP_CAT(::boost::compute::scalar, _)
  35. // converts float, 4 to ::boost::compute::float4_
  36. #define BOOST_COMPUTE_MAKE_VECTOR_TYPE(scalar, size) \
  37. BOOST_PP_CAT(BOOST_PP_CAT(::boost::compute::scalar, size), _)
  38. namespace detail {
  39. // specialized vector_type base classes that provide the
  40. // (x,y), (x,y,z,w), (s0..s7), (s0..sf) accessors
  41. template<class Scalar, size_t N> class vector_type_desc;
  42. template<class Scalar>
  43. class vector_type_desc<Scalar, 2>
  44. {
  45. public:
  46. Scalar x, y;
  47. Scalar& operator[](size_t i)
  48. {
  49. return (&x)[i];
  50. }
  51. const Scalar operator[](size_t i) const
  52. {
  53. return (&x)[i];
  54. }
  55. };
  56. template<class Scalar>
  57. class vector_type_desc<Scalar, 4> : public vector_type_desc<Scalar, 2>
  58. {
  59. public:
  60. Scalar z, w;
  61. };
  62. template<class Scalar>
  63. class vector_type_desc<Scalar, 8>
  64. {
  65. public:
  66. Scalar s0, s1, s2, s3, s4, s5, s6, s7;
  67. Scalar& operator[](size_t i)
  68. {
  69. return (&s0)[i];
  70. }
  71. const Scalar operator[](size_t i) const
  72. {
  73. return (&s0)[i];
  74. }
  75. };
  76. template<class Scalar>
  77. class vector_type_desc<Scalar, 16> : public vector_type_desc<Scalar, 8>
  78. {
  79. public:
  80. Scalar s8, s9, sa, sb, sc, sd, se, sf;
  81. };
  82. } // end detail namespace
  83. // vector data types
  84. template<class Scalar, size_t N>
  85. class vector_type : public detail::vector_type_desc<Scalar, N>
  86. {
  87. typedef detail::vector_type_desc<Scalar, N> base_type;
  88. public:
  89. typedef Scalar scalar_type;
  90. vector_type()
  91. : base_type()
  92. {
  93. BOOST_STATIC_ASSERT(sizeof(Scalar) * N == sizeof(vector_type<Scalar, N>));
  94. }
  95. explicit vector_type(const Scalar scalar)
  96. {
  97. for(size_t i = 0; i < N; i++)
  98. (*this)[i] = scalar;
  99. }
  100. vector_type(const vector_type<Scalar, N> &other)
  101. {
  102. std::memcpy(this, &other, sizeof(Scalar) * N);
  103. }
  104. vector_type<Scalar, N>&
  105. operator=(const vector_type<Scalar, N> &other)
  106. {
  107. std::memcpy(this, &other, sizeof(Scalar) * N);
  108. return *this;
  109. }
  110. size_t size() const
  111. {
  112. return N;
  113. }
  114. bool operator==(const vector_type<Scalar, N> &other) const
  115. {
  116. return std::memcmp(this, &other, sizeof(Scalar) * N) == 0;
  117. }
  118. bool operator!=(const vector_type<Scalar, N> &other) const
  119. {
  120. return !(*this == other);
  121. }
  122. };
  123. #define BOOST_COMPUTE_VECTOR_TYPE_CTOR_ARG_FUNCTION(z, i, _) \
  124. BOOST_PP_COMMA_IF(i) scalar_type BOOST_PP_CAT(arg, i)
  125. #define BOOST_COMPUTE_VECTOR_TYPE_DECLARE_CTOR_ARGS(scalar, size) \
  126. BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_CTOR_ARG_FUNCTION, _)
  127. #define BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_ARG(z, i, _) \
  128. (*this)[i] = BOOST_PP_CAT(arg, i);
  129. #define BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_SINGLE_ARG(z, i, _) \
  130. (*this)[i] = arg;
  131. #define BOOST_COMPUTE_DECLARE_VECTOR_TYPE_CLASS(cl_scalar, size, class_name) \
  132. class class_name : public vector_type<cl_scalar, size> \
  133. { \
  134. public: \
  135. class_name() { } \
  136. explicit class_name( scalar_type arg ) \
  137. { \
  138. BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_SINGLE_ARG, _) \
  139. } \
  140. class_name( \
  141. BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_CTOR_ARG_FUNCTION, _) \
  142. ) \
  143. { \
  144. BOOST_PP_REPEAT(size, BOOST_COMPUTE_VECTOR_TYPE_ASSIGN_CTOR_ARG, _) \
  145. } \
  146. };
  147. #define BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, size) \
  148. BOOST_COMPUTE_DECLARE_VECTOR_TYPE_CLASS(BOOST_PP_CAT(cl_, scalar), \
  149. size, \
  150. BOOST_PP_CAT(BOOST_PP_CAT(scalar, size), _)) \
  151. \
  152. inline std::ostream& operator<<( \
  153. std::ostream &s, \
  154. const BOOST_COMPUTE_MAKE_VECTOR_TYPE(scalar, size) &v) \
  155. { \
  156. s << BOOST_PP_STRINGIZE(BOOST_PP_CAT(scalar, size)) << "("; \
  157. for(size_t i = 0; i < size; i++){\
  158. s << v[i]; \
  159. if(i != size - 1){\
  160. s << ", "; \
  161. } \
  162. } \
  163. s << ")"; \
  164. return s; \
  165. }
  166. #define BOOST_COMPUTE_DECLARE_VECTOR_TYPES(scalar) \
  167. BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 2) \
  168. BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 4) \
  169. BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 8) \
  170. BOOST_COMPUTE_DECLARE_VECTOR_TYPE(scalar, 16) \
  171. BOOST_COMPUTE_DECLARE_VECTOR_TYPES(char)
  172. BOOST_COMPUTE_DECLARE_VECTOR_TYPES(uchar)
  173. BOOST_COMPUTE_DECLARE_VECTOR_TYPES(short)
  174. BOOST_COMPUTE_DECLARE_VECTOR_TYPES(ushort)
  175. BOOST_COMPUTE_DECLARE_VECTOR_TYPES(int)
  176. BOOST_COMPUTE_DECLARE_VECTOR_TYPES(uint)
  177. BOOST_COMPUTE_DECLARE_VECTOR_TYPES(long)
  178. BOOST_COMPUTE_DECLARE_VECTOR_TYPES(ulong)
  179. BOOST_COMPUTE_DECLARE_VECTOR_TYPES(float)
  180. BOOST_COMPUTE_DECLARE_VECTOR_TYPES(double)
  181. } // end compute namespace
  182. } // end boost namespace
  183. #endif // BOOST_COMPUTE_TYPES_FUNDAMENTAL_HPP