• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/data/development/ViennaCL/ViennaCL-1.1.2/viennacl/scalar.hpp

Go to the documentation of this file.
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

Generated on Sat May 21 2011 20:36:50 for ViennaCL - The Vienna Computing Library by  doxygen 1.7.1