Bolt  1.1
C++ template library with support for OpenCL
clcode.h
Go to the documentation of this file.
1 /***************************************************************************
2 * Copyright 2012 - 2013 Advanced Micro Devices, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 
16 ***************************************************************************/
17 
18 #pragma once
19 #if !defined( BOLT_CL_CLCODE_H )
20 #define BOLT_CL_CLCODE_H
21 
22 #include <string>
23 
41 #define STRINGIFY_CODE2( ... ) #__VA_ARGS__
42 #define STRINGIFY_CODE( ... ) STRINGIFY_CODE2( __VA_ARGS__ )
43 
47 #define BOLT_CODE_STRING( ... ) STRINGIFY_CODE( __VA_ARGS__ ); __VA_ARGS__;
48 
55 #define BOLT_HOST_DEVICE_DEFINITION( ... ) "namespace bolt { namespace cl {\n" STRINGIFY_CODE( __VA_ARGS__ ) "\n } } \n" ; __VA_ARGS__;
56 
82 /*
83 template<typename T>
84 struct foobar : std::false_type
85 { };
86 
87 */
88 template< typename TypeNameType >
89 struct TypeName
90 {
91  static std::string get()
92  {
93  static_assert( sizeof(TypeNameType) == 0 , "Bolt< error >: Unknown typename; define missing TypeName with Bolt provided macro's" );
94 // return "";
95 
96  }
97 };
98 
109 template< typename Type >
110 struct ClCode
111 {
112  static std::string get()
113  {
114  return "";
115  }
116 };
117 
133 #define BOLT_CREATE_TYPENAME( Type ) \
134  template<> struct TypeName< Type > { static std::string get( ) { return #Type; } };
135 
150 #if defined(WIN32)
151 #define BOLT_CREATE_CLCODE(Type,CODE_STRING) \
152  template<> struct ClCode< Type > { static std::vector< std::string > dependencies;\
153  static void addDependency(std::string s) { dependencies.push_back(s); }; \
154  static std::string getDependingCodeString() { \
155  std::string c;\
156  for (std::vector< std::string >::iterator i = dependencies.begin(); i != dependencies.end(); i++) { c = c + *i; } \
157  return c; \
158  };\
159  static std::string getCodeString() { return CODE_STRING; }; \
160  static std::string get() { return getDependingCodeString() + getCodeString(); }; };\
161  __declspec( selectany ) std::vector< std::string > ClCode< Type >::dependencies;
162 #else
163 #define BOLT_CREATE_CLCODE(Type,CODE_STRING) \
164  template<> struct ClCode< Type > { static std::vector< std::string > dependencies;\
165  static void addDependency(std::string s) { dependencies.push_back(s); }; \
166  static std::string getDependingCodeString() { \
167  std::string c;\
168  for (std::vector< std::string >::iterator i = dependencies.begin(); i != dependencies.end(); i++) { c = c + *i; } \
169  return c; \
170  };\
171  static std::string getCodeString() { return CODE_STRING; }; \
172  static std::string get() { return getDependingCodeString() + getCodeString(); }; };\
173 __attribute__((weak)) std::vector< std::string > ClCode< Type >::dependencies;
174 
175 
176 #endif
177 
186 #define BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, OLDTYPE, NEWTYPE ) \
187  BOLT_CREATE_TYPENAME( CONTAINER< NEWTYPE > ) \
188  BOLT_CREATE_CLCODE( CONTAINER< NEWTYPE >, ClCode< CONTAINER< OLDTYPE > >::get( ) )
189 
199 #define BOLT_TEMPLATE_REGISTER_NEW_ITERATOR( CONTAINER, OLDTYPE, NEWTYPE ) \
200  BOLT_CREATE_TYPENAME( CONTAINER< NEWTYPE >::iterator ) \
201  BOLT_CREATE_CLCODE( CONTAINER< NEWTYPE >::iterator, ClCode< CONTAINER< OLDTYPE >::iterator >::get( ) )
202 
203 #define BOLT_CREATE_DEFINE( DefineName,D,... ) struct DefineName {}; BOLT_CREATE_CLCODE( DefineName, std::string("#ifndef ") + std::string(#D) + std::string(" \n")\
204  + std::string("#define ") + std::string(#D) + std::string(" ") + std::string(#__VA_ARGS__) + std::string(" \n")\
205  + std::string("#endif \n"));
206 
213 #define BOLT_FUNCTOR( T, ... ) __VA_ARGS__; \
214  BOLT_CREATE_TYPENAME( T ); \
215  BOLT_CREATE_CLCODE( T, std::string("#ifndef ") + std::string("BOLT_FUNCTOR_") + std::string(#T) + std::string(" \n")\
216  + std::string("#define ") + std::string("BOLT_FUNCTOR_") + std::string(#T) + std::string(" \n")\
217  + std::string(#__VA_ARGS__) + std::string(" \n")\
218  + std::string("#endif \n"));
219 
220 
229 #define BOLT_TEMPLATE_FUNCTOR1( CONTAINER, TYPE1, ... ) \
230  __VA_ARGS__; \
231  BOLT_CREATE_TYPENAME( CONTAINER<TYPE1> ) \
232  BOLT_CREATE_CLCODE( CONTAINER<TYPE1>, #__VA_ARGS__ )
233 
243 #define BOLT_TEMPLATE_FUNCTOR2( CONTAINER, TYPE1, TYPE2, ... ) \
244  __VA_ARGS__; \
245  BOLT_CREATE_TYPENAME( CONTAINER<TYPE1> ) \
246  BOLT_CREATE_CLCODE( CONTAINER<TYPE1>, #__VA_ARGS__ ) \
247  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE2 )
248 
259 #define BOLT_TEMPLATE_FUNCTOR3( CONTAINER, TYPE1, TYPE2, TYPE3, ... ) \
260  __VA_ARGS__; \
261  BOLT_CREATE_TYPENAME( CONTAINER<TYPE1> ) \
262  BOLT_CREATE_CLCODE( CONTAINER<TYPE1>, #__VA_ARGS__ ) \
263  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE2 ) \
264  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE3 )
265 
277 #define BOLT_TEMPLATE_FUNCTOR4( CONTAINER, TYPE1, TYPE2, TYPE3, TYPE4, ... ) \
278  __VA_ARGS__; \
279  BOLT_CREATE_TYPENAME( CONTAINER<TYPE1> ) \
280  BOLT_CREATE_CLCODE( CONTAINER<TYPE1>, #__VA_ARGS__ ) \
281  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE2 ) \
282  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE3 ) \
283  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE4 )
284 
293 #define BOLT_CREATE_CODE_SNIPPET( Name, ... ) \
294  __VA_ARGS__;\
295  struct Name {};\
296  BOLT_CREATE_CLCODE(Name, std::string("#ifndef ") + std::string(#Name) +std::string(" \n") \
297  + std::string("#define ") + std::string(#Name) + std::string(" \n") \
298  + std::string(#__VA_ARGS__) + std::string(" \n") \
299  + std::string("#endif \n"));
300 
307 #define BOLT_ADD_DEPENDENCY( Type, DependingType ) ClCode<Type>::addDependency(ClCode<DependingType>::get());
308 
309 #endif