• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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