ViennaCL - The Vienna Computing Library
1.5.1
|
00001 #ifndef VIENNACL_LINALG_MATRIX_OPERATIONS_HPP_ 00002 #define VIENNACL_LINALG_MATRIX_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/vector.hpp" 00028 #include "viennacl/vector_proxy.hpp" 00029 #include "viennacl/tools/tools.hpp" 00030 #include "viennacl/meta/enable_if.hpp" 00031 #include "viennacl/meta/predicate.hpp" 00032 #include "viennacl/meta/result_of.hpp" 00033 #include "viennacl/traits/size.hpp" 00034 #include "viennacl/traits/start.hpp" 00035 #include "viennacl/traits/handle.hpp" 00036 #include "viennacl/traits/stride.hpp" 00037 #include "viennacl/vector.hpp" 00038 #include "viennacl/linalg/host_based/matrix_operations.hpp" 00039 00040 #ifdef VIENNACL_WITH_OPENCL 00041 #include "viennacl/linalg/opencl/matrix_operations.hpp" 00042 #endif 00043 00044 #ifdef VIENNACL_WITH_CUDA 00045 #include "viennacl/linalg/cuda/matrix_operations.hpp" 00046 #endif 00047 00048 namespace viennacl 00049 { 00050 namespace linalg 00051 { 00052 00053 template <typename NumericT, typename F, 00054 typename ScalarType1> 00055 void am(matrix_base<NumericT, F> & mat1, 00056 matrix_base<NumericT, F> const & mat2, ScalarType1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha) 00057 { 00058 switch (viennacl::traits::handle(mat1).get_active_handle_id()) 00059 { 00060 case viennacl::MAIN_MEMORY: 00061 viennacl::linalg::host_based::am(mat1, mat2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha); 00062 break; 00063 #ifdef VIENNACL_WITH_OPENCL 00064 case viennacl::OPENCL_MEMORY: 00065 viennacl::linalg::opencl::am(mat1, mat2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha); 00066 break; 00067 #endif 00068 #ifdef VIENNACL_WITH_CUDA 00069 case viennacl::CUDA_MEMORY: 00070 viennacl::linalg::cuda::am(mat1, mat2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha); 00071 break; 00072 #endif 00073 case viennacl::MEMORY_NOT_INITIALIZED: 00074 throw memory_exception("not initialised!"); 00075 default: 00076 throw memory_exception("not implemented"); 00077 } 00078 } 00079 00080 00081 template <typename NumericT, typename F, 00082 typename ScalarType1, typename ScalarType2> 00083 void ambm(matrix_base<NumericT, F> & mat1, 00084 matrix_base<NumericT, F> const & mat2, ScalarType1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, 00085 matrix_base<NumericT, F> const & mat3, ScalarType2 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta) 00086 { 00087 switch (viennacl::traits::handle(mat1).get_active_handle_id()) 00088 { 00089 case viennacl::MAIN_MEMORY: 00090 viennacl::linalg::host_based::ambm(mat1, 00091 mat2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00092 mat3, beta, len_beta, reciprocal_beta, flip_sign_beta); 00093 break; 00094 #ifdef VIENNACL_WITH_OPENCL 00095 case viennacl::OPENCL_MEMORY: 00096 viennacl::linalg::opencl::ambm(mat1, 00097 mat2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00098 mat3, beta, len_beta, reciprocal_beta, flip_sign_beta); 00099 break; 00100 #endif 00101 #ifdef VIENNACL_WITH_CUDA 00102 case viennacl::CUDA_MEMORY: 00103 viennacl::linalg::cuda::ambm(mat1, 00104 mat2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00105 mat3, beta, len_beta, reciprocal_beta, flip_sign_beta); 00106 break; 00107 #endif 00108 case viennacl::MEMORY_NOT_INITIALIZED: 00109 throw memory_exception("not initialised!"); 00110 default: 00111 throw memory_exception("not implemented"); 00112 } 00113 } 00114 00115 00116 template <typename NumericT, typename F, 00117 typename ScalarType1, typename ScalarType2> 00118 void ambm_m(matrix_base<NumericT, F> & mat1, 00119 matrix_base<NumericT, F> const & mat2, ScalarType1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, 00120 matrix_base<NumericT, F> const & mat3, ScalarType2 const & beta, vcl_size_t len_beta, bool reciprocal_beta, bool flip_sign_beta) 00121 { 00122 switch (viennacl::traits::handle(mat1).get_active_handle_id()) 00123 { 00124 case viennacl::MAIN_MEMORY: 00125 viennacl::linalg::host_based::ambm_m(mat1, 00126 mat2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00127 mat3, beta, len_beta, reciprocal_beta, flip_sign_beta); 00128 break; 00129 #ifdef VIENNACL_WITH_OPENCL 00130 case viennacl::OPENCL_MEMORY: 00131 viennacl::linalg::opencl::ambm_m(mat1, 00132 mat2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00133 mat3, 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::ambm_m(mat1, 00139 mat2, alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00140 mat3, 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 00151 template <typename NumericT, typename F> 00152 void matrix_assign(matrix_base<NumericT, F> & mat, NumericT s, bool clear = false) 00153 { 00154 switch (viennacl::traits::handle(mat).get_active_handle_id()) 00155 { 00156 case viennacl::MAIN_MEMORY: 00157 viennacl::linalg::host_based::matrix_assign(mat, s, clear); 00158 break; 00159 #ifdef VIENNACL_WITH_OPENCL 00160 case viennacl::OPENCL_MEMORY: 00161 viennacl::linalg::opencl::matrix_assign(mat, s, clear); 00162 break; 00163 #endif 00164 #ifdef VIENNACL_WITH_CUDA 00165 case viennacl::CUDA_MEMORY: 00166 viennacl::linalg::cuda::matrix_assign(mat, s, clear); 00167 break; 00168 #endif 00169 case viennacl::MEMORY_NOT_INITIALIZED: 00170 throw memory_exception("not initialised!"); 00171 default: 00172 throw memory_exception("not implemented"); 00173 } 00174 } 00175 00176 00177 template <typename NumericT, typename F> 00178 void matrix_diagonal_assign(matrix_base<NumericT, F> & mat, NumericT s) 00179 { 00180 switch (viennacl::traits::handle(mat).get_active_handle_id()) 00181 { 00182 case viennacl::MAIN_MEMORY: 00183 viennacl::linalg::host_based::matrix_diagonal_assign(mat, s); 00184 break; 00185 #ifdef VIENNACL_WITH_OPENCL 00186 case viennacl::OPENCL_MEMORY: 00187 viennacl::linalg::opencl::matrix_diagonal_assign(mat, s); 00188 break; 00189 #endif 00190 #ifdef VIENNACL_WITH_CUDA 00191 case viennacl::CUDA_MEMORY: 00192 viennacl::linalg::cuda::matrix_diagonal_assign(mat, s); 00193 break; 00194 #endif 00195 case viennacl::MEMORY_NOT_INITIALIZED: 00196 throw memory_exception("not initialised!"); 00197 default: 00198 throw memory_exception("not implemented"); 00199 } 00200 } 00201 00202 00204 template <typename NumericT, typename F> 00205 void matrix_diag_from_vector(const vector_base<NumericT> & v, int k, matrix_base<NumericT, F> & A) 00206 { 00207 switch (viennacl::traits::handle(v).get_active_handle_id()) 00208 { 00209 case viennacl::MAIN_MEMORY: 00210 viennacl::linalg::host_based::matrix_diag_from_vector(v, k, A); 00211 break; 00212 #ifdef VIENNACL_WITH_OPENCL 00213 case viennacl::OPENCL_MEMORY: 00214 viennacl::linalg::opencl::matrix_diag_from_vector(v, k, A); 00215 break; 00216 #endif 00217 #ifdef VIENNACL_WITH_CUDA 00218 case viennacl::CUDA_MEMORY: 00219 viennacl::linalg::cuda::matrix_diag_from_vector(v, k, A); 00220 break; 00221 #endif 00222 case viennacl::MEMORY_NOT_INITIALIZED: 00223 throw memory_exception("not initialised!"); 00224 default: 00225 throw memory_exception("not implemented"); 00226 } 00227 } 00228 00230 template <typename NumericT, typename F> 00231 void matrix_diag_to_vector(const matrix_base<NumericT, F> & A, int k, vector_base<NumericT> & v) 00232 { 00233 switch (viennacl::traits::handle(A).get_active_handle_id()) 00234 { 00235 case viennacl::MAIN_MEMORY: 00236 viennacl::linalg::host_based::matrix_diag_to_vector(A, k, v); 00237 break; 00238 #ifdef VIENNACL_WITH_OPENCL 00239 case viennacl::OPENCL_MEMORY: 00240 viennacl::linalg::opencl::matrix_diag_to_vector(A, k, v); 00241 break; 00242 #endif 00243 #ifdef VIENNACL_WITH_CUDA 00244 case viennacl::CUDA_MEMORY: 00245 viennacl::linalg::cuda::matrix_diag_to_vector(A, k, v); 00246 break; 00247 #endif 00248 case viennacl::MEMORY_NOT_INITIALIZED: 00249 throw memory_exception("not initialised!"); 00250 default: 00251 throw memory_exception("not implemented"); 00252 } 00253 } 00254 00255 template <typename NumericT, typename F> 00256 void matrix_row(const matrix_base<NumericT, F> & A, unsigned int i, vector_base<NumericT> & v) 00257 { 00258 switch (viennacl::traits::handle(A).get_active_handle_id()) 00259 { 00260 case viennacl::MAIN_MEMORY: 00261 viennacl::linalg::host_based::matrix_row(A, i, v); 00262 break; 00263 #ifdef VIENNACL_WITH_OPENCL 00264 case viennacl::OPENCL_MEMORY: 00265 viennacl::linalg::opencl::matrix_row(A, i, v); 00266 break; 00267 #endif 00268 #ifdef VIENNACL_WITH_CUDA 00269 case viennacl::CUDA_MEMORY: 00270 viennacl::linalg::cuda::matrix_row(A, i, v); 00271 break; 00272 #endif 00273 case viennacl::MEMORY_NOT_INITIALIZED: 00274 throw memory_exception("not initialised!"); 00275 default: 00276 throw memory_exception("not implemented"); 00277 } 00278 } 00279 00280 template <typename NumericT, typename F> 00281 void matrix_column(const matrix_base<NumericT, F> & A, unsigned int j, vector_base<NumericT> & v) 00282 { 00283 switch (viennacl::traits::handle(A).get_active_handle_id()) 00284 { 00285 case viennacl::MAIN_MEMORY: 00286 viennacl::linalg::host_based::matrix_column(A, j, v); 00287 break; 00288 #ifdef VIENNACL_WITH_OPENCL 00289 case viennacl::OPENCL_MEMORY: 00290 viennacl::linalg::opencl::matrix_column(A, j, v); 00291 break; 00292 #endif 00293 #ifdef VIENNACL_WITH_CUDA 00294 case viennacl::CUDA_MEMORY: 00295 viennacl::linalg::cuda::matrix_column(A, j, v); 00296 break; 00297 #endif 00298 case viennacl::MEMORY_NOT_INITIALIZED: 00299 throw memory_exception("not initialised!"); 00300 default: 00301 throw memory_exception("not implemented"); 00302 } 00303 } 00304 00310 template <typename T, typename F> 00311 void norm_frobenius_impl(matrix_base<T, F> const & A, 00312 scalar<T> & result) 00313 { 00314 typedef typename matrix_base<T, F>::handle_type HandleType; 00315 viennacl::vector_base<T> temp(const_cast<HandleType &>(A.handle()), A.internal_size(), 0, 1); 00316 norm_2_impl(temp, result); 00317 } 00318 00324 template <typename T, typename F> 00325 void norm_frobenius_cpu(matrix_base<T, F> const & A, 00326 T & result) 00327 { 00328 typedef typename matrix_base<T, F>::handle_type HandleType; 00329 viennacl::vector_base<T> temp(const_cast<HandleType &>(A.handle()), A.internal_size(), 0, 1); 00330 norm_2_cpu(temp, result); 00331 } 00332 00333 // 00335 // 00336 00337 00338 00339 // A * x 00340 00349 template <typename NumericT, typename F> 00350 void prod_impl(const matrix_base<NumericT, F> & mat, 00351 const vector_base<NumericT> & vec, 00352 vector_base<NumericT> & result) 00353 { 00354 assert( (viennacl::traits::size1(mat) == viennacl::traits::size(result)) && bool("Size check failed at v1 = prod(A, v2): size1(A) != size(v1)")); 00355 assert( (viennacl::traits::size2(mat) == viennacl::traits::size(vec)) && bool("Size check failed at v1 = prod(A, v2): size2(A) != size(v2)")); 00356 00357 switch (viennacl::traits::handle(mat).get_active_handle_id()) 00358 { 00359 case viennacl::MAIN_MEMORY: 00360 viennacl::linalg::host_based::prod_impl(mat, vec, result); 00361 break; 00362 #ifdef VIENNACL_WITH_OPENCL 00363 case viennacl::OPENCL_MEMORY: 00364 viennacl::linalg::opencl::prod_impl(mat, vec, result); 00365 break; 00366 #endif 00367 #ifdef VIENNACL_WITH_CUDA 00368 case viennacl::CUDA_MEMORY: 00369 viennacl::linalg::cuda::prod_impl(mat, vec, 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 00380 // trans(A) * x 00381 00390 template <typename NumericT, typename F> 00391 void prod_impl(const matrix_expression< const matrix_base<NumericT, F>, const matrix_base<NumericT, F>, op_trans> & mat_trans, 00392 const vector_base<NumericT> & vec, 00393 vector_base<NumericT> & result) 00394 { 00395 assert( (viennacl::traits::size1(mat_trans.lhs()) == viennacl::traits::size(vec)) && bool("Size check failed at v1 = trans(A) * v2: size1(A) != size(v2)")); 00396 assert( (viennacl::traits::size2(mat_trans.lhs()) == viennacl::traits::size(result)) && bool("Size check failed at v1 = trans(A) * v2: size2(A) != size(v1)")); 00397 00398 switch (viennacl::traits::handle(mat_trans.lhs()).get_active_handle_id()) 00399 { 00400 case viennacl::MAIN_MEMORY: 00401 viennacl::linalg::host_based::prod_impl(mat_trans, vec, result); 00402 break; 00403 #ifdef VIENNACL_WITH_OPENCL 00404 case viennacl::OPENCL_MEMORY: 00405 viennacl::linalg::opencl::prod_impl(mat_trans, vec, result); 00406 break; 00407 #endif 00408 #ifdef VIENNACL_WITH_CUDA 00409 case viennacl::CUDA_MEMORY: 00410 viennacl::linalg::cuda::prod_impl(mat_trans, vec, result); 00411 break; 00412 #endif 00413 case viennacl::MEMORY_NOT_INITIALIZED: 00414 throw memory_exception("not initialised!"); 00415 default: 00416 throw memory_exception("not implemented"); 00417 } 00418 } 00419 00420 00421 // 00423 // 00424 00430 template <typename NumericT, typename F1, typename F2, typename F3, typename ScalarType > 00431 void prod_impl(const matrix_base<NumericT, F1> & A, 00432 const matrix_base<NumericT, F2> & B, 00433 matrix_base<NumericT, F3> & C, 00434 ScalarType alpha, 00435 ScalarType beta) 00436 { 00437 assert( (viennacl::traits::size1(A) == viennacl::traits::size1(C)) && bool("Size check failed at C = prod(A, B): size1(A) != size1(C)")); 00438 assert( (viennacl::traits::size2(A) == viennacl::traits::size1(B)) && bool("Size check failed at C = prod(A, B): size2(A) != size1(B)")); 00439 assert( (viennacl::traits::size2(B) == viennacl::traits::size2(C)) && bool("Size check failed at C = prod(A, B): size2(B) != size2(C)")); 00440 00441 00442 switch (viennacl::traits::handle(A).get_active_handle_id()) 00443 { 00444 case viennacl::MAIN_MEMORY: 00445 viennacl::linalg::host_based::prod_impl(A, B, C, alpha, beta); 00446 break; 00447 #ifdef VIENNACL_WITH_OPENCL 00448 case viennacl::OPENCL_MEMORY: 00449 viennacl::linalg::opencl::prod_impl(A, B, C, alpha, beta); 00450 break; 00451 #endif 00452 #ifdef VIENNACL_WITH_CUDA 00453 case viennacl::CUDA_MEMORY: 00454 viennacl::linalg::cuda::prod_impl(A, B, C, alpha, beta); 00455 break; 00456 #endif 00457 case viennacl::MEMORY_NOT_INITIALIZED: 00458 throw memory_exception("not initialised!"); 00459 default: 00460 throw memory_exception("not implemented"); 00461 } 00462 } 00463 00464 00465 00471 template <typename NumericT, typename F1, typename F2, typename F3, typename ScalarType > 00472 void prod_impl(const viennacl::matrix_expression< const matrix_base<NumericT, F1>, 00473 const matrix_base<NumericT, F1>, 00474 op_trans> & A, 00475 const matrix_base<NumericT, F2> & B, 00476 matrix_base<NumericT, F3> & C, 00477 ScalarType alpha, 00478 ScalarType beta) 00479 { 00480 assert(viennacl::traits::size2(A.lhs()) == viennacl::traits::size1(C) && bool("Size check failed at C = prod(trans(A), B): size2(A) != size1(C)")); 00481 assert(viennacl::traits::size1(A.lhs()) == viennacl::traits::size1(B) && bool("Size check failed at C = prod(trans(A), B): size1(A) != size1(B)")); 00482 assert(viennacl::traits::size2(B) == viennacl::traits::size2(C) && bool("Size check failed at C = prod(trans(A), B): size2(B) != size2(C)")); 00483 00484 switch (viennacl::traits::handle(A.lhs()).get_active_handle_id()) 00485 { 00486 case viennacl::MAIN_MEMORY: 00487 viennacl::linalg::host_based::prod_impl(A, B, C, alpha, beta); 00488 break; 00489 #ifdef VIENNACL_WITH_OPENCL 00490 case viennacl::OPENCL_MEMORY: 00491 viennacl::linalg::opencl::prod_impl(A, B, C, alpha, beta); 00492 break; 00493 #endif 00494 #ifdef VIENNACL_WITH_CUDA 00495 case viennacl::CUDA_MEMORY: 00496 viennacl::linalg::cuda::prod_impl(A, B, C, alpha, beta); 00497 break; 00498 #endif 00499 case viennacl::MEMORY_NOT_INITIALIZED: 00500 throw memory_exception("not initialised!"); 00501 default: 00502 throw memory_exception("not implemented"); 00503 } 00504 } 00505 00506 00507 00508 00514 template <typename NumericT, typename F1, typename F2, typename F3, typename ScalarType > 00515 void prod_impl(const matrix_base<NumericT, F1> & A, 00516 const viennacl::matrix_expression< const matrix_base<NumericT, F2>, const matrix_base<NumericT, F2>, op_trans> & B, 00517 matrix_base<NumericT, F3> & C, 00518 ScalarType alpha, 00519 ScalarType beta) 00520 { 00521 assert(viennacl::traits::size1(A) == viennacl::traits::size1(C) && bool("Size check failed at C = prod(A, trans(B)): size1(A) != size1(C)")); 00522 assert(viennacl::traits::size2(A) == viennacl::traits::size2(B.lhs()) && bool("Size check failed at C = prod(A, trans(B)): size2(A) != size2(B)")); 00523 assert(viennacl::traits::size1(B.lhs()) == viennacl::traits::size2(C) && bool("Size check failed at C = prod(A, trans(B)): size1(B) != size2(C)")); 00524 00525 switch (viennacl::traits::handle(A).get_active_handle_id()) 00526 { 00527 case viennacl::MAIN_MEMORY: 00528 viennacl::linalg::host_based::prod_impl(A, B, C, alpha, beta); 00529 break; 00530 #ifdef VIENNACL_WITH_OPENCL 00531 case viennacl::OPENCL_MEMORY: 00532 viennacl::linalg::opencl::prod_impl(A, B, C, alpha, beta); 00533 break; 00534 #endif 00535 #ifdef VIENNACL_WITH_CUDA 00536 case viennacl::CUDA_MEMORY: 00537 viennacl::linalg::cuda::prod_impl(A, B, C, alpha, beta); 00538 break; 00539 #endif 00540 case viennacl::MEMORY_NOT_INITIALIZED: 00541 throw memory_exception("not initialised!"); 00542 default: 00543 throw memory_exception("not implemented"); 00544 } 00545 } 00546 00547 00548 00554 template <typename NumericT, typename F1, typename F2, typename F3, typename ScalarType > 00555 void prod_impl(const viennacl::matrix_expression< const matrix_base<NumericT, F1>, const matrix_base<NumericT, F1>, op_trans> & A, 00556 const viennacl::matrix_expression< const matrix_base<NumericT, F2>, const matrix_base<NumericT, F2>, op_trans> & B, 00557 matrix_base<NumericT, F3> & C, 00558 ScalarType alpha, 00559 ScalarType beta) 00560 { 00561 assert(viennacl::traits::size2(A.lhs()) == viennacl::traits::size1(C) && bool("Size check failed at C = prod(trans(A), trans(B)): size2(A) != size1(C)")); 00562 assert(viennacl::traits::size1(A.lhs()) == viennacl::traits::size2(B.lhs()) && bool("Size check failed at C = prod(trans(A), trans(B)): size1(A) != size2(B)")); 00563 assert(viennacl::traits::size1(B.lhs()) == viennacl::traits::size2(C) && bool("Size check failed at C = prod(trans(A), trans(B)): size1(B) != size2(C)")); 00564 00565 switch (viennacl::traits::handle(A.lhs()).get_active_handle_id()) 00566 { 00567 case viennacl::MAIN_MEMORY: 00568 viennacl::linalg::host_based::prod_impl(A, B, C, alpha, beta); 00569 break; 00570 #ifdef VIENNACL_WITH_OPENCL 00571 case viennacl::OPENCL_MEMORY: 00572 viennacl::linalg::opencl::prod_impl(A, B, C, alpha, beta); 00573 break; 00574 #endif 00575 #ifdef VIENNACL_WITH_CUDA 00576 case viennacl::CUDA_MEMORY: 00577 viennacl::linalg::cuda::prod_impl(A, B, C, alpha, beta); 00578 break; 00579 #endif 00580 case viennacl::MEMORY_NOT_INITIALIZED: 00581 throw memory_exception("not initialised!"); 00582 default: 00583 throw memory_exception("not implemented"); 00584 } 00585 } 00586 00587 00589 00590 00591 00597 template <typename T, typename F, typename OP> 00598 void element_op(matrix_base<T, F> & A, 00599 matrix_expression<const matrix_base<T, F>, const matrix_base<T, F>, OP> const & proxy) 00600 { 00601 assert( (viennacl::traits::size1(A) == viennacl::traits::size1(proxy)) && bool("Size check failed at A = element_op(B): size1(A) != size1(B)")); 00602 assert( (viennacl::traits::size2(A) == viennacl::traits::size2(proxy)) && bool("Size check failed at A = element_op(B): size2(A) != size2(B)")); 00603 00604 switch (viennacl::traits::handle(A).get_active_handle_id()) 00605 { 00606 case viennacl::MAIN_MEMORY: 00607 viennacl::linalg::host_based::element_op(A, proxy); 00608 break; 00609 #ifdef VIENNACL_WITH_OPENCL 00610 case viennacl::OPENCL_MEMORY: 00611 viennacl::linalg::opencl::element_op(A, proxy); 00612 break; 00613 #endif 00614 #ifdef VIENNACL_WITH_CUDA 00615 case viennacl::CUDA_MEMORY: 00616 viennacl::linalg::cuda::element_op(A, proxy); 00617 break; 00618 #endif 00619 case viennacl::MEMORY_NOT_INITIALIZED: 00620 throw memory_exception("not initialised!"); 00621 default: 00622 throw memory_exception("not implemented"); 00623 } 00624 } 00625 00626 00627 #define VIENNACL_MAKE_BINARY_OP(OPNAME)\ 00628 template <typename T, typename F>\ 00629 viennacl::matrix_expression<const matrix_base<T, F>, const matrix_base<T, F>, op_element_binary<op_##OPNAME> >\ 00630 element_##OPNAME(matrix_base<T, F> const & A, matrix_base<T, F> const & B)\ 00631 {\ 00632 return viennacl::matrix_expression<const matrix_base<T, F>, const matrix_base<T, F>, op_element_binary<op_##OPNAME> >(A, B);\ 00633 }\ 00634 \ 00635 template <typename M1, typename M2, typename OP, typename T, typename F>\ 00636 viennacl::matrix_expression<const matrix_expression<const M1, const M2, OP>,\ 00637 const matrix_base<T, F>,\ 00638 op_element_binary<op_##OPNAME> >\ 00639 element_##OPNAME(matrix_expression<const M1, const M2, OP> const & proxy, matrix_base<T, F> const & B)\ 00640 {\ 00641 return viennacl::matrix_expression<const matrix_expression<const M1, const M2, OP>,\ 00642 const matrix_base<T, F>,\ 00643 op_element_binary<op_##OPNAME> >(proxy, B);\ 00644 }\ 00645 \ 00646 template <typename T, typename F, typename M2, typename M3, typename OP>\ 00647 viennacl::matrix_expression<const matrix_base<T, F>,\ 00648 const matrix_expression<const M2, const M3, OP>,\ 00649 op_element_binary<op_##OPNAME> >\ 00650 element_##OPNAME(matrix_base<T, F> const & A, matrix_expression<const M2, const M3, OP> const & proxy)\ 00651 {\ 00652 return viennacl::matrix_expression<const matrix_base<T, F>,\ 00653 const matrix_expression<const M2, const M3, OP>,\ 00654 op_element_binary<op_##OPNAME> >(A, proxy);\ 00655 }\ 00656 \ 00657 template <typename M1, typename M2, typename OP1,\ 00658 typename M3, typename M4, typename OP2>\ 00659 viennacl::matrix_expression<const matrix_expression<const M1, const M2, OP1>,\ 00660 const matrix_expression<const M3, const M4, OP2>,\ 00661 op_element_binary<op_##OPNAME> >\ 00662 element_##OPNAME(matrix_expression<const M1, const M2, OP1> const & proxy1,\ 00663 matrix_expression<const M3, const M4, OP2> const & proxy2)\ 00664 {\ 00665 return viennacl::matrix_expression<const matrix_expression<const M1, const M2, OP1>,\ 00666 const matrix_expression<const M3, const M4, OP2>,\ 00667 op_element_binary<op_##OPNAME> >(proxy1, proxy2);\ 00668 } 00669 00670 VIENNACL_MAKE_BINARY_OP(prod) 00671 VIENNACL_MAKE_BINARY_OP(div) 00672 VIENNACL_MAKE_BINARY_OP(pow) 00673 00674 #undef VIENNACL_GENERATE_BINARY_OP_OVERLOADS 00675 00676 00677 00678 #define VIENNACL_MAKE_UNARY_ELEMENT_OP(funcname) \ 00679 template <typename T, typename F> \ 00680 viennacl::matrix_expression<const matrix_base<T, F>, const matrix_base<T, F>, op_element_unary<op_##funcname> > \ 00681 element_##funcname(matrix_base<T, F> const & A) \ 00682 { \ 00683 return viennacl::matrix_expression<const matrix_base<T, F>, const matrix_base<T, F>, op_element_unary<op_##funcname> >(A, A); \ 00684 } \ 00685 template <typename LHS, typename RHS, typename OP> \ 00686 viennacl::matrix_expression<const matrix_expression<const LHS, const RHS, OP>, \ 00687 const matrix_expression<const LHS, const RHS, OP>, \ 00688 op_element_unary<op_##funcname> > \ 00689 element_##funcname(matrix_expression<const LHS, const RHS, OP> const & proxy) \ 00690 { \ 00691 return viennacl::matrix_expression<const matrix_expression<const LHS, const RHS, OP>, \ 00692 const matrix_expression<const LHS, const RHS, OP>, \ 00693 op_element_unary<op_##funcname> >(proxy, proxy); \ 00694 } \ 00695 00696 VIENNACL_MAKE_UNARY_ELEMENT_OP(abs) 00697 VIENNACL_MAKE_UNARY_ELEMENT_OP(acos) 00698 VIENNACL_MAKE_UNARY_ELEMENT_OP(asin) 00699 VIENNACL_MAKE_UNARY_ELEMENT_OP(atan) 00700 VIENNACL_MAKE_UNARY_ELEMENT_OP(ceil) 00701 VIENNACL_MAKE_UNARY_ELEMENT_OP(cos) 00702 VIENNACL_MAKE_UNARY_ELEMENT_OP(cosh) 00703 VIENNACL_MAKE_UNARY_ELEMENT_OP(exp) 00704 VIENNACL_MAKE_UNARY_ELEMENT_OP(fabs) 00705 VIENNACL_MAKE_UNARY_ELEMENT_OP(floor) 00706 VIENNACL_MAKE_UNARY_ELEMENT_OP(log) 00707 VIENNACL_MAKE_UNARY_ELEMENT_OP(log10) 00708 VIENNACL_MAKE_UNARY_ELEMENT_OP(sin) 00709 VIENNACL_MAKE_UNARY_ELEMENT_OP(sinh) 00710 VIENNACL_MAKE_UNARY_ELEMENT_OP(sqrt) 00711 VIENNACL_MAKE_UNARY_ELEMENT_OP(tan) 00712 VIENNACL_MAKE_UNARY_ELEMENT_OP(tanh) 00713 00714 #undef VIENNACL_MAKE_UNARY_ELEMENT_OP 00715 00716 00717 // 00719 // 00720 00721 00727 template <typename NumericT> 00728 viennacl::matrix_expression<const vector_base<NumericT>, const vector_base<NumericT>, op_prod> 00729 outer_prod(const vector_base<NumericT> & vec1, const vector_base<NumericT> & vec2) 00730 { 00731 return viennacl::matrix_expression< const vector_base<NumericT>, const vector_base<NumericT>, op_prod>(vec1, vec2); 00732 } 00733 00734 00747 template <typename NumericT, typename F, typename S1> 00748 void scaled_rank_1_update(matrix_base<NumericT, F> & mat1, 00749 S1 const & alpha, vcl_size_t len_alpha, bool reciprocal_alpha, bool flip_sign_alpha, 00750 const vector_base<NumericT> & vec1, 00751 const vector_base<NumericT> & vec2) 00752 { 00753 switch (viennacl::traits::handle(mat1).get_active_handle_id()) 00754 { 00755 case viennacl::MAIN_MEMORY: 00756 viennacl::linalg::host_based::scaled_rank_1_update(mat1, 00757 alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00758 vec1, vec2); 00759 break; 00760 #ifdef VIENNACL_WITH_OPENCL 00761 case viennacl::OPENCL_MEMORY: 00762 viennacl::linalg::opencl::scaled_rank_1_update(mat1, 00763 alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00764 vec1, vec2); 00765 break; 00766 #endif 00767 #ifdef VIENNACL_WITH_CUDA 00768 case viennacl::CUDA_MEMORY: 00769 viennacl::linalg::cuda::scaled_rank_1_update(mat1, 00770 alpha, len_alpha, reciprocal_alpha, flip_sign_alpha, 00771 vec1, vec2); 00772 break; 00773 #endif 00774 case viennacl::MEMORY_NOT_INITIALIZED: 00775 throw memory_exception("not initialised!"); 00776 default: 00777 throw memory_exception("not implemented"); 00778 } 00779 } 00780 00781 } //namespace linalg 00782 00783 00784 00785 00786 // 00788 // 00789 00790 00791 //v += A * x 00797 template <typename NumericT, typename F> 00798 vector<NumericT> 00799 operator+=(vector_base<NumericT> & v1, 00800 const viennacl::vector_expression< const matrix_base<NumericT, F>, const vector_base<NumericT>, viennacl::op_prod> & proxy) 00801 { 00802 assert(viennacl::traits::size1(proxy.lhs()) == v1.size() && bool("Size check failed for v1 += A * v2: size1(A) != size(v1)")); 00803 00804 vector<NumericT> result(viennacl::traits::size1(proxy.lhs())); 00805 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result); 00806 v1 += result; 00807 return v1; 00808 } 00809 00815 template <typename NumericT, typename F> 00816 vector<NumericT> 00817 operator-=(vector_base<NumericT> & v1, 00818 const viennacl::vector_expression< const matrix_base<NumericT, F>, const vector_base<NumericT>, viennacl::op_prod> & proxy) 00819 { 00820 assert(viennacl::traits::size1(proxy.lhs()) == v1.size() && bool("Size check failed for v1 -= A * v2: size1(A) != size(v1)")); 00821 00822 vector<NumericT> result(viennacl::traits::size1(proxy.lhs())); 00823 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result); 00824 v1 -= result; 00825 return v1; 00826 } 00827 00828 00829 00830 00831 00832 //free functions: 00838 template <typename NumericT, typename F> 00839 viennacl::vector<NumericT> 00840 operator+(const vector_base<NumericT> & v1, 00841 const vector_expression< const matrix_base<NumericT, F>, const vector_base<NumericT>, op_prod> & proxy) 00842 { 00843 assert(viennacl::traits::size1(proxy.lhs()) == viennacl::traits::size(v1) && bool("Size check failed for v1 + A * v2: size1(A) != size(v1)")); 00844 00845 vector<NumericT> result(viennacl::traits::size(v1)); 00846 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result); 00847 result += v1; 00848 return result; 00849 } 00850 00856 template <typename NumericT, typename F> 00857 viennacl::vector<NumericT> 00858 operator-(const vector_base<NumericT> & v1, 00859 const vector_expression< const matrix_base<NumericT, F>, const vector_base<NumericT>, op_prod> & proxy) 00860 { 00861 assert(viennacl::traits::size1(proxy.lhs()) == viennacl::traits::size(v1) && bool("Size check failed for v1 - A * v2: size1(A) != size(v1)")); 00862 00863 vector<NumericT> result(viennacl::traits::size(v1)); 00864 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result); 00865 result = v1 - result; 00866 return result; 00867 } 00868 00869 00871 00872 00873 //v += A^T * x 00879 template <typename NumericT, typename F> 00880 vector<NumericT> 00881 operator+=(vector_base<NumericT> & v1, 00882 const vector_expression< const matrix_expression<const matrix_base<NumericT, F>, const matrix_base<NumericT, F>, op_trans>, 00883 const vector_base<NumericT>, 00884 op_prod> & proxy) 00885 { 00886 assert(viennacl::traits::size2(proxy.lhs()) == v1.size() && bool("Size check failed in v1 += trans(A) * v2: size2(A) != size(v1)")); 00887 00888 vector<NumericT> result(viennacl::traits::size2(proxy.lhs())); 00889 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result); 00890 v1 += result; 00891 return v1; 00892 } 00893 00894 //v -= A^T * x 00900 template <typename NumericT, typename F> 00901 vector<NumericT> 00902 operator-=(vector_base<NumericT> & v1, 00903 const vector_expression< const matrix_expression<const matrix_base<NumericT, F>, const matrix_base<NumericT, F>, op_trans>, 00904 const vector_base<NumericT>, 00905 op_prod> & proxy) 00906 { 00907 assert(viennacl::traits::size2(proxy.lhs()) == v1.size() && bool("Size check failed in v1 += trans(A) * v2: size2(A) != size(v1)")); 00908 00909 vector<NumericT> result(viennacl::traits::size2(proxy.lhs())); 00910 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result); 00911 v1 -= result; 00912 return v1; 00913 } 00914 00915 00916 //free functions: 00922 template <typename NumericT, typename F> 00923 vector<NumericT> 00924 operator+(const vector_base<NumericT> & v1, 00925 const vector_expression< const matrix_expression<const matrix_base<NumericT, F>, const matrix_base<NumericT, F>, op_trans>, 00926 const vector_base<NumericT>, 00927 op_prod> & proxy) 00928 { 00929 assert(viennacl::traits::size2(proxy.lhs()) == viennacl::traits::size(v1) && bool("Size check failed in v1 + trans(A) * v2: size2(A) != size(v1)")); 00930 00931 vector<NumericT> result(viennacl::traits::size(v1)); 00932 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result); 00933 result += v1; 00934 return result; 00935 } 00936 00942 template <typename NumericT, typename F> 00943 vector<NumericT> 00944 operator-(const vector_base<NumericT> & v1, 00945 const vector_expression< const matrix_expression<const matrix_base<NumericT, F>, const matrix_base<NumericT, F>, op_trans>, 00946 const vector_base<NumericT>, 00947 op_prod> & proxy) 00948 { 00949 assert(viennacl::traits::size2(proxy.lhs()) == viennacl::traits::size(v1) && bool("Size check failed in v1 - trans(A) * v2: size2(A) != size(v1)")); 00950 00951 vector<NumericT> result(viennacl::traits::size(v1)); 00952 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result); 00953 result = v1 - result; 00954 return result; 00955 } 00956 00957 00958 } //namespace viennacl 00959 00960 00961 #endif