Voxel
 All Classes Namespaces Files Functions Typedefs Enumerations Enumerator Macros Pages
opencl_converter.h
Go to the documentation of this file.
1 #pragma once
2 
3 #ifndef OPENCL_CONVERTER_H
4 #define OPENCL_CONVERTER_H
5 
6 
7 /**
8  \file
9  \brief Contains OpenCL::Converter class.
10 
11  In addition to the Converter default specialization, this file also defines
12  specializations for fixed-size arrays (using \c std::array for the host
13  type), builtin integer and floating-point types, and vectors (using Vector
14  for the host type, e.g. <tt>Vector< float, 3 ></tt> maps to \c cl_float3).
15 */
16 
17 
18 
19 
20 #include "settings.h"
21 
22 
23 
24 
25 #if ( SETTING_OPENCL != 0 )
26 
27 
28 
29 
30 #include "vector.h"
31 
32 #include <CL/cl.h>
33 
34 #include <array>
35 
36 #include <stdint.h>
37 
38 
39 
40 
41 namespace OpenCL {
42 
43 
44 
45 
46 /*==============================================================================
47  Converter class and helper functions
48 ==============================================================================*/
49 
50 
51 /**
52  \brief Converts data for transmission to OpenCL device.
53 
54  \param t_Type Host type from which to convert.
55 
56  This class, and its specializations, are inspired by the way that \c
57  boost::serialization works. Every convertable host type has two associated
58  pieces of information: the OpenCL type to which it converts (stored in the
59  \c Type typedef), and a function for actually performing the conversion
60  (the \c Convert static function).
61 
62  The default specialization of this class maps \c t_Type::OpenCLType to \c
63  Type, and \c t_Type::OpenCLConvert to \c Convert. Hence, if you don't want
64  to explicitly specialize this class for your type, you can instead add
65  these two members, and they'll be used automatically.
66 
67  This class is primarily used by Synchronized::Heap and
68  Synchronized::TextureHeap, which keep the host state synchronized with OpenCL
69  by, for every convertable object on the host, allocating a corresponding
70  block of memory on the OpenCL device, and using this class to convert
71  objects before transferring them over, whenever the host object changes.
72 
73  \see \ref Synchronized::Heap
74  \see \ref Synchronized::TextureHeap
75 */
76 template< typename t_Type >
77 struct Converter {
78 
79  typedef typename t_Type::OpenCLType Type;
80 
81  static Type Convert( t_Type const& source ) {
82 
83  return source.OpenCLConvert();
84  }
85 };
86 
87 
88 /// \brief Helper function which calls Converter::Convert for the type of its argument.
89 template< typename t_Type >
90 inline typename Converter< t_Type >::Type Convert( t_Type const& source ) {
91 
92  return Converter< t_Type >::Convert( source );
93 }
94 
95 
96 
97 
98 /*==============================================================================
99  Converter array specialization
100 ==============================================================================*/
101 
102 
103 /**
104  \brief Converter specialization for fixed-size arrays.
105 
106  \param t_Type Host type of array elements.
107  \param t_Size Number of elements.
108 
109  On the host, convertable fixed-size arrays are instances of \c std::array.
110  They are serialized to the device by simply using the appropriate Converter
111  element-by-element.
112 
113  \see \ref Converter
114 */
115 template< typename t_Type, size_t t_Size >
116 struct Converter< std::array< t_Type, t_Size > > {
117 
118  typedef std::array< typename Converter< t_Type >::Type, t_Size > Type;
119 
120  static Type Convert( std::array< t_Type, t_Size > const& source ) {
121 
122  Type result;
123  for ( size_t ii = 0; ii < t_Size; ++ii )
124  result[ ii ] = Converter< t_Type >::Convert( source[ ii ] );
125  return result;
126  }
127 };
128 
129 
130 
131 
132 /*==============================================================================
133  Converter builtin specializations
134 ==============================================================================*/
135 
136 
137 // **TODO: most of these are NOPs. is the compiler smart enough to realize this?
138 
139 #define OPENCL_COMMA ,
140 
141 /// \brief Generates converter specialization which converts the host type \p ss to the OpenCL type \p dd.
142 #define OPENCL_CONVERTER1( ss, dd ) \
143  template<> \
144  struct Converter< ss > { \
145  typedef dd Type; \
146  static Type Convert( ss const& source ) { \
147  return source; \
148  } \
149  };
150 
151 /// \brief Generates converter specialization which converts the host 2D vector type \p ss to the OpenCL 2D vector type \p dd.
152 #define OPENCL_CONVERTER2( ss, dd ) \
153  template<> \
154  struct Converter< ss > { \
155  typedef dd Type; \
156  static Type Convert( ss const& source ) { \
157  Type const result = { { source[ 0 ], source[ 1 ] } }; \
158  return result; \
159  } \
160  };
161 
162 /// \brief Generates converter specialization which converts the host 3D vector type \p ss to the OpenCL 3D vector type \p dd.
163 #define OPENCL_CONVERTER3( ss, dd ) \
164  template<> \
165  struct Converter< ss > { \
166  typedef dd Type; \
167  static Type Convert( ss const& source ) { \
168  Type const result = { { source[ 0 ], source[ 1 ], source[ 2 ] } }; \
169  return result; \
170  } \
171  };
172 
173 /// \brief Generates converter specialization which converts the host 4D vector type \p ss to the OpenCL 4D vector type \p dd.
174 #define OPENCL_CONVERTER4( ss, dd ) \
175  template<> \
176  struct Converter< ss > { \
177  typedef dd Type; \
178  static Type Convert( ss const& source ) { \
179  Type const result = { { source[ 0 ], source[ 1 ], source[ 2 ], source[ 3 ] } }; \
180  return result; \
181  } \
182  };
183 
184 /// \brief Generates converter specialization which converts the host 8D vector type \p ss to the OpenCL 8D vector type \p dd.
185 #define OPENCL_CONVERTER8( ss, dd ) \
186  template<> \
187  struct Converter< ss > { \
188  typedef dd Type; \
189  static Type Convert( ss const& source ) { \
190  Type const result = { { source[ 0 ], source[ 1 ], source[ 2 ], source[ 3 ], source[ 4 ], source[ 5 ], source[ 6 ], source[ 7 ] } }; \
191  return result; \
192  } \
193  };
194 
195 /// \brief Generates converter specialization which converts the host 16D vector type \p ss to the OpenCL 16D vector type \p dd.
196 #define OPENCL_CONVERTER16( ss, dd ) \
197  template<> \
198  struct Converter< ss > { \
199  typedef dd Type; \
200  static Type Convert( ss const& source ) { \
201  Type const result = { { source[ 0 ], source[ 1 ], source[ 2 ], source[ 3 ], source[ 4 ], source[ 5 ], source[ 6 ], source[ 7 ], source[ 8 ], source[ 9 ], source[ 10 ], source[ 11 ], source[ 12 ], source[ 13 ], source[ 14 ], source[ 15 ] } }; \
202  return result; \
203  } \
204  };
205 
206 /// \brief Generates converter specializations which convert the host type \p ss to the OpenCL type \p dd, and likewise <tt>Vector< ss, n ></tt> to \c ddn for \f$n \in \{ 1, 2, 3, 4, 8, 16 \}\f$.
207 #define OPENCL_CONVERTER( ss, dd ) \
208  OPENCL_CONVERTER1( ss, dd ) \
209  OPENCL_CONVERTER2( Vector< ss OPENCL_COMMA 2 >, dd##2 ) \
210  OPENCL_CONVERTER3( Vector< ss OPENCL_COMMA 3 >, dd##3 ) \
211  OPENCL_CONVERTER4( Vector< ss OPENCL_COMMA 4 >, dd##4 ) \
212  OPENCL_CONVERTER8( Vector< ss OPENCL_COMMA 8 >, dd##8 ) \
213  OPENCL_CONVERTER16( Vector< ss OPENCL_COMMA 16 >, dd##16 )
214 
215 
216 OPENCL_CONVERTER( int8_t, cl_char )
217 OPENCL_CONVERTER( uint8_t, cl_uchar )
218 OPENCL_CONVERTER( int16_t, cl_short )
219 OPENCL_CONVERTER( uint16_t, cl_ushort )
220 OPENCL_CONVERTER( int32_t, cl_int )
221 OPENCL_CONVERTER( uint32_t, cl_uint )
222 OPENCL_CONVERTER( int64_t, cl_long )
223 OPENCL_CONVERTER( uint64_t, cl_ulong )
224 OPENCL_CONVERTER( float, cl_float )
225 OPENCL_CONVERTER( double, cl_double )
226 
227 
228 #undef OPENCL_COMMA
229 #undef OPENCL_CONVERTER1
230 #undef OPENCL_CONVERTER2
231 #undef OPENCL_CONVERTER3
232 #undef OPENCL_CONVERTER4
233 #undef OPENCL_CONVERTER8
234 #undef OPENCL_CONVERTER16
235 #undef OPENCL_CONVERTER
236 
237 
238 
239 
240 } // namespace OpenCL
241 
242 
243 
244 
245 #endif // SETTING_OPENCL
246 
247 
248 
249 
250 #endif // OPENCL_CONVERTER_H