Bolt  1.3
C++ template library with support for OpenCL
clcode.h
Go to the documentation of this file.
1 /***************************************************************************
2 * © 2012,2014 Advanced Micro Devices, Inc. All rights reserved.
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( ... ) \
134  template<> struct TypeName< __VA_ARGS__ > { static std::string get( ) { return #__VA_ARGS__; } };
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 
214 #define BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, OLDTYPE, NEWTYPE ) \
215  BOLT_CREATE_TYPENAME( CONTAINER< NEWTYPE > ) \
216  BOLT_CREATE_CLCODE( CONTAINER< NEWTYPE >, ClCode< CONTAINER< OLDTYPE > >::get( ) )
217 
265 #define BOLT_TEMPLATE_REGISTER_NEW_ITERATOR( CONTAINER, OLDTYPE, NEWTYPE ) \
266  BOLT_CREATE_TYPENAME( CONTAINER< NEWTYPE >::iterator ) \
267  BOLT_CREATE_CLCODE( CONTAINER< NEWTYPE >::iterator, ClCode< CONTAINER< OLDTYPE >::iterator >::get( ) )
268 
275 #define BOLT_CREATE_DEFINE( DefineName,D,... ) struct DefineName {}; BOLT_CREATE_CLCODE( DefineName, std::string("#ifndef ") + std::string(#D) + std::string(" \n")\
276  + std::string("#define ") + std::string(#D) + std::string(" ") + std::string(#__VA_ARGS__) + std::string(" \n")\
277  + std::string("#endif \n"));
278 
279 
393 #if defined(WIN32)
394 #define BOLT_TEMPLATE_REGISTER_NEW_TRANSFORM_ITERATOR( FUNCTOR, DATATYPE) \
395  BOLT_CREATE_TYPENAME( bolt::cl::transform_iterator< FUNCTOR, bolt::cl::device_vector< DATATYPE >::iterator > );\
396  template<> struct ClCode< bolt::cl::transform_iterator< FUNCTOR, bolt::cl::device_vector< DATATYPE >::iterator > > { static std::vector< std::string > dependencies;\
397  static void addDependency(std::string s) { dependencies.push_back(s); }; \
398  static std::string getDependingCodeString() { \
399  std::string c;\
400  for (std::vector< std::string >::iterator i = dependencies.begin(); i != dependencies.end(); i++) { c = c + *i; } \
401  return c; \
402  };\
403  static std::string getCodeString() { return ClCode<DATATYPE>::get() + ClCode<FUNCTOR>::get() + bolt::cl::deviceTransformIteratorTemplate; }; \
404  static std::string get() { return getDependingCodeString() + getCodeString(); }; };\
405  __declspec( selectany ) std::vector< std::string > ClCode< bolt::cl::transform_iterator< FUNCTOR, bolt::cl::device_vector< DATATYPE >::iterator > >::dependencies;
406 #else
407 #define BOLT_TEMPLATE_REGISTER_NEW_TRANSFORM_ITERATOR( FUNCTOR, DATATYPE) \
408  BOLT_CREATE_TYPENAME( bolt::cl::transform_iterator< FUNCTOR, bolt::cl::device_vector< DATATYPE >::iterator > );\
409  template<> struct ClCode< bolt::cl::transform_iterator< FUNCTOR, bolt::cl::device_vector< DATATYPE >::iterator > > { static std::vector< std::string > dependencies;\
410  static void addDependency(std::string s) { dependencies.push_back(s); }; \
411  static std::string getDependingCodeString() { \
412  std::string c;\
413  for (std::vector< std::string >::iterator i = dependencies.begin(); i != dependencies.end(); i++) { c = c + *i; } \
414  return c; \
415  };\
416  static std::string getCodeString() { return ClCode<DATATYPE>::get() + ClCode<FUNCTOR>::get() + bolt::cl::deviceTransformIteratorTemplate; }; \
417  static std::string get() { return getDependingCodeString() + getCodeString(); }; };\
418  __attribute__((weak)) std::vector< std::string > ClCode< bolt::cl::transform_iterator< FUNCTOR, bolt::cl::device_vector< DATATYPE >::iterator > >::dependencies;
419 #endif
420 
485 #if defined(WIN32)
486 #define BOLT_TEMPLATE_REGISTER_NEW_PERMUTATION_ITERATOR( ELEMENT_ITERATOR, INDEX_ITERATOR) \
487  BOLT_CREATE_TYPENAME( bolt::cl::permutation_iterator< ELEMENT_ITERATOR, INDEX_ITERATOR > );\
488  template<> struct ClCode< bolt::cl::permutation_iterator< ELEMENT_ITERATOR, INDEX_ITERATOR > > { static std::vector< std::string > dependencies;\
489  static void addDependency(std::string s) { dependencies.push_back(s); }; \
490  static std::string getDependingCodeString() { \
491  std::string c;\
492  for (std::vector< std::string >::iterator i = dependencies.begin(); i != dependencies.end(); i++) { c = c + *i; } \
493  return c; \
494  };\
495  static std::string getCodeString() { return ClCode<ELEMENT_ITERATOR>::get() + ClCode<INDEX_ITERATOR>::get() + bolt::cl::devicePermutationIteratorTemplate; }; \
496  static std::string get() { return getDependingCodeString() + getCodeString(); }; };\
497  __declspec( selectany ) std::vector< std::string > ClCode< bolt::cl::permutation_iterator< ELEMENT_ITERATOR, INDEX_ITERATOR > >::dependencies;
498 #else
499 #define BOLT_TEMPLATE_REGISTER_NEW_PERMUTATION_ITERATOR( ELEMENT_ITERATOR, INDEX_ITERATOR) \
500  BOLT_CREATE_TYPENAME( bolt::cl::permutation_iterator< ELEMENT_ITERATOR, INDEX_ITERATOR > );\
501  template<> struct ClCode< bolt::cl::permutation_iterator< ELEMENT_ITERATOR, INDEX_ITERATOR > > { static std::vector< std::string > dependencies;\
502  static void addDependency(std::string s) { dependencies.push_back(s); }; \
503  static std::string getDependingCodeString() { \
504  std::string c;\
505  for (std::vector< std::string >::iterator i = dependencies.begin(); i != dependencies.end(); i++) { c = c + *i; } \
506  return c; \
507  };\
508  static std::string getCodeString() { return ClCode<ELEMENT_ITERATOR>::get() + ClCode<INDEX_ITERATOR>::get() + bolt::cl::devicePermutationIteratorTemplate; }; \
509  static std::string get() { return getDependingCodeString() + getCodeString(); }; };\
510  __attribute__((weak)) std::vector< std::string > ClCode< bolt::cl::permutation_iterator< ELEMENT_ITERATOR, INDEX_ITERATOR > >::dependencies;
511 #endif
512 
513 
546 #define BOLT_FUNCTOR( T, ... ) __VA_ARGS__; \
547  BOLT_CREATE_TYPENAME( T ); \
548  BOLT_CREATE_CLCODE( T, std::string("#ifndef ") + std::string("BOLT_FUNCTOR_") + std::string(#T) + std::string(" \n")\
549  + std::string("#define ") + std::string("BOLT_FUNCTOR_") + std::string(#T) + std::string(" \n")\
550  + std::string(#__VA_ARGS__) + std::string(" \n")\
551  + std::string("#endif \n"));
552 
553 
608 #define BOLT_TEMPLATE_FUNCTOR1( CONTAINER, TYPE1, ... ) \
609  __VA_ARGS__; \
610  BOLT_CREATE_TYPENAME( CONTAINER<TYPE1> ) \
611  BOLT_CREATE_CLCODE( CONTAINER<TYPE1>, #__VA_ARGS__ )
612 
622 #define BOLT_TEMPLATE_FUNCTOR2( CONTAINER, TYPE1, TYPE2, ... ) \
623  __VA_ARGS__; \
624  BOLT_CREATE_TYPENAME( CONTAINER<TYPE1> ) \
625  BOLT_CREATE_CLCODE( CONTAINER<TYPE1>, #__VA_ARGS__ ) \
626  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE2 )
627 
638 #define BOLT_TEMPLATE_FUNCTOR3( CONTAINER, TYPE1, TYPE2, TYPE3, ... ) \
639  __VA_ARGS__; \
640  BOLT_CREATE_TYPENAME( CONTAINER<TYPE1> ) \
641  BOLT_CREATE_CLCODE( CONTAINER<TYPE1>, #__VA_ARGS__ ) \
642  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE2 ) \
643  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE3 )
644 
656 #define BOLT_TEMPLATE_FUNCTOR4( CONTAINER, TYPE1, TYPE2, TYPE3, TYPE4, ... ) \
657  __VA_ARGS__; \
658  BOLT_CREATE_TYPENAME( CONTAINER<TYPE1> ) \
659  BOLT_CREATE_CLCODE( CONTAINER<TYPE1>, #__VA_ARGS__ ) \
660  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE2 ) \
661  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE3 ) \
662  BOLT_TEMPLATE_REGISTER_NEW_TYPE( CONTAINER, TYPE1, TYPE4 )
663 
672 #define BOLT_CREATE_CODE_SNIPPET( Name, ... ) \
673  __VA_ARGS__;\
674  struct Name {};\
675  BOLT_CREATE_CLCODE(Name, std::string("#ifndef ") + std::string(#Name) +std::string(" \n") \
676  + std::string("#define ") + std::string(#Name) + std::string(" \n") \
677  + std::string(#__VA_ARGS__) + std::string(" \n") \
678  + std::string("#endif \n"));
679 
719 #define BOLT_ADD_DEPENDENCY( Type, DependingType ) ClCode<Type>::addDependency(ClCode<DependingType>::get());
720 
721 #endif
722