|
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_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()); //resize without preserving values 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 void init_cpu() 00140 { 00141 std::vector< std::map<unsigned int, ScalarType> > cpu_check; 00142 std::vector<ScalarType> diag_M_inv_cpu(system_matrix.size1()); 00143 00144 copy(system_matrix, cpu_check); 00145 viennacl::tools::const_sparse_matrix_adapter<ScalarType> cpu_check_adapter(cpu_check); 00146 00147 for (typename viennacl::tools::const_sparse_matrix_adapter<ScalarType>::const_iterator1 row_it = cpu_check_adapter.begin1(); 00148 row_it != cpu_check_adapter.end1(); 00149 ++row_it) 00150 { 00151 diag_M_inv_cpu[row_it.index1()] = 0; 00152 for (typename viennacl::tools::const_sparse_matrix_adapter<ScalarType>::const_iterator2 col_it = row_it.begin(); 00153 col_it != row_it.end(); 00154 ++col_it) 00155 { 00156 if (tag_.norm() == 1) 00157 diag_M_inv_cpu[col_it.index1()] += std::fabs(*col_it); 00158 else 00159 diag_M_inv_cpu[col_it.index1()] += (*col_it) * (*col_it); 00160 } 00161 if (diag_M_inv_cpu[row_it.index1()] == 0) 00162 throw "ViennaCL: Zero row encountered while setting up row scaling preconditioner!"; 00163 00164 if (tag_.norm() == 1) 00165 diag_M_inv_cpu[row_it.index1()] = static_cast<ScalarType>(1.0) / diag_M_inv_cpu[row_it.index1()]; 00166 else 00167 diag_M_inv_cpu[row_it.index1()] = static_cast<ScalarType>(1.0) / std::sqrt(diag_M_inv_cpu[row_it.index1()]); 00168 } 00169 00170 diag_M_inv.resize(system_matrix.size1(), false); 00171 viennacl::fast_copy(diag_M_inv_cpu, diag_M_inv); 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 //run kernel (reuse Jacobi kernel): 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
1.7.6.1