ViennaCL - The Vienna Computing Library
1.5.1
|
00001 #ifndef VIENNACL_LINALG_SPAI_HPP 00002 #define VIENNACL_LINALG_SPAI_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 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