ViennaCL - The Vienna Computing Library  1.5.2
viennacl/device_specific/tree_parsing/map.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_DEVICE_SPECIFIC_TREE_PARSING_MAP_HPP
00002 #define VIENNACL_DEVICE_SPECIFIC_TREE_PARSING_MAP_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 
00028 #include "viennacl/forwards.h"
00029 
00030 #include "viennacl/scheduler/forwards.h"
00031 #include "viennacl/scheduler/io.hpp"
00032 #include "viennacl/device_specific/forwards.h"
00033 
00034 #include "viennacl/tools/shared_ptr.hpp"
00035 
00036 #include "viennacl/device_specific/forwards.h"
00037 #include "viennacl/device_specific/tree_parsing/traverse.hpp"
00038 #include "viennacl/device_specific/utils.hpp"
00039 #include "viennacl/device_specific/mapped_objects.hpp"
00040 
00041 #include "viennacl/traits/row_major.hpp"
00042 
00043 namespace viennacl{
00044 
00045   namespace device_specific{
00046 
00047     namespace tree_parsing{
00048 
00050       class map_functor : public traversal_functor{
00051 
00052           scheduler::statement_node_numeric_type numeric_type(scheduler::statement const * statement, unsigned int root_idx) const
00053           {
00054               scheduler::statement_node const * root_node = &statement->array()[root_idx];
00055               while(root_node->lhs.numeric_type==scheduler::INVALID_NUMERIC_TYPE)
00056                   root_node = &statement->array()[root_node->lhs.node_index];
00057               return root_node->lhs.numeric_type;
00058           }
00059 
00060         public:
00061           typedef tools::shared_ptr<mapped_object> result_type;
00062 
00063           map_functor(symbolic_binder & binder, mapping_type & mapping) : binder_(binder), mapping_(mapping){ }
00064 
00066           template<class T>
00067           result_type binary_leaf(scheduler::statement const * statement, unsigned int root_idx, mapping_type const * mapping) const
00068           {
00069             return result_type(new T(utils::numeric_type_to_string(numeric_type(statement,root_idx)), binder_.get(NULL), mapped_object::node_info(mapping, statement, root_idx)));
00070           }
00071 
00072           template<class ScalarType>
00073           result_type operator()(ScalarType const & /*sca*l*/) const
00074           {
00075             return result_type(new mapped_host_scalar(utils::type_to_string<ScalarType>::value(), binder_.get(NULL)));
00076           }
00077 
00079           template<class ScalarType>
00080           result_type operator()(scalar<ScalarType> const & scal) const
00081           {
00082             return result_type(new mapped_scalar(utils::type_to_string<ScalarType>::value(), binder_.get(&viennacl::traits::handle(scal))));
00083           }
00084 
00086           template<class ScalarType>
00087           result_type operator()(vector_base<ScalarType> const & vec) const
00088           {
00089             return result_type(new mapped_vector(utils::type_to_string<ScalarType>::value(), binder_.get(&viennacl::traits::handle(vec))));
00090           }
00091 
00093           template<class ScalarType>
00094           result_type operator()(implicit_vector_base<ScalarType> const & /*vec*/) const
00095           {
00096             return result_type(new mapped_implicit_vector(utils::type_to_string<ScalarType>::value(), binder_.get(NULL)));
00097           }
00098 
00100           template<class ScalarType>
00101           result_type operator()(matrix_base<ScalarType> const & mat) const
00102           {
00103             return result_type(new mapped_matrix(utils::type_to_string<ScalarType>::value(), binder_.get(&viennacl::traits::handle(mat)),
00104                                                   viennacl::traits::row_major(mat)));
00105           }
00106 
00108           template<class ScalarType>
00109           result_type operator()(implicit_matrix_base<ScalarType> const & /*mat*/) const
00110           {
00111             return result_type(new mapped_implicit_matrix(utils::type_to_string<ScalarType>::value(), binder_.get(NULL)));
00112           }
00113 
00115           void operator()(scheduler::statement const & statement, unsigned int root_idx, node_type node_type) const {
00116             mapping_type::key_type key(root_idx, node_type);
00117             scheduler::statement_node const & root_node = statement.array()[root_idx];
00118 
00119             if(node_type == LHS_NODE_TYPE && root_node.lhs.type_family != scheduler::COMPOSITE_OPERATION_FAMILY)
00120                  mapping_.insert(mapping_type::value_type(key, utils::call_on_element(root_node.lhs, *this)));
00121             else if(node_type == RHS_NODE_TYPE && root_node.rhs.type_family != scheduler::COMPOSITE_OPERATION_FAMILY)
00122                  mapping_.insert(mapping_type::value_type(key,  utils::call_on_element(root_node.rhs, *this)));
00123             else if( node_type== PARENT_NODE_TYPE)
00124             {
00125                 if(root_node.op.type==scheduler::OPERATION_BINARY_VECTOR_DIAG_TYPE)
00126                   mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_vector_diag>(&statement, root_idx, &mapping_)));
00127                 else if(root_node.op.type==scheduler::OPERATION_BINARY_MATRIX_DIAG_TYPE)
00128                   mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_matrix_diag>(&statement, root_idx, &mapping_)));
00129                 else if(root_node.op.type==scheduler::OPERATION_BINARY_MATRIX_ROW_TYPE)
00130                   mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_matrix_row>(&statement, root_idx, &mapping_)));
00131                 else if(root_node.op.type==scheduler::OPERATION_BINARY_MATRIX_COLUMN_TYPE)
00132                   mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_matrix_column>(&statement, root_idx, &mapping_)));
00133                 else if(is_scalar_reduction(root_node))
00134                   mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_scalar_reduction>(&statement, root_idx, &mapping_)));
00135                 else if(is_vector_reduction(root_node))
00136                   mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_vector_reduction>(&statement, root_idx, &mapping_)));
00137                 else if(root_node.op.type == scheduler::OPERATION_BINARY_MAT_MAT_PROD_TYPE)
00138                   mapping_.insert(mapping_type::value_type(key, binary_leaf<mapped_matrix_product>(&statement, root_idx, &mapping_)));
00139                 else if(root_node.op.type == scheduler::OPERATION_UNARY_TRANS_TYPE){
00140                   key.second = tree_parsing::LHS_NODE_TYPE;
00141                   mapping_type::iterator it = mapping_.insert(mapping_type::value_type(key, utils::call_on_element(root_node.lhs, *this))).first;
00142                   ((mapped_matrix *)it->second.get())->flip_transpose();
00143                 }
00144            }
00145           }
00146 
00147         private:
00148           symbolic_binder & binder_;
00149           mapping_type & mapping_;
00150       };
00151 
00152     }
00153 
00154   }
00155 
00156 }
00157 #endif