ViennaCL - The Vienna Computing Library
1.5.1
|
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