ViennaCL - The Vienna Computing Library  1.5.0
viennacl/scheduler/execute_util.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_SCHEDULER_EXECUTE_UTIL_HPP
00002 #define VIENNACL_SCHEDULER_EXECUTE_UTIL_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 <assert.h>
00027 
00028 #include "viennacl/forwards.h"
00029 #include "viennacl/scalar.hpp"
00030 #include "viennacl/vector.hpp"
00031 #include "viennacl/matrix.hpp"
00032 #include "viennacl/scheduler/forwards.h"
00033 
00034 namespace viennacl
00035 {
00036   namespace scheduler
00037   {
00038     namespace detail
00039     {
00040       //
00041       inline lhs_rhs_element const & extract_representative_vector(statement const & s, lhs_rhs_element const & element)
00042       {
00043         switch (element.type_family)
00044         {
00045         case VECTOR_TYPE_FAMILY:
00046           return element;
00047         case COMPOSITE_OPERATION_FAMILY:
00048         {
00049           statement_node const & leaf = s.array()[element.node_index];
00050 
00051           if (leaf.op.type_family == OPERATION_UNARY_TYPE_FAMILY)
00052             return extract_representative_vector(s, leaf.lhs);
00053           switch (leaf.op.type)
00054           {
00055           case OPERATION_BINARY_ADD_TYPE:
00056           case OPERATION_BINARY_SUB_TYPE:
00057           case OPERATION_BINARY_MULT_TYPE:
00058           case OPERATION_BINARY_DIV_TYPE:
00059           case OPERATION_BINARY_ELEMENT_PROD_TYPE:
00060           case OPERATION_BINARY_ELEMENT_DIV_TYPE:
00061             return extract_representative_vector(s, leaf.lhs);
00062           case OPERATION_BINARY_MAT_VEC_PROD_TYPE:
00063             return extract_representative_vector(s, leaf.rhs);
00064           default:
00065             throw statement_not_supported_exception("Vector leaf encountered an invalid binary operation!");
00066           }
00067         }
00068         default:
00069           throw statement_not_supported_exception("Vector leaf encountered an invalid node type!");
00070         }
00071       }
00072 
00073 
00074       // helper routines for extracting the scalar type
00075       inline float convert_to_float(float f) { return f; }
00076       inline float convert_to_float(double d) { return static_cast<float>(d); }
00077       inline float convert_to_float(lhs_rhs_element const & el)
00078       {
00079         if (el.type_family == SCALAR_TYPE_FAMILY && el.subtype == HOST_SCALAR_TYPE && el.numeric_type == FLOAT_TYPE)
00080           return el.host_float;
00081         if (el.type_family == SCALAR_TYPE_FAMILY && el.subtype == DEVICE_SCALAR_TYPE && el.numeric_type == FLOAT_TYPE)
00082           return *el.scalar_float;
00083 
00084         throw statement_not_supported_exception("Cannot convert to float");
00085       }
00086 
00087       // helper routines for extracting the scalar type
00088       inline double convert_to_double(float d) { return static_cast<double>(d); }
00089       inline double convert_to_double(double d) { return d; }
00090       inline double convert_to_double(lhs_rhs_element const & el)
00091       {
00092         if (el.type_family == SCALAR_TYPE_FAMILY && el.subtype == HOST_SCALAR_TYPE && el.numeric_type == DOUBLE_TYPE)
00093           return el.host_double;
00094         if (el.type_family == SCALAR_TYPE_FAMILY && el.subtype == DEVICE_SCALAR_TYPE && el.numeric_type == DOUBLE_TYPE)
00095           return *el.scalar_double;
00096 
00097         throw statement_not_supported_exception("Cannot convert to double");
00098       }
00099 
00101 
00102       inline void new_element(lhs_rhs_element & new_elem, lhs_rhs_element const & old_element)
00103       {
00104         new_elem.type_family  = old_element.type_family;
00105         new_elem.subtype      = old_element.subtype;
00106         new_elem.numeric_type = old_element.numeric_type;
00107         if (new_elem.type_family == SCALAR_TYPE_FAMILY)
00108         {
00109           assert(new_elem.subtype == DEVICE_SCALAR_TYPE && bool("Expected a device scalar in root node"));
00110 
00111           switch (new_elem.numeric_type)
00112           {
00113             case FLOAT_TYPE:
00114               new_elem.scalar_float = new viennacl::scalar<float>();
00115               return;
00116             case DOUBLE_TYPE:
00117               new_elem.scalar_double = new viennacl::scalar<double>();
00118               return;
00119             default:
00120               throw statement_not_supported_exception("Invalid vector type for vector construction");
00121           }
00122         }
00123         else if (new_elem.type_family == VECTOR_TYPE_FAMILY)
00124         {
00125           assert(new_elem.subtype == DENSE_VECTOR_TYPE && bool("Expected a dense vector in root node"));
00126 
00127           switch (new_elem.numeric_type)
00128           {
00129             case FLOAT_TYPE:
00130               new_elem.vector_float = new viennacl::vector<float>((old_element.vector_float)->size());
00131               return;
00132             case DOUBLE_TYPE:
00133               new_elem.vector_double = new viennacl::vector<double>((old_element.vector_float)->size());
00134               return;
00135             default:
00136               throw statement_not_supported_exception("Invalid vector type for vector construction");
00137           }
00138         }
00139         else if (new_elem.type_family == MATRIX_TYPE_FAMILY)
00140         {
00141           assert( (new_elem.subtype == DENSE_COL_MATRIX_TYPE || new_elem.subtype == DENSE_ROW_MATRIX_TYPE)
00142                  && bool("Expected a dense matrix in root node"));
00143 
00144           if (new_elem.subtype == DENSE_COL_MATRIX_TYPE)
00145           {
00146             switch (new_elem.numeric_type)
00147             {
00148               case FLOAT_TYPE:
00149                 new_elem.matrix_col_float = new viennacl::matrix<float, viennacl::column_major>((old_element.matrix_col_float)->size1(), (old_element.matrix_col_float)->size2());
00150                 return;
00151               case DOUBLE_TYPE:
00152                 new_elem.matrix_col_double = new viennacl::matrix<double, viennacl::column_major>((old_element.matrix_col_double)->size1(), (old_element.matrix_col_double)->size2());
00153                 return;
00154               default:
00155                 throw statement_not_supported_exception("Invalid vector type for vector construction");
00156             }
00157           }
00158           else if (new_elem.subtype == DENSE_ROW_MATRIX_TYPE)
00159           {
00160             switch (new_elem.numeric_type)
00161             {
00162               case FLOAT_TYPE:
00163                 new_elem.matrix_row_float = new viennacl::matrix<float, viennacl::row_major>((old_element.matrix_row_float)->size1(), (old_element.matrix_row_float)->size2());
00164                 return;
00165               case DOUBLE_TYPE:
00166                 new_elem.matrix_row_double = new viennacl::matrix<double, viennacl::row_major>((old_element.matrix_row_double)->size1(), (old_element.matrix_row_double)->size2());
00167                 return;
00168               default:
00169                 throw statement_not_supported_exception("Invalid vector type for vector construction");
00170             }
00171           }
00172           else
00173             throw statement_not_supported_exception("Expected a dense matrix in root node when creating a temporary");
00174         }
00175         else
00176           throw statement_not_supported_exception("Unknown type familty when creating new temporary object");
00177       }
00178 
00179       inline void delete_element(lhs_rhs_element & elem)
00180       {
00181         if (elem.type_family == SCALAR_TYPE_FAMILY)
00182         {
00183           switch (elem.numeric_type)
00184           {
00185             case FLOAT_TYPE:
00186               delete elem.scalar_float;
00187               return;
00188             case DOUBLE_TYPE:
00189               delete elem.scalar_double;
00190               return;
00191             default:
00192               throw statement_not_supported_exception("Invalid vector type for vector destruction");
00193           }
00194         }
00195         else if (elem.type_family == VECTOR_TYPE_FAMILY)
00196         {
00197           switch (elem.numeric_type)
00198           {
00199             case FLOAT_TYPE:
00200               delete elem.vector_float;
00201               return;
00202             case DOUBLE_TYPE:
00203               delete elem.vector_double;
00204               return;
00205             default:
00206               throw statement_not_supported_exception("Invalid vector type for vector destruction");
00207           }
00208         }
00209         else if (elem.type_family == MATRIX_TYPE_FAMILY)
00210         {
00211           if (elem.subtype == DENSE_COL_MATRIX_TYPE)
00212           {
00213             switch (elem.numeric_type)
00214             {
00215               case FLOAT_TYPE:
00216                 delete elem.matrix_col_float;
00217                 return;
00218               case DOUBLE_TYPE:
00219                 delete elem.matrix_col_double;
00220                 return;
00221               default:
00222                 throw statement_not_supported_exception("Invalid vector type for vector destruction");
00223             }
00224           }
00225           else if (elem.subtype == DENSE_ROW_MATRIX_TYPE)
00226           {
00227             switch (elem.numeric_type)
00228             {
00229               case FLOAT_TYPE:
00230                 delete elem.matrix_row_float;
00231                 return;
00232               case DOUBLE_TYPE:
00233                 delete elem.matrix_row_double;
00234                 return;
00235               default:
00236                 throw statement_not_supported_exception("Invalid vector type for vector destruction");
00237             }
00238           }
00239           else
00240             throw statement_not_supported_exception("Expected a dense matrix in root node when deleting temporary");
00241         }
00242         else
00243           throw statement_not_supported_exception("Unknown type familty when deleting temporary object");
00244       }
00245 
00246     } // namespace detail
00247 
00248 
00249   } // namespace scheduler
00250 } // namespace viennacl
00251 
00252 #endif
00253