ViennaCL - The Vienna Computing Library
1.5.2
|
00001 #ifndef VIENNACL_SCHEDULER_EXECUTE_ELEMENTWISE_HPP 00002 #define VIENNACL_SCHEDULER_EXECUTE_ELEMENTWISE_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 #include "viennacl/scheduler/forwards.h" 00028 #include "viennacl/scheduler/execute_util.hpp" 00029 #include "viennacl/linalg/vector_operations.hpp" 00030 #include "viennacl/linalg/matrix_operations.hpp" 00031 00032 namespace viennacl 00033 { 00034 namespace scheduler 00035 { 00036 namespace detail 00037 { 00038 // result = element_op(x,y) for vectors or matrices x, y 00039 inline void element_op(lhs_rhs_element result, 00040 lhs_rhs_element const & x, 00041 operation_node_type op_type) 00042 { 00043 assert( result.numeric_type == x.numeric_type && bool("Numeric type not the same!")); 00044 assert( result.type_family == x.type_family && bool("Subtype not the same!")); 00045 00046 if (x.subtype == DENSE_VECTOR_TYPE) 00047 { 00048 assert( result.subtype == x.subtype && bool("result not of vector type for unary elementwise operation")); 00049 if (x.numeric_type == FLOAT_TYPE) 00050 { 00051 switch (op_type) 00052 { 00053 #define VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPNAME, SCALARTYPE, OPTAG) \ 00054 case OPNAME: viennacl::linalg::element_op(*result.vector_##SCALARTYPE, \ 00055 viennacl::vector_expression<const vector_base<SCALARTYPE>, const vector_base<SCALARTYPE>, \ 00056 op_element_unary<OPTAG> >(*x.vector_##SCALARTYPE, *x.vector_##SCALARTYPE)); break; 00057 00058 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ABS_TYPE, float, op_abs) 00059 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ACOS_TYPE, float, op_acos) 00060 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ASIN_TYPE, float, op_asin) 00061 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ATAN_TYPE, float, op_atan) 00062 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_CEIL_TYPE, float, op_ceil) 00063 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COS_TYPE, float, op_cos) 00064 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COSH_TYPE, float, op_cosh) 00065 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_EXP_TYPE, float, op_exp) 00066 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FABS_TYPE, float, op_fabs) 00067 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FLOOR_TYPE, float, op_floor) 00068 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG_TYPE, float, op_log) 00069 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG10_TYPE, float, op_log10) 00070 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SIN_TYPE, float, op_sin) 00071 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SINH_TYPE, float, op_sinh) 00072 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SQRT_TYPE, float, op_sqrt) 00073 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TAN_TYPE, float, op_tan) 00074 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TANH_TYPE, float, op_tanh) 00075 default: 00076 throw statement_not_supported_exception("Invalid op_type in unary elementwise operations"); 00077 } 00078 } 00079 else if (x.numeric_type == DOUBLE_TYPE) 00080 { 00081 switch (op_type) 00082 { 00083 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ABS_TYPE, double, op_abs) 00084 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ACOS_TYPE, double, op_acos) 00085 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ASIN_TYPE, double, op_asin) 00086 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ATAN_TYPE, double, op_atan) 00087 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_CEIL_TYPE, double, op_ceil) 00088 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COS_TYPE, double, op_cos) 00089 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COSH_TYPE, double, op_cosh) 00090 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_EXP_TYPE, double, op_exp) 00091 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FABS_TYPE, double, op_fabs) 00092 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FLOOR_TYPE, double, op_floor) 00093 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG_TYPE, double, op_log) 00094 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG10_TYPE, double, op_log10) 00095 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SIN_TYPE, double, op_sin) 00096 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SINH_TYPE, double, op_sinh) 00097 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SQRT_TYPE, double, op_sqrt) 00098 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TAN_TYPE, double, op_tan) 00099 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TANH_TYPE, double, op_tanh) 00100 00101 #undef VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP 00102 default: 00103 throw statement_not_supported_exception("Invalid op_type in unary elementwise operations"); 00104 } 00105 } 00106 else 00107 throw statement_not_supported_exception("Invalid numeric type in unary elementwise operator"); 00108 } 00109 else if (x.subtype == DENSE_ROW_MATRIX_TYPE) 00110 { 00111 if (x.numeric_type == FLOAT_TYPE) 00112 { 00113 switch (op_type) 00114 { 00115 #define VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPNAME, SCALARTYPE, OPTAG) \ 00116 case OPNAME: viennacl::linalg::element_op(*result.matrix_row_##SCALARTYPE, \ 00117 viennacl::matrix_expression<const matrix_base<SCALARTYPE, viennacl::row_major>, const matrix_base<SCALARTYPE, viennacl::row_major>, \ 00118 op_element_unary<OPTAG> >(*x.matrix_row_##SCALARTYPE, *x.matrix_row_##SCALARTYPE)); break; 00119 00120 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ABS_TYPE, float, op_abs) 00121 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ACOS_TYPE, float, op_acos) 00122 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ASIN_TYPE, float, op_asin) 00123 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ATAN_TYPE, float, op_atan) 00124 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_CEIL_TYPE, float, op_ceil) 00125 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COS_TYPE, float, op_cos) 00126 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COSH_TYPE, float, op_cosh) 00127 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_EXP_TYPE, float, op_exp) 00128 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FABS_TYPE, float, op_fabs) 00129 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FLOOR_TYPE, float, op_floor) 00130 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG_TYPE, float, op_log) 00131 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG10_TYPE, float, op_log10) 00132 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SIN_TYPE, float, op_sin) 00133 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SINH_TYPE, float, op_sinh) 00134 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SQRT_TYPE, float, op_sqrt) 00135 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TAN_TYPE, float, op_tan) 00136 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TANH_TYPE, float, op_tanh) 00137 default: 00138 throw statement_not_supported_exception("Invalid op_type in unary elementwise operations"); 00139 } 00140 00141 } 00142 else if (x.numeric_type == DOUBLE_TYPE) 00143 { 00144 switch (op_type) 00145 { 00146 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ABS_TYPE, double, op_abs) 00147 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ACOS_TYPE, double, op_acos) 00148 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ASIN_TYPE, double, op_asin) 00149 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ATAN_TYPE, double, op_atan) 00150 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_CEIL_TYPE, double, op_ceil) 00151 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COS_TYPE, double, op_cos) 00152 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COSH_TYPE, double, op_cosh) 00153 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_EXP_TYPE, double, op_exp) 00154 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FABS_TYPE, double, op_fabs) 00155 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FLOOR_TYPE, double, op_floor) 00156 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG_TYPE, double, op_log) 00157 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG10_TYPE, double, op_log10) 00158 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SIN_TYPE, double, op_sin) 00159 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SINH_TYPE, double, op_sinh) 00160 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SQRT_TYPE, double, op_sqrt) 00161 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TAN_TYPE, double, op_tan) 00162 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TANH_TYPE, double, op_tanh) 00163 default: 00164 throw statement_not_supported_exception("Invalid op_type in unary elementwise operations"); 00165 } 00166 } 00167 else 00168 throw statement_not_supported_exception("Invalid numeric type in unary elementwise operator"); 00169 00170 #undef VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP 00171 00172 } 00173 else if (x.subtype == DENSE_COL_MATRIX_TYPE) 00174 { 00175 if (x.numeric_type == FLOAT_TYPE) 00176 { 00177 switch (op_type) 00178 { 00179 #define VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPNAME, SCALARTYPE, OPTAG) \ 00180 case OPNAME: viennacl::linalg::element_op(*result.matrix_col_##SCALARTYPE, \ 00181 viennacl::matrix_expression<const matrix_base<SCALARTYPE, viennacl::column_major>, const matrix_base<SCALARTYPE, viennacl::column_major>, \ 00182 op_element_unary<OPTAG> >(*x.matrix_col_##SCALARTYPE, *x.matrix_col_##SCALARTYPE)); break; 00183 00184 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ABS_TYPE, float, op_abs) 00185 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ACOS_TYPE, float, op_acos) 00186 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ASIN_TYPE, float, op_asin) 00187 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ATAN_TYPE, float, op_atan) 00188 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_CEIL_TYPE, float, op_ceil) 00189 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COS_TYPE, float, op_cos) 00190 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COSH_TYPE, float, op_cosh) 00191 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_EXP_TYPE, float, op_exp) 00192 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FABS_TYPE, float, op_fabs) 00193 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FLOOR_TYPE, float, op_floor) 00194 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG_TYPE, float, op_log) 00195 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG10_TYPE, float, op_log10) 00196 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SIN_TYPE, float, op_sin) 00197 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SINH_TYPE, float, op_sinh) 00198 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SQRT_TYPE, float, op_sqrt) 00199 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TAN_TYPE, float, op_tan) 00200 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TANH_TYPE, float, op_tanh) 00201 default: 00202 throw statement_not_supported_exception("Invalid op_type in unary elementwise operations"); 00203 } 00204 00205 } 00206 else if (x.numeric_type == DOUBLE_TYPE) 00207 { 00208 switch (op_type) 00209 { 00210 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ABS_TYPE, double, op_abs) 00211 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ACOS_TYPE, double, op_acos) 00212 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ASIN_TYPE, double, op_asin) 00213 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_ATAN_TYPE, double, op_atan) 00214 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_CEIL_TYPE, double, op_ceil) 00215 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COS_TYPE, double, op_cos) 00216 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_COSH_TYPE, double, op_cosh) 00217 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_EXP_TYPE, double, op_exp) 00218 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FABS_TYPE, double, op_fabs) 00219 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_FLOOR_TYPE, double, op_floor) 00220 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG_TYPE, double, op_log) 00221 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_LOG10_TYPE, double, op_log10) 00222 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SIN_TYPE, double, op_sin) 00223 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SINH_TYPE, double, op_sinh) 00224 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_SQRT_TYPE, double, op_sqrt) 00225 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TAN_TYPE, double, op_tan) 00226 VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP(OPERATION_UNARY_TANH_TYPE, double, op_tanh) 00227 default: 00228 throw statement_not_supported_exception("Invalid op_type in unary elementwise operations"); 00229 } 00230 } 00231 else 00232 throw statement_not_supported_exception("Invalid numeric type in unary elementwise operator"); 00233 00234 #undef VIENNACL_SCHEDULER_GENERATE_UNARY_ELEMENT_OP 00235 } 00236 } 00237 00238 // result = element_op(x,y) for vectors or matrices x, y 00239 inline void element_op(lhs_rhs_element result, 00240 lhs_rhs_element const & x, 00241 lhs_rhs_element const & y, 00242 operation_node_type op_type) 00243 { 00244 assert( x.numeric_type == y.numeric_type && bool("Numeric type not the same!")); 00245 assert( result.numeric_type == y.numeric_type && bool("Numeric type not the same!")); 00246 00247 assert( x.type_family == y.type_family && bool("Subtype not the same!")); 00248 assert( result.type_family == y.type_family && bool("Subtype not the same!")); 00249 00250 switch (op_type) 00251 { 00252 00253 case OPERATION_BINARY_ELEMENT_DIV_TYPE: 00254 if (x.subtype == DENSE_VECTOR_TYPE) 00255 { 00256 switch (x.numeric_type) 00257 { 00258 case FLOAT_TYPE: 00259 viennacl::linalg::element_op(*result.vector_float, 00260 vector_expression<const vector_base<float>, 00261 const vector_base<float>, 00262 op_element_binary<op_div> >(*x.vector_float, *y.vector_float)); 00263 break; 00264 case DOUBLE_TYPE: 00265 viennacl::linalg::element_op(*result.vector_double, 00266 vector_expression<const vector_base<double>, 00267 const vector_base<double>, 00268 op_element_binary<op_div> >(*x.vector_double, *y.vector_double)); 00269 break; 00270 default: 00271 throw statement_not_supported_exception("Invalid numeric type for binary elementwise division"); 00272 } 00273 } 00274 else if (x.subtype == DENSE_ROW_MATRIX_TYPE) 00275 { 00276 switch (x.numeric_type) 00277 { 00278 case FLOAT_TYPE: 00279 viennacl::linalg::element_op(*result.matrix_row_float, 00280 matrix_expression< const matrix_base<float, row_major>, 00281 const matrix_base<float, row_major>, 00282 op_element_binary<op_div> >(*x.matrix_row_float, *y.matrix_row_float)); 00283 break; 00284 case DOUBLE_TYPE: 00285 viennacl::linalg::element_op(*result.matrix_row_double, 00286 matrix_expression< const matrix_base<double, row_major>, 00287 const matrix_base<double, row_major>, 00288 op_element_binary<op_div> >(*x.matrix_row_double, *y.matrix_row_double)); 00289 break; 00290 default: 00291 throw statement_not_supported_exception("Invalid numeric type for binary elementwise division"); 00292 } 00293 } 00294 else if (x.subtype == DENSE_COL_MATRIX_TYPE) 00295 { 00296 switch (x.numeric_type) 00297 { 00298 case FLOAT_TYPE: 00299 viennacl::linalg::element_op(*result.matrix_col_float, 00300 matrix_expression< const matrix_base<float, column_major>, 00301 const matrix_base<float, column_major>, 00302 op_element_binary<op_div> >(*x.matrix_col_float, *y.matrix_col_float)); 00303 break; 00304 case DOUBLE_TYPE: 00305 viennacl::linalg::element_op(*result.matrix_col_double, 00306 matrix_expression< const matrix_base<double, column_major>, 00307 const matrix_base<double, column_major>, 00308 op_element_binary<op_div> >(*x.matrix_col_double, *y.matrix_col_double)); 00309 break; 00310 default: 00311 throw statement_not_supported_exception("Invalid numeric type for binary elementwise division"); 00312 } 00313 } 00314 else 00315 throw statement_not_supported_exception("Invalid operand type for binary elementwise division"); 00316 break; 00317 00318 00319 case OPERATION_BINARY_ELEMENT_PROD_TYPE: 00320 if (x.subtype == DENSE_VECTOR_TYPE) 00321 { 00322 switch (x.numeric_type) 00323 { 00324 case FLOAT_TYPE: 00325 viennacl::linalg::element_op(*result.vector_float, 00326 vector_expression<const vector_base<float>, 00327 const vector_base<float>, 00328 op_element_binary<op_prod> >(*x.vector_float, *y.vector_float)); 00329 break; 00330 case DOUBLE_TYPE: 00331 viennacl::linalg::element_op(*result.vector_double, 00332 vector_expression<const vector_base<double>, 00333 const vector_base<double>, 00334 op_element_binary<op_prod> >(*x.vector_double, *y.vector_double)); 00335 break; 00336 default: 00337 throw statement_not_supported_exception("Invalid numeric type for binary elementwise division"); 00338 } 00339 } 00340 else if (x.subtype == DENSE_ROW_MATRIX_TYPE) 00341 { 00342 switch (x.numeric_type) 00343 { 00344 case FLOAT_TYPE: 00345 viennacl::linalg::element_op(*result.matrix_row_float, 00346 matrix_expression< const matrix_base<float, row_major>, 00347 const matrix_base<float, row_major>, 00348 op_element_binary<op_prod> >(*x.matrix_row_float, *y.matrix_row_float)); 00349 break; 00350 case DOUBLE_TYPE: 00351 viennacl::linalg::element_op(*result.matrix_row_double, 00352 matrix_expression< const matrix_base<double, row_major>, 00353 const matrix_base<double, row_major>, 00354 op_element_binary<op_prod> >(*x.matrix_row_double, *y.matrix_row_double)); 00355 break; 00356 default: 00357 throw statement_not_supported_exception("Invalid numeric type for binary elementwise division"); 00358 } 00359 } 00360 else if (x.subtype == DENSE_COL_MATRIX_TYPE) 00361 { 00362 switch (x.numeric_type) 00363 { 00364 case FLOAT_TYPE: 00365 viennacl::linalg::element_op(*result.matrix_col_float, 00366 matrix_expression< const matrix_base<float, column_major>, 00367 const matrix_base<float, column_major>, 00368 op_element_binary<op_prod> >(*x.matrix_col_float, *y.matrix_col_float)); 00369 break; 00370 case DOUBLE_TYPE: 00371 viennacl::linalg::element_op(*result.matrix_col_double, 00372 matrix_expression< const matrix_base<double, column_major>, 00373 const matrix_base<double, column_major>, 00374 op_element_binary<op_prod> >(*x.matrix_col_double, *y.matrix_col_double)); 00375 break; 00376 default: 00377 throw statement_not_supported_exception("Invalid numeric type for binary elementwise division"); 00378 } 00379 } 00380 else 00381 throw statement_not_supported_exception("Invalid operand type for binary elementwise division"); 00382 break; 00383 default: 00384 throw statement_not_supported_exception("Invalid operation type for binary elementwise operations"); 00385 } 00386 } 00387 } 00388 00390 inline void execute_element_composite(statement const & s, statement_node const & root_node) 00391 { 00392 statement_node const & leaf = s.array()[root_node.rhs.node_index]; 00393 00394 statement_node new_root_lhs; 00395 statement_node new_root_rhs; 00396 00397 // check for temporary on lhs: 00398 if (leaf.lhs.type_family == COMPOSITE_OPERATION_FAMILY) 00399 { 00400 detail::new_element(new_root_lhs.lhs, root_node.lhs); 00401 00402 new_root_lhs.op.type_family = OPERATION_BINARY_TYPE_FAMILY; 00403 new_root_lhs.op.type = OPERATION_BINARY_ASSIGN_TYPE; 00404 00405 new_root_lhs.rhs.type_family = COMPOSITE_OPERATION_FAMILY; 00406 new_root_lhs.rhs.subtype = INVALID_SUBTYPE; 00407 new_root_lhs.rhs.numeric_type = INVALID_NUMERIC_TYPE; 00408 new_root_lhs.rhs.node_index = leaf.lhs.node_index; 00409 00410 // work on subexpression: 00411 // TODO: Catch exception, free temporary, then rethrow 00412 detail::execute_composite(s, new_root_lhs); 00413 } 00414 00415 if (leaf.op.type == OPERATION_BINARY_ELEMENT_PROD_TYPE || leaf.op.type == OPERATION_BINARY_ELEMENT_DIV_TYPE) 00416 { 00417 // check for temporary on rhs: 00418 if (leaf.rhs.type_family == COMPOSITE_OPERATION_FAMILY) 00419 { 00420 detail::new_element(new_root_rhs.lhs, root_node.lhs); 00421 00422 new_root_rhs.op.type_family = OPERATION_BINARY_TYPE_FAMILY; 00423 new_root_rhs.op.type = OPERATION_BINARY_ASSIGN_TYPE; 00424 00425 new_root_rhs.rhs.type_family = COMPOSITE_OPERATION_FAMILY; 00426 new_root_rhs.rhs.subtype = INVALID_SUBTYPE; 00427 new_root_rhs.rhs.numeric_type = INVALID_NUMERIC_TYPE; 00428 new_root_rhs.rhs.node_index = leaf.rhs.node_index; 00429 00430 // work on subexpression: 00431 // TODO: Catch exception, free temporary, then rethrow 00432 detail::execute_composite(s, new_root_rhs); 00433 } 00434 00435 lhs_rhs_element x = (leaf.lhs.type_family == COMPOSITE_OPERATION_FAMILY) ? new_root_lhs.lhs : leaf.lhs; 00436 lhs_rhs_element y = (leaf.rhs.type_family == COMPOSITE_OPERATION_FAMILY) ? new_root_rhs.lhs : leaf.rhs; 00437 00438 // compute element-wise operation: 00439 detail::element_op(root_node.lhs, x, y, leaf.op.type); 00440 00441 if (leaf.rhs.type_family == COMPOSITE_OPERATION_FAMILY) 00442 detail::delete_element(new_root_rhs.lhs); 00443 } 00444 else if (leaf.op.type_family == OPERATION_UNARY_TYPE_FAMILY) 00445 { 00446 lhs_rhs_element x = (leaf.lhs.type_family == COMPOSITE_OPERATION_FAMILY) ? new_root_lhs.lhs : leaf.lhs; 00447 00448 // compute element-wise operation: 00449 detail::element_op(root_node.lhs, x, leaf.op.type); 00450 } 00451 else 00452 throw statement_not_supported_exception("Unsupported elementwise operation."); 00453 00454 // clean up: 00455 if (leaf.lhs.type_family == COMPOSITE_OPERATION_FAMILY) 00456 detail::delete_element(new_root_lhs.lhs); 00457 00458 } 00459 00460 00461 } // namespace scheduler 00462 00463 } // namespace viennacl 00464 00465 #endif 00466