Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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());
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
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 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
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