ViennaCL - The Vienna Computing Library  1.5.2
viennacl/device_specific/tree_parsing/statement_representation.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_DEVICE_SPECIFIC_TREE_PARSING_STATEMENT_REPRESENTATION_HPP
00002 #define VIENNACL_DEVICE_SPECIFIC_TREE_PARSING_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 
00031 #include "viennacl/scheduler/forwards.h"
00032 
00033 #include "viennacl/device_specific/forwards.h"
00034 #include "viennacl/device_specific/tree_parsing/traverse.hpp"
00035 #include "viennacl/device_specific/utils.hpp"
00036 #include "viennacl/device_specific/mapped_objects.hpp"
00037 
00038 
00039 namespace viennacl{
00040 
00041   namespace device_specific{
00042 
00043     namespace tree_parsing{
00044 
00045       class statement_representation_functor : public traversal_functor{
00046         private:
00047           static void append_id(char * & ptr, unsigned int val){
00048             if(val==0)
00049               *ptr++='0';
00050             else
00051               while(val>0)
00052               {
00053                   *ptr++='0' + (val % 10);
00054                   val /= 10;
00055               }
00056           }
00057 
00058         public:
00059           typedef void result_type;
00060 
00061           statement_representation_functor(symbolic_binder & binder, char *& ptr) : binder_(binder), ptr_(ptr){ }
00062 
00063           template<class ScalarType>
00064           inline result_type operator()(ScalarType const & /*scal*/) const
00065           {
00066             *ptr_++='h'; //host
00067             *ptr_++='s'; //scalar
00068             *ptr_++=utils::first_letter_of_type<ScalarType>::value();
00069           }
00070 
00072           template<class ScalarType>
00073           inline result_type operator()(scalar<ScalarType> const & scal) const
00074           {
00075             *ptr_++='s'; //scalar
00076             *ptr_++=utils::first_letter_of_type<ScalarType>::value();
00077             append_id(ptr_, binder_.get(&traits::handle(scal)));
00078           }
00079 
00081           template<class ScalarType>
00082           inline result_type operator()(vector_base<ScalarType> const & vec) const
00083           {
00084             *ptr_++='v'; //vector
00085             *ptr_++=utils::first_letter_of_type<ScalarType>::value();
00086             append_id(ptr_, binder_.get(&traits::handle(vec)));
00087           }
00088 
00090           template<class ScalarType>
00091           inline result_type operator()(implicit_vector_base<ScalarType> const & /*vec*/) const
00092           {
00093             *ptr_++='i'; //implicit
00094             *ptr_++='v'; //vector
00095             *ptr_++=utils::first_letter_of_type<ScalarType>::value();
00096           }
00097 
00099           template<class ScalarType>
00100           inline result_type operator()(matrix_base<ScalarType> const & mat) const
00101           {
00102             *ptr_++='m'; //Matrix
00103             *ptr_++=utils::first_letter_of_type<ScalarType>::value();
00104             append_id(ptr_, binder_.get(&traits::handle(mat)));
00105           }
00106 
00108           template<class ScalarType>
00109           inline result_type operator()(implicit_matrix_base<ScalarType> const & /*mat*/) const
00110           {
00111             *ptr_++='i'; //implicit
00112             *ptr_++='m'; //matrix
00113             *ptr_++=utils::first_letter_of_type<ScalarType>::value();
00114           }
00115 
00116           static inline void append(char*& p, const char * str)
00117           {
00118             std::size_t n = std::strlen(str);
00119             std::memcpy(p, str, n);
00120             p+=n;
00121           }
00122 
00123           inline void operator()(scheduler::statement const & statement, unsigned int root_idx, node_type node_type) const
00124           {
00125             scheduler::statement_node const & root_node = statement.array()[root_idx];
00126             if(node_type==LHS_NODE_TYPE && root_node.lhs.type_family != scheduler::COMPOSITE_OPERATION_FAMILY)
00127               utils::call_on_element(root_node.lhs, *this);
00128             else if(root_node.op.type_family==scheduler::OPERATION_BINARY_TYPE_FAMILY && node_type==RHS_NODE_TYPE && root_node.rhs.type_family != scheduler::COMPOSITE_OPERATION_FAMILY)
00129               utils::call_on_element(root_node.rhs, *this);
00130             else if(node_type==PARENT_NODE_TYPE)
00131               append_id(ptr_,root_node.op.type);
00132           }
00133 
00134         private:
00135           symbolic_binder & binder_;
00136           char *& ptr_;
00137       };
00138 
00139       inline std::string statements_representation(statements_container const & statements, binding_policy_t binding_policy)
00140       {
00141           std::vector<char> program_name_vector(256);
00142           char* program_name = program_name_vector.data();
00143           if(statements.order()==statements_container::INDEPENDENT)
00144             *program_name++='i';
00145           else
00146             *program_name++='s';
00147           tools::shared_ptr<symbolic_binder> binder = make_binder(binding_policy);
00148           for(statements_container::data_type::const_iterator it = statements.data().begin() ; it != statements.data().end() ; ++it)
00149               tree_parsing::traverse(*it, it->root(), tree_parsing::statement_representation_functor(*binder, program_name),true);
00150           *program_name='\0';
00151           return std::string(program_name_vector.data());
00152       }
00153 
00154     }
00155 
00156   }
00157 
00158 }
00159 #endif