ViennaCL - The Vienna Computing Library  1.5.1
viennacl/linalg/sparse_matrix_operations.hpp
Go to the documentation of this file.
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