ViennaCL - The Vienna Computing Library  1.5.0
viennacl/linalg/spai.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_LINALG_SPAI_HPP
00002 #define VIENNACL_LINALG_SPAI_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 
00028 #include <utility>
00029 #include <iostream>
00030 #include <fstream>
00031 #include <string>
00032 #include <algorithm>
00033 #include <vector>
00034 #include <math.h>
00035 #include <map>
00036 
00037 // ViennaCL includes
00038 #include "viennacl/linalg/detail/spai/spai_tag.hpp"
00039 #include "viennacl/linalg/qr.hpp"
00040 #include "viennacl/linalg/prod.hpp"
00041 #include "viennacl/linalg/detail/spai/spai-dynamic.hpp"
00042 #include "viennacl/linalg/detail/spai/spai-static.hpp"
00043 #include "viennacl/linalg/detail/spai/sparse_vector.hpp"
00044 #include "viennacl/linalg/detail/spai/block_matrix.hpp"
00045 #include "viennacl/linalg/detail/spai/block_vector.hpp"
00046 #include "viennacl/linalg/detail/spai/fspai.hpp"
00047 #include "viennacl/linalg/detail/spai/spai.hpp"
00048 
00049 //boost includes
00050 #include "boost/numeric/ublas/vector.hpp"
00051 #include "boost/numeric/ublas/matrix.hpp"
00052 #include "boost/numeric/ublas/matrix_proxy.hpp"
00053 #include "boost/numeric/ublas/vector_proxy.hpp"
00054 #include "boost/numeric/ublas/storage.hpp"
00055 #include "boost/numeric/ublas/io.hpp"
00056 #include "boost/numeric/ublas/lu.hpp"
00057 #include "boost/numeric/ublas/triangular.hpp"
00058 #include "boost/numeric/ublas/matrix_expression.hpp"
00059 
00060 
00061 namespace viennacl
00062 {
00063     namespace linalg
00064     {
00065 
00066         typedef viennacl::linalg::detail::spai::spai_tag         spai_tag;
00067         typedef viennacl::linalg::detail::spai::fspai_tag        fspai_tag;
00068 
00073         //UBLAS version
00074         template <typename MatrixType>
00075         class spai_precond
00076         {
00077         public:
00078             typedef typename MatrixType::value_type ScalarType;
00079             typedef typename boost::numeric::ublas::vector<ScalarType> VectorType;
00084             spai_precond(const MatrixType& A,
00085                          const spai_tag& tag): tag_(tag){
00086 
00087                 //VCLMatrixType vcl_Ap((unsigned int)A.size2(), (unsigned int)A.size1()), vcl_A((unsigned int)A.size1(), (unsigned int)A.size2()),
00088                 //vcl_At((unsigned int)A.size1(), (unsigned int)A.size2());
00089                 //UBLASDenseMatrixType dA = A;
00090                 MatrixType pA(A.size1(), A.size2());
00091                 MatrixType At;
00092                 //std::cout<<A<<std::endl;
00093                 if(!tag_.getIsRight()){
00094                     viennacl::linalg::detail::spai::sparse_transpose(A, At);
00095                 }else{
00096                     At = A;
00097                 }
00098                 pA = At;
00099                 viennacl::linalg::detail::spai::initPreconditioner(pA, spai_m_);
00100                 viennacl::linalg::detail::spai::computeSPAI(At, spai_m_, tag_);
00101                 //(At, pA, tag_.getIsRight(), tag_.getIsStatic(), (ScalarType)_tag.getResidualNormThreshold(), (unsigned int)_tag.getIterationLimit(),
00102                  //_spai_m);
00103 
00104             }
00108             void apply(VectorType& vec) const {
00109                 vec = viennacl::linalg::prod(spai_m_, vec);
00110             }
00111         private:
00112             // variables
00113             spai_tag tag_;
00114             // result of SPAI
00115             MatrixType spai_m_;
00116         };
00117 
00118         //VIENNACL version
00123         template <typename ScalarType, unsigned int MAT_ALIGNMENT>
00124         class spai_precond< viennacl::compressed_matrix<ScalarType, MAT_ALIGNMENT> >
00125         {
00126             typedef viennacl::compressed_matrix<ScalarType, MAT_ALIGNMENT> MatrixType;
00127             typedef boost::numeric::ublas::compressed_matrix<ScalarType> UBLASSparseMatrixType;
00128             typedef viennacl::vector<ScalarType> VectorType;
00129             typedef viennacl::matrix<ScalarType> VCLDenseMatrixType;
00130 
00131             typedef boost::numeric::ublas::vector<ScalarType> UBLASVectorType;
00132         public:
00133 
00138             spai_precond(const MatrixType& A,
00139                          const spai_tag& tag): tag_(tag), spai_m_(viennacl::traits::context(A))
00140             {
00141                 viennacl::ocl::context & ctx = const_cast<viennacl::ocl::context &>(viennacl::traits::opencl_handle(A).context());
00142                 viennacl::linalg::opencl::kernels::spai<ScalarType>::init(ctx);
00143 
00144                 MatrixType At(A.size1(), A.size2(), viennacl::context(ctx));
00145                 UBLASSparseMatrixType ubls_A(A.size1(), A.size2()), ubls_spai_m;
00146                 UBLASSparseMatrixType ubls_At;
00147                 viennacl::copy(A, ubls_A);
00148                 if(!tag_.getIsRight()){
00149                     viennacl::linalg::detail::spai::sparse_transpose(ubls_A, ubls_At);
00150                 }
00151                 else{
00152                     ubls_At = ubls_A;
00153                 }
00154                 //current pattern is A
00155                 //pA = ubls_At;
00156                 //execute SPAI with ublas matrix types
00157                 viennacl::linalg::detail::spai::initPreconditioner(ubls_At, ubls_spai_m);
00158                 viennacl::copy(ubls_At, At);
00159                 viennacl::linalg::detail::spai::computeSPAI(At, ubls_At, ubls_spai_m, spai_m_, tag_);
00160                 //viennacl::copy(ubls_spai_m, spai_m_);
00161                 tmp_.resize(A.size1(), viennacl::traits::context(A), false);
00162             }
00166             void apply(VectorType& vec) const {
00167                 tmp_ = viennacl::linalg::prod(spai_m_, vec);
00168                 vec = tmp_;
00169             }
00170         private:
00171             // variables
00172             spai_tag tag_;
00173             // result of SPAI
00174             MatrixType spai_m_;
00175             mutable VectorType tmp_;
00176         };
00177 
00178 
00179         //
00180         // FSPAI
00181         //
00182 
00187         //UBLAS version
00188         template <typename MatrixType>
00189         class fspai_precond
00190         {
00191             typedef typename MatrixType::value_type ScalarType;
00192             typedef typename boost::numeric::ublas::vector<ScalarType> VectorType;
00193             typedef typename boost::numeric::ublas::matrix<ScalarType> UBLASDenseMatrixType;
00194             typedef typename viennacl::matrix<ScalarType> VCLMatrixType;
00195         public:
00196 
00201             fspai_precond(const MatrixType& A,
00202                         const fspai_tag& tag): tag_(tag)
00203             {
00204                 MatrixType pA = A;
00205                 viennacl::linalg::detail::spai::computeFSPAI(A, pA, L, L_trans, tag_);
00206             }
00207 
00211             void apply(VectorType& vec) const
00212             {
00213               VectorType temp = viennacl::linalg::prod(L_trans, vec);
00214               vec = viennacl::linalg::prod(L, temp);
00215             }
00216 
00217         private:
00218             // variables
00219             const fspai_tag & tag_;
00220             // result of SPAI
00221             MatrixType L;
00222             MatrixType L_trans;
00223         };
00224 
00225 
00226 
00227 
00228 
00229         //
00230         // ViennaCL version
00231         //
00236         template <typename ScalarType, unsigned int MAT_ALIGNMENT>
00237         class fspai_precond< viennacl::compressed_matrix<ScalarType, MAT_ALIGNMENT> >
00238         {
00239             typedef viennacl::compressed_matrix<ScalarType, MAT_ALIGNMENT>   MatrixType;
00240             typedef viennacl::vector<ScalarType> VectorType;
00241             typedef viennacl::matrix<ScalarType> VCLDenseMatrixType;
00242             typedef boost::numeric::ublas::compressed_matrix<ScalarType> UBLASSparseMatrixType;
00243             typedef boost::numeric::ublas::vector<ScalarType> UBLASVectorType;
00244         public:
00245 
00250             fspai_precond(const MatrixType & A,
00251                           const fspai_tag & tag) : tag_(tag), L(viennacl::traits::context(A)), L_trans(viennacl::traits::context(A)), temp_apply_vec_(A.size1(), viennacl::traits::context(A))
00252             {
00253                 //UBLASSparseMatrixType ubls_A;
00254                 UBLASSparseMatrixType ublas_A(A.size1(), A.size2());
00255                 UBLASSparseMatrixType pA(A.size1(), A.size2());
00256                 UBLASSparseMatrixType ublas_L(A.size1(), A.size2());
00257                 UBLASSparseMatrixType ublas_L_trans(A.size1(), A.size2());
00258                 viennacl::copy(A, ublas_A);
00259                 //viennacl::copy(ubls_A, vcl_A);
00260                 //vcl_At = viennacl::linalg::prod(vcl_A, vcl_A);
00261                 //vcl_pA = viennacl::linalg::prod(vcl_A, vcl_At);
00262                 //viennacl::copy(vcl_pA, pA);
00263                 pA = ublas_A;
00264                 //execute SPAI with ublas matrix types
00265                 viennacl::linalg::detail::spai::computeFSPAI(ublas_A, pA, ublas_L, ublas_L_trans, tag_);
00266                 //copy back to GPU
00267                 viennacl::copy(ublas_L, L);
00268                 viennacl::copy(ublas_L_trans, L_trans);
00269             }
00270 
00271 
00275             void apply(VectorType& vec) const
00276             {
00277               temp_apply_vec_ = viennacl::linalg::prod(L_trans, vec);
00278               vec = viennacl::linalg::prod(L, temp_apply_vec_);
00279             }
00280 
00281         private:
00282             // variables
00283             const fspai_tag & tag_;
00284             MatrixType L;
00285             MatrixType L_trans;
00286             mutable VectorType temp_apply_vec_;
00287         };
00288 
00289 
00290     }
00291 }
00292 #endif