|
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_SCALAR_HPP_ 00016 #define _VIENNACL_SCALAR_HPP_ 00017 00022 #include "viennacl/forwards.h" 00023 #include "viennacl/ocl/backend.hpp" 00024 #include "viennacl/linalg/kernels/scalar_kernels.h" 00025 00026 #include <iostream> 00027 00028 namespace viennacl 00029 { 00037 template <typename LHS, typename RHS, typename OP> 00038 class scalar_expression 00039 { 00040 typedef typename LHS::value_type DummyType; //Visual C++ 2005 does not allow to write LHS::value_type::value_type 00041 public: 00042 typedef typename DummyType::value_type ScalarType; 00043 00044 scalar_expression(LHS & lhs, RHS & rhs) : _lhs(lhs), _rhs(rhs) {} 00045 00047 LHS & get_lhs() const { return _lhs; } 00049 RHS & get_rhs() const { return _rhs; } 00050 00052 operator ScalarType () const 00053 { 00054 viennacl::scalar<ScalarType> temp; 00055 temp = *this; 00056 return temp; 00057 } 00058 00059 private: 00060 LHS & _lhs; 00061 RHS & _rhs; 00062 }; 00063 00071 template<class TYPE> 00072 class scalar 00073 { 00074 public: 00076 typedef typename viennacl::tools::CHECK_SCALAR_TEMPLATE_ARGUMENT<TYPE>::ResultType value_type; 00077 00079 scalar() 00080 { 00081 viennacl::linalg::kernels::scalar<TYPE, 1>::init(); 00082 val_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE)); 00083 } 00085 scalar(TYPE val) 00086 { 00087 viennacl::linalg::kernels::scalar<TYPE, 1>::init(); 00088 val_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE), &val); 00089 } 00090 00096 explicit scalar(cl_mem mem, size_t size) : val_(mem) { val_.inc(); } 00097 00099 template <typename T1, typename T2, typename OP> 00100 scalar(scalar_expression<T1, T2, OP> const & proxy) 00101 { 00102 viennacl::linalg::kernels::scalar<TYPE, 1>::init(); 00103 val_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE)); 00104 *this = proxy; 00105 } 00106 00107 //copy constructor 00109 scalar(const scalar & other) : val_(viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE))) 00110 { 00111 //copy value: 00112 cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), other.handle(), handle(), 0, 0, sizeof(TYPE), 0, NULL, NULL); 00113 VIENNACL_ERR_CHECK(err); 00114 } 00115 00117 operator TYPE() const 00118 { 00119 TYPE tmp; 00120 cl_int err; 00121 err = clEnqueueReadBuffer(viennacl::ocl::get_queue().handle(), val_, CL_TRUE, 0, sizeof(TYPE), &tmp, 0, NULL, NULL); 00122 VIENNACL_ERR_CHECK(err); 00123 return tmp; 00124 } 00125 00127 scalar<TYPE> & operator= (entry_proxy<TYPE> const & other) 00128 { 00129 //copy value: 00130 cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), other.handle(), handle(), other.index() * sizeof(TYPE), 0, sizeof(TYPE), 0, NULL, NULL); 00131 VIENNACL_ERR_CHECK(err); 00132 return *this; 00133 } 00134 00136 scalar<TYPE> & operator= (scalar<TYPE> const & other) 00137 { 00138 //copy value: 00139 cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), other.handle(), handle(), 0, 0, sizeof(TYPE), 0, NULL, NULL); 00140 VIENNACL_ERR_CHECK(err); 00141 00142 return *this; 00143 } 00144 00145 scalar<TYPE> & operator= (float cpu_other) 00146 { 00147 //copy value: 00148 TYPE other = cpu_other; 00149 cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL); 00150 VIENNACL_ERR_CHECK(err); 00151 00152 return *this; 00153 } 00154 00155 scalar<TYPE> & operator= (double cpu_other) 00156 { 00157 //copy value: 00158 TYPE other = cpu_other; 00159 cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL); 00160 VIENNACL_ERR_CHECK(err); 00161 00162 return *this; 00163 } 00164 00165 scalar<TYPE> & operator= (long cpu_other) 00166 { 00167 //copy value: 00168 TYPE other = cpu_other; 00169 cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL); 00170 VIENNACL_ERR_CHECK(err); 00171 00172 return *this; 00173 } 00174 00175 scalar<TYPE> & operator= (unsigned long cpu_other) 00176 { 00177 //copy value: 00178 TYPE other = cpu_other; 00179 cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL); 00180 VIENNACL_ERR_CHECK(err); 00181 00182 return *this; 00183 } 00184 00185 scalar<TYPE> & operator= (int cpu_other) 00186 { 00187 //copy value: 00188 TYPE other = cpu_other; 00189 cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL); 00190 VIENNACL_ERR_CHECK(err); 00191 00192 return *this; 00193 } 00194 00195 scalar<TYPE> & operator= (unsigned int cpu_other) 00196 { 00197 //copy value: 00198 TYPE other = cpu_other; 00199 cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL); 00200 VIENNACL_ERR_CHECK(err); 00201 00202 return *this; 00203 } 00205 template <typename T1, typename T2> 00206 scalar<TYPE> & operator= (scalar_expression<T1, T2, op_inner_prod> const & proxy) 00207 { 00208 viennacl::linalg::inner_prod_impl(proxy.get_lhs(), proxy.get_rhs(), *this); 00209 return *this; 00210 } 00211 00213 template <typename T1, typename T2> 00214 scalar<TYPE> & operator= (scalar_expression<T1, T2, op_norm_1> const & proxy) 00215 { 00216 viennacl::linalg::norm_1_impl(proxy.get_lhs(), *this); 00217 return *this; 00218 } 00219 00221 template <typename T1, typename T2> 00222 scalar<TYPE> & operator= (scalar_expression<T1, T2, op_norm_2> const & proxy) 00223 { 00224 viennacl::linalg::norm_2_impl(proxy.get_lhs(), *this); 00225 return *this; 00226 } 00227 00229 template <typename T1, typename T2> 00230 scalar<TYPE> & operator= (scalar_expression<T1, T2, op_norm_inf> const & proxy) 00231 { 00232 viennacl::linalg::norm_inf_impl(proxy.get_lhs(), *this); 00233 return *this; 00234 } 00235 00237 scalar<TYPE> & operator += (scalar<TYPE> const & other) 00238 { 00239 //get kernel: 00240 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_add"); 00241 k.local_work_size(0, 1); 00242 k.global_work_size(0, 1); 00243 00244 viennacl::ocl::enqueue(k(val_, other.val_)); 00245 return *this; 00246 } 00248 scalar<TYPE> & operator += (TYPE other) 00249 { 00250 //get kernel: 00251 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_add"); 00252 k.local_work_size(0, 1); 00253 k.global_work_size(0, 1); 00254 00255 viennacl::ocl::enqueue(k(val_, other.val_)); 00256 return *this; 00257 } 00258 00259 00261 scalar<TYPE> & operator -= (scalar<TYPE> const & other) 00262 { 00263 //get kernel: 00264 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_sub"); 00265 k.local_work_size(0, 1); 00266 k.global_work_size(0, 1); 00267 00268 viennacl::ocl::enqueue(k(val_, other.val_)); 00269 return *this; 00270 } 00272 scalar<TYPE> & operator -= (TYPE other) 00273 { 00274 //get kernel: 00275 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_sub"); 00276 k.local_work_size(0, 1); 00277 k.global_work_size(0, 1); 00278 00279 viennacl::ocl::enqueue(k(val_, other.val_)); 00280 return *this; 00281 } 00282 00283 00285 scalar<TYPE> & operator *= (scalar<TYPE> const & other) 00286 { 00287 //get kernel: 00288 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_mul"); 00289 k.local_work_size(0, 1); 00290 k.global_work_size(0, 1); 00291 00292 viennacl::ocl::enqueue(k(val_, other.val_)); 00293 return *this; 00294 } 00296 scalar<TYPE> & operator *= (TYPE other) 00297 { 00298 //get kernel: 00299 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_mul"); 00300 k.local_work_size(0, 1); 00301 k.global_work_size(0, 1); 00302 00303 viennacl::ocl::enqueue(k(val_, other.val_)); 00304 return *this; 00305 } 00306 00307 00309 00310 scalar<TYPE> & operator /= (scalar<TYPE> const & other) 00311 { 00312 //get kernel: 00313 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_div"); 00314 k.local_work_size(0, 1); 00315 k.global_work_size(0, 1); 00316 00317 viennacl::ocl::enqueue(k(val_, other.val_)); 00318 return *this; 00319 } 00321 scalar<TYPE> & operator /= (TYPE other) 00322 { 00323 //get kernel: 00324 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_div"); 00325 k.local_work_size(0, 1); 00326 k.global_work_size(0, 1); 00327 00328 viennacl::ocl::enqueue(k(val_, other.val_)); 00329 return *this; 00330 } 00331 00332 00334 00335 scalar<TYPE> operator + (scalar<TYPE> const & other) 00336 { 00337 scalar<TYPE> result; 00338 //get kernel: 00339 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "add"); 00340 k.local_work_size(0, 1); 00341 k.global_work_size(0, 1); 00342 00343 viennacl::ocl::enqueue(k(val_, other.val_, result)); 00344 return result; 00345 } 00347 template <typename T1, typename T2, typename OP> 00348 scalar<TYPE> operator + (scalar_expression<T1, T2, OP> const & proxy) const 00349 { 00350 scalar<TYPE> result = proxy; 00351 //get kernel: 00352 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "add"); 00353 k.local_work_size(0, 1); 00354 k.global_work_size(0, 1); 00355 00356 viennacl::ocl::enqueue(k(val_, result, result)); 00357 return result; 00358 } 00360 scalar<TYPE> operator + (TYPE other) 00361 { 00362 scalar<TYPE> result; 00363 //get kernel: 00364 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_add"); 00365 k.local_work_size(0, 1); 00366 k.global_work_size(0, 1); 00367 00368 viennacl::ocl::enqueue(k(val_, other, result)); 00369 return result; 00370 } 00371 00372 00374 00375 scalar<TYPE> operator - (scalar<TYPE> const & other) const 00376 { 00377 scalar<TYPE> result; 00378 //get kernel: 00379 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "sub"); 00380 k.local_work_size(0, 1); 00381 k.global_work_size(0, 1); 00382 00383 viennacl::ocl::enqueue(k(val_, other.val_, result)); 00384 return result; 00385 } 00387 template <typename T1, typename T2, typename OP> 00388 scalar<TYPE> operator - (scalar_expression<T1, T2, OP> const & proxy) const 00389 { 00390 scalar<TYPE> result = *this; 00391 //get kernel: 00392 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "sub"); 00393 k.local_work_size(0, 1); 00394 k.global_work_size(0, 1); 00395 00396 viennacl::ocl::enqueue(k(val_, result, result)); 00397 return result; 00398 } 00400 scalar<TYPE> operator - (TYPE other) const 00401 { 00402 scalar<TYPE> result; 00403 //get kernel: 00404 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_sub"); 00405 k.local_work_size(0, 1); 00406 k.global_work_size(0, 1); 00407 00408 viennacl::ocl::enqueue(k(val_, other, result)); 00409 return result; 00410 00411 return result; 00412 } 00413 00415 00416 scalar<TYPE> operator * (scalar<TYPE> const & other) const 00417 { 00418 scalar<TYPE> result; 00419 //get kernel: 00420 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "mul"); 00421 k.local_work_size(0, 1); 00422 k.global_work_size(0, 1); 00423 00424 viennacl::ocl::enqueue(k(val_, other.val_, result)); 00425 return result; 00426 } 00428 template <typename T1, typename T2, typename OP> 00429 scalar<TYPE> operator * (scalar_expression<T1, T2, OP> const & proxy) const 00430 { 00431 scalar<TYPE> result = proxy; 00432 //get kernel: 00433 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "mul"); 00434 k.local_work_size(0, 1); 00435 k.global_work_size(0, 1); 00436 00437 viennacl::ocl::enqueue(k(val_, result, result)); 00438 return result; 00439 } 00441 scalar<TYPE> operator * (TYPE other) const 00442 { 00443 scalar<TYPE> result; 00444 //get kernel: 00445 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_mul"); 00446 k.local_work_size(0, 1); 00447 k.global_work_size(0, 1); 00448 00449 viennacl::ocl::enqueue(k(val_, other, result)); 00450 return result; 00451 } 00452 00454 00455 scalar<TYPE> operator / (scalar<TYPE> const & other) const 00456 { 00457 scalar<TYPE> result; 00458 //get kernel: 00459 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "divide"); 00460 k.local_work_size(0, 1); 00461 k.global_work_size(0, 1); 00462 00463 viennacl::ocl::enqueue(k(val_, other.val_, result)); 00464 return result; 00465 } 00467 template <typename T1, typename T2, typename OP> 00468 scalar<TYPE> operator / (scalar_expression<T1, T2, OP> const & proxy) const 00469 { 00470 scalar<TYPE> result = proxy; 00471 //get kernel: 00472 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "divide"); 00473 k.local_work_size(0, 1); 00474 k.global_work_size(0, 1); 00475 00476 viennacl::ocl::enqueue(k(val_, result, result)); 00477 return result; 00478 } 00480 scalar<TYPE> operator / (TYPE other) const 00481 { 00482 scalar<TYPE> result; 00483 //get kernel: 00484 viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_div"); 00485 k.local_work_size(0, 1); 00486 k.global_work_size(0, 1); 00487 00488 viennacl::ocl::enqueue(k(val_, other, result)); 00489 return result; 00490 } 00491 00493 const viennacl::ocl::handle<cl_mem> & handle() const { return val_; } 00494 00495 private: 00496 viennacl::ocl::handle<cl_mem> val_; 00497 }; 00498 00499 00500 //stream operators: 00502 template<class SCALARTYPE> 00503 std::ostream & operator<<(std::ostream & s, const scalar<SCALARTYPE> & val) 00504 { 00505 SCALARTYPE temp = val; 00506 s << temp; 00507 return s; 00508 } 00509 00511 template<class SCALARTYPE> 00512 std::istream & operator>>(std::istream & s, const scalar<SCALARTYPE> & val) 00513 { 00514 SCALARTYPE temp; 00515 s >> temp; 00516 val = temp; 00517 return s; 00518 } 00519 00520 } //namespace viennacl 00521 00522 #endif
1.7.6.1