• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/data/development/ViennaCL/dev/viennacl/linalg/jacobi_precond.hpp

Go to the documentation of this file.
00001 #ifndef VIENNACL_JACOBI_PRECOND_HPP_
00002 #define VIENNACL_JACOBI_PRECOND_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2011, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008 
00009                             -----------------
00010                   ViennaCL - The Vienna Computing Library
00011                             -----------------
00012 
00013    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00014                
00015    (A list of authors and contributors can be found in the PDF manual)
00016 
00017    License:         MIT (X11), see file LICENSE in the base directory
00018 ============================================================================= */
00019 
00024 #include <vector>
00025 #include <cmath>
00026 #include "viennacl/forwards.h"
00027 #include "viennacl/vector.hpp"
00028 #include "viennacl/compressed_matrix.hpp"
00029 #include "viennacl/tools/tools.hpp"
00030 
00031 #include <map>
00032 
00033 namespace viennacl
00034 {
00035   namespace linalg
00036   {
00037     
00040     class jacobi_tag {};
00041     
00042 
00045     template <typename MatrixType>
00046     class jacobi_precond
00047     {
00048       typedef typename MatrixType::value_type      ScalarType;
00049       
00050       public:
00051         jacobi_precond(MatrixType const & mat, jacobi_tag const & tag) : system_matrix(mat)
00052         {
00053           assert(mat.size1() == mat.size2());
00054           diag_A_inv.resize(mat.size1());  //resize without preserving values
00055           
00056           for (typename MatrixType::const_iterator1 row_it = system_matrix.begin1();
00057                 row_it != system_matrix.end1();
00058                 ++row_it)
00059           {
00060             bool diag_found = false;
00061             for (typename MatrixType::const_iterator2 col_it = row_it.begin();
00062                   col_it != row_it.end();
00063                   ++col_it)
00064             {
00065               if (col_it.index1() == col_it.index2())
00066               {
00067                 diag_A_inv[col_it.index1()] = static_cast<ScalarType>(1.0) / *col_it;
00068                 diag_found = true;
00069               }
00070             }
00071             if (!diag_found)
00072               throw "ViennaCL: Zero in diagonal encountered while setting up Jacobi preconditioner!";
00073           }
00074         }
00075         
00076         
00078         template <typename VectorType>
00079         void apply(VectorType & vec) const
00080         {
00081           assert(vec.size() == diag_A_inv.size());
00082           for (size_t i=0; i<vec.size(); ++i)
00083           {
00084             vec[i] *= diag_A_inv[i];
00085           }
00086         }
00087         
00088       private:
00089         MatrixType const & system_matrix;
00090         std::vector<ScalarType> diag_A_inv;
00091     };
00092 
00093     
00098     template <typename ScalarType, unsigned int MAT_ALIGNMENT>
00099     class jacobi_precond< compressed_matrix<ScalarType, MAT_ALIGNMENT> >
00100     {
00101       typedef compressed_matrix<ScalarType, MAT_ALIGNMENT>   MatrixType;
00102       
00103       public:
00104         jacobi_precond(MatrixType const & mat, jacobi_tag const & tag) : system_matrix(mat), diag_A_inv(mat.size1())
00105         {
00106           assert(system_matrix.size1() == system_matrix.size2());
00107 
00108           init_gpu();
00109         }
00110           
00111         /*void init_cpu()
00112         {
00113           
00114           std::vector< std::map<unsigned int, ScalarType> > cpu_check;
00115           std::vector<ScalarType> diag_A_inv_cpu(system_matrix.size1());
00116           
00117           copy(system_matrix, cpu_check);
00118           viennacl::tools::const_sparse_matrix_adapter<ScalarType> cpu_check_adapter(cpu_check);
00119           
00120           for (typename viennacl::tools::const_sparse_matrix_adapter<ScalarType>::const_iterator1 row_it = cpu_check_adapter.begin1();
00121                 row_it != cpu_check_adapter.end1();
00122                 ++row_it)
00123           {
00124             bool diag_found = false;
00125             for (typename viennacl::tools::const_sparse_matrix_adapter<ScalarType>::const_iterator2 col_it = row_it.begin();
00126                   col_it != row_it.end();
00127                   ++col_it)
00128             {
00129               if (col_it.index1() == col_it.index2())
00130               {
00131                 diag_found = true;
00132                 diag_A_inv_cpu[col_it.index1()] = static_cast<ScalarType>(1.0) / *col_it;
00133               }
00134             }
00135             if (!diag_found)
00136               throw "ViennaCL: Zero in diagonal encountered while setting up Jacobi preconditioner!";
00137           }
00138           
00139           diag_A_inv.resize(system_matrix.size1(), false);
00140           viennacl::fast_copy(diag_A_inv_cpu, diag_A_inv);
00141         }*/
00142         
00143         void init_gpu()
00144         {
00145           viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(
00146                                               viennacl::linalg::kernels::compressed_matrix<ScalarType, MAT_ALIGNMENT>::program_name(),
00147                                               "jacobi_precond");
00148 
00149           viennacl::ocl::enqueue( k(system_matrix.handle1(), system_matrix.handle2(), system_matrix.handle(), 
00150                                     diag_A_inv, static_cast<cl_uint>(diag_A_inv.size())) );        
00151         }
00152         
00153         
00154         template <unsigned int ALIGNMENT>
00155         void apply(viennacl::vector<ScalarType, ALIGNMENT> & vec) const
00156         {
00157           assert(viennacl::traits::size1(system_matrix) == viennacl::traits::size(vec));
00158           
00159           //run kernel:
00160           viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::vector<ScalarType, ALIGNMENT>::program_name(),
00161                                                                 "diag_precond");
00162 
00163           viennacl::ocl::enqueue(
00164              k(viennacl::traits::handle(diag_A_inv), cl_uint(viennacl::traits::start(diag_A_inv)), cl_uint(viennacl::traits::size(diag_A_inv)),
00165                viennacl::traits::handle(vec), cl_uint(viennacl::traits::start(vec)), cl_uint(viennacl::traits::size(vec)) )
00166                                 );        
00167         }
00168         
00169       private:
00170         MatrixType const & system_matrix;
00171         viennacl::vector<ScalarType> diag_A_inv;
00172     };
00173 
00174   }
00175 }
00176 
00177 
00178 
00179 
00180 #endif
00181 
00182 
00183 

Generated on Fri Dec 30 2011 23:20:43 for ViennaCL - The Vienna Computing Library by  doxygen 1.7.1