00001 #ifndef VIENNACL_COMPRESSED_MATRIX_OPERATIONS_HPP_
00002 #define VIENNACL_COMPRESSED_MATRIX_OPERATIONS_HPP_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00024 #include "viennacl/forwards.h"
00025 #include "viennacl/ocl/device.hpp"
00026 #include "viennacl/ocl/handle.hpp"
00027 #include "viennacl/ocl/kernel.hpp"
00028 #include "viennacl/scalar.hpp"
00029 #include "viennacl/vector.hpp"
00030 #include "viennacl/tools/tools.hpp"
00031 #include "viennacl/linalg/kernels/compressed_matrix_kernels.h"
00032
00033 namespace viennacl
00034 {
00035 namespace linalg
00036 {
00037
00045 template<class SCALARTYPE, unsigned int ALIGNMENT, unsigned int VECTOR_ALIGNMENT>
00046 vector_expression<const compressed_matrix<SCALARTYPE, ALIGNMENT>,
00047 const vector<SCALARTYPE, VECTOR_ALIGNMENT>,
00048 op_prod > prod_impl(const compressed_matrix<SCALARTYPE, ALIGNMENT> & mat,
00049 const vector<SCALARTYPE, VECTOR_ALIGNMENT> & vec)
00050 {
00051 return vector_expression<const compressed_matrix<SCALARTYPE, ALIGNMENT>,
00052 const vector<SCALARTYPE, VECTOR_ALIGNMENT>,
00053 op_prod >(mat, vec);
00054 }
00055
00065 template<class TYPE, unsigned int ALIGNMENT, unsigned int VECTOR_ALIGNMENT>
00066 void prod_impl(const viennacl::compressed_matrix<TYPE, ALIGNMENT> & mat,
00067 const viennacl::vector<TYPE, VECTOR_ALIGNMENT> & vec,
00068 viennacl::vector<TYPE, VECTOR_ALIGNMENT> & result,
00069 size_t NUM_THREADS = 0)
00070 {
00071 assert(mat.size1() == result.size());
00072 assert(mat.size2() == vec.size());
00073
00074 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::compressed_matrix<TYPE, ALIGNMENT>::program_name(), "vec_mul");
00075
00076 viennacl::ocl::enqueue(k(mat.handle1(), mat.handle2(), mat.handle(), vec, result, static_cast<cl_uint>(mat.size1())));
00077 }
00078
00084 template<typename SCALARTYPE, unsigned int MAT_ALIGNMENT, unsigned int VEC_ALIGNMENT>
00085 void inplace_solve(compressed_matrix<SCALARTYPE, MAT_ALIGNMENT> const & L, vector<SCALARTYPE, VEC_ALIGNMENT> & vec, viennacl::linalg::unit_lower_tag)
00086 {
00087 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>::program_name(), "lu_forward");
00088 unsigned int threads = k.local_work_size();
00089
00090 k.global_work_size(k.local_work_size());
00091 viennacl::ocl::enqueue(k(L.handle1(), L.handle2(), L,
00092 viennacl::ocl::local_mem(sizeof(int) * (threads+1)),
00093 viennacl::ocl::local_mem(sizeof(SCALARTYPE) * threads),
00094 vec, L.size1()));
00095 }
00096
00103 template<typename SCALARTYPE, unsigned int MAT_ALIGNMENT, unsigned int VEC_ALIGNMENT, typename TAG>
00104 vector<SCALARTYPE, VEC_ALIGNMENT> solve(compressed_matrix<SCALARTYPE, MAT_ALIGNMENT> const & L,
00105 const vector<SCALARTYPE, VEC_ALIGNMENT> & vec,
00106 const viennacl::linalg::unit_lower_tag & tag)
00107 {
00108
00109 vector<SCALARTYPE, VEC_ALIGNMENT> result(vec.size());
00110 result = vec;
00111
00112 inplace_solve(L, result, tag);
00113
00114 return result;
00115 }
00116
00117
00123 template<typename SCALARTYPE, unsigned int MAT_ALIGNMENT, unsigned int VEC_ALIGNMENT>
00124 void inplace_solve(compressed_matrix<SCALARTYPE, MAT_ALIGNMENT> const & U, vector<SCALARTYPE, VEC_ALIGNMENT> & vec, viennacl::linalg::upper_tag)
00125 {
00126 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>::program_name(), "lu_backward");
00127 unsigned int threads = k.local_work_size();
00128
00129 k.global_work_size(k.local_work_size());
00130 viennacl::ocl::enqueue(k(U.handle1(), U.handle2(), U.handle(),
00131 viennacl::ocl::local_mem(sizeof(int) * (threads+2)),
00132 viennacl::ocl::local_mem(sizeof(SCALARTYPE) * (threads+2)),
00133 vec, U.size1()));
00134 }
00135
00142 template<typename SCALARTYPE, unsigned int MAT_ALIGNMENT, unsigned int VEC_ALIGNMENT, typename TAG>
00143 vector<SCALARTYPE, VEC_ALIGNMENT> solve(compressed_matrix<SCALARTYPE, MAT_ALIGNMENT> const & L,
00144 const vector<SCALARTYPE, VEC_ALIGNMENT> & vec,
00145 viennacl::linalg::upper_tag const & tag)
00146 {
00147
00148 vector<SCALARTYPE, VEC_ALIGNMENT> result(vec.size());
00149 result = vec;
00150
00151 inplace_solve(L, result, tag);
00152
00153 return result;
00154 }
00155
00156
00157 }
00158
00159
00160
00161
00166 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00167 template <unsigned int MAT_ALIGNMENT>
00168 viennacl::vector<SCALARTYPE, ALIGNMENT> &
00169 viennacl::vector<SCALARTYPE, ALIGNMENT>::operator=(const viennacl::vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00170 const viennacl::vector<SCALARTYPE, ALIGNMENT>,
00171 viennacl::op_prod> & proxy)
00172 {
00173
00174 if (proxy.rhs().handle() == this->handle())
00175 {
00176 viennacl::vector<SCALARTYPE, ALIGNMENT> result(proxy.rhs().size());
00177 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
00178 *this = result;
00179 return *this;
00180 }
00181 else
00182 {
00183 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), *this);
00184 return *this;
00185 }
00186 return *this;
00187 }
00188
00189
00194 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00195 template <unsigned int MAT_ALIGNMENT>
00196 viennacl::vector<SCALARTYPE, ALIGNMENT> &
00197 viennacl::vector<SCALARTYPE, ALIGNMENT>::operator+=(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00198 const vector<SCALARTYPE, ALIGNMENT>,
00199 op_prod> & proxy)
00200 {
00201 vector<SCALARTYPE, ALIGNMENT> result(proxy.lhs().size1());
00202 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
00203 *this += result;
00204 return *this;
00205 }
00206
00211 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00212 template <unsigned int MAT_ALIGNMENT>
00213 viennacl::vector<SCALARTYPE, ALIGNMENT> &
00214 viennacl::vector<SCALARTYPE, ALIGNMENT>::operator-=(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00215 const vector<SCALARTYPE, ALIGNMENT>,
00216 op_prod> & proxy)
00217 {
00218 vector<SCALARTYPE, ALIGNMENT> result(proxy.lhs().size1());
00219 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
00220 *this -= result;
00221 return *this;
00222 }
00223
00224
00225
00230 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00231 template <unsigned int MAT_ALIGNMENT>
00232 viennacl::vector<SCALARTYPE, ALIGNMENT>
00233 viennacl::vector<SCALARTYPE, ALIGNMENT>::operator+(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00234 const vector<SCALARTYPE, ALIGNMENT>,
00235 op_prod> & proxy)
00236 {
00237 assert(proxy.lhs().size1() == size());
00238 vector<SCALARTYPE, ALIGNMENT> result(size());
00239 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
00240 result += *this;
00241 return result;
00242 }
00243
00248 template <typename SCALARTYPE, unsigned int ALIGNMENT>
00249 template <unsigned int MAT_ALIGNMENT>
00250 viennacl::vector<SCALARTYPE, ALIGNMENT>
00251 viennacl::vector<SCALARTYPE, ALIGNMENT>::operator-(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00252 const vector<SCALARTYPE, ALIGNMENT>,
00253 op_prod> & proxy)
00254 {
00255 assert(proxy.lhs().size1() == size());
00256 vector<SCALARTYPE, ALIGNMENT> result(size());
00257 viennacl::linalg::prod_impl(proxy.lhs(), proxy.rhs(), result);
00258 result = *this - result;
00259 return result;
00260 }
00261
00262 }
00263
00264
00265 #endif