ViennaCL - The Vienna Computing Library
1.5.2
|
00001 #ifndef VIENNACL_LINALG_VECTOR_OPERATIONS_HPP_ 00002 #define VIENNACL_LINALG_VECTOR_OPERATIONS_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 00025 #include "viennacl/forwards.h" 00026 #include "viennacl/scalar.hpp" 00027 #include "viennacl/tools/tools.hpp" 00028 #include "viennacl/meta/predicate.hpp" 00029 #include "viennacl/meta/enable_if.hpp" 00030 #include "viennacl/traits/size.hpp" 00031 #include "viennacl/traits/start.hpp" 00032 #include "viennacl/traits/handle.hpp" 00033 #include "viennacl/traits/stride.hpp" 00034 #include "viennacl/linalg/host_based/vector_operations.hpp" 00035 00036 #ifdef VIENNACL_WITH_OPENCL 00037 #include "viennacl/linalg/opencl/vector_operations.hpp" 00038 #endif 00039 00040 #ifdef VIENNACL_WITH_CUDA 00041 #include "viennacl/linalg/cuda/vector_operations.hpp" 00042 #endif 00043 00044 namespace viennacl 00045 { 00046 namespace linalg 00047 { 00048 template <typename T, typename ScalarType1> 00049 void av(vector_base<T> & vec1, 00050 vector_base<T> const & vec2, ScalarType1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha) 00051 { 00052 assert(viennacl::traits::size(vec1) == viennacl::traits::size(vec2) && bool("Incompatible vector sizes in v1 = v2 @ alpha: size(v1) != size(v2)")); 00053 00054 switch (viennacl::traits::handle(vec1).get_active_handle_id()) 00055 { 00056 case viennacl::MAIN_MEMORY: 00057 viennacl::linalg::host_based::av(vec1, vec2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha); 00058 break; 00059 #ifdef VIENNACL_WITH_OPENCL 00060 case viennacl::OPENCL_MEMORY: 00061 viennacl::linalg::opencl::av(vec1, vec2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha); 00062 break; 00063 #endif 00064 #ifdef VIENNACL_WITH_CUDA 00065 case viennacl::CUDA_MEMORY: 00066 viennacl::linalg::cuda::av(vec1, vec2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha); 00067 break; 00068 #endif 00069 case viennacl::MEMORY_NOT_INITIALIZED: 00070 throw memory_exception("not initialised!"); 00071 default: 00072 throw memory_exception("not implemented"); 00073 } 00074 } 00075 00076 00077 template <typename T, typename ScalarType1, typename ScalarType2> 00078 void avbv(vector_base<T> & vec1, 00079 vector_base<T> const & vec2, ScalarType1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, 00080 vector_base<T> const & vec3, ScalarType2 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta) 00081 { 00082 assert(viennacl::traits::size(vec1) == viennacl::traits::size(vec2) && bool("Incompatible vector sizes in v1 = v2 @ alpha + v3 @ beta: size(v1) != size(v2)")); 00083 assert(viennacl::traits::size(vec2) == viennacl::traits::size(vec3) && bool("Incompatible vector sizes in v1 = v2 @ alpha + v3 @ beta: size(v2) != size(v3)")); 00084 00085 switch (viennacl::traits::handle(vec1).get_active_handle_id()) 00086 { 00087 case viennacl::MAIN_MEMORY: 00088 viennacl::linalg::host_based::avbv(vec1, 00089 vec2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00090 vec3, beta, len_beta, reciprocal_beta, flip_sign_beta); 00091 break; 00092 #ifdef VIENNACL_WITH_OPENCL 00093 case viennacl::OPENCL_MEMORY: 00094 viennacl::linalg::opencl::avbv(vec1, 00095 vec2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00096 vec3, beta, len_beta, reciprocal_beta, flip_sign_beta); 00097 break; 00098 #endif 00099 #ifdef VIENNACL_WITH_CUDA 00100 case viennacl::CUDA_MEMORY: 00101 viennacl::linalg::cuda::avbv(vec1, 00102 vec2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00103 vec3, beta, len_beta, reciprocal_beta, flip_sign_beta); 00104 break; 00105 #endif 00106 case viennacl::MEMORY_NOT_INITIALIZED: 00107 throw memory_exception("not initialised!"); 00108 default: 00109 throw memory_exception("not implemented"); 00110 } 00111 } 00112 00113 00114 template <typename T, typename ScalarType1, typename ScalarType2> 00115 void avbv_v(vector_base<T> & vec1, 00116 vector_base<T> const & vec2, ScalarType1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, 00117 vector_base<T> const & vec3, ScalarType2 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta) 00118 { 00119 assert(viennacl::traits::size(vec1) == viennacl::traits::size(vec2) && bool("Incompatible vector sizes in v1 += v2 @ alpha + v3 @ beta: size(v1) != size(v2)")); 00120 assert(viennacl::traits::size(vec2) == viennacl::traits::size(vec3) && bool("Incompatible vector sizes in v1 += v2 @ alpha + v3 @ beta: size(v2) != size(v3)")); 00121 00122 switch (viennacl::traits::handle(vec1).get_active_handle_id()) 00123 { 00124 case viennacl::MAIN_MEMORY: 00125 viennacl::linalg::host_based::avbv_v(vec1, 00126 vec2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00127 vec3, beta, len_beta, reciprocal_beta, flip_sign_beta); 00128 break; 00129 #ifdef VIENNACL_WITH_OPENCL 00130 case viennacl::OPENCL_MEMORY: 00131 viennacl::linalg::opencl::avbv_v(vec1, 00132 vec2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00133 vec3, beta, len_beta, reciprocal_beta, flip_sign_beta); 00134 break; 00135 #endif 00136 #ifdef VIENNACL_WITH_CUDA 00137 case viennacl::CUDA_MEMORY: 00138 viennacl::linalg::cuda::avbv_v(vec1, 00139 vec2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00140 vec3, beta, len_beta, reciprocal_beta, flip_sign_beta); 00141 break; 00142 #endif 00143 case viennacl::MEMORY_NOT_INITIALIZED: 00144 throw memory_exception("not initialised!"); 00145 default: 00146 throw memory_exception("not implemented"); 00147 } 00148 } 00149 00150 00157 template <typename T> 00158 void vector_assign(vector_base<T> & vec1, const T & alpha, bool up_to_internal_size = false) 00159 { 00160 switch (viennacl::traits::handle(vec1).get_active_handle_id()) 00161 { 00162 case viennacl::MAIN_MEMORY: 00163 viennacl::linalg::host_based::vector_assign(vec1, alpha, up_to_internal_size); 00164 break; 00165 #ifdef VIENNACL_WITH_OPENCL 00166 case viennacl::OPENCL_MEMORY: 00167 viennacl::linalg::opencl::vector_assign(vec1, alpha, up_to_internal_size); 00168 break; 00169 #endif 00170 #ifdef VIENNACL_WITH_CUDA 00171 case viennacl::CUDA_MEMORY: 00172 viennacl::linalg::cuda::vector_assign(vec1, alpha, up_to_internal_size); 00173 break; 00174 #endif 00175 case viennacl::MEMORY_NOT_INITIALIZED: 00176 throw memory_exception("not initialised!"); 00177 default: 00178 throw memory_exception("not implemented"); 00179 } 00180 } 00181 00182 00188 template <typename T> 00189 void vector_swap(vector_base<T> & vec1, vector_base<T> & vec2) 00190 { 00191 assert(viennacl::traits::size(vec1) == viennacl::traits::size(vec2) && bool("Incompatible vector sizes in vector_swap()")); 00192 00193 switch (viennacl::traits::handle(vec1).get_active_handle_id()) 00194 { 00195 case viennacl::MAIN_MEMORY: 00196 viennacl::linalg::host_based::vector_swap(vec1, vec2); 00197 break; 00198 #ifdef VIENNACL_WITH_OPENCL 00199 case viennacl::OPENCL_MEMORY: 00200 viennacl::linalg::opencl::vector_swap(vec1, vec2); 00201 break; 00202 #endif 00203 #ifdef VIENNACL_WITH_CUDA 00204 case viennacl::CUDA_MEMORY: 00205 viennacl::linalg::cuda::vector_swap(vec1, vec2); 00206 break; 00207 #endif 00208 case viennacl::MEMORY_NOT_INITIALIZED: 00209 throw memory_exception("not initialised!"); 00210 default: 00211 throw memory_exception("not implemented"); 00212 } 00213 } 00214 00215 00217 00218 00219 00225 template <typename T, typename OP> 00226 void element_op(vector_base<T> & vec1, 00227 vector_expression<const vector_base<T>, const vector_base<T>, OP> const & proxy) 00228 { 00229 assert(viennacl::traits::size(vec1) == viennacl::traits::size(proxy) && bool("Incompatible vector sizes in element_op()")); 00230 00231 switch (viennacl::traits::handle(vec1).get_active_handle_id()) 00232 { 00233 case viennacl::MAIN_MEMORY: 00234 viennacl::linalg::host_based::element_op(vec1, proxy); 00235 break; 00236 #ifdef VIENNACL_WITH_OPENCL 00237 case viennacl::OPENCL_MEMORY: 00238 viennacl::linalg::opencl::element_op(vec1, proxy); 00239 break; 00240 #endif 00241 #ifdef VIENNACL_WITH_CUDA 00242 case viennacl::CUDA_MEMORY: 00243 viennacl::linalg::cuda::element_op(vec1, proxy); 00244 break; 00245 #endif 00246 case viennacl::MEMORY_NOT_INITIALIZED: 00247 throw memory_exception("not initialised!"); 00248 default: 00249 throw memory_exception("not implemented"); 00250 } 00251 } 00252 00255 // Helper macro for generating binary element-wise operations such as element_prod(), element_div(), element_pow() without unnecessary code duplication */ 00256 #define VIENNACL_GENERATE_BINARY_ELEMENTOPERATION_OVERLOADS(OPNAME) \ 00257 template <typename T> \ 00258 viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<op_##OPNAME> > \ 00259 element_##OPNAME(vector_base<T> const & v1, vector_base<T> const & v2) \ 00260 { \ 00261 return viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_binary<op_##OPNAME> >(v1, v2); \ 00262 } \ 00263 \ 00264 template <typename V1, typename V2, typename OP, typename T> \ 00265 viennacl::vector_expression<const vector_expression<const V1, const V2, OP>, const vector_base<T>, op_element_binary<op_##OPNAME> > \ 00266 element_##OPNAME(vector_expression<const V1, const V2, OP> const & proxy, vector_base<T> const & v2) \ 00267 { \ 00268 return viennacl::vector_expression<const vector_expression<const V1, const V2, OP>, const vector_base<T>, op_element_binary<op_##OPNAME> >(proxy, v2); \ 00269 } \ 00270 \ 00271 template <typename T, typename V2, typename V3, typename OP> \ 00272 viennacl::vector_expression<const vector_base<T>, const vector_expression<const V2, const V3, OP>, op_element_binary<op_##OPNAME> > \ 00273 element_##OPNAME(vector_base<T> const & v1, vector_expression<const V2, const V3, OP> const & proxy) \ 00274 { \ 00275 return viennacl::vector_expression<const vector_base<T>, const vector_expression<const V2, const V3, OP>, op_element_binary<op_##OPNAME> >(v1, proxy); \ 00276 } \ 00277 \ 00278 template <typename V1, typename V2, typename OP1, \ 00279 typename V3, typename V4, typename OP2> \ 00280 viennacl::vector_expression<const vector_expression<const V1, const V2, OP1>, \ 00281 const vector_expression<const V3, const V4, OP2>, \ 00282 op_element_binary<op_##OPNAME> > \ 00283 element_##OPNAME(vector_expression<const V1, const V2, OP1> const & proxy1, \ 00284 vector_expression<const V3, const V4, OP2> const & proxy2) \ 00285 {\ 00286 return viennacl::vector_expression<const vector_expression<const V1, const V2, OP1>, \ 00287 const vector_expression<const V3, const V4, OP2>, \ 00288 op_element_binary<op_##OPNAME> >(proxy1, proxy2); \ 00289 } 00290 00291 VIENNACL_GENERATE_BINARY_ELEMENTOPERATION_OVERLOADS(prod) //for element_prod() 00292 VIENNACL_GENERATE_BINARY_ELEMENTOPERATION_OVERLOADS(div) //for element_div() 00293 VIENNACL_GENERATE_BINARY_ELEMENTOPERATION_OVERLOADS(pow) //for element_pow() 00294 00295 #undef VIENNACL_GENERATE_BINARY_ELEMENTOPERATION_OVERLOADS 00296 00297 // Helper macro for generating unary element-wise operations such as element_exp(), element_sin(), etc. without unnecessary code duplication */ 00298 #define VIENNACL_MAKE_UNARY_ELEMENT_OP(funcname) \ 00299 template <typename T> \ 00300 viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<op_##funcname> > \ 00301 element_##funcname(vector_base<T> const & v) \ 00302 { \ 00303 return viennacl::vector_expression<const vector_base<T>, const vector_base<T>, op_element_unary<op_##funcname> >(v, v); \ 00304 } \ 00305 template <typename LHS, typename RHS, typename OP> \ 00306 viennacl::vector_expression<const vector_expression<const LHS, const RHS, OP>, \ 00307 const vector_expression<const LHS, const RHS, OP>, \ 00308 op_element_unary<op_##funcname> > \ 00309 element_##funcname(vector_expression<const LHS, const RHS, OP> const & proxy) \ 00310 { \ 00311 return viennacl::vector_expression<const vector_expression<const LHS, const RHS, OP>, \ 00312 const vector_expression<const LHS, const RHS, OP>, \ 00313 op_element_unary<op_##funcname> >(proxy, proxy); \ 00314 } \ 00315 00316 VIENNACL_MAKE_UNARY_ELEMENT_OP(abs) 00317 VIENNACL_MAKE_UNARY_ELEMENT_OP(acos) 00318 VIENNACL_MAKE_UNARY_ELEMENT_OP(asin) 00319 VIENNACL_MAKE_UNARY_ELEMENT_OP(atan) 00320 VIENNACL_MAKE_UNARY_ELEMENT_OP(ceil) 00321 VIENNACL_MAKE_UNARY_ELEMENT_OP(cos) 00322 VIENNACL_MAKE_UNARY_ELEMENT_OP(cosh) 00323 VIENNACL_MAKE_UNARY_ELEMENT_OP(exp) 00324 VIENNACL_MAKE_UNARY_ELEMENT_OP(fabs) 00325 VIENNACL_MAKE_UNARY_ELEMENT_OP(floor) 00326 VIENNACL_MAKE_UNARY_ELEMENT_OP(log) 00327 VIENNACL_MAKE_UNARY_ELEMENT_OP(log10) 00328 VIENNACL_MAKE_UNARY_ELEMENT_OP(sin) 00329 VIENNACL_MAKE_UNARY_ELEMENT_OP(sinh) 00330 VIENNACL_MAKE_UNARY_ELEMENT_OP(sqrt) 00331 VIENNACL_MAKE_UNARY_ELEMENT_OP(tan) 00332 VIENNACL_MAKE_UNARY_ELEMENT_OP(tanh) 00333 00334 #undef VIENNACL_MAKE_UNARY_ELEMENT_OP 00335 00338 00339 00340 00341 //implementation of inner product: 00342 //namespace { 00343 00350 template <typename T> 00351 void inner_prod_impl(vector_base<T> const & vec1, 00352 vector_base<T> const & vec2, 00353 scalar<T> & result) 00354 { 00355 assert( vec1.size() == vec2.size() && bool("Size mismatch") ); 00356 00357 switch (viennacl::traits::handle(vec1).get_active_handle_id()) 00358 { 00359 case viennacl::MAIN_MEMORY: 00360 viennacl::linalg::host_based::inner_prod_impl(vec1, vec2, result); 00361 break; 00362 #ifdef VIENNACL_WITH_OPENCL 00363 case viennacl::OPENCL_MEMORY: 00364 viennacl::linalg::opencl::inner_prod_impl(vec1, vec2, result); 00365 break; 00366 #endif 00367 #ifdef VIENNACL_WITH_CUDA 00368 case viennacl::CUDA_MEMORY: 00369 viennacl::linalg::cuda::inner_prod_impl(vec1, vec2, result); 00370 break; 00371 #endif 00372 case viennacl::MEMORY_NOT_INITIALIZED: 00373 throw memory_exception("not initialised!"); 00374 default: 00375 throw memory_exception("not implemented"); 00376 } 00377 } 00378 00379 // vector expression on lhs 00380 template <typename LHS, typename RHS, typename OP, typename T> 00381 void inner_prod_impl(viennacl::vector_expression<LHS, RHS, OP> const & vec1, 00382 vector_base<T> const & vec2, 00383 scalar<T> & result) 00384 { 00385 viennacl::vector<T> temp = vec1; 00386 inner_prod_impl(temp, vec2, result); 00387 } 00388 00389 00390 // vector expression on rhs 00391 template <typename T, typename LHS, typename RHS, typename OP> 00392 void inner_prod_impl(vector_base<T> const & vec1, 00393 viennacl::vector_expression<LHS, RHS, OP> const & vec2, 00394 scalar<T> & result) 00395 { 00396 viennacl::vector<T> temp = vec2; 00397 inner_prod_impl(vec1, temp, result); 00398 } 00399 00400 00401 // vector expression on lhs and rhs 00402 template <typename LHS1, typename RHS1, typename OP1, 00403 typename LHS2, typename RHS2, typename OP2, typename T> 00404 void inner_prod_impl(viennacl::vector_expression<LHS1, RHS1, OP1> const & vec1, 00405 viennacl::vector_expression<LHS2, RHS2, OP2> const & vec2, 00406 scalar<T> & result) 00407 { 00408 viennacl::vector<T> temp1 = vec1; 00409 viennacl::vector<T> temp2 = vec2; 00410 inner_prod_impl(temp1, temp2, result); 00411 } 00412 00413 00414 00415 00422 template <typename T> 00423 void inner_prod_cpu(vector_base<T> const & vec1, 00424 vector_base<T> const & vec2, 00425 T & result) 00426 { 00427 assert( vec1.size() == vec2.size() && bool("Size mismatch") ); 00428 00429 switch (viennacl::traits::handle(vec1).get_active_handle_id()) 00430 { 00431 case viennacl::MAIN_MEMORY: 00432 viennacl::linalg::host_based::inner_prod_impl(vec1, vec2, result); 00433 break; 00434 #ifdef VIENNACL_WITH_OPENCL 00435 case viennacl::OPENCL_MEMORY: 00436 viennacl::linalg::opencl::inner_prod_cpu(vec1, vec2, result); 00437 break; 00438 #endif 00439 #ifdef VIENNACL_WITH_CUDA 00440 case viennacl::CUDA_MEMORY: 00441 viennacl::linalg::cuda::inner_prod_cpu(vec1, vec2, result); 00442 break; 00443 #endif 00444 case viennacl::MEMORY_NOT_INITIALIZED: 00445 throw memory_exception("not initialised!"); 00446 default: 00447 throw memory_exception("not implemented"); 00448 } 00449 } 00450 00451 // vector expression on lhs 00452 template <typename LHS, typename RHS, typename OP, typename T> 00453 void inner_prod_cpu(viennacl::vector_expression<LHS, RHS, OP> const & vec1, 00454 vector_base<T> const & vec2, 00455 T & result) 00456 { 00457 viennacl::vector<T> temp = vec1; 00458 inner_prod_cpu(temp, vec2, result); 00459 } 00460 00461 00462 // vector expression on rhs 00463 template <typename T, typename LHS, typename RHS, typename OP> 00464 void inner_prod_cpu(vector_base<T> const & vec1, 00465 viennacl::vector_expression<LHS, RHS, OP> const & vec2, 00466 T & result) 00467 { 00468 viennacl::vector<T> temp = vec2; 00469 inner_prod_cpu(vec1, temp, result); 00470 } 00471 00472 00473 // vector expression on lhs and rhs 00474 template <typename LHS1, typename RHS1, typename OP1, 00475 typename LHS2, typename RHS2, typename OP2, typename S3> 00476 void inner_prod_cpu(viennacl::vector_expression<LHS1, RHS1, OP1> const & vec1, 00477 viennacl::vector_expression<LHS2, RHS2, OP2> const & vec2, 00478 S3 & result) 00479 { 00480 viennacl::vector<S3> temp1 = vec1; 00481 viennacl::vector<S3> temp2 = vec2; 00482 inner_prod_cpu(temp1, temp2, result); 00483 } 00484 00485 00486 00493 template <typename T> 00494 void inner_prod_impl(vector_base<T> const & x, 00495 vector_tuple<T> const & y_tuple, 00496 vector_base<T> & result) 00497 { 00498 assert( x.size() == y_tuple.const_at(0).size() && bool("Size mismatch") ); 00499 assert( result.size() == y_tuple.const_size() && bool("Number of elements does not match result size") ); 00500 00501 switch (viennacl::traits::handle(x).get_active_handle_id()) 00502 { 00503 case viennacl::MAIN_MEMORY: 00504 viennacl::linalg::host_based::inner_prod_impl(x, y_tuple, result); 00505 break; 00506 #ifdef VIENNACL_WITH_OPENCL 00507 case viennacl::OPENCL_MEMORY: 00508 viennacl::linalg::opencl::inner_prod_impl(x, y_tuple, result); 00509 break; 00510 #endif 00511 #ifdef VIENNACL_WITH_CUDA 00512 case viennacl::CUDA_MEMORY: 00513 viennacl::linalg::cuda::inner_prod_impl(x, y_tuple, result); 00514 break; 00515 #endif 00516 case viennacl::MEMORY_NOT_INITIALIZED: 00517 throw memory_exception("not initialised!"); 00518 default: 00519 throw memory_exception("not implemented"); 00520 } 00521 } 00522 00523 00529 template <typename T> 00530 void norm_1_impl(vector_base<T> const & vec, 00531 scalar<T> & result) 00532 { 00533 switch (viennacl::traits::handle(vec).get_active_handle_id()) 00534 { 00535 case viennacl::MAIN_MEMORY: 00536 viennacl::linalg::host_based::norm_1_impl(vec, result); 00537 break; 00538 #ifdef VIENNACL_WITH_OPENCL 00539 case viennacl::OPENCL_MEMORY: 00540 viennacl::linalg::opencl::norm_1_impl(vec, result); 00541 break; 00542 #endif 00543 #ifdef VIENNACL_WITH_CUDA 00544 case viennacl::CUDA_MEMORY: 00545 viennacl::linalg::cuda::norm_1_impl(vec, result); 00546 break; 00547 #endif 00548 case viennacl::MEMORY_NOT_INITIALIZED: 00549 throw memory_exception("not initialised!"); 00550 default: 00551 throw memory_exception("not implemented"); 00552 } 00553 } 00554 00555 00561 template <typename LHS, typename RHS, typename OP, typename S2> 00562 void norm_1_impl(viennacl::vector_expression<LHS, RHS, OP> const & vec, 00563 S2 & result) 00564 { 00565 viennacl::vector<typename viennacl::result_of::cpu_value_type<S2>::type> temp = vec; 00566 norm_1_impl(temp, result); 00567 } 00568 00569 00570 00576 template <typename T> 00577 void norm_1_cpu(vector_base<T> const & vec, 00578 T & result) 00579 { 00580 switch (viennacl::traits::handle(vec).get_active_handle_id()) 00581 { 00582 case viennacl::MAIN_MEMORY: 00583 viennacl::linalg::host_based::norm_1_impl(vec, result); 00584 break; 00585 #ifdef VIENNACL_WITH_OPENCL 00586 case viennacl::OPENCL_MEMORY: 00587 viennacl::linalg::opencl::norm_1_cpu(vec, result); 00588 break; 00589 #endif 00590 #ifdef VIENNACL_WITH_CUDA 00591 case viennacl::CUDA_MEMORY: 00592 viennacl::linalg::cuda::norm_1_cpu(vec, result); 00593 break; 00594 #endif 00595 case viennacl::MEMORY_NOT_INITIALIZED: 00596 throw memory_exception("not initialised!"); 00597 default: 00598 throw memory_exception("not implemented"); 00599 } 00600 } 00601 00607 template <typename LHS, typename RHS, typename OP, typename S2> 00608 void norm_1_cpu(viennacl::vector_expression<LHS, RHS, OP> const & vec, 00609 S2 & result) 00610 { 00611 viennacl::vector<typename viennacl::result_of::cpu_value_type<LHS>::type> temp = vec; 00612 norm_1_cpu(temp, result); 00613 } 00614 00615 00616 00617 00623 template <typename T> 00624 void norm_2_impl(vector_base<T> const & vec, 00625 scalar<T> & result) 00626 { 00627 switch (viennacl::traits::handle(vec).get_active_handle_id()) 00628 { 00629 case viennacl::MAIN_MEMORY: 00630 viennacl::linalg::host_based::norm_2_impl(vec, result); 00631 break; 00632 #ifdef VIENNACL_WITH_OPENCL 00633 case viennacl::OPENCL_MEMORY: 00634 viennacl::linalg::opencl::norm_2_impl(vec, result); 00635 break; 00636 #endif 00637 #ifdef VIENNACL_WITH_CUDA 00638 case viennacl::CUDA_MEMORY: 00639 viennacl::linalg::cuda::norm_2_impl(vec, result); 00640 break; 00641 #endif 00642 case viennacl::MEMORY_NOT_INITIALIZED: 00643 throw memory_exception("not initialised!"); 00644 default: 00645 throw memory_exception("not implemented"); 00646 } 00647 } 00648 00654 template <typename LHS, typename RHS, typename OP, typename T> 00655 void norm_2_impl(viennacl::vector_expression<LHS, RHS, OP> const & vec, 00656 scalar<T> & result) 00657 { 00658 viennacl::vector<T> temp = vec; 00659 norm_2_impl(temp, result); 00660 } 00661 00662 00668 template <typename T> 00669 void norm_2_cpu(vector_base<T> const & vec, 00670 T & result) 00671 { 00672 switch (viennacl::traits::handle(vec).get_active_handle_id()) 00673 { 00674 case viennacl::MAIN_MEMORY: 00675 viennacl::linalg::host_based::norm_2_impl(vec, result); 00676 break; 00677 #ifdef VIENNACL_WITH_OPENCL 00678 case viennacl::OPENCL_MEMORY: 00679 viennacl::linalg::opencl::norm_2_cpu(vec, result); 00680 break; 00681 #endif 00682 #ifdef VIENNACL_WITH_CUDA 00683 case viennacl::CUDA_MEMORY: 00684 viennacl::linalg::cuda::norm_2_cpu(vec, result); 00685 break; 00686 #endif 00687 case viennacl::MEMORY_NOT_INITIALIZED: 00688 throw memory_exception("not initialised!"); 00689 default: 00690 throw memory_exception("not implemented"); 00691 } 00692 } 00693 00699 template <typename LHS, typename RHS, typename OP, typename S2> 00700 void norm_2_cpu(viennacl::vector_expression<LHS, RHS, OP> const & vec, 00701 S2 & result) 00702 { 00703 viennacl::vector<typename viennacl::result_of::cpu_value_type<LHS>::type> temp = vec; 00704 norm_2_cpu(temp, result); 00705 } 00706 00707 00708 00709 00715 template <typename T> 00716 void norm_inf_impl(vector_base<T> const & vec, 00717 scalar<T> & result) 00718 { 00719 switch (viennacl::traits::handle(vec).get_active_handle_id()) 00720 { 00721 case viennacl::MAIN_MEMORY: 00722 viennacl::linalg::host_based::norm_inf_impl(vec, result); 00723 break; 00724 #ifdef VIENNACL_WITH_OPENCL 00725 case viennacl::OPENCL_MEMORY: 00726 viennacl::linalg::opencl::norm_inf_impl(vec, result); 00727 break; 00728 #endif 00729 #ifdef VIENNACL_WITH_CUDA 00730 case viennacl::CUDA_MEMORY: 00731 viennacl::linalg::cuda::norm_inf_impl(vec, result); 00732 break; 00733 #endif 00734 case viennacl::MEMORY_NOT_INITIALIZED: 00735 throw memory_exception("not initialised!"); 00736 default: 00737 throw memory_exception("not implemented"); 00738 } 00739 } 00740 00746 template <typename LHS, typename RHS, typename OP, typename T> 00747 void norm_inf_impl(viennacl::vector_expression<LHS, RHS, OP> const & vec, 00748 scalar<T> & result) 00749 { 00750 viennacl::vector<T> temp = vec; 00751 norm_inf_impl(temp, result); 00752 } 00753 00754 00760 template <typename T> 00761 void norm_inf_cpu(vector_base<T> const & vec, 00762 T & result) 00763 { 00764 switch (viennacl::traits::handle(vec).get_active_handle_id()) 00765 { 00766 case viennacl::MAIN_MEMORY: 00767 viennacl::linalg::host_based::norm_inf_impl(vec, result); 00768 break; 00769 #ifdef VIENNACL_WITH_OPENCL 00770 case viennacl::OPENCL_MEMORY: 00771 viennacl::linalg::opencl::norm_inf_cpu(vec, result); 00772 break; 00773 #endif 00774 #ifdef VIENNACL_WITH_CUDA 00775 case viennacl::CUDA_MEMORY: 00776 viennacl::linalg::cuda::norm_inf_cpu(vec, result); 00777 break; 00778 #endif 00779 case viennacl::MEMORY_NOT_INITIALIZED: 00780 throw memory_exception("not initialised!"); 00781 default: 00782 throw memory_exception("not implemented"); 00783 } 00784 } 00785 00791 template <typename LHS, typename RHS, typename OP, typename S2> 00792 void norm_inf_cpu(viennacl::vector_expression<LHS, RHS, OP> const & vec, 00793 S2 & result) 00794 { 00795 viennacl::vector<typename viennacl::result_of::cpu_value_type<LHS>::type> temp = vec; 00796 norm_inf_cpu(temp, result); 00797 } 00798 00799 00800 //This function should return a CPU scalar, otherwise statements like 00801 // vcl_rhs[index_norm_inf(vcl_rhs)] 00802 // are ambiguous 00808 template <typename T> 00809 vcl_size_t index_norm_inf(vector_base<T> const & vec) 00810 { 00811 switch (viennacl::traits::handle(vec).get_active_handle_id()) 00812 { 00813 case viennacl::MAIN_MEMORY: 00814 return viennacl::linalg::host_based::index_norm_inf(vec); 00815 #ifdef VIENNACL_WITH_OPENCL 00816 case viennacl::OPENCL_MEMORY: 00817 return viennacl::linalg::opencl::index_norm_inf(vec); 00818 #endif 00819 #ifdef VIENNACL_WITH_CUDA 00820 case viennacl::CUDA_MEMORY: 00821 return viennacl::linalg::cuda::index_norm_inf(vec); 00822 #endif 00823 case viennacl::MEMORY_NOT_INITIALIZED: 00824 throw memory_exception("not initialised!"); 00825 default: 00826 throw memory_exception("not implemented"); 00827 } 00828 } 00829 00834 template <typename LHS, typename RHS, typename OP> 00835 vcl_size_t index_norm_inf(viennacl::vector_expression<LHS, RHS, OP> const & vec) 00836 { 00837 viennacl::vector<typename viennacl::result_of::cpu_value_type<LHS>::type> temp = vec; 00838 return index_norm_inf(temp); 00839 } 00840 00841 00851 template <typename T> 00852 void plane_rotation(vector_base<T> & vec1, 00853 vector_base<T> & vec2, 00854 T alpha, T beta) 00855 { 00856 switch (viennacl::traits::handle(vec1).get_active_handle_id()) 00857 { 00858 case viennacl::MAIN_MEMORY: 00859 viennacl::linalg::host_based::plane_rotation(vec1, vec2, alpha, beta); 00860 break; 00861 #ifdef VIENNACL_WITH_OPENCL 00862 case viennacl::OPENCL_MEMORY: 00863 viennacl::linalg::opencl::plane_rotation(vec1, vec2, alpha, beta); 00864 break; 00865 #endif 00866 #ifdef VIENNACL_WITH_CUDA 00867 case viennacl::CUDA_MEMORY: 00868 viennacl::linalg::cuda::plane_rotation(vec1, vec2, alpha, beta); 00869 break; 00870 #endif 00871 case viennacl::MEMORY_NOT_INITIALIZED: 00872 throw memory_exception("not initialised!"); 00873 default: 00874 throw memory_exception("not implemented"); 00875 } 00876 } 00877 00878 } //namespace linalg 00879 00880 template <typename T, typename LHS, typename RHS, typename OP> 00881 vector_base<T> & operator += (vector_base<T> & v1, const vector_expression<const LHS, const RHS, OP> & proxy) 00882 { 00883 assert( (viennacl::traits::size(proxy) == v1.size()) && bool("Incompatible vector sizes!")); 00884 assert( (v1.size() > 0) && bool("Vector not yet initialized!") ); 00885 00886 linalg::detail::op_executor<vector_base<T>, op_inplace_add, vector_expression<const LHS, const RHS, OP> >::apply(v1, proxy); 00887 00888 return v1; 00889 } 00890 00891 template <typename T, typename LHS, typename RHS, typename OP> 00892 vector_base<T> & operator -= (vector_base<T> & v1, const vector_expression<const LHS, const RHS, OP> & proxy) 00893 { 00894 assert( (viennacl::traits::size(proxy) == v1.size()) && bool("Incompatible vector sizes!")); 00895 assert( (v1.size() > 0) && bool("Vector not yet initialized!") ); 00896 00897 linalg::detail::op_executor<vector_base<T>, op_inplace_sub, vector_expression<const LHS, const RHS, OP> >::apply(v1, proxy); 00898 00899 return v1; 00900 } 00901 00902 } //namespace viennacl 00903 00904 00905 #endif