ViennaCL - The Vienna Computing Library
1.5.0
|
00001 #ifndef VIENNACL_GENERATOR_STATEMENT_REPRESENTATION_HPP 00002 #define VIENNACL_GENERATOR_STATEMENT_REPRESENTATION_HPP 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2013, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 Portions of this software are copyright by UChicago Argonne, LLC. 00009 00010 ----------------- 00011 ViennaCL - The Vienna Computing Library 00012 ----------------- 00013 00014 Project Head: Karl Rupp rupp@iue.tuwien.ac.at 00015 00016 (A list of authors and contributors can be found in the PDF manual) 00017 00018 License: MIT (X11), see file LICENSE in the base directory 00019 ============================================================================= */ 00020 00021 00026 #include <set> 00027 #include <cstring> 00028 00029 #include "viennacl/forwards.h" 00030 #include "viennacl/scheduler/forwards.h" 00031 #include "viennacl/generator/forwards.h" 00032 00033 #include "viennacl/tools/shared_ptr.hpp" 00034 00035 #include "viennacl/ocl/backend.hpp" 00036 #include "viennacl/ocl/kernel.hpp" 00037 00038 #include "viennacl/traits/start.hpp" 00039 #include "viennacl/traits/stride.hpp" 00040 00041 #include "viennacl/generator/helpers.hpp" 00042 #include "viennacl/generator/utils.hpp" 00043 #include "viennacl/generator/mapped_objects.hpp" 00044 00045 namespace viennacl{ 00046 00047 namespace generator{ 00048 00049 namespace detail{ 00050 00052 class statement_representation_functor : public traversal_functor{ 00053 private: 00054 unsigned int get_id(void * handle) const{ 00055 unsigned int i = 0; 00056 for( ; i < 64 ; ++i){ 00057 void* current = memory_[i]; 00058 if(current==NULL) 00059 break; 00060 if(current==handle) 00061 return i; 00062 } 00063 memory_[i] = handle; 00064 return i; 00065 } 00066 00067 static void append_id(char * & ptr, unsigned int val){ 00068 if(val==0) 00069 *ptr++='0'; 00070 else 00071 while(val>0) 00072 { 00073 *ptr++=static_cast<char>('0') + static_cast<char>(val % 10); 00074 val /= 10; 00075 } 00076 } 00077 00078 public: 00079 typedef void result_type; 00080 00081 statement_representation_functor(void* (&memory)[64], unsigned int , char *& ptr) : memory_(memory), ptr_(ptr){ } 00082 00083 template<class ScalarType> 00084 result_type operator()(ScalarType const & /*scal*/) const { 00085 *ptr_++='h'; //host 00086 *ptr_++='s'; //scalar 00087 *ptr_++=utils::first_letter_of_type<ScalarType>::value(); 00088 } 00089 00091 template<class ScalarType> 00092 result_type operator()(scalar<ScalarType> const & scal) const { 00093 *ptr_++='s'; //scalar 00094 *ptr_++=utils::first_letter_of_type<ScalarType>::value(); 00095 append_id(ptr_, get_id((void*)&scal)); 00096 } 00097 00099 template<class ScalarType> 00100 result_type operator()(vector_base<ScalarType> const & vec) const { 00101 *ptr_++='v'; //vector 00102 if(viennacl::traits::start(vec)>0) 00103 *ptr_++='r'; 00104 if(vec.stride()>1) 00105 *ptr_++='s'; 00106 *ptr_++=utils::first_letter_of_type<ScalarType>::value(); 00107 append_id(ptr_, get_id((void*)&vec)); 00108 } 00109 00111 template<class ScalarType> 00112 result_type operator()(implicit_vector_base<ScalarType> const & vec) const { 00113 *ptr_++='i'; //implicit 00114 *ptr_++='v'; //vector 00115 if(vec.is_value_static()) 00116 *ptr_++='v'; //value 00117 if(vec.has_index()) 00118 *ptr_++='i'; 00119 *ptr_++=utils::first_letter_of_type<ScalarType>::value(); 00120 } 00121 00123 template<class ScalarType, class Layout> 00124 result_type operator()(matrix_base<ScalarType, Layout> const & mat) const { 00125 *ptr_++='m'; //vector 00126 if(viennacl::traits::start1(mat)>0) 00127 *ptr_++='r'; 00128 if(viennacl::traits::stride1(mat)>1) 00129 *ptr_++='s'; 00130 if(viennacl::traits::start2(mat)>0) 00131 *ptr_++='r'; 00132 if(viennacl::traits::stride2(mat)>1) 00133 *ptr_++='s'; 00134 *ptr_++=utils::first_letter_of_type<ScalarType>::value(); 00135 *ptr_++=utils::first_letter_of_type<Layout>::value(); 00136 append_id(ptr_, get_id((void*)&mat)); 00137 } 00138 00140 template<class ScalarType> 00141 result_type operator()(implicit_matrix_base<ScalarType> const & mat) const { 00142 *ptr_++='i'; //implicit 00143 *ptr_++='m'; //matrix 00144 if(mat.is_value_static()) 00145 *ptr_++='v'; //value 00146 *ptr_++=utils::first_letter_of_type<ScalarType>::value(); 00147 } 00148 00149 void operator()(scheduler::statement const *, scheduler::statement_node const * root_node, detail::node_type node_type) const { 00150 if(node_type==LHS_NODE_TYPE && root_node->lhs.type_family != scheduler::COMPOSITE_OPERATION_FAMILY) 00151 utils::call_on_element(root_node->lhs, *this); 00152 else if(node_type==RHS_NODE_TYPE && root_node->rhs.type_family != scheduler::COMPOSITE_OPERATION_FAMILY) 00153 utils::call_on_element(root_node->rhs, *this); 00154 else if(node_type==PARENT_NODE_TYPE){ 00155 const char * op_expr = detail::generate(root_node->op.type); 00156 vcl_size_t n = std::strlen(op_expr); 00157 std::memcpy(ptr_, op_expr, n); 00158 ptr_+=n; 00159 } 00160 } 00161 00162 private: 00163 void* (&memory_)[64]; 00164 char *& ptr_; 00165 }; 00166 00167 } 00168 00169 } 00170 00171 } 00172 #endif