ViennaCL - The Vienna Computing Library
1.5.1
|
00001 #ifndef VIENNACL_SCHEDULER_EXECUTE_AXBX_HPP 00002 #define VIENNACL_SCHEDULER_EXECUTE_AXBX_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 00029 #include "viennacl/scheduler/execute_scalar_assign.hpp" 00030 #include "viennacl/scheduler/execute_generic_dispatcher.hpp" 00031 00032 namespace viennacl 00033 { 00034 namespace scheduler 00035 { 00036 namespace detail 00037 { 00039 inline void execute_axbx(statement const & s, statement_node const & root_node) 00040 { 00041 statement::container_type const & expr = s.array(); 00042 00043 statement_node const & leaf = expr[root_node.rhs.node_index]; 00044 00045 if (leaf.op.type == OPERATION_BINARY_ADD_TYPE || leaf.op.type == OPERATION_BINARY_SUB_TYPE) // x = (y) +- (z) where y and z are either data objects or expressions 00046 { 00047 bool flip_sign_z = (leaf.op.type == OPERATION_BINARY_SUB_TYPE); 00048 00049 if ( leaf.lhs.type_family != COMPOSITE_OPERATION_FAMILY 00050 && leaf.rhs.type_family != COMPOSITE_OPERATION_FAMILY) 00051 { 00052 lhs_rhs_element u = root_node.lhs; 00053 lhs_rhs_element v = leaf.lhs; 00054 lhs_rhs_element w = leaf.rhs; 00055 switch (root_node.op.type) 00056 { 00057 case OPERATION_BINARY_ASSIGN_TYPE: 00058 detail::axbx(u, 00059 v, 1.0, 1, false, false, 00060 w, 1.0, 1, false, flip_sign_z); 00061 break; 00062 case OPERATION_BINARY_INPLACE_ADD_TYPE: 00063 detail::axbx_x(u, 00064 v, 1.0, 1, false, false, 00065 w, 1.0, 1, false, flip_sign_z); 00066 break; 00067 case OPERATION_BINARY_INPLACE_SUB_TYPE: 00068 detail::axbx_x(u, 00069 v, 1.0, 1, false, true, 00070 w, 1.0, 1, false, !flip_sign_z); 00071 break; 00072 default: 00073 throw statement_not_supported_exception("Unsupported binary operator for operation in root note (should be =, +=, or -=)"); 00074 } 00075 } 00076 else if ( leaf.lhs.type_family == COMPOSITE_OPERATION_FAMILY 00077 && leaf.rhs.type_family != COMPOSITE_OPERATION_FAMILY) // x = (y) + z, y being a subtree itself, z being a scalar, vector, or matrix 00078 { 00079 statement_node const & y = expr[leaf.lhs.node_index]; 00080 00081 if (y.op.type_family == OPERATION_BINARY_TYPE_FAMILY) 00082 { 00083 // y might be 'v * alpha' or 'v / alpha' with {scalar|vector|matrix} v 00084 if ( (y.op.type == OPERATION_BINARY_MULT_TYPE || y.op.type == OPERATION_BINARY_DIV_TYPE) 00085 && y.lhs.type_family != COMPOSITE_OPERATION_FAMILY 00086 && y.rhs.type_family == SCALAR_TYPE_FAMILY) 00087 { 00088 lhs_rhs_element u = root_node.lhs; 00089 lhs_rhs_element v = y.lhs; 00090 lhs_rhs_element w = leaf.rhs; 00091 lhs_rhs_element alpha = y.rhs; 00092 00093 bool is_division = (y.op.type == OPERATION_BINARY_DIV_TYPE); 00094 switch (root_node.op.type) 00095 { 00096 case OPERATION_BINARY_ASSIGN_TYPE: 00097 detail::axbx(u, 00098 v, alpha, 1, is_division, false, 00099 w, 1.0, 1, false, flip_sign_z); 00100 break; 00101 case OPERATION_BINARY_INPLACE_ADD_TYPE: 00102 detail::axbx_x(u, 00103 v, alpha, 1, is_division, false, 00104 w, 1.0, 1, false, flip_sign_z); 00105 break; 00106 case OPERATION_BINARY_INPLACE_SUB_TYPE: 00107 detail::axbx_x(u, 00108 v, alpha, 1, is_division, true, 00109 w, 1.0, 1, false, !flip_sign_z); 00110 break; 00111 default: 00112 throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)"); 00113 } 00114 } 00115 else // no built-in kernel, we use a temporary. 00116 { 00117 statement_node new_root_y; 00118 00119 detail::new_element(new_root_y.lhs, root_node.lhs); 00120 00121 new_root_y.op.type_family = OPERATION_BINARY_TYPE_FAMILY; 00122 new_root_y.op.type = OPERATION_BINARY_ASSIGN_TYPE; 00123 00124 new_root_y.rhs.type_family = COMPOSITE_OPERATION_FAMILY; 00125 new_root_y.rhs.subtype = INVALID_SUBTYPE; 00126 new_root_y.rhs.numeric_type = INVALID_NUMERIC_TYPE; 00127 new_root_y.rhs.node_index = leaf.lhs.node_index; 00128 00129 // work on subexpression: 00130 // TODO: Catch exception, free temporary, then rethrow 00131 execute_composite(s, new_root_y); 00132 00133 // now add: 00134 lhs_rhs_element u = root_node.lhs; 00135 lhs_rhs_element v = new_root_y.lhs; 00136 lhs_rhs_element w = leaf.rhs; 00137 switch (root_node.op.type) 00138 { 00139 case OPERATION_BINARY_ASSIGN_TYPE: 00140 detail::axbx(u, 00141 v, 1.0, 1, false, false, 00142 w, 1.0, 1, false, flip_sign_z); 00143 break; 00144 case OPERATION_BINARY_INPLACE_ADD_TYPE: 00145 detail::axbx_x(u, 00146 v, 1.0, 1, false, false, 00147 w, 1.0, 1, false, flip_sign_z); 00148 break; 00149 case OPERATION_BINARY_INPLACE_SUB_TYPE: 00150 detail::axbx_x(u, 00151 v, 1.0, 1, false, true, 00152 w, 1.0, 1, false, !flip_sign_z); 00153 break; 00154 default: 00155 throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)"); 00156 } 00157 00158 detail::delete_element(new_root_y.lhs); 00159 } 00160 } 00161 else 00162 throw statement_not_supported_exception("Cannot deal with unary operations on vectors"); 00163 00164 } 00165 else if ( leaf.lhs.type_family != COMPOSITE_OPERATION_FAMILY 00166 && leaf.rhs.type_family == COMPOSITE_OPERATION_FAMILY) // x = y + (z), y being vector, z being a subtree itself 00167 { 00168 statement_node const & z = expr[leaf.rhs.node_index]; 00169 00170 if (z.op.type_family == OPERATION_BINARY_TYPE_FAMILY) 00171 { 00172 // z might be 'v * alpha' or 'v / alpha' with vector v 00173 if ( (z.op.type == OPERATION_BINARY_MULT_TYPE || z.op.type == OPERATION_BINARY_DIV_TYPE) 00174 && z.lhs.type_family != COMPOSITE_OPERATION_FAMILY 00175 && z.rhs.type_family == SCALAR_TYPE_FAMILY) 00176 { 00177 lhs_rhs_element u = root_node.lhs; 00178 lhs_rhs_element v = leaf.lhs; 00179 lhs_rhs_element w = z.lhs; 00180 lhs_rhs_element beta = z.rhs; 00181 00182 bool is_division = (z.op.type == OPERATION_BINARY_DIV_TYPE); 00183 switch (root_node.op.type) 00184 { 00185 case OPERATION_BINARY_ASSIGN_TYPE: 00186 detail::axbx(u, 00187 v, 1.0, 1, false, false, 00188 w, beta, 1, is_division, flip_sign_z); 00189 break; 00190 case OPERATION_BINARY_INPLACE_ADD_TYPE: 00191 detail::axbx_x(u, 00192 v, 1.0, 1, false, false, 00193 w, beta, 1, is_division, flip_sign_z); 00194 break; 00195 case OPERATION_BINARY_INPLACE_SUB_TYPE: 00196 detail::axbx_x(u, 00197 v, 1.0, 1, false, true, 00198 w, beta, 1, is_division, !flip_sign_z); 00199 break; 00200 default: 00201 throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)"); 00202 } 00203 } 00204 else // no built-in kernel, we use a temporary. 00205 { 00206 statement_node new_root_z; 00207 00208 detail::new_element(new_root_z.lhs, root_node.lhs); 00209 00210 new_root_z.op.type_family = OPERATION_BINARY_TYPE_FAMILY; 00211 new_root_z.op.type = OPERATION_BINARY_ASSIGN_TYPE; 00212 00213 new_root_z.rhs.type_family = COMPOSITE_OPERATION_FAMILY; 00214 new_root_z.rhs.subtype = INVALID_SUBTYPE; 00215 new_root_z.rhs.numeric_type = INVALID_NUMERIC_TYPE; 00216 new_root_z.rhs.node_index = leaf.rhs.node_index; 00217 00218 // work on subexpression: 00219 // TODO: Catch exception, free temporary, then rethrow 00220 execute_composite(s, new_root_z); 00221 00222 // now add: 00223 lhs_rhs_element u = root_node.lhs; 00224 lhs_rhs_element v = leaf.lhs; 00225 lhs_rhs_element w = new_root_z.lhs; 00226 switch (root_node.op.type) 00227 { 00228 case OPERATION_BINARY_ASSIGN_TYPE: 00229 detail::axbx(u, 00230 v, 1.0, 1, false, false, 00231 w, 1.0, 1, false, flip_sign_z); 00232 break; 00233 case OPERATION_BINARY_INPLACE_ADD_TYPE: 00234 detail::axbx_x(u, 00235 v, 1.0, 1, false, false, 00236 w, 1.0, 1, false, flip_sign_z); 00237 break; 00238 case OPERATION_BINARY_INPLACE_SUB_TYPE: 00239 detail::axbx_x(u, 00240 v, 1.0, 1, false, true, 00241 w, 1.0, 1, false, !flip_sign_z); 00242 break; 00243 default: 00244 throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)"); 00245 } 00246 00247 detail::delete_element(new_root_z.lhs); 00248 } 00249 } 00250 else 00251 throw statement_not_supported_exception("Cannot deal with unary operations on vectors"); 00252 00253 } 00254 else if ( leaf.lhs.type_family == COMPOSITE_OPERATION_FAMILY 00255 && leaf.rhs.type_family == COMPOSITE_OPERATION_FAMILY) // x = (y) + (z), y and z being subtrees 00256 { 00257 statement_node const & y = expr[leaf.lhs.node_index]; 00258 statement_node const & z = expr[leaf.rhs.node_index]; 00259 00260 if ( y.op.type_family == OPERATION_BINARY_TYPE_FAMILY 00261 && z.op.type_family == OPERATION_BINARY_TYPE_FAMILY) 00262 { 00263 // z might be 'v * alpha' or 'v / alpha' with vector v 00264 if ( (y.op.type == OPERATION_BINARY_MULT_TYPE || y.op.type == OPERATION_BINARY_DIV_TYPE) 00265 && y.lhs.type_family != COMPOSITE_OPERATION_FAMILY 00266 && y.rhs.type_family == SCALAR_TYPE_FAMILY 00267 && (z.op.type == OPERATION_BINARY_MULT_TYPE || z.op.type == OPERATION_BINARY_DIV_TYPE) 00268 && z.lhs.type_family != COMPOSITE_OPERATION_FAMILY 00269 && z.rhs.type_family == SCALAR_TYPE_FAMILY) 00270 { 00271 lhs_rhs_element u = root_node.lhs; 00272 lhs_rhs_element v = y.lhs; 00273 lhs_rhs_element w = z.lhs; 00274 lhs_rhs_element alpha = y.rhs; 00275 lhs_rhs_element beta = z.rhs; 00276 00277 bool is_division_y = (y.op.type == OPERATION_BINARY_DIV_TYPE); 00278 bool is_division_z = (z.op.type == OPERATION_BINARY_DIV_TYPE); 00279 switch (root_node.op.type) 00280 { 00281 case OPERATION_BINARY_ASSIGN_TYPE: 00282 detail::axbx(u, 00283 v, alpha, 1, is_division_y, false, 00284 w, beta, 1, is_division_z, flip_sign_z); 00285 break; 00286 case OPERATION_BINARY_INPLACE_ADD_TYPE: 00287 detail::axbx_x(u, 00288 v, alpha, 1, is_division_y, false, 00289 w, beta, 1, is_division_z, flip_sign_z); 00290 break; 00291 case OPERATION_BINARY_INPLACE_SUB_TYPE: 00292 detail::axbx_x(u, 00293 v, alpha, 1, is_division_y, true, 00294 w, beta, 1, is_division_z, !flip_sign_z); 00295 break; 00296 default: 00297 throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)"); 00298 } 00299 } 00300 else // no built-in kernel, we use a temporary. 00301 { 00302 statement_node new_root_y; 00303 00304 detail::new_element(new_root_y.lhs, root_node.lhs); 00305 00306 new_root_y.op.type_family = OPERATION_BINARY_TYPE_FAMILY; 00307 new_root_y.op.type = OPERATION_BINARY_ASSIGN_TYPE; 00308 00309 new_root_y.rhs.type_family = COMPOSITE_OPERATION_FAMILY; 00310 new_root_y.rhs.subtype = INVALID_SUBTYPE; 00311 new_root_y.rhs.numeric_type = INVALID_NUMERIC_TYPE; 00312 new_root_y.rhs.node_index = leaf.lhs.node_index; 00313 00314 // work on subexpression: 00315 // TODO: Catch exception, free temporary, then rethrow 00316 execute_composite(s, new_root_y); 00317 00318 statement_node new_root_z; 00319 00320 detail::new_element(new_root_z.lhs, root_node.lhs); 00321 00322 new_root_z.op.type_family = OPERATION_BINARY_TYPE_FAMILY; 00323 new_root_z.op.type = OPERATION_BINARY_ASSIGN_TYPE; 00324 00325 new_root_z.rhs.type_family = COMPOSITE_OPERATION_FAMILY; 00326 new_root_z.rhs.subtype = INVALID_SUBTYPE; 00327 new_root_z.rhs.numeric_type = INVALID_NUMERIC_TYPE; 00328 new_root_z.rhs.node_index = leaf.rhs.node_index; 00329 00330 // work on subexpression: 00331 // TODO: Catch exception, free temporaries, then rethrow 00332 execute_composite(s, new_root_z); 00333 00334 // now add: 00335 lhs_rhs_element u = root_node.lhs; 00336 lhs_rhs_element v = new_root_y.lhs; 00337 lhs_rhs_element w = new_root_z.lhs; 00338 00339 switch (root_node.op.type) 00340 { 00341 case OPERATION_BINARY_ASSIGN_TYPE: 00342 detail::axbx(u, 00343 v, 1.0, 1, false, false, 00344 w, 1.0, 1, false, flip_sign_z); 00345 break; 00346 case OPERATION_BINARY_INPLACE_ADD_TYPE: 00347 detail::axbx_x(u, 00348 v, 1.0, 1, false, false, 00349 w, 1.0, 1, false, flip_sign_z); 00350 break; 00351 case OPERATION_BINARY_INPLACE_SUB_TYPE: 00352 detail::axbx_x(u, 00353 v, 1.0, 1, false, true, 00354 w, 1.0, 1, false, !flip_sign_z); 00355 break; 00356 default: 00357 throw statement_not_supported_exception("Unsupported binary operator for vector operation in root note (should be =, +=, or -=)"); 00358 } 00359 00360 detail::delete_element(new_root_y.lhs); 00361 detail::delete_element(new_root_z.lhs); 00362 } 00363 } 00364 else 00365 throw statement_not_supported_exception("Cannot deal with unary operations on vectors"); 00366 } 00367 else 00368 throw statement_not_supported_exception("Cannot deal with addition of vectors"); 00369 } 00370 else 00371 throw statement_not_supported_exception("Unsupported binary operator for vector operations"); 00372 } 00373 00374 } // namespace detail 00375 } // namespace scheduler 00376 } // namespace viennacl 00377 00378 #endif 00379