ViennaCL - The Vienna Computing Library
1.5.0
|
00001 #ifndef VIENNACL_LINALG_DIRECT_SOLVE_HPP_ 00002 #define VIENNACL_LINALG_DIRECT_SOLVE_HPP_ 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2013, 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/meta/enable_if.hpp" 00027 #include "viennacl/vector.hpp" 00028 #include "viennacl/matrix.hpp" 00029 #include "viennacl/linalg/host_based/direct_solve.hpp" 00030 00031 #ifdef VIENNACL_WITH_OPENCL 00032 #include "viennacl/linalg/opencl/direct_solve.hpp" 00033 #endif 00034 00035 #ifdef VIENNACL_WITH_CUDA 00036 #include "viennacl/linalg/cuda/direct_solve.hpp" 00037 #endif 00038 00039 namespace viennacl 00040 { 00041 namespace linalg 00042 { 00043 00044 // 00045 // A \ B: 00046 // 00047 00053 template <typename NumericT, typename F1, typename F2, typename SOLVERTAG> 00054 void inplace_solve(const matrix_base<NumericT, F1> & A, matrix_base<NumericT, F2> & B, SOLVERTAG) 00055 { 00056 assert( (viennacl::traits::size1(A) == viennacl::traits::size2(A)) && bool("Size check failed in inplace_solve(): size1(A) != size2(A)")); 00057 assert( (viennacl::traits::size1(A) == viennacl::traits::size1(B)) && bool("Size check failed in inplace_solve(): size1(A) != size1(B)")); 00058 00059 switch (viennacl::traits::handle(A).get_active_handle_id()) 00060 { 00061 case viennacl::MAIN_MEMORY: 00062 viennacl::linalg::host_based::inplace_solve(A, B, SOLVERTAG()); 00063 break; 00064 #ifdef VIENNACL_WITH_OPENCL 00065 case viennacl::OPENCL_MEMORY: 00066 viennacl::linalg::opencl::inplace_solve(A, B, SOLVERTAG()); 00067 break; 00068 #endif 00069 #ifdef VIENNACL_WITH_CUDA 00070 case viennacl::CUDA_MEMORY: 00071 viennacl::linalg::cuda::inplace_solve(A, B, SOLVERTAG()); 00072 break; 00073 #endif 00074 case viennacl::MEMORY_NOT_INITIALIZED: 00075 throw memory_exception("not initialised!"); 00076 default: 00077 throw memory_exception("not implemented"); 00078 } 00079 } 00080 00086 template <typename NumericT, typename F1, typename F2, typename SOLVERTAG> 00087 void inplace_solve(const matrix_base<NumericT, F1> & A, 00088 matrix_expression< const matrix_base<NumericT, F2>, const matrix_base<NumericT, F2>, op_trans> proxy_B, 00089 SOLVERTAG) 00090 { 00091 assert( (viennacl::traits::size1(A) == viennacl::traits::size2(A)) && bool("Size check failed in inplace_solve(): size1(A) != size2(A)")); 00092 assert( (viennacl::traits::size1(A) == viennacl::traits::size1(proxy_B)) && bool("Size check failed in inplace_solve(): size1(A) != size1(B^T)")); 00093 00094 switch (viennacl::traits::handle(A).get_active_handle_id()) 00095 { 00096 case viennacl::MAIN_MEMORY: 00097 viennacl::linalg::host_based::inplace_solve(A, proxy_B, SOLVERTAG()); 00098 break; 00099 #ifdef VIENNACL_WITH_OPENCL 00100 case viennacl::OPENCL_MEMORY: 00101 viennacl::linalg::opencl::inplace_solve(A, proxy_B, SOLVERTAG()); 00102 break; 00103 #endif 00104 #ifdef VIENNACL_WITH_CUDA 00105 case viennacl::CUDA_MEMORY: 00106 viennacl::linalg::cuda::inplace_solve(A, proxy_B, SOLVERTAG()); 00107 break; 00108 #endif 00109 case viennacl::MEMORY_NOT_INITIALIZED: 00110 throw memory_exception("not initialised!"); 00111 default: 00112 throw memory_exception("not implemented"); 00113 } 00114 } 00115 00116 //upper triangular solver for transposed lower triangular matrices 00122 template <typename NumericT, typename F1, typename F2, typename SOLVERTAG> 00123 void inplace_solve(const matrix_expression< const matrix_base<NumericT, F1>, const matrix_base<NumericT, F1>, op_trans> & proxy_A, 00124 matrix_base<NumericT, F2> & B, 00125 SOLVERTAG) 00126 { 00127 assert( (viennacl::traits::size1(proxy_A) == viennacl::traits::size2(proxy_A)) && bool("Size check failed in inplace_solve(): size1(A) != size2(A)")); 00128 assert( (viennacl::traits::size1(proxy_A) == viennacl::traits::size1(B)) && bool("Size check failed in inplace_solve(): size1(A^T) != size1(B)")); 00129 00130 switch (viennacl::traits::handle(proxy_A.lhs()).get_active_handle_id()) 00131 { 00132 case viennacl::MAIN_MEMORY: 00133 viennacl::linalg::host_based::inplace_solve(proxy_A, B, SOLVERTAG()); 00134 break; 00135 #ifdef VIENNACL_WITH_OPENCL 00136 case viennacl::OPENCL_MEMORY: 00137 viennacl::linalg::opencl::inplace_solve(proxy_A, B, SOLVERTAG()); 00138 break; 00139 #endif 00140 #ifdef VIENNACL_WITH_CUDA 00141 case viennacl::CUDA_MEMORY: 00142 viennacl::linalg::cuda::inplace_solve(proxy_A, B, SOLVERTAG()); 00143 break; 00144 #endif 00145 case viennacl::MEMORY_NOT_INITIALIZED: 00146 throw memory_exception("not initialised!"); 00147 default: 00148 throw memory_exception("not implemented"); 00149 } 00150 } 00151 00157 template <typename NumericT, typename F1, typename F2, typename SOLVERTAG> 00158 void inplace_solve(const matrix_expression< const matrix_base<NumericT, F1>, const matrix_base<NumericT, F1>, op_trans> & proxy_A, 00159 matrix_expression< const matrix_base<NumericT, F2>, const matrix_base<NumericT, F2>, op_trans> proxy_B, 00160 SOLVERTAG) 00161 { 00162 assert( (viennacl::traits::size1(proxy_A) == viennacl::traits::size2(proxy_A)) && bool("Size check failed in inplace_solve(): size1(A) != size2(A)")); 00163 assert( (viennacl::traits::size1(proxy_A) == viennacl::traits::size1(proxy_B)) && bool("Size check failed in inplace_solve(): size1(A^T) != size1(B^T)")); 00164 00165 switch (viennacl::traits::handle(proxy_A.lhs()).get_active_handle_id()) 00166 { 00167 case viennacl::MAIN_MEMORY: 00168 viennacl::linalg::host_based::inplace_solve(proxy_A, proxy_B, SOLVERTAG()); 00169 break; 00170 #ifdef VIENNACL_WITH_OPENCL 00171 case viennacl::OPENCL_MEMORY: 00172 viennacl::linalg::opencl::inplace_solve(proxy_A, proxy_B, SOLVERTAG()); 00173 break; 00174 #endif 00175 #ifdef VIENNACL_WITH_CUDA 00176 case viennacl::CUDA_MEMORY: 00177 viennacl::linalg::cuda::inplace_solve(proxy_A, proxy_B, SOLVERTAG()); 00178 break; 00179 #endif 00180 case viennacl::MEMORY_NOT_INITIALIZED: 00181 throw memory_exception("not initialised!"); 00182 default: 00183 throw memory_exception("not implemented"); 00184 } 00185 } 00186 00187 // 00188 // A \ b 00189 // 00190 00191 template <typename NumericT, typename F, typename SOLVERTAG> 00192 void inplace_solve(const matrix_base<NumericT, F> & mat, 00193 vector_base<NumericT> & vec, 00194 SOLVERTAG) 00195 { 00196 assert( (mat.size1() == vec.size()) && bool("Size check failed in inplace_solve(): size1(A) != size(b)")); 00197 assert( (mat.size2() == vec.size()) && bool("Size check failed in inplace_solve(): size2(A) != size(b)")); 00198 00199 switch (viennacl::traits::handle(mat).get_active_handle_id()) 00200 { 00201 case viennacl::MAIN_MEMORY: 00202 viennacl::linalg::host_based::inplace_solve(mat, vec, SOLVERTAG()); 00203 break; 00204 #ifdef VIENNACL_WITH_OPENCL 00205 case viennacl::OPENCL_MEMORY: 00206 viennacl::linalg::opencl::inplace_solve(mat, vec, SOLVERTAG()); 00207 break; 00208 #endif 00209 #ifdef VIENNACL_WITH_CUDA 00210 case viennacl::CUDA_MEMORY: 00211 viennacl::linalg::cuda::inplace_solve(mat, vec, SOLVERTAG()); 00212 break; 00213 #endif 00214 case viennacl::MEMORY_NOT_INITIALIZED: 00215 throw memory_exception("not initialised!"); 00216 default: 00217 throw memory_exception("not implemented"); 00218 } 00219 } 00220 00226 template <typename NumericT, typename F, typename SOLVERTAG> 00227 void inplace_solve(const matrix_expression< const matrix_base<NumericT, F>, const matrix_base<NumericT, F>, op_trans> & proxy, 00228 vector_base<NumericT> & vec, 00229 SOLVERTAG) 00230 { 00231 assert( (proxy.lhs().size1() == vec.size()) && bool("Size check failed in inplace_solve(): size1(A) != size(b)")); 00232 assert( (proxy.lhs().size2() == vec.size()) && bool("Size check failed in inplace_solve(): size2(A) != size(b)")); 00233 00234 switch (viennacl::traits::handle(proxy.lhs()).get_active_handle_id()) 00235 { 00236 case viennacl::MAIN_MEMORY: 00237 viennacl::linalg::host_based::inplace_solve(proxy, vec, SOLVERTAG()); 00238 break; 00239 #ifdef VIENNACL_WITH_OPENCL 00240 case viennacl::OPENCL_MEMORY: 00241 viennacl::linalg::opencl::inplace_solve(proxy, vec, SOLVERTAG()); 00242 break; 00243 #endif 00244 #ifdef VIENNACL_WITH_CUDA 00245 case viennacl::CUDA_MEMORY: 00246 viennacl::linalg::cuda::inplace_solve(proxy, vec, SOLVERTAG()); 00247 break; 00248 #endif 00249 case viennacl::MEMORY_NOT_INITIALIZED: 00250 throw memory_exception("not initialised!"); 00251 default: 00252 throw memory_exception("not implemented"); 00253 } 00254 } 00255 00257 00258 00265 template <typename NumericT, typename F1, typename F2, typename SOLVERTAG> 00266 matrix<NumericT, F2> solve(const matrix_base<NumericT, F1> & A, 00267 const matrix_base<NumericT, F2> & B, 00268 SOLVERTAG tag) 00269 { 00270 // do an inplace solve on the result vector: 00271 matrix<NumericT, F2> result(B); 00272 00273 inplace_solve(A, result, tag); 00274 00275 return result; 00276 } 00277 00278 00280 00287 template <typename NumericT, typename F1, typename F2, typename SOLVERTAG> 00288 matrix<NumericT, F2> solve(const matrix_base<NumericT, F1> & A, 00289 const matrix_expression< const matrix_base<NumericT, F2>, const matrix_base<NumericT, F2>, op_trans> & proxy, 00290 SOLVERTAG tag) 00291 { 00292 // do an inplace solve on the result vector: 00293 matrix<NumericT, F2> result(proxy); 00294 00295 inplace_solve(A, result, tag); 00296 00297 return result; 00298 } 00299 00306 template <typename NumericT, typename F1, typename SOLVERTAG> 00307 vector<NumericT> solve(const matrix_base<NumericT, F1> & mat, 00308 const vector_base<NumericT> & vec, 00309 SOLVERTAG const & tag) 00310 { 00311 // do an inplace solve on the result vector: 00312 vector<NumericT> result(vec); 00313 00314 inplace_solve(mat, result, tag); 00315 00316 return result; 00317 } 00318 00319 00321 00327 template <typename NumericT, typename F1, typename F2, typename SOLVERTAG> 00328 matrix<NumericT, F2> solve(const matrix_expression< const matrix_base<NumericT, F1>, const matrix_base<NumericT, F1>, op_trans> & proxy, 00329 const matrix_base<NumericT, F2> & B, 00330 SOLVERTAG tag) 00331 { 00332 // do an inplace solve on the result vector: 00333 matrix<NumericT, F2> result(B); 00334 00335 inplace_solve(proxy, result, tag); 00336 00337 return result; 00338 } 00339 00340 00347 template <typename NumericT, typename F1, typename F2, typename SOLVERTAG> 00348 matrix<NumericT, F2> solve(const matrix_expression< const matrix_base<NumericT, F1>, const matrix_base<NumericT, F1>, op_trans> & proxy_A, 00349 const matrix_expression< const matrix_base<NumericT, F2>, const matrix_base<NumericT, F2>, op_trans> & proxy_B, 00350 SOLVERTAG tag) 00351 { 00352 // do an inplace solve on the result vector: 00353 matrix<NumericT, F2> result(proxy_B); 00354 00355 inplace_solve(proxy_A, result, tag); 00356 00357 return result; 00358 } 00359 00366 template <typename NumericT, typename F1, typename SOLVERTAG> 00367 vector<NumericT> solve(const matrix_expression< const matrix_base<NumericT, F1>, const matrix_base<NumericT, F1>, op_trans> & proxy, 00368 const vector_base<NumericT> & vec, 00369 SOLVERTAG const & tag) 00370 { 00371 // do an inplace solve on the result vector: 00372 vector<NumericT> result(vec); 00373 00374 inplace_solve(proxy, result, tag); 00375 00376 return result; 00377 } 00378 00379 00380 } 00381 } 00382 00383 #endif