Go to the documentation of this file.00001 #ifndef VIENNACL_JACOBI_PRECOND_HPP_
00002 #define VIENNACL_JACOBI_PRECOND_HPP_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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());
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
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
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
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