ViennaCL - The Vienna Computing Library
1.5.1
|
00001 #ifndef VIENNACL_LINALG_SPARSE_MATRIX_OPERATIONS_HPP_ 00002 #define VIENNACL_LINALG_SPARSE_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/matrix.hpp" 00029 #include "viennacl/tools/tools.hpp" 00030 #include "viennacl/linalg/host_based/sparse_matrix_operations.hpp" 00031 00032 #ifdef VIENNACL_WITH_OPENCL 00033 #include "viennacl/linalg/opencl/sparse_matrix_operations.hpp" 00034 #endif 00035 00036 #ifdef VIENNACL_WITH_CUDA 00037 #include "viennacl/linalg/cuda/sparse_matrix_operations.hpp" 00038 #endif 00039 00040 namespace viennacl 00041 { 00042 namespace linalg 00043 { 00044 00045 namespace detail 00046 { 00047 00048 template<typename SparseMatrixType, typename SCALARTYPE, unsigned int VEC_ALIGNMENT> 00049 typename viennacl::enable_if< viennacl::is_any_sparse_matrix<SparseMatrixType>::value >::type 00050 row_info(SparseMatrixType const & mat, 00051 vector<SCALARTYPE, VEC_ALIGNMENT> & vec, 00052 row_info_types info_selector) 00053 { 00054 switch (viennacl::traits::handle(mat).get_active_handle_id()) 00055 { 00056 case viennacl::MAIN_MEMORY: 00057 viennacl::linalg::host_based::detail::row_info(mat, vec, info_selector); 00058 break; 00059 #ifdef VIENNACL_WITH_OPENCL 00060 case viennacl::OPENCL_MEMORY: 00061 viennacl::linalg::opencl::detail::row_info(mat, vec, info_selector); 00062 break; 00063 #endif 00064 #ifdef VIENNACL_WITH_CUDA 00065 case viennacl::CUDA_MEMORY: 00066 viennacl::linalg::cuda::detail::row_info(mat, vec, info_selector); 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 00078 00079 00080 // A * x 00081 00090 template<typename SparseMatrixType, class ScalarType> 00091 typename viennacl::enable_if< viennacl::is_any_sparse_matrix<SparseMatrixType>::value>::type 00092 prod_impl(const SparseMatrixType & mat, 00093 const viennacl::vector_base<ScalarType> & vec, 00094 viennacl::vector_base<ScalarType> & result) 00095 { 00096 assert( (mat.size1() == result.size()) && bool("Size check failed for compressed matrix-vector product: size1(mat) != size(result)")); 00097 assert( (mat.size2() == vec.size()) && bool("Size check failed for compressed matrix-vector product: size2(mat) != size(x)")); 00098 00099 switch (viennacl::traits::handle(mat).get_active_handle_id()) 00100 { 00101 case viennacl::MAIN_MEMORY: 00102 viennacl::linalg::host_based::prod_impl(mat, vec, result); 00103 break; 00104 #ifdef VIENNACL_WITH_OPENCL 00105 case viennacl::OPENCL_MEMORY: 00106 viennacl::linalg::opencl::prod_impl(mat, vec, result); 00107 break; 00108 #endif 00109 #ifdef VIENNACL_WITH_CUDA 00110 case viennacl::CUDA_MEMORY: 00111 viennacl::linalg::cuda::prod_impl(mat, vec, result); 00112 break; 00113 #endif 00114 case viennacl::MEMORY_NOT_INITIALIZED: 00115 throw memory_exception("not initialised!"); 00116 default: 00117 throw memory_exception("not implemented"); 00118 } 00119 } 00120 00121 00122 // A * B 00131 template<typename SparseMatrixType, class ScalarType, typename F1, typename F2> 00132 typename viennacl::enable_if< viennacl::is_any_sparse_matrix<SparseMatrixType>::value>::type 00133 prod_impl(const SparseMatrixType & sp_mat, 00134 const viennacl::matrix_base<ScalarType, F1> & d_mat, 00135 viennacl::matrix_base<ScalarType, F2> & result) 00136 { 00137 assert( (sp_mat.size1() == result.size1()) && bool("Size check failed for compressed matrix - dense matrix product: size1(sp_mat) != size1(result)")); 00138 assert( (sp_mat.size2() == d_mat.size1()) && bool("Size check failed for compressed matrix - dense matrix product: size2(sp_mat) != size1(d_mat)")); 00139 00140 switch (viennacl::traits::handle(sp_mat).get_active_handle_id()) 00141 { 00142 case viennacl::MAIN_MEMORY: 00143 viennacl::linalg::host_based::prod_impl(sp_mat, d_mat, result); 00144 break; 00145 #ifdef VIENNACL_WITH_OPENCL 00146 case viennacl::OPENCL_MEMORY: 00147 viennacl::linalg::opencl::prod_impl(sp_mat, d_mat, result); 00148 break; 00149 #endif 00150 #ifdef VIENNACL_WITH_CUDA 00151 case viennacl::CUDA_MEMORY: 00152 viennacl::linalg::cuda::prod_impl(sp_mat, d_mat, result); 00153 break; 00154 #endif 00155 case viennacl::MEMORY_NOT_INITIALIZED: 00156 throw memory_exception("not initialised!"); 00157 default: 00158 throw memory_exception("not implemented"); 00159 } 00160 } 00161 00162 // A * transpose(B) 00171 template<typename SparseMatrixType, class ScalarType, typename F1, typename F2> 00172 typename viennacl::enable_if< viennacl::is_any_sparse_matrix<SparseMatrixType>::value>::type 00173 prod_impl(const SparseMatrixType & sp_mat, 00174 const viennacl::matrix_expression<const viennacl::matrix_base<ScalarType, F1>, 00175 const viennacl::matrix_base<ScalarType, F1>, 00176 viennacl::op_trans>& d_mat, 00177 viennacl::matrix_base<ScalarType, F2> & result) 00178 { 00179 assert( (sp_mat.size1() == result.size1()) && bool("Size check failed for compressed matrix - dense matrix product: size1(sp_mat) != size1(result)")); 00180 assert( (sp_mat.size2() == d_mat.size1()) && bool("Size check failed for compressed matrix - dense matrix product: size2(sp_mat) != size1(d_mat)")); 00181 00182 switch (viennacl::traits::handle(sp_mat).get_active_handle_id()) 00183 { 00184 case viennacl::MAIN_MEMORY: 00185 viennacl::linalg::host_based::prod_impl(sp_mat, d_mat, result); 00186 break; 00187 #ifdef VIENNACL_WITH_OPENCL 00188 case viennacl::OPENCL_MEMORY: 00189 viennacl::linalg::opencl::prod_impl(sp_mat, d_mat, result); 00190 break; 00191 #endif 00192 #ifdef VIENNACL_WITH_CUDA 00193 case viennacl::CUDA_MEMORY: 00194 viennacl::linalg::cuda::prod_impl(sp_mat, d_mat, result); 00195 break; 00196 #endif 00197 case viennacl::MEMORY_NOT_INITIALIZED: 00198 throw memory_exception("not initialised!"); 00199 default: 00200 throw memory_exception("not implemented"); 00201 } 00202 } 00203 00210 template<typename SparseMatrixType, class ScalarType, typename SOLVERTAG> 00211 typename viennacl::enable_if< viennacl::is_any_sparse_matrix<SparseMatrixType>::value>::type 00212 inplace_solve(const SparseMatrixType & mat, 00213 viennacl::vector_base<ScalarType> & vec, 00214 SOLVERTAG tag) 00215 { 00216 assert( (mat.size1() == mat.size2()) && bool("Size check failed for triangular solve on compressed matrix: size1(mat) != size2(mat)")); 00217 assert( (mat.size2() == vec.size()) && bool("Size check failed for compressed matrix-vector product: size2(mat) != size(x)")); 00218 00219 switch (viennacl::traits::handle(mat).get_active_handle_id()) 00220 { 00221 case viennacl::MAIN_MEMORY: 00222 viennacl::linalg::host_based::inplace_solve(mat, vec, tag); 00223 break; 00224 #ifdef VIENNACL_WITH_OPENCL 00225 case viennacl::OPENCL_MEMORY: 00226 viennacl::linalg::opencl::inplace_solve(mat, vec, tag); 00227 break; 00228 #endif 00229 #ifdef VIENNACL_WITH_CUDA 00230 case viennacl::CUDA_MEMORY: 00231 viennacl::linalg::cuda::inplace_solve(mat, vec, tag); 00232 break; 00233 #endif 00234 case viennacl::MEMORY_NOT_INITIALIZED: 00235 throw memory_exception("not initialised!"); 00236 default: 00237 throw memory_exception("not implemented"); 00238 } 00239 } 00240 00241 00248 template<typename SparseMatrixType, class ScalarType, typename SOLVERTAG> 00249 typename viennacl::enable_if< viennacl::is_any_sparse_matrix<SparseMatrixType>::value>::type 00250 inplace_solve(const matrix_expression<const SparseMatrixType, const SparseMatrixType, op_trans> & mat, 00251 viennacl::vector_base<ScalarType> & vec, 00252 SOLVERTAG tag) 00253 { 00254 assert( (mat.size1() == mat.size2()) && bool("Size check failed for triangular solve on transposed compressed matrix: size1(mat) != size2(mat)")); 00255 assert( (mat.size1() == vec.size()) && bool("Size check failed for transposed compressed matrix triangular solve: size1(mat) != size(x)")); 00256 00257 switch (viennacl::traits::handle(mat.lhs()).get_active_handle_id()) 00258 { 00259 case viennacl::MAIN_MEMORY: 00260 viennacl::linalg::host_based::inplace_solve(mat, vec, tag); 00261 break; 00262 #ifdef VIENNACL_WITH_OPENCL 00263 case viennacl::OPENCL_MEMORY: 00264 viennacl::linalg::opencl::inplace_solve(mat, vec, tag); 00265 break; 00266 #endif 00267 #ifdef VIENNACL_WITH_CUDA 00268 case viennacl::CUDA_MEMORY: 00269 viennacl::linalg::cuda::inplace_solve(mat, vec, tag); 00270 break; 00271 #endif 00272 case viennacl::MEMORY_NOT_INITIALIZED: 00273 throw memory_exception("not initialised!"); 00274 default: 00275 throw memory_exception("not implemented"); 00276 } 00277 } 00278 00279 00280 00281 namespace detail 00282 { 00283 00284 template<typename SparseMatrixType, class ScalarType, typename SOLVERTAG> 00285 typename viennacl::enable_if< viennacl::is_any_sparse_matrix<SparseMatrixType>::value>::type 00286 block_inplace_solve(const matrix_expression<const SparseMatrixType, const SparseMatrixType, op_trans> & mat, 00287 viennacl::backend::mem_handle const & block_index_array, vcl_size_t num_blocks, 00288 viennacl::vector_base<ScalarType> const & mat_diagonal, 00289 viennacl::vector_base<ScalarType> & vec, 00290 SOLVERTAG tag) 00291 { 00292 assert( (mat.size1() == mat.size2()) && bool("Size check failed for triangular solve on transposed compressed matrix: size1(mat) != size2(mat)")); 00293 assert( (mat.size1() == vec.size()) && bool("Size check failed for transposed compressed matrix triangular solve: size1(mat) != size(x)")); 00294 00295 switch (viennacl::traits::handle(mat.lhs()).get_active_handle_id()) 00296 { 00297 case viennacl::MAIN_MEMORY: 00298 viennacl::linalg::host_based::detail::block_inplace_solve(mat, block_index_array, num_blocks, mat_diagonal, vec, tag); 00299 break; 00300 #ifdef VIENNACL_WITH_OPENCL 00301 case viennacl::OPENCL_MEMORY: 00302 viennacl::linalg::opencl::detail::block_inplace_solve(mat, block_index_array, num_blocks, mat_diagonal, vec, tag); 00303 break; 00304 #endif 00305 #ifdef VIENNACL_WITH_CUDA 00306 case viennacl::CUDA_MEMORY: 00307 viennacl::linalg::cuda::detail::block_inplace_solve(mat, block_index_array, num_blocks, mat_diagonal, vec, tag); 00308 break; 00309 #endif 00310 case viennacl::MEMORY_NOT_INITIALIZED: 00311 throw memory_exception("not initialised!"); 00312 default: 00313 throw memory_exception("not implemented"); 00314 } 00315 } 00316 00317 00318 } 00319 00320 00321 00322 } //namespace linalg 00323 00324 00326 template<typename M1> 00327 typename viennacl::enable_if<viennacl::is_any_sparse_matrix<M1>::value, 00328 matrix_expression< const M1, const M1, op_trans> 00329 >::type 00330 trans(const M1 & mat) 00331 { 00332 return matrix_expression< const M1, const M1, op_trans>(mat, mat); 00333 } 00334 00335 //free functions: 00341 template <typename SCALARTYPE, typename SparseMatrixType> 00342 typename viennacl::enable_if< viennacl::is_any_sparse_matrix<SparseMatrixType>::value, 00343 viennacl::vector<SCALARTYPE> >::type 00344 operator+(viennacl::vector_base<SCALARTYPE> & result, 00345 const viennacl::vector_expression< const SparseMatrixType, const viennacl::vector_base<SCALARTYPE>, viennacl::op_prod> & proxy) 00346 { 00347 assert(proxy.lhs().size1() == result.size() && bool("Dimensions for addition of sparse matrix-vector product to vector don't match!")); 00348 vector<SCALARTYPE> temp(proxy.lhs().size1()); 00349 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), temp); 00350 result += temp; 00351 return result; 00352 } 00353 00359 template <typename SCALARTYPE, typename SparseMatrixType> 00360 typename viennacl::enable_if< viennacl::is_any_sparse_matrix<SparseMatrixType>::value, 00361 viennacl::vector<SCALARTYPE> >::type 00362 operator-(viennacl::vector_base<SCALARTYPE> & result, 00363 const viennacl::vector_expression< const SparseMatrixType, const viennacl::vector_base<SCALARTYPE>, viennacl::op_prod> & proxy) 00364 { 00365 assert(proxy.lhs().size1() == result.size() && bool("Dimensions for addition of sparse matrix-vector product to vector don't match!")); 00366 vector<SCALARTYPE> temp(proxy.lhs().size1()); 00367 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), temp); 00368 result += temp; 00369 return result; 00370 } 00371 00372 } //namespace viennacl 00373 00374 00375 #endif