ViennaCL - The Vienna Computing Library  1.5.2
viennacl/scheduler/forwards.h
Go to the documentation of this file.
00001 #ifndef VIENNACL_SCHEDULER_STATEMENT_HPP
00002 #define VIENNACL_SCHEDULER_STATEMENT_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 "viennacl/forwards.h"
00027 
00028 #include <vector>
00029 
00030 namespace viennacl
00031 {
00032   namespace scheduler
00033   {
00034 
00036     class statement_not_supported_exception : public std::exception
00037     {
00038     public:
00039       statement_not_supported_exception() : message_() {}
00040       statement_not_supported_exception(std::string message) : message_("ViennaCL: Internal error: The scheduler encountered a problem with the operation provided: " + message) {}
00041 
00042       virtual const char* what() const throw() { return message_.c_str(); }
00043 
00044       virtual ~statement_not_supported_exception() throw() {}
00045     private:
00046       std::string message_;
00047     };
00048 
00049 
00051     enum operation_node_type_family
00052     {
00053       OPERATION_INVALID_TYPE_FAMILY = 0,
00054 
00055       // unary or binary expression
00056       OPERATION_UNARY_TYPE_FAMILY,
00057       OPERATION_BINARY_TYPE_FAMILY
00058     };
00059 
00061     enum operation_node_type
00062     {
00063       OPERATION_INVALID_TYPE = 0,
00064 
00065       // unary expression
00066       OPERATION_UNARY_ABS_TYPE,
00067       OPERATION_UNARY_ACOS_TYPE,
00068       OPERATION_UNARY_ASIN_TYPE,
00069       OPERATION_UNARY_ATAN_TYPE,
00070       OPERATION_UNARY_CEIL_TYPE,
00071       OPERATION_UNARY_COS_TYPE,
00072       OPERATION_UNARY_COSH_TYPE,
00073       OPERATION_UNARY_EXP_TYPE,
00074       OPERATION_UNARY_FABS_TYPE,
00075       OPERATION_UNARY_FLOOR_TYPE,
00076       OPERATION_UNARY_LOG_TYPE,
00077       OPERATION_UNARY_LOG10_TYPE,
00078       OPERATION_UNARY_SIN_TYPE,
00079       OPERATION_UNARY_SINH_TYPE,
00080       OPERATION_UNARY_SQRT_TYPE,
00081       OPERATION_UNARY_TAN_TYPE,
00082       OPERATION_UNARY_TANH_TYPE,
00083       OPERATION_UNARY_TRANS_TYPE,
00084       OPERATION_UNARY_NORM_1_TYPE,
00085       OPERATION_UNARY_NORM_2_TYPE,
00086       OPERATION_UNARY_NORM_INF_TYPE,
00087 
00088       // binary expression
00089       OPERATION_BINARY_ACCESS_TYPE,
00090       OPERATION_BINARY_ASSIGN_TYPE,
00091       OPERATION_BINARY_INPLACE_ADD_TYPE,
00092       OPERATION_BINARY_INPLACE_SUB_TYPE,
00093       OPERATION_BINARY_ADD_TYPE,
00094       OPERATION_BINARY_SUB_TYPE,
00095       OPERATION_BINARY_MAT_VEC_PROD_TYPE,
00096       OPERATION_BINARY_MAT_MAT_PROD_TYPE,
00097       OPERATION_BINARY_MULT_TYPE,    // scalar times vector/matrix
00098       OPERATION_BINARY_DIV_TYPE,     // vector/matrix divided by scalar
00099       OPERATION_BINARY_ELEMENT_PROD_TYPE,
00100       OPERATION_BINARY_ELEMENT_DIV_TYPE,
00101       OPERATION_BINARY_INNER_PROD_TYPE
00102     };
00103 
00104 
00105 
00106     namespace result_of
00107     {
00109       template <typename T>
00110       struct op_type_info
00111       {
00112         typedef typename T::ERROR_UNKNOWN_OP_TYPE   error_type;
00113       };
00114 
00117       // unary operations
00118       template <> struct op_type_info<op_element_unary<op_abs>   > { enum { id = OPERATION_UNARY_ABS_TYPE,   family = OPERATION_UNARY_TYPE_FAMILY }; };
00119       template <> struct op_type_info<op_element_unary<op_acos>  > { enum { id = OPERATION_UNARY_ACOS_TYPE,  family = OPERATION_UNARY_TYPE_FAMILY }; };
00120       template <> struct op_type_info<op_element_unary<op_asin>  > { enum { id = OPERATION_UNARY_ASIN_TYPE,  family = OPERATION_UNARY_TYPE_FAMILY }; };
00121       template <> struct op_type_info<op_element_unary<op_atan>  > { enum { id = OPERATION_UNARY_ATAN_TYPE,  family = OPERATION_UNARY_TYPE_FAMILY }; };
00122       template <> struct op_type_info<op_element_unary<op_ceil>  > { enum { id = OPERATION_UNARY_CEIL_TYPE,  family = OPERATION_UNARY_TYPE_FAMILY }; };
00123       template <> struct op_type_info<op_element_unary<op_cos>   > { enum { id = OPERATION_UNARY_COS_TYPE,   family = OPERATION_UNARY_TYPE_FAMILY }; };
00124       template <> struct op_type_info<op_element_unary<op_cosh>  > { enum { id = OPERATION_UNARY_COSH_TYPE,  family = OPERATION_UNARY_TYPE_FAMILY }; };
00125       template <> struct op_type_info<op_element_unary<op_exp>   > { enum { id = OPERATION_UNARY_EXP_TYPE,   family = OPERATION_UNARY_TYPE_FAMILY }; };
00126       template <> struct op_type_info<op_element_unary<op_fabs>  > { enum { id = OPERATION_UNARY_FABS_TYPE,  family = OPERATION_UNARY_TYPE_FAMILY }; };
00127       template <> struct op_type_info<op_element_unary<op_floor> > { enum { id = OPERATION_UNARY_FLOOR_TYPE, family = OPERATION_UNARY_TYPE_FAMILY }; };
00128       template <> struct op_type_info<op_element_unary<op_log>   > { enum { id = OPERATION_UNARY_LOG_TYPE,   family = OPERATION_UNARY_TYPE_FAMILY }; };
00129       template <> struct op_type_info<op_element_unary<op_log10> > { enum { id = OPERATION_UNARY_LOG10_TYPE, family = OPERATION_UNARY_TYPE_FAMILY }; };
00130       template <> struct op_type_info<op_element_unary<op_sin>   > { enum { id = OPERATION_UNARY_SIN_TYPE,   family = OPERATION_UNARY_TYPE_FAMILY }; };
00131       template <> struct op_type_info<op_element_unary<op_sinh>  > { enum { id = OPERATION_UNARY_SINH_TYPE,  family = OPERATION_UNARY_TYPE_FAMILY }; };
00132       template <> struct op_type_info<op_element_unary<op_sqrt>  > { enum { id = OPERATION_UNARY_SQRT_TYPE,  family = OPERATION_UNARY_TYPE_FAMILY }; };
00133       template <> struct op_type_info<op_element_unary<op_tan>   > { enum { id = OPERATION_UNARY_TAN_TYPE,   family = OPERATION_UNARY_TYPE_FAMILY }; };
00134       template <> struct op_type_info<op_element_unary<op_tanh>  > { enum { id = OPERATION_UNARY_TANH_TYPE,  family = OPERATION_UNARY_TYPE_FAMILY }; };
00135       template <> struct op_type_info<op_norm_1                  > { enum { id = OPERATION_UNARY_NORM_1_TYPE,   family = OPERATION_UNARY_TYPE_FAMILY }; };
00136       template <> struct op_type_info<op_norm_2                  > { enum { id = OPERATION_UNARY_NORM_2_TYPE,   family = OPERATION_UNARY_TYPE_FAMILY }; };
00137       template <> struct op_type_info<op_norm_inf                > { enum { id = OPERATION_UNARY_NORM_INF_TYPE, family = OPERATION_UNARY_TYPE_FAMILY }; };
00138       template <> struct op_type_info<op_trans                   > { enum { id = OPERATION_UNARY_TRANS_TYPE, family = OPERATION_UNARY_TYPE_FAMILY }; };
00139 
00140       // binary operations
00141       template <> struct op_type_info<op_assign>                   { enum { id = OPERATION_BINARY_ASSIGN_TYPE,       family = OPERATION_BINARY_TYPE_FAMILY }; };
00142       template <> struct op_type_info<op_inplace_add>              { enum { id = OPERATION_BINARY_INPLACE_ADD_TYPE,  family = OPERATION_BINARY_TYPE_FAMILY }; };
00143       template <> struct op_type_info<op_inplace_sub>              { enum { id = OPERATION_BINARY_INPLACE_SUB_TYPE,  family = OPERATION_BINARY_TYPE_FAMILY }; };
00144       template <> struct op_type_info<op_add>                      { enum { id = OPERATION_BINARY_ADD_TYPE,          family = OPERATION_BINARY_TYPE_FAMILY }; };
00145       template <> struct op_type_info<op_sub>                      { enum { id = OPERATION_BINARY_SUB_TYPE,          family = OPERATION_BINARY_TYPE_FAMILY }; };
00146       template <> struct op_type_info<op_prod>                     { enum { id = OPERATION_BINARY_MAT_VEC_PROD_TYPE, family = OPERATION_BINARY_TYPE_FAMILY }; };
00147       template <> struct op_type_info<op_mat_mat_prod>             { enum { id = OPERATION_BINARY_MAT_MAT_PROD_TYPE, family = OPERATION_BINARY_TYPE_FAMILY }; };
00148       template <> struct op_type_info<op_mult>                     { enum { id = OPERATION_BINARY_MULT_TYPE,         family = OPERATION_BINARY_TYPE_FAMILY }; };
00149       template <> struct op_type_info<op_div>                      { enum { id = OPERATION_BINARY_DIV_TYPE,          family = OPERATION_BINARY_TYPE_FAMILY }; };
00150       template <> struct op_type_info<op_element_binary<op_prod> > { enum { id = OPERATION_BINARY_ELEMENT_PROD_TYPE, family = OPERATION_BINARY_TYPE_FAMILY }; };
00151       template <> struct op_type_info<op_element_binary<op_div>  > { enum { id = OPERATION_BINARY_ELEMENT_DIV_TYPE,  family = OPERATION_BINARY_TYPE_FAMILY }; };
00152       template <> struct op_type_info<op_inner_prod>               { enum { id = OPERATION_BINARY_INNER_PROD_TYPE,   family = OPERATION_BINARY_TYPE_FAMILY }; };
00153 
00155     } // namespace result_of
00156 
00157 
00158 
00159 
00160 
00162     enum statement_node_type_family
00163     {
00164       INVALID_TYPE_FAMILY = 0,
00165 
00166       // LHS or RHS are again an expression:
00167       COMPOSITE_OPERATION_FAMILY,
00168 
00169       // device scalars:
00170       SCALAR_TYPE_FAMILY,
00171 
00172       // vector:
00173       VECTOR_TYPE_FAMILY,
00174 
00175       // matrices:
00176       MATRIX_TYPE_FAMILY
00177     };
00178 
00180     enum statement_node_subtype
00181     {
00182       INVALID_SUBTYPE = 0, //when type is COMPOSITE_OPERATION_FAMILY
00183 
00184       HOST_SCALAR_TYPE,
00185       DEVICE_SCALAR_TYPE,
00186 
00187       DENSE_VECTOR_TYPE,
00188       IMPLICIT_VECTOR_TYPE,
00189 
00190       DENSE_ROW_MATRIX_TYPE,
00191       DENSE_COL_MATRIX_TYPE,
00192       IMPLICIT_MATRIX_TYPE,
00193 
00194       COMPRESSED_MATRIX_TYPE,
00195       COORDINATE_MATRIX_TYPE,
00196       ELL_MATRIX_TYPE,
00197       HYB_MATRIX_TYPE
00198 
00199       // other matrix types to be added here
00200     };
00201 
00203     enum statement_node_numeric_type
00204     {
00205       INVALID_NUMERIC_TYPE = 0, //when type is COMPOSITE_OPERATION_FAMILY
00206 
00207       CHAR_TYPE,
00208       UCHAR_TYPE,
00209       SHORT_TYPE,
00210       USHORT_TYPE,
00211       INT_TYPE,
00212       UINT_TYPE,
00213       LONG_TYPE,
00214       ULONG_TYPE,
00215       HALF_TYPE,
00216       FLOAT_TYPE,
00217       DOUBLE_TYPE
00218     };
00219 
00220 
00221     namespace result_of
00222     {
00224 
00226       template <typename T>
00227       struct numeric_type_id {};
00228 
00231       template <> struct numeric_type_id<char>           { enum { value = CHAR_TYPE   }; };
00232       template <> struct numeric_type_id<unsigned char>  { enum { value = UCHAR_TYPE  }; };
00233       template <> struct numeric_type_id<short>          { enum { value = SHORT_TYPE  }; };
00234       template <> struct numeric_type_id<unsigned short> { enum { value = USHORT_TYPE }; };
00235       template <> struct numeric_type_id<int>            { enum { value = INT_TYPE    }; };
00236       template <> struct numeric_type_id<unsigned int>   { enum { value = UINT_TYPE   }; };
00237       template <> struct numeric_type_id<long>           { enum { value = LONG_TYPE   }; };
00238       template <> struct numeric_type_id<unsigned long>  { enum { value = ULONG_TYPE  }; };
00239       template <> struct numeric_type_id<float>          { enum { value = FLOAT_TYPE  }; };
00240       template <> struct numeric_type_id<double>         { enum { value = DOUBLE_TYPE }; };
00241 
00244 
00245 
00247       template <typename F>
00248       struct layout_type_id {};
00249 
00252       template <> struct layout_type_id<viennacl::column_major> { enum { value = DENSE_COL_MATRIX_TYPE }; };
00253       template <> struct layout_type_id<viennacl::row_major   > { enum { value = DENSE_ROW_MATRIX_TYPE }; };
00254 
00256     }
00257 
00258 
00259 
00267     struct lhs_rhs_element
00268     {
00269       statement_node_type_family   type_family;
00270       statement_node_subtype       subtype;
00271       statement_node_numeric_type  numeric_type;
00272 
00273       union
00274       {
00276         vcl_size_t        node_index;
00277 
00279 
00280         // host scalars:
00281         char               host_char;
00282         unsigned char      host_uchar;
00283         short              host_short;
00284         unsigned short     host_ushort;
00285         int                host_int;
00286         unsigned int       host_uint;
00287         long               host_long;
00288         unsigned long      host_ulong;
00289         float              host_float;
00290         double             host_double;
00291 
00292         // Note: ViennaCL types have potentially expensive copy-CTORs, hence using pointers:
00293 
00294         // scalars:
00295         //viennacl::scalar<char>             *scalar_char;
00296         //viennacl::scalar<unsigned char>    *scalar_uchar;
00297         //viennacl::scalar<short>            *scalar_short;
00298         //viennacl::scalar<unsigned short>   *scalar_ushort;
00299         //viennacl::scalar<int>              *scalar_int;
00300         //viennacl::scalar<unsigned int>     *scalar_uint;
00301         //viennacl::scalar<long>             *scalar_long;
00302         //viennacl::scalar<unsigned long>    *scalar_ulong;
00303         viennacl::scalar<float>            *scalar_float;
00304         viennacl::scalar<double>           *scalar_double;
00305 
00306         // vectors:
00307         //viennacl::vector_base<char>             *vector_char;
00308         //viennacl::vector_base<unsigned char>    *vector_uchar;
00309         //viennacl::vector_base<short>            *vector_short;
00310         //viennacl::vector_base<unsigned short>   *vector_ushort;
00311         //viennacl::vector_base<int>              *vector_int;
00312         //viennacl::vector_base<unsigned int>     *vector_uint;
00313         //viennacl::vector_base<long>             *vector_long;
00314         //viennacl::vector_base<unsigned long>    *vector_ulong;
00315         viennacl::vector_base<float>            *vector_float;
00316         viennacl::vector_base<double>           *vector_double;
00317 
00318         // implicit vectors:
00319         //viennacl::implicit_vector_base<char>             *implicit_vector_char;
00320         //viennacl::implicit_vector_base<unsigned char>    *implicit_vector_uchar;
00321         //viennacl::implicit_vector_base<short>            *implicit_vector_short;
00322         //viennacl::implicit_vector_base<unsigned short>   *implicit_vector_ushort;
00323         //viennacl::implicit_vector_base<int>              *implicit_vector_int;
00324         //viennacl::implicit_vector_base<unsigned int>     *implicit_vector_uint;
00325         //viennacl::implicit_vector_base<long>             *implicit_vector_long;
00326         //viennacl::implicit_vector_base<unsigned long>    *implicit_vector_ulong;
00327         viennacl::implicit_vector_base<float>            *implicit_vector_float;
00328         viennacl::implicit_vector_base<double>           *implicit_vector_double;
00329 
00330         // row-major matrices:
00331         //viennacl::matrix_base<char>             *matrix_row_char;
00332         //viennacl::matrix_base<unsigned char>    *matrix_row_uchar;
00333         //viennacl::matrix_base<short>            *matrix_row_short;
00334         //viennacl::matrix_base<unsigned short>   *matrix_row_ushort;
00335         //viennacl::matrix_base<int>              *matrix_row_int;
00336         //viennacl::matrix_base<unsigned int>     *matrix_row_uint;
00337         //viennacl::matrix_base<long>             *matrix_row_long;
00338         //viennacl::matrix_base<unsigned long>    *matrix_row_ulong;
00339         viennacl::matrix_base<float>            *matrix_row_float;
00340         viennacl::matrix_base<double>           *matrix_row_double;
00341 
00342         // column-major matrices:
00343         //viennacl::matrix_base<char,           viennacl::column_major>    *matrix_col_char;
00344         //viennacl::matrix_base<unsigned char,  viennacl::column_major>    *matrix_col_uchar;
00345         //viennacl::matrix_base<short,          viennacl::column_major>    *matrix_col_short;
00346         //viennacl::matrix_base<unsigned short, viennacl::column_major>    *matrix_col_ushort;
00347         //viennacl::matrix_base<int,            viennacl::column_major>    *matrix_col_int;
00348         //viennacl::matrix_base<unsigned int,   viennacl::column_major>    *matrix_col_uint;
00349         //viennacl::matrix_base<long,           viennacl::column_major>    *matrix_col_long;
00350         //viennacl::matrix_base<unsigned long,  viennacl::column_major>    *matrix_col_ulong;
00351         viennacl::matrix_base<float,          viennacl::column_major>    *matrix_col_float;
00352         viennacl::matrix_base<double,         viennacl::column_major>    *matrix_col_double;
00353 
00354         //viennacl::implicit_matrix_base<char>             *implicit_matrix_char;
00355         //viennacl::implicit_matrix_base<unsigned char>    *implicit_matrix_uchar;
00356         //viennacl::implicit_matrix_base<short>            *implicit_matrix_short;
00357         //viennacl::implicit_matrix_base<unsigned short>   *implicit_matrix_ushort;
00358         //viennacl::implicit_matrix_base<int>              *implicit_matrix_int;
00359         //viennacl::implicit_matrix_base<unsigned int>     *implicit_matrix_uint;
00360         //viennacl::implicit_matrix_base<long>             *implicit_matrix_long;
00361         //viennacl::implicit_matrix_base<unsigned long>    *implicit_matrix_ulong;
00362         viennacl::implicit_matrix_base<float>            *implicit_matrix_float;
00363         viennacl::implicit_matrix_base<double>           *implicit_matrix_double;
00364 
00365         //viennacl::compressed_matrix<float>    *compressed_matrix_char;
00366         //viennacl::compressed_matrix<double>   *compressed_matrix_uchar;
00367         //viennacl::compressed_matrix<float>    *compressed_matrix_short;
00368         //viennacl::compressed_matrix<double>   *compressed_matrix_ushort;
00369         //viennacl::compressed_matrix<float>    *compressed_matrix_int;
00370         //viennacl::compressed_matrix<double>   *compressed_matrix_uint;
00371         //viennacl::compressed_matrix<float>    *compressed_matrix_long;
00372         //viennacl::compressed_matrix<double>   *compressed_matrix_ulong;
00373         viennacl::compressed_matrix<float>    *compressed_matrix_float;
00374         viennacl::compressed_matrix<double>   *compressed_matrix_double;
00375 
00376         //viennacl::coordinate_matrix<float>    *coordinate_matrix_char;
00377         //viennacl::coordinate_matrix<double>   *coordinate_matrix_uchar;
00378         //viennacl::coordinate_matrix<float>    *coordinate_matrix_short;
00379         //viennacl::coordinate_matrix<double>   *coordinate_matrix_ushort;
00380         //viennacl::coordinate_matrix<float>    *coordinate_matrix_int;
00381         //viennacl::coordinate_matrix<double>   *coordinate_matrix_uint;
00382         //viennacl::coordinate_matrix<float>    *coordinate_matrix_long;
00383         //viennacl::coordinate_matrix<double>   *coordinate_matrix_ulong;
00384         viennacl::coordinate_matrix<float>    *coordinate_matrix_float;
00385         viennacl::coordinate_matrix<double>   *coordinate_matrix_double;
00386 
00387         //viennacl::ell_matrix<float>    *ell_matrix_char;
00388         //viennacl::ell_matrix<double>   *ell_matrix_uchar;
00389         //viennacl::ell_matrix<float>    *ell_matrix_short;
00390         //viennacl::ell_matrix<double>   *ell_matrix_ushort;
00391         //viennacl::ell_matrix<float>    *ell_matrix_int;
00392         //viennacl::ell_matrix<double>   *ell_matrix_uint;
00393         //viennacl::ell_matrix<float>    *ell_matrix_long;
00394         //viennacl::ell_matrix<double>   *ell_matrix_ulong;
00395         viennacl::ell_matrix<float>    *ell_matrix_float;
00396         viennacl::ell_matrix<double>   *ell_matrix_double;
00397 
00398         //viennacl::hyb_matrix<float>    *hyb_matrix_char;
00399         //viennacl::hyb_matrix<double>   *hyb_matrix_uchar;
00400         //viennacl::hyb_matrix<float>    *hyb_matrix_short;
00401         //viennacl::hyb_matrix<double>   *hyb_matrix_ushort;
00402         //viennacl::hyb_matrix<float>    *hyb_matrix_int;
00403         //viennacl::hyb_matrix<double>   *hyb_matrix_uint;
00404         //viennacl::hyb_matrix<float>    *hyb_matrix_long;
00405         //viennacl::hyb_matrix<double>   *hyb_matrix_ulong;
00406         viennacl::hyb_matrix<float>    *hyb_matrix_float;
00407         viennacl::hyb_matrix<double>   *hyb_matrix_double;
00408       };
00409     };
00410 
00411 
00413     struct op_element
00414     {
00415       operation_node_type_family   type_family;
00416       operation_node_type          type;
00417     };
00418 
00420     struct statement_node
00421     {
00422       lhs_rhs_element    lhs;
00423       op_element         op;
00424       lhs_rhs_element    rhs;
00425     };
00426 
00427     namespace result_of
00428     {
00429 
00431       template <class T> struct num_nodes { enum { value = 0 }; };
00433       template <class LHS, class OP, class RHS> struct num_nodes<       vector_expression<LHS, RHS, OP> > { enum { value = 1 + num_nodes<LHS>::value + num_nodes<RHS>::value }; };
00434       template <class LHS, class OP, class RHS> struct num_nodes< const vector_expression<LHS, RHS, OP> > { enum { value = 1 + num_nodes<LHS>::value + num_nodes<RHS>::value }; };
00435       template <class LHS, class OP, class RHS> struct num_nodes<       matrix_expression<LHS, RHS, OP> > { enum { value = 1 + num_nodes<LHS>::value + num_nodes<RHS>::value }; };
00436       template <class LHS, class OP, class RHS> struct num_nodes< const matrix_expression<LHS, RHS, OP> > { enum { value = 1 + num_nodes<LHS>::value + num_nodes<RHS>::value }; };
00437       template <class LHS, class OP, class RHS> struct num_nodes<       scalar_expression<LHS, RHS, OP> > { enum { value = 1 + num_nodes<LHS>::value + num_nodes<RHS>::value }; };
00438       template <class LHS, class OP, class RHS> struct num_nodes< const scalar_expression<LHS, RHS, OP> > { enum { value = 1 + num_nodes<LHS>::value + num_nodes<RHS>::value }; };
00441     }
00442 
00447     class statement
00448     {
00449       public:
00450         typedef statement_node              value_type;
00451         typedef viennacl::vcl_size_t        size_type;
00452         typedef std::vector<value_type>     container_type;
00453 
00454         statement(container_type const & custom_array) : array_(custom_array) {}
00455 
00459         template <typename LHS, typename OP, typename RHS>
00460         statement(LHS & lhs, OP const &, RHS const & rhs) : array_(1 + result_of::num_nodes<RHS>::value)
00461         {
00462           // set OP:
00463           array_[0].op.type_family = operation_node_type_family(result_of::op_type_info<OP>::family);
00464           array_[0].op.type        = operation_node_type(result_of::op_type_info<OP>::id);
00465 
00466           // set LHS:
00467           add_lhs(0, 1, lhs);
00468 
00469           // set RHS:
00470           add_rhs(0, 1, rhs);
00471         }
00472 
00473         container_type const & array() const { return array_; }
00474 
00475         size_type root() const { return 0; }
00476 
00477       private:
00478 
00480 
00481         // TODO: add integer vector overloads here
00482         void assign_element(lhs_rhs_element & elem, viennacl::scalar<float>  const & t) { elem.scalar_float  = const_cast<viennacl::scalar<float> *>(&t); }
00483         void assign_element(lhs_rhs_element & elem, viennacl::scalar<double> const & t) { elem.scalar_double = const_cast<viennacl::scalar<double> *>(&t); }
00484 
00486         // TODO: add integer vector overloads here
00487         void assign_element(lhs_rhs_element & elem, viennacl::vector_base<float>  const & t) { elem.vector_float  = const_cast<viennacl::vector_base<float> *>(&t); }
00488         void assign_element(lhs_rhs_element & elem, viennacl::vector_base<double> const & t) { elem.vector_double = const_cast<viennacl::vector_base<double> *>(&t); }
00489 
00491         // TODO: add integer matrix overloads here
00492         void assign_element(lhs_rhs_element & elem, viennacl::matrix_base<float,  viennacl::column_major> const & t) { elem.matrix_col_float  = const_cast<viennacl::matrix_base<float,  viennacl::column_major> *>(&t); }
00493         void assign_element(lhs_rhs_element & elem, viennacl::matrix_base<float,  viennacl::row_major>    const & t) { elem.matrix_row_float  = const_cast<viennacl::matrix_base<float,  viennacl::row_major>    *>(&t); }
00494         void assign_element(lhs_rhs_element & elem, viennacl::matrix_base<double, viennacl::column_major> const & t) { elem.matrix_col_double = const_cast<viennacl::matrix_base<double, viennacl::column_major> *>(&t); }
00495         void assign_element(lhs_rhs_element & elem, viennacl::matrix_base<double, viennacl::row_major>    const & t) { elem.matrix_row_double = const_cast<viennacl::matrix_base<double, viennacl::row_major>    *>(&t); }
00496 
00497         void assign_element(lhs_rhs_element & elem, viennacl::compressed_matrix<float>  const & m) { elem.compressed_matrix_float  = const_cast<viennacl::compressed_matrix<float>  *>(&m); }
00498         void assign_element(lhs_rhs_element & elem, viennacl::compressed_matrix<double> const & m) { elem.compressed_matrix_double = const_cast<viennacl::compressed_matrix<double> *>(&m); }
00499 
00500         void assign_element(lhs_rhs_element & elem, viennacl::coordinate_matrix<float>  const & m) { elem.coordinate_matrix_float  = const_cast<viennacl::coordinate_matrix<float>  *>(&m); }
00501         void assign_element(lhs_rhs_element & elem, viennacl::coordinate_matrix<double> const & m) { elem.coordinate_matrix_double = const_cast<viennacl::coordinate_matrix<double> *>(&m); }
00502 
00503         void assign_element(lhs_rhs_element & elem, viennacl::ell_matrix<float>  const & m) { elem.ell_matrix_float  = const_cast<viennacl::ell_matrix<float>  *>(&m); }
00504         void assign_element(lhs_rhs_element & elem, viennacl::ell_matrix<double> const & m) { elem.ell_matrix_double = const_cast<viennacl::ell_matrix<double> *>(&m); }
00505 
00506         void assign_element(lhs_rhs_element & elem, viennacl::hyb_matrix<float>  const & m) { elem.hyb_matrix_float  = const_cast<viennacl::hyb_matrix<float>  *>(&m); }
00507         void assign_element(lhs_rhs_element & elem, viennacl::hyb_matrix<double> const & m) { elem.hyb_matrix_double = const_cast<viennacl::hyb_matrix<double> *>(&m); }
00508 
00510 
00511         vcl_size_t add_element(vcl_size_t       next_free,
00512                                 lhs_rhs_element & elem,
00513                                 float const &     t)
00514         {
00515           elem.type_family  = SCALAR_TYPE_FAMILY;
00516           elem.subtype      = HOST_SCALAR_TYPE;
00517           elem.numeric_type = FLOAT_TYPE;
00518           elem.host_float   = t;
00519           return next_free;
00520         }
00521 
00522         vcl_size_t add_element(vcl_size_t       next_free,
00523                                 lhs_rhs_element & elem,
00524                                 double const &    t)
00525         {
00526           elem.type_family  = SCALAR_TYPE_FAMILY;
00527           elem.subtype      = HOST_SCALAR_TYPE;
00528           elem.numeric_type = DOUBLE_TYPE;
00529           elem.host_double  = t;
00530           return next_free;
00531         }
00532 
00533         template <typename T>
00534         vcl_size_t add_element(vcl_size_t next_free,
00535                                 lhs_rhs_element            & elem,
00536                                 viennacl::scalar<T> const & t)
00537         {
00538           elem.type_family  = SCALAR_TYPE_FAMILY;
00539           elem.subtype      = DEVICE_SCALAR_TYPE;
00540           elem.numeric_type = statement_node_numeric_type(result_of::numeric_type_id<T>::value);
00541           assign_element(elem, t);
00542           return next_free;
00543         }
00544 
00545 
00546         template <typename T>
00547         vcl_size_t add_element(vcl_size_t next_free,
00548                                 lhs_rhs_element            & elem,
00549                                 viennacl::vector_base<T> const & t)
00550         {
00551           elem.type_family           = VECTOR_TYPE_FAMILY;
00552           elem.subtype               = DENSE_VECTOR_TYPE;
00553           elem.numeric_type          = statement_node_numeric_type(result_of::numeric_type_id<T>::value);
00554           assign_element(elem, t);
00555           return next_free;
00556         }
00557 
00558         template <typename T, typename F>
00559         vcl_size_t add_element(vcl_size_t next_free,
00560                                 lhs_rhs_element            & elem,
00561                                 viennacl::matrix_base<T, F> const & t)
00562         {
00563           elem.type_family  = MATRIX_TYPE_FAMILY;
00564           elem.subtype      = statement_node_subtype(result_of::layout_type_id<F>::value);
00565           elem.numeric_type = statement_node_numeric_type(result_of::numeric_type_id<T>::value);
00566           assign_element(elem, t);
00567           return next_free;
00568         }
00569 
00570         template <typename T>
00571         vcl_size_t add_element(vcl_size_t next_free,
00572                                 lhs_rhs_element            & elem,
00573                                 viennacl::compressed_matrix<T> const & t)
00574         {
00575           elem.type_family  = MATRIX_TYPE_FAMILY;
00576           elem.subtype      = COMPRESSED_MATRIX_TYPE;
00577           elem.numeric_type = statement_node_numeric_type(result_of::numeric_type_id<T>::value);
00578           assign_element(elem, t);
00579           return next_free;
00580         }
00581 
00582         template <typename T>
00583         vcl_size_t add_element(vcl_size_t next_free,
00584                                 lhs_rhs_element            & elem,
00585                                 viennacl::coordinate_matrix<T> const & t)
00586         {
00587           elem.type_family  = MATRIX_TYPE_FAMILY;
00588           elem.subtype      = COORDINATE_MATRIX_TYPE;
00589           elem.numeric_type = statement_node_numeric_type(result_of::numeric_type_id<T>::value);
00590           assign_element(elem, t);
00591           return next_free;
00592         }
00593 
00594         template <typename T>
00595         vcl_size_t add_element(vcl_size_t next_free,
00596                                 lhs_rhs_element            & elem,
00597                                 viennacl::ell_matrix<T> const & t)
00598         {
00599           elem.type_family  = MATRIX_TYPE_FAMILY;
00600           elem.subtype      = ELL_MATRIX_TYPE;
00601           elem.numeric_type = statement_node_numeric_type(result_of::numeric_type_id<T>::value);
00602           assign_element(elem, t);
00603           return next_free;
00604         }
00605 
00606         template <typename T>
00607         vcl_size_t add_element(vcl_size_t next_free,
00608                                 lhs_rhs_element            & elem,
00609                                 viennacl::hyb_matrix<T> const & t)
00610         {
00611           elem.type_family  = MATRIX_TYPE_FAMILY;
00612           elem.subtype      = HYB_MATRIX_TYPE;
00613           elem.numeric_type = statement_node_numeric_type(result_of::numeric_type_id<T>::value);
00614           assign_element(elem, t);
00615           return next_free;
00616         }
00617 
00618 
00620 
00621         template <typename LHS, typename RHS, typename OP>
00622         vcl_size_t add_element(vcl_size_t       next_free,
00623                                 lhs_rhs_element & elem,
00624                                 viennacl::scalar_expression<LHS, RHS, OP> const & t)
00625         {
00626           elem.type_family  = COMPOSITE_OPERATION_FAMILY;
00627           elem.subtype      = INVALID_SUBTYPE;
00628           elem.numeric_type = INVALID_NUMERIC_TYPE;
00629           elem.node_index   = next_free;
00630           return add_node(next_free, next_free + 1, t);
00631         }
00632 
00633         template <typename LHS, typename RHS, typename OP>
00634         vcl_size_t add_element(vcl_size_t       next_free,
00635                                 lhs_rhs_element & elem,
00636                                 viennacl::vector_expression<LHS, RHS, OP> const & t)
00637         {
00638           elem.type_family  = COMPOSITE_OPERATION_FAMILY;
00639           elem.subtype      = INVALID_SUBTYPE;
00640           elem.numeric_type = INVALID_NUMERIC_TYPE;
00641           elem.node_index   = next_free;
00642           return add_node(next_free, next_free + 1, t);
00643         }
00644 
00645         template <typename LHS, typename RHS, typename OP>
00646         vcl_size_t add_element(vcl_size_t next_free,
00647                                 lhs_rhs_element & elem,
00648                                 viennacl::matrix_expression<LHS, RHS, OP> const & t)
00649         {
00650           elem.type_family   = COMPOSITE_OPERATION_FAMILY;
00651           elem.subtype      = INVALID_SUBTYPE;
00652           elem.numeric_type = INVALID_NUMERIC_TYPE;
00653           elem.node_index    = next_free;
00654           return add_node(next_free, next_free + 1, t);
00655         }
00656 
00657 
00659 
00660 
00661         template <typename T>
00662         vcl_size_t add_lhs(vcl_size_t current_index, vcl_size_t next_free, T const & t)
00663         {
00664           return add_element(next_free, array_[current_index].lhs, t);
00665         }
00666 
00667         template <typename T>
00668         vcl_size_t add_rhs(vcl_size_t current_index, vcl_size_t next_free, T const & t)
00669         {
00670           return add_element(next_free, array_[current_index].rhs, t);
00671         }
00672 
00674 
00675         template <template <typename, typename, typename> class ExpressionT, typename LHS, typename RHS, typename OP>
00676         vcl_size_t add_node(vcl_size_t current_index, vcl_size_t next_free, ExpressionT<LHS, RHS, OP> const & proxy)
00677         {
00678           // set OP:
00679           array_[current_index].op.type_family = operation_node_type_family(result_of::op_type_info<OP>::family);
00680           array_[current_index].op.type        = operation_node_type(result_of::op_type_info<OP>::id);
00681 
00682           // set LHS and RHS:
00683           if (array_[current_index].op.type_family == OPERATION_UNARY_TYPE_FAMILY)
00684           {
00685             // unary expression: set rhs to invalid:
00686             array_[current_index].rhs.type_family  = INVALID_TYPE_FAMILY;
00687             array_[current_index].rhs.subtype      = INVALID_SUBTYPE;
00688             array_[current_index].rhs.numeric_type = INVALID_NUMERIC_TYPE;
00689             return add_lhs(current_index, next_free, proxy.lhs());
00690           }
00691 
00692           return add_rhs(current_index, add_lhs(current_index, next_free, proxy.lhs()), proxy.rhs());
00693 
00694         }
00695 
00696         container_type   array_;
00697     };
00698 
00699     namespace detail
00700     {
00702       inline void execute_composite(statement const & /* s */, statement_node const & /* root_node */);
00703     }
00704 
00705   } // namespace scheduler
00706 
00707 } // namespace viennacl
00708 
00709 #endif
00710