ViennaCL - The Vienna Computing Library  1.5.1
viennacl/generator/statement_representation_functor.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_GENERATOR_STATEMENT_REPRESENTATION_HPP
00002 #define VIENNACL_GENERATOR_STATEMENT_REPRESENTATION_HPP
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2014, 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