ViennaCL - The Vienna Computing Library  1.5.2
viennacl/generator/map_functor.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_GENERATOR_MAP_GENERATE_PROTOTYPE_HPP
00002 #define VIENNACL_GENERATOR_MAP_GENERATE_PROTOTYPE_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 
00028 #include "viennacl/forwards.h"
00029 #include "viennacl/vector.hpp"
00030 #include "viennacl/matrix.hpp"
00031 #include "viennacl/scheduler/forwards.h"
00032 #include "viennacl/generator/forwards.h"
00033 
00034 #include "viennacl/tools/shared_ptr.hpp"
00035 
00036 #include "viennacl/generator/helpers.hpp"
00037 #include "viennacl/generator/utils.hpp"
00038 #include "viennacl/generator/mapped_objects.hpp"
00039 
00040 namespace viennacl{
00041 
00042   namespace generator{
00043 
00044     namespace detail{
00045 
00047       class map_functor : public traversal_functor{
00048           std::string create_name(unsigned int & current_arg, std::map<void *, vcl_size_t> & memory, void * handle) const{
00049             if(handle==NULL)
00050               return "arg" + utils::to_string(current_arg_++);
00051             if(memory.insert(std::make_pair(handle, current_arg)).second)
00052               return "arg" + utils::to_string(current_arg_++);
00053             else
00054               return "arg" + utils::to_string(memory[handle]);
00055           }
00056 
00057         public:
00058           typedef container_ptr_type result_type;
00059 
00060           map_functor(std::map<void *, vcl_size_t> & memory, unsigned int & current_arg, mapping_type & mapping) : memory_(memory), current_arg_(current_arg), mapping_(mapping){ }
00061 
00063           template<class T>
00064           result_type binary_leaf(viennacl::scheduler::statement const * statement, viennacl::scheduler::statement_node const * root_node, mapping_type const * mapping) const {
00065             T * p = new T("float");
00066 
00067             p->info_.statement = statement;
00068             p->info_.root_node = root_node;
00069             p->info_.mapping = mapping;
00070 
00071             return container_ptr_type(p);
00072           }
00073 
00074           template<class ScalarType>
00075           result_type operator()(ScalarType const & /*scal*/) const {
00076             mapped_host_scalar * p = new mapped_host_scalar(utils::type_to_string<ScalarType>::value());
00077             p->name_ = create_name(current_arg_, memory_, NULL);
00078             return container_ptr_type(p);
00079           }
00080 
00082           template<class ScalarType>
00083           result_type operator()(scalar<ScalarType> const & scal) const {
00084             mapped_scalar * p = new mapped_scalar(utils::type_to_string<ScalarType>::value());
00085             p->name_ = create_name(current_arg_, memory_, (void*)&scal);
00086             return container_ptr_type(p);
00087           }
00088 
00090           template<class ScalarType>
00091           result_type operator()(vector_base<ScalarType> const & vec) const {
00092             mapped_vector * p = new mapped_vector(utils::type_to_string<ScalarType>::value());
00093             p->name_ = create_name(current_arg_, memory_, (void*)&vec);
00094             if(vec.start() > 0)
00095               p->start_name_ = p->name_ +"_start";
00096             if(vec.stride() > 1)
00097               p->stride_name_ = p->name_ + "_stride";
00098             return container_ptr_type(p);
00099           }
00100 
00102           template<class ScalarType>
00103           result_type operator()(implicit_vector_base<ScalarType> const & vec) const {
00104             mapped_implicit_vector * p = new mapped_implicit_vector(utils::type_to_string<ScalarType>::value());
00105 
00106             if(vec.is_value_static()==false)
00107               p->value_name_ = create_name(current_arg_, memory_, NULL);
00108             if(vec.has_index())
00109               p->value_name_ = create_name(current_arg_, memory_, NULL);
00110             return container_ptr_type(p);
00111           }
00112 
00114           template<class ScalarType, class Layout>
00115           result_type operator()(matrix_base<ScalarType, Layout> const & mat) const {
00116             mapped_matrix * p = new mapped_matrix(utils::type_to_string<ScalarType>::value());
00117             p->name_ = create_name(current_arg_, memory_, (void*)&mat);
00118             p->is_row_major_ = static_cast<bool>(utils::is_same_type<Layout, viennacl::row_major>::value);
00119             if(mat.start1() > 0)
00120               p->start1_name_ = p->name_ +"_start1";
00121             if(mat.stride1() > 1)
00122               p->stride1_name_ = p->name_ + "_stride1";
00123             if(mat.start2() > 0)
00124               p->start2_name_ = p->name_ +"_start2";
00125             if(mat.stride2() > 1)
00126               p->stride2_name_ = p->name_ + "_stride2";
00127             return container_ptr_type(p);
00128           }
00129 
00131           template<class ScalarType>
00132           result_type operator()(implicit_matrix_base<ScalarType> const & mat) const {
00133             mapped_implicit_matrix * p = new mapped_implicit_matrix(utils::type_to_string<ScalarType>::value());
00134 
00135             if(mat.is_value_static()==false)
00136               p->value_name_ = create_name(current_arg_, memory_, NULL);
00137 
00138             return container_ptr_type(p);
00139           }
00140 
00142           void operator()(viennacl::scheduler::statement const * statement, viennacl::scheduler::statement_node const * root_node, detail::node_type node_type) const {
00143             const key_type key(root_node, node_type);
00144             if(node_type == LHS_NODE_TYPE && root_node->lhs.type_family != viennacl::scheduler::COMPOSITE_OPERATION_FAMILY)
00145                  mapping_.insert(mapping_type::value_type(key, utils::call_on_element(root_node->lhs, *this)));
00146             else if(node_type == RHS_NODE_TYPE && root_node->rhs.type_family != viennacl::scheduler::COMPOSITE_OPERATION_FAMILY)
00147                  mapping_.insert(mapping_type::value_type(key,  utils::call_on_element(root_node->rhs, *this)));
00148             else if( node_type== PARENT_NODE_TYPE){
00149                   viennacl::scheduler::operation_node_type op_type = root_node->op.type;
00150                 if(op_type == viennacl::scheduler::OPERATION_BINARY_INNER_PROD_TYPE)
00151                   mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_scalar_reduction>(statement, root_node, &mapping_)));
00152                 else if(op_type == viennacl::scheduler::OPERATION_BINARY_MAT_VEC_PROD_TYPE)
00153                   mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_vector_reduction>(statement, root_node, &mapping_)));
00154                 else if(op_type == viennacl::scheduler::OPERATION_BINARY_MAT_MAT_PROD_TYPE)
00155                   mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_matrix_product>(statement, root_node, &mapping_)));
00156             }
00157           }
00158 
00159         private:
00160           std::map<void *, vcl_size_t> & memory_;
00161           unsigned int & current_arg_;
00162           mapping_type & mapping_;
00163       };
00164 
00165     }
00166 
00167   }
00168 
00169 }
00170 #endif