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