|
ViennaCL - The Vienna Computing Library 1.3.0
|
00001 #ifndef VIENNACL_GENERATOR_TRAITS_RESULT_OF_HPP 00002 #define VIENNACL_GENERATOR_TRAITS_RESULT_OF_HPP 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2012, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 00009 ----------------- 00010 ViennaCL - The Vienna Computing Library 00011 ----------------- 00012 00013 Project Head: Karl Rupp rupp@iue.tuwien.ac.at 00014 00015 (A list of authors and contributors can be found in the PDF manual) 00016 00017 License: MIT (X11), see file LICENSE in the base directory 00018 ============================================================================= */ 00019 00026 #include <string> 00027 00028 #include "viennacl/generator/traits/general_purpose_traits.hpp" 00029 #include "viennacl/generator/forwards.h" 00030 #include "viennacl/generator/meta_tools/utils.hpp" 00031 #include "viennacl/generator/elementwise_modifier.hpp" 00032 #include "viennacl/ocl/local_mem.hpp" 00033 #include "viennacl/ocl/handle.hpp" 00034 #include "viennacl/forwards.h" 00035 #include "CL/cl.h" 00036 00037 namespace viennacl 00038 { 00039 namespace generator 00040 { 00041 namespace result_of 00042 { 00043 00044 class runtime_wrapper 00045 { 00046 protected: 00047 bool is_temporary_; 00048 std::string name_; 00049 int arg_id_; 00050 00051 public: 00052 runtime_wrapper(bool _is_temporary, std::string const & _name, int _arg_id) 00053 : is_temporary_(_is_temporary), name_(_name), arg_id_(_arg_id) {} 00054 00055 bool is_temporary() const { return is_temporary_; } 00056 int arg_id() const { return arg_id_; } 00057 std::string name() const { return name_; } 00058 00059 virtual void enqueue(unsigned int arg_pos, 00060 viennacl::ocl::kernel & k, 00061 std::map<unsigned int, viennacl::any> & runtime_args, 00062 std::map<std::string, viennacl::ocl::handle<cl_mem> > & temporaries) = 0; 00063 }; 00064 00065 class shared_memory_wrapper : public runtime_wrapper 00066 { 00067 public: 00068 shared_memory_wrapper() : runtime_wrapper(true, "shared_memory_ptr", -1 ){ } 00069 00070 void enqueue(unsigned int arg_pos, 00071 viennacl::ocl::kernel & k, 00072 std::map<unsigned int, viennacl::any> & runtime_args, 00073 std::map<std::string, viennacl::ocl::handle<cl_mem> > & temporaries) 00074 { 00075 unsigned int lmem_size = k.local_work_size(); 00076 k.arg(arg_pos, viennacl::ocl::local_mem(lmem_size*sizeof(float))); 00077 } 00078 00079 }; 00080 00081 template <class T, class SIZE_T> 00082 struct vector_runtime_wrapper : public runtime_wrapper 00083 { 00084 private: 00085 unsigned int size_id_; 00086 00087 template<typename ScalarType, unsigned int Alignment> 00088 typename SIZE_T::size_type size(viennacl::vector<ScalarType,Alignment> * size_arg) { return size_arg->size(); } 00089 00090 template<typename ScalarType, class F, unsigned int Alignment> 00091 typename SIZE_T::size_type size(viennacl::matrix<ScalarType,F,Alignment> * size_arg) { return size_arg->size2(); } 00092 00093 template<typename ScalarType, unsigned int Alignment> 00094 typename SIZE_T::size_type internal_size(viennacl::vector<ScalarType,Alignment> * size_arg) { return size_arg->internal_size(); } 00095 00096 template<typename ScalarType, class F, unsigned int Alignment> 00097 typename SIZE_T::size_type internal_size(viennacl::matrix<ScalarType,F,Alignment> * size_arg) { return size_arg->internal_size2(); } 00098 00099 public: 00100 vector_runtime_wrapper(bool _is_temporary, std::string const & _name, int _arg_id, unsigned int _size_id) 00101 : runtime_wrapper(_is_temporary,_name,_arg_id),size_id_(_size_id) {} 00102 00103 void enqueue(unsigned int arg_pos, 00104 viennacl::ocl::kernel & k, 00105 std::map<unsigned int, viennacl::any> & runtime_args, 00106 std::map<std::string, 00107 viennacl::ocl::handle<cl_mem> > & temporaries) 00108 { 00109 SIZE_T * size_arg = viennacl::any_cast<SIZE_T * >(runtime_args[size_id_]); 00110 viennacl::ocl::handle<cl_mem> handle = NULL; 00111 if(is_temporary_) 00112 { 00113 if(temporaries.find(name_)==temporaries.end()) 00114 { 00115 temporaries.insert( 00116 std::make_pair(name_, 00117 viennacl::ocl::handle<cl_mem>( 00118 viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, 00119 size_arg->internal_size()*sizeof(typename T::value_type)) 00120 ) 00121 ) 00122 ); 00123 } 00124 handle = temporaries[name_]; 00125 } 00126 else 00127 { 00128 T * current_arg = viennacl::any_cast<T * >(runtime_args[arg_id_]); 00129 handle = current_arg->handle(); 00130 } 00131 k.arg(arg_pos, handle ); 00132 k.arg(arg_pos+1,cl_uint(size(size_arg))); 00133 k.arg(arg_pos+2,cl_uint(internal_size(size_arg))); 00134 } 00135 }; 00136 00137 template <class T, class SIZE_DESCRIPTOR> 00138 struct vector_expression : public runtime_wrapper 00139 { 00140 typedef T type; 00141 typedef typename SIZE_DESCRIPTOR::ScalarType ScalarType; 00142 static const unsigned int Alignment = SIZE_DESCRIPTOR::Alignment; 00143 00144 static runtime_wrapper * runtime_descriptor() 00145 { 00146 return new vector_runtime_wrapper<viennacl::vector<ScalarType,Alignment>, 00147 typename SIZE_DESCRIPTOR::runtime_type>(viennacl::generator::is_temporary<T>::value, 00148 T::name(), 00149 T::id,SIZE_DESCRIPTOR::id); 00150 } 00151 00152 static const std::string size_expression() 00153 { 00154 return SIZE_DESCRIPTOR::size2_name(); 00155 } 00156 00157 static const std::string internal_size_expression() 00158 { 00159 return SIZE_DESCRIPTOR::internal_size2_name() + "/" + to_string(Alignment); 00160 } 00161 }; 00162 00163 template <class T, class SIZE1_T, class SIZE2_T> 00164 struct matrix_runtime_wrapper : public runtime_wrapper 00165 { 00166 private: 00167 unsigned int size1_id_; 00168 unsigned int size2_id_; 00169 public: 00170 matrix_runtime_wrapper(bool _is_temporary, 00171 std::string const & _name, 00172 int _arg_id, 00173 unsigned int _size1_id, 00174 unsigned int _size2_id) 00175 : runtime_wrapper(_is_temporary,_name,_arg_id), size1_id_(_size1_id), size2_id_(_size2_id) {} 00176 00177 unsigned int n_elements(){ return size1_id_*size2_id_; } 00178 00179 void enqueue(unsigned int arg_pos, 00180 viennacl::ocl::kernel & k, 00181 std::map<unsigned int, viennacl::any> & runtime_args, 00182 std::map<std::string, 00183 viennacl::ocl::handle<cl_mem> > & temporaries) 00184 { 00185 if (is_temporary_) {} 00186 00187 T * current_arg = any_cast<T * >(runtime_args[arg_id_]); 00188 SIZE1_T * size1_arg = any_cast<SIZE1_T * >(runtime_args[size1_id_]); 00189 SIZE2_T * size2_arg = any_cast<SIZE2_T * >(runtime_args[size2_id_]); 00190 k.arg(arg_pos, current_arg->handle()); 00191 k.arg(arg_pos+1,cl_uint(size1_arg->size1())); 00192 k.arg(arg_pos+2,cl_uint(size2_arg->size2())); 00193 k.arg(arg_pos+3,cl_uint(size1_arg->internal_size1())); 00194 k.arg(arg_pos+4,cl_uint(size2_arg->internal_size2())); 00195 } 00196 }; 00197 00198 template <class T, class SIZE1_DESCRIPTOR, class SIZE2_DESCRIPTOR> 00199 struct matrix_expression 00200 { 00201 typedef typename SIZE1_DESCRIPTOR::ScalarType ScalarType; 00202 typedef typename SIZE1_DESCRIPTOR::Layout Layout; 00203 static const unsigned int Alignment = SIZE1_DESCRIPTOR::Alignment; 00204 00205 static runtime_wrapper * runtime_descriptor() 00206 { 00207 return new matrix_runtime_wrapper<viennacl::matrix<ScalarType,Layout,Alignment>, 00208 typename SIZE1_DESCRIPTOR::runtime_type, 00209 typename SIZE2_DESCRIPTOR::runtime_type>(is_temporary<T>::value,T::name(), 00210 T::id,SIZE1_DESCRIPTOR::id, 00211 SIZE2_DESCRIPTOR::id); 00212 } 00213 00214 static const std::string size1_expression() 00215 { 00216 return SIZE1_DESCRIPTOR::size1_name(); 00217 } 00218 00219 static const std::string size2_expression() 00220 { 00221 return SIZE2_DESCRIPTOR::size2_name(); 00222 } 00223 00224 static const std::string internal_size1_expression() 00225 { 00226 return SIZE1_DESCRIPTOR::internal_size1_name() + "/" + to_string(Alignment); 00227 } 00228 00229 static const std::string internal_size2_expression() 00230 { 00231 return SIZE2_DESCRIPTOR::internal_size2_name() + "/" + to_string(Alignment); 00232 } 00233 00234 typedef T type; 00235 }; 00236 00237 template <class T> 00238 struct scalar_size_descriptor 00239 { 00240 static unsigned int size(viennacl::ocl::kernel & k) { return 1; } 00241 }; 00242 00243 template <class LHS, class RHS, bool is_temporary> 00244 struct scalar_size_descriptor<compound_node<LHS,inner_prod_type,RHS,is_temporary> > 00245 { 00246 static unsigned int size(viennacl::ocl::kernel & k) 00247 { 00248 return k.global_work_size(0)/k.local_work_size(0); 00249 } 00250 }; 00251 00252 template <class T> 00253 struct scalar_runtime_wrapper: public runtime_wrapper 00254 { 00255 typedef typename T::ScalarType ScalarType; 00256 00257 scalar_runtime_wrapper(bool _is_temporary, std::string const & _name, int _arg_id) : runtime_wrapper(_is_temporary,_name,_arg_id){} 00258 00259 void enqueue(unsigned int arg_pos, 00260 viennacl::ocl::kernel & k, 00261 std::map<unsigned int, 00262 viennacl::any> & runtime_args, 00263 std::map<std::string, 00264 viennacl::ocl::handle<cl_mem> > & temporaries) 00265 { 00266 if(is_temporary_) 00267 { 00268 if(temporaries.find(name_)==temporaries.end()) 00269 { 00270 temporaries.insert( 00271 std::make_pair(name_, 00272 viennacl::ocl::handle<cl_mem>( 00273 viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, 00274 scalar_size_descriptor<T>::size(k)*sizeof(ScalarType)) 00275 ) 00276 ) 00277 ); 00278 } 00279 k.arg(arg_pos, temporaries[name_]); 00280 } 00281 00282 if(arg_id_==-2) 00283 k.arg(arg_pos, temporaries[name_]); 00284 else 00285 { 00286 viennacl::scalar<ScalarType>* current_arg = any_cast<viennacl::scalar<ScalarType> * >(runtime_args[arg_id_]); 00287 k.arg(arg_pos, current_arg->handle()); 00288 } 00289 00290 } 00291 }; 00292 00293 template <unsigned int ID, class ScalarType> 00294 struct scalar_runtime_wrapper<viennacl::generator::cpu_symbolic_scalar<ID, ScalarType> >: public runtime_wrapper 00295 { 00296 scalar_runtime_wrapper(bool _is_temporary, std::string const & _name, int _arg_id) : runtime_wrapper(_is_temporary,_name,_arg_id){ } 00297 00298 void enqueue(unsigned int arg_pos, 00299 viennacl::ocl::kernel & k, 00300 std::map<unsigned int, viennacl::any> & runtime_args, 00301 std::map<std::string, viennacl::ocl::handle<cl_mem> > & temporaries) 00302 { 00303 ScalarType* current_arg = any_cast<ScalarType * >(runtime_args[arg_id_]); 00304 k.arg(arg_pos, cl_float(*current_arg)); 00305 } 00306 }; 00307 00308 template <class T> 00309 struct scalar_expression 00310 { 00311 typedef typename T::ScalarType ScalarType; 00312 00313 static runtime_wrapper * runtime_descriptor() 00314 { 00315 return new scalar_runtime_wrapper<T>(is_temporary<T>::value,T::name(),T::id); 00316 } 00317 }; 00318 00319 /* 00320 * Compound Nodes - General case 00321 */ 00322 template <class T> 00323 struct expression_type 00324 { 00325 typedef NullType Result; 00326 }; 00327 00328 template <class LHS, class OP, class RHS, bool is_temporary> 00329 struct expression_type<compound_node<LHS,OP,RHS,is_temporary> > 00330 { 00331 private: 00332 typedef typename expression_type<LHS>::Result LHS_Result; 00333 typedef typename expression_type<RHS>::Result RHS_Result; 00334 00335 public: 00336 typedef typename expression_type<compound_node<LHS_Result, OP, RHS_Result,is_temporary> >::Result Result; 00337 }; 00338 00339 /* 00340 * Compound Nodes - usual operators 00341 */ 00342 template <class LHS, class LHS_SIZE_DESCRIPTOR ,class OP ,class RHS, class RHS_SIZE_DESCRIPTOR ,bool is_temporary> 00343 struct expression_type<compound_node<vector_expression<LHS,LHS_SIZE_DESCRIPTOR>, 00344 OP, 00345 vector_expression<RHS,RHS_SIZE_DESCRIPTOR>, 00346 is_temporary> 00347 > 00348 { 00349 private: 00350 typedef compound_node<LHS ,OP, RHS, is_temporary> T; 00351 00352 public: 00353 typedef vector_expression<T, LHS_SIZE_DESCRIPTOR> Result; 00354 }; 00355 00356 00357 template <class LHS, class LHS_SIZE1_DESCRIPTOR, class LHS_SIZE2_DESCRIPTOR, 00358 class OP, 00359 class RHS, class RHS_SIZE1_DESCRIPTOR, class RHS_SIZE2_DESCRIPTOR, 00360 bool is_temporary> 00361 struct expression_type<compound_node<matrix_expression<LHS, LHS_SIZE1_DESCRIPTOR, LHS_SIZE2_DESCRIPTOR>, 00362 OP, 00363 matrix_expression<RHS, RHS_SIZE1_DESCRIPTOR, RHS_SIZE2_DESCRIPTOR>, 00364 is_temporary> 00365 > 00366 { 00367 private: 00368 typedef compound_node<LHS ,OP, RHS, is_temporary> T; 00369 00370 public: 00371 typedef matrix_expression<T, LHS_SIZE1_DESCRIPTOR, LHS_SIZE2_DESCRIPTOR> Result; 00372 }; 00373 00374 template <class LHS, class OP, class RHS, bool is_temporary> 00375 struct expression_type<compound_node<scalar_expression<LHS>, 00376 OP, 00377 scalar_expression<RHS>, 00378 is_temporary> 00379 > 00380 { 00381 private: 00382 typedef compound_node<LHS ,OP, RHS, is_temporary> T; 00383 00384 public: 00385 typedef scalar_expression<T> Result; 00386 }; 00387 00388 /* 00389 * Scalar Operators 00390 */ 00391 template <class LHS, class LHS_SIZE_DESCRIPTOR, 00392 class OP, 00393 class RHS, 00394 bool is_temporary> 00395 struct expression_type<compound_node<vector_expression<LHS,LHS_SIZE_DESCRIPTOR>, 00396 OP, 00397 scalar_expression<RHS>, 00398 is_temporary> > 00399 { 00400 private: 00401 typedef compound_node<LHS ,OP, RHS, is_temporary> T; 00402 public: 00403 typedef vector_expression<T, LHS_SIZE_DESCRIPTOR> Result; 00404 }; 00405 00406 template <class LHS, 00407 class OP, 00408 class RHS, class RHS_SIZE_DESCRIPTOR, 00409 bool is_temporary> 00410 struct expression_type<compound_node<scalar_expression<LHS>, 00411 OP, 00412 vector_expression<RHS,RHS_SIZE_DESCRIPTOR>, 00413 is_temporary> 00414 > 00415 { 00416 private: 00417 typedef compound_node<LHS ,OP, RHS, is_temporary> T; 00418 public: 00419 typedef vector_expression<T, RHS_SIZE_DESCRIPTOR> Result; 00420 }; 00421 00422 00423 template <class LHS, class LHS_SIZE1_DESCRIPTOR, class LHS_SIZE2_DESCRIPTOR, 00424 class OP, 00425 class RHS, bool is_temporary> 00426 struct expression_type<compound_node<matrix_expression<LHS,LHS_SIZE1_DESCRIPTOR,LHS_SIZE2_DESCRIPTOR>, 00427 OP, 00428 scalar_expression<RHS>, 00429 is_temporary> 00430 > 00431 { 00432 private: 00433 typedef compound_node<LHS ,OP, RHS, is_temporary> T; 00434 public: 00435 typedef matrix_expression<T, LHS_SIZE1_DESCRIPTOR, LHS_SIZE2_DESCRIPTOR> Result; 00436 }; 00437 00438 template <class LHS, 00439 class OP, 00440 class RHS, class RHS_SIZE1_DESCRIPTOR, class RHS_SIZE2_DESCRIPTOR, 00441 bool is_temporary> 00442 struct expression_type<compound_node<scalar_expression<LHS>, 00443 OP, 00444 matrix_expression<RHS,RHS_SIZE1_DESCRIPTOR, RHS_SIZE2_DESCRIPTOR>, 00445 is_temporary> 00446 > 00447 { 00448 private: 00449 typedef compound_node<LHS ,OP, RHS, is_temporary> T; 00450 public: 00451 typedef matrix_expression<T, RHS_SIZE1_DESCRIPTOR, RHS_SIZE2_DESCRIPTOR> Result; 00452 }; 00453 00454 00455 /* 00456 * Compound Nodes - Non Trivial Operators 00457 */ 00458 00459 //Matrix-Vector product 00460 template <class LHS, class LHS_SIZE1_DESCRIPTOR, class LHS_SIZE2_DESCRIPTOR, 00461 class RHS, class RHS_SIZE_DESCRIPTOR, 00462 bool is_temporary> 00463 struct expression_type<compound_node<matrix_expression<LHS, LHS_SIZE1_DESCRIPTOR, LHS_SIZE2_DESCRIPTOR>, 00464 prod_type, 00465 vector_expression<RHS,RHS_SIZE_DESCRIPTOR>, 00466 is_temporary> 00467 > 00468 { 00469 typedef vector_expression<compound_node<LHS,prod_type,RHS,is_temporary>, LHS_SIZE1_DESCRIPTOR > Result; 00470 }; 00471 00472 template <class T> 00473 struct expression_type<inner_prod_impl_t<T> > 00474 { 00475 typedef scalar_expression<T> Result; 00476 }; 00477 00478 //Matrix-Matrix product 00479 template <class LHS, class LHS_SIZE1_DESCRIPTOR, class LHS_SIZE2_DESCRIPTOR, 00480 class RHS, class RHS_SIZE1_DESCRIPTOR, class RHS_SIZE2_DESCRIPTOR, 00481 bool is_temporary> 00482 struct expression_type<compound_node<matrix_expression<LHS, LHS_SIZE1_DESCRIPTOR, LHS_SIZE2_DESCRIPTOR>, 00483 prod_type, 00484 matrix_expression<RHS,RHS_SIZE1_DESCRIPTOR,RHS_SIZE2_DESCRIPTOR>, 00485 is_temporary> 00486 > 00487 { 00488 typedef matrix_expression<compound_node<LHS,prod_type,RHS,is_temporary>, LHS_SIZE1_DESCRIPTOR, RHS_SIZE2_DESCRIPTOR > Result; 00489 }; 00490 00491 //Inner product 00492 template <class LHS, class LHS_SIZE_DESCRIPTOR, 00493 class RHS, class RHS_SIZE_DESCRIPTOR, 00494 bool is_temporary> 00495 struct expression_type< compound_node<vector_expression<LHS,LHS_SIZE_DESCRIPTOR>, 00496 inner_prod_type, 00497 vector_expression<RHS,RHS_SIZE_DESCRIPTOR>, 00498 is_temporary> 00499 > 00500 { 00501 typedef scalar_expression<compound_node<LHS,inner_prod_type,RHS,is_temporary> > Result; 00502 }; 00503 00504 00505 /* 00506 * Elementwise Modifiers 00507 */ 00508 template <class T, std::string (*U)()> 00509 struct expression_type< elementwise_modifier_impl<T,U> > 00510 { 00511 typedef typename expression_type<T>::Result Result; 00512 }; 00513 00514 template <class T, class SIZE_DESCRIPTOR> 00515 struct expression_type< vector_expression<T,SIZE_DESCRIPTOR> > 00516 { 00517 typedef typename expression_type<T>::Result Result; 00518 }; 00519 00520 template <class T, class SIZE1_DESCRIPTOR, class SIZE2_DESCRIPTOR> 00521 struct expression_type< matrix_expression<T,SIZE1_DESCRIPTOR,SIZE2_DESCRIPTOR> > 00522 { 00523 typedef typename expression_type<T>::Result Result; 00524 }; 00525 00526 template <class T> 00527 struct expression_type< scalar_expression<T> > 00528 { 00529 typedef typename expression_type<T>::Result Result; 00530 }; 00531 00532 /* 00533 * Symbolic Vectors 00534 */ 00535 00536 template <unsigned int ID,typename SCALARTYPE, unsigned int ALIGNMENT> 00537 struct expression_type< symbolic_vector<ID,SCALARTYPE,ALIGNMENT> > 00538 { 00539 typedef vector_expression<symbolic_vector<ID,SCALARTYPE,ALIGNMENT>, 00540 symbolic_vector<ID,SCALARTYPE,ALIGNMENT> > Result; 00541 }; 00542 00543 template <class Ref> 00544 struct expression_type<tmp_symbolic_vector<Ref> > 00545 { 00546 typedef vector_expression<tmp_symbolic_vector<Ref>, Ref> Result; 00547 }; 00548 00549 /* 00550 * Symbolic Matrices 00551 */ 00552 00553 template <unsigned int ID,typename SCALARTYPE, class F, unsigned int ALIGNMENT> 00554 struct expression_type<symbolic_matrix<ID,SCALARTYPE,F,ALIGNMENT> > 00555 { 00556 private: 00557 typedef symbolic_matrix<ID,SCALARTYPE,F,ALIGNMENT> T; 00558 public: 00559 typedef matrix_expression<T, T, T> Result; 00560 }; 00561 00562 template <class Ref> 00563 struct expression_type<tmp_symbolic_matrix<Ref> > 00564 { 00565 typedef matrix_expression<tmp_symbolic_matrix<Ref>, Ref, Ref > Result; 00566 }; 00567 00568 /* 00569 * Symbolic Scalars 00570 */ 00571 00572 template <unsigned int ID, typename SCALARTYPE> 00573 struct expression_type<cpu_symbolic_scalar<ID, SCALARTYPE> > 00574 { 00575 typedef scalar_expression<cpu_symbolic_scalar<ID, SCALARTYPE> > Result; 00576 }; 00577 00578 template <unsigned int ID, typename SCALARTYPE> 00579 struct expression_type<gpu_symbolic_scalar<ID, SCALARTYPE> > 00580 { 00581 typedef scalar_expression< gpu_symbolic_scalar<ID, SCALARTYPE> > Result; 00582 }; 00583 00584 00585 } 00586 } 00587 } 00588 00589 #endif 00590 00591
1.7.4