Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef _VIENNACL_ROW_SCALING_HPP_
00016 #define _VIENNACL_ROW_SCALING_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 row_scaling_tag
00039 {
00040 public:
00045 row_scaling_tag(unsigned int p = 2) : norm_(p) {}
00046
00048 unsigned int norm() const { return norm_; }
00049
00050 private:
00051 unsigned int norm_;
00052 };
00053
00054
00057 template <typename MatrixType>
00058 class row_scaling
00059 {
00060 typedef typename MatrixType::value_type ScalarType;
00061
00062 public:
00068 row_scaling(MatrixType const & mat, row_scaling_tag const & tag) : system_matrix(mat), tag_(tag)
00069 {
00070 assert(mat.size1() == mat.size2());
00071 diag_M_inv.resize(mat.size1());
00072
00073 for (typename MatrixType::const_iterator1 row_it = system_matrix.begin1();
00074 row_it != system_matrix.end1();
00075 ++row_it)
00076 {
00077 diag_M_inv[row_it.index1()];
00078 for (typename MatrixType::const_iterator2 col_it = row_it.begin();
00079 col_it != row_it.end();
00080 ++col_it)
00081 {
00082 if (tag_.norm() == 1)
00083 diag_M_inv[col_it.index1()] += std::fabs(*col_it);
00084 else
00085 diag_M_inv[col_it.index1()] += (*col_it) * (*col_it);
00086 }
00087 if (diag_M_inv[row_it.index1()] == 0)
00088 throw "ViennaCL: Zero row encountered while setting up row scaling preconditioner!";
00089
00090 if (tag_.norm() == 1)
00091 diag_M_inv[row_it.index1()] = static_cast<ScalarType>(1.0) / diag_M_inv[row_it.index1()];
00092 else
00093 diag_M_inv[row_it.index1()] = static_cast<ScalarType>(1.0) / std::sqrt(diag_M_inv[row_it.index1()]);
00094 }
00095 }
00096
00097
00099 template <typename VectorType>
00100 void apply(VectorType & vec) const
00101 {
00102 assert(vec.size() == diag_M_inv.size());
00103 for (size_t i=0; i<vec.size(); ++i)
00104 {
00105 vec[i] *= diag_M_inv[i];
00106 }
00107 }
00108
00109 private:
00110 MatrixType const & system_matrix;
00111 row_scaling_tag const & tag_;
00112 std::vector<ScalarType> diag_M_inv;
00113 };
00114
00115
00120 template <typename ScalarType, unsigned int MAT_ALIGNMENT>
00121 class row_scaling< compressed_matrix<ScalarType, MAT_ALIGNMENT> >
00122 {
00123 typedef compressed_matrix<ScalarType, MAT_ALIGNMENT> MatrixType;
00124
00125 public:
00131 row_scaling(MatrixType const & mat, row_scaling_tag const & tag) : system_matrix(mat), tag_(tag), diag_M_inv(mat.size1())
00132 {
00133 assert(system_matrix.size1() == system_matrix.size2());
00134
00135 init_gpu();
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 void init_gpu()
00175 {
00176 if (tag_.norm() == 1)
00177 {
00178 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(
00179 viennacl::linalg::kernels::compressed_matrix<ScalarType, MAT_ALIGNMENT>::program_name(),
00180 "row_scaling_1");
00181
00182 viennacl::ocl::enqueue( k(system_matrix.handle1(), system_matrix.handle2(), system_matrix.handle(),
00183 diag_M_inv, static_cast<cl_uint>(diag_M_inv.size())) );
00184 }
00185 else
00186 {
00187 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(
00188 viennacl::linalg::kernels::compressed_matrix<ScalarType, MAT_ALIGNMENT>::program_name(),
00189 "row_scaling_2");
00190
00191 viennacl::ocl::enqueue( k(system_matrix.handle1(), system_matrix.handle2(), system_matrix.handle(),
00192 diag_M_inv, static_cast<cl_uint>(diag_M_inv.size())) );
00193 }
00194 }
00195
00196 template <unsigned int ALIGNMENT>
00197 void apply(viennacl::vector<ScalarType, ALIGNMENT> & vec) const
00198 {
00199 assert(system_matrix.size1() == vec.size());
00200
00201
00202 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::vector<ScalarType, ALIGNMENT>::program_name(),
00203 "diag_precond");
00204
00205 viennacl::ocl::enqueue( k(diag_M_inv, vec, static_cast<cl_uint>(vec.size())) );
00206 }
00207
00208 private:
00209 MatrixType const & system_matrix;
00210 row_scaling_tag const & tag_;
00211 viennacl::vector<ScalarType> diag_M_inv;
00212 };
00213
00214 }
00215 }
00216
00217
00218
00219
00220 #endif
00221
00222
00223