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

/data/development/ViennaCL/dev/viennacl/scalar.hpp

Go to the documentation of this file.
00001 #ifndef VIENNACL_SCALAR_HPP_
00002 #define VIENNACL_SCALAR_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2011, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008 
00009                             -----------------
00010                   ViennaCL - The Vienna Computing Library
00011                             -----------------
00012 
00013    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00014                
00015    (A list of authors and contributors can be found in the PDF manual)
00016 
00017    License:         MIT (X11), see file LICENSE in the base directory
00018 ============================================================================= */
00019 
00024 #include "viennacl/forwards.h"
00025 #include "viennacl/ocl/backend.hpp"
00026 #include "viennacl/linalg/kernels/scalar_kernels.h"
00027 
00028 #include <iostream>
00029 
00030 namespace viennacl
00031 {
00039     template <typename LHS, typename RHS, typename OP>
00040     class scalar_expression
00041     {
00042         typedef typename LHS::value_type          DummyType; //Visual C++ 2005 does not allow to write LHS::value_type::value_type
00043       public:
00044         typedef typename DummyType::value_type    ScalarType;
00045         
00046         scalar_expression(LHS & lhs, RHS & rhs) : _lhs(lhs), _rhs(rhs) {}
00047         
00049         LHS & get_lhs() const { return _lhs; }
00051         RHS & get_rhs() const { return _rhs; }
00052 
00054         operator ScalarType () const
00055         {
00056           viennacl::scalar<ScalarType> temp;
00057           temp = *this;
00058           return temp;
00059         }
00060 
00061       private:
00062         LHS & _lhs;
00063         RHS & _rhs;
00064     };
00065     
00073     template<class TYPE>
00074     class scalar
00075     {
00076     public:
00078       typedef typename viennacl::tools::CHECK_SCALAR_TEMPLATE_ARGUMENT<TYPE>::ResultType   value_type;
00079       
00081       scalar()
00082       {
00083         viennacl::linalg::kernels::scalar<TYPE, 1>::init(); 
00084         val_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE));
00085       }
00087       scalar(TYPE val)
00088       {
00089         viennacl::linalg::kernels::scalar<TYPE, 1>::init(); 
00090         val_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE), &val);
00091       }
00092       
00098       explicit scalar(cl_mem mem, size_t size) : val_(mem) { val_.inc(); }
00099 
00101       template <typename T1, typename T2, typename OP>
00102       scalar(scalar_expression<T1, T2, OP> const & proxy)
00103       {
00104         viennacl::linalg::kernels::scalar<TYPE, 1>::init(); 
00105         val_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE));
00106         *this = proxy;
00107       }
00108 
00109       //copy constructor
00111       scalar(const scalar & other) : val_(viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE)))
00112       {
00113         //copy value:
00114         cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), other.handle(), handle(), 0, 0, sizeof(TYPE), 0, NULL, NULL);
00115         VIENNACL_ERR_CHECK(err);
00116       }
00117 
00119       operator TYPE() const
00120       {
00121         TYPE tmp;
00122         cl_int err;
00123         err = clEnqueueReadBuffer(viennacl::ocl::get_queue().handle(), val_, CL_TRUE, 0, sizeof(TYPE), &tmp, 0, NULL, NULL);
00124         VIENNACL_ERR_CHECK(err);
00125         return tmp;
00126       } 
00127       
00129       scalar<TYPE> & operator= (entry_proxy<TYPE> const & other)
00130       {
00131         //copy value:
00132         cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), other.handle(), handle(), other.index() * sizeof(TYPE), 0, sizeof(TYPE), 0, NULL, NULL);
00133         VIENNACL_ERR_CHECK(err);
00134         return *this;
00135       }
00136 
00138       scalar<TYPE> & operator= (scalar<TYPE> const & other)
00139       {
00140         //copy value:
00141         cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), other.handle(), handle(), 0, 0, sizeof(TYPE), 0, NULL, NULL);
00142         VIENNACL_ERR_CHECK(err);
00143         
00144         return *this;
00145       }
00146 
00147       scalar<TYPE> & operator= (float cpu_other)
00148       {
00149         //copy value:
00150         TYPE other = cpu_other;
00151         cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
00152         VIENNACL_ERR_CHECK(err);
00153         
00154         return *this;
00155       }
00156 
00157       scalar<TYPE> & operator= (double cpu_other)
00158       {
00159         //copy value:
00160         TYPE other = cpu_other;
00161         cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
00162         VIENNACL_ERR_CHECK(err);
00163         
00164         return *this;
00165       }
00166 
00167       scalar<TYPE> & operator= (long cpu_other)
00168       {
00169         //copy value:
00170         TYPE other = cpu_other;
00171         cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
00172         VIENNACL_ERR_CHECK(err);
00173         
00174         return *this;
00175       }
00176 
00177       scalar<TYPE> & operator= (unsigned long cpu_other)
00178       {
00179         //copy value:
00180         TYPE other = cpu_other;
00181         cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
00182         VIENNACL_ERR_CHECK(err);
00183         
00184         return *this;
00185       }
00186 
00187       scalar<TYPE> & operator= (int cpu_other)
00188       {
00189         //copy value:
00190         TYPE other = cpu_other;
00191         cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
00192         VIENNACL_ERR_CHECK(err);
00193         
00194         return *this;
00195       }
00196 
00197       scalar<TYPE> & operator= (unsigned int cpu_other)
00198       {
00199         //copy value:
00200         TYPE other = cpu_other;
00201         cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
00202         VIENNACL_ERR_CHECK(err);
00203         
00204         return *this;
00205       }
00207       template <typename T1, typename T2>
00208       scalar<TYPE> & operator= (scalar_expression<T1, T2, op_inner_prod> const & proxy)
00209       {
00210         viennacl::linalg::inner_prod_impl(proxy.get_lhs(), proxy.get_rhs(), *this);
00211         return *this;
00212       }
00213 
00215       template <typename T1, typename T2>
00216       scalar<TYPE> & operator= (scalar_expression<T1, T2, op_norm_1> const & proxy)
00217       {
00218         viennacl::linalg::norm_1_impl(proxy.get_lhs(), *this);
00219         return *this;
00220       }
00221 
00223       template <typename T1, typename T2>
00224       scalar<TYPE> & operator= (scalar_expression<T1, T2, op_norm_2> const & proxy)
00225       {
00226         viennacl::linalg::norm_2_impl(proxy.get_lhs(), *this);
00227         return *this;
00228       }
00229 
00231       template <typename T1, typename T2>
00232       scalar<TYPE> & operator= (scalar_expression<T1, T2, op_norm_inf> const & proxy)
00233       {
00234         viennacl::linalg::norm_inf_impl(proxy.get_lhs(), *this);
00235         return *this;
00236       }
00237 
00239       scalar<TYPE> & operator += (scalar<TYPE> const & other)
00240       {
00241         //get kernel:
00242         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_add");
00243         k.local_work_size(0, 1);
00244         k.global_work_size(0, 1);
00245         
00246         viennacl::ocl::enqueue(k(val_, other.val_));
00247         return *this;
00248       }
00250       scalar<TYPE> & operator += (TYPE other)
00251       {
00252         //get kernel:
00253         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_add");
00254         k.local_work_size(0, 1);
00255         k.global_work_size(0, 1);
00256 
00257         viennacl::ocl::enqueue(k(val_, other.val_));        
00258         return *this;
00259       }
00260 
00261 
00263       scalar<TYPE> & operator -= (scalar<TYPE> const & other)
00264       {
00265         //get kernel:
00266         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_sub");
00267         k.local_work_size(0, 1);
00268         k.global_work_size(0, 1);
00269         
00270         viennacl::ocl::enqueue(k(val_, other.val_));
00271         return *this;
00272       }
00274       scalar<TYPE> & operator -= (TYPE other)
00275       {
00276         //get kernel:
00277         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_sub");
00278         k.local_work_size(0, 1);
00279         k.global_work_size(0, 1);
00280 
00281         viennacl::ocl::enqueue(k(val_, other.val_));        
00282         return *this;
00283       }
00284 
00285 
00287       scalar<TYPE> & operator *= (scalar<TYPE> const & other)
00288       {
00289         //get kernel:
00290         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_mul");
00291         k.local_work_size(0, 1);
00292         k.global_work_size(0, 1);
00293         
00294         viennacl::ocl::enqueue(k(val_, other.val_));
00295         return *this;
00296       }
00298       scalar<TYPE> & operator *= (TYPE other)
00299       {
00300         //get kernel:
00301         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_mul");
00302         k.local_work_size(0, 1);
00303         k.global_work_size(0, 1);
00304 
00305         viennacl::ocl::enqueue(k(val_, other.val_));        
00306         return *this;
00307       }
00308 
00309 
00311 
00312       scalar<TYPE> & operator /= (scalar<TYPE> const & other)
00313       {
00314         //get kernel:
00315         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_div");
00316         k.local_work_size(0, 1);
00317         k.global_work_size(0, 1);
00318         
00319         viennacl::ocl::enqueue(k(val_, other.val_));
00320         return *this;
00321       }
00323       scalar<TYPE> & operator /= (TYPE other)
00324       {
00325         //get kernel:
00326         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_div");
00327         k.local_work_size(0, 1);
00328         k.global_work_size(0, 1);
00329 
00330         viennacl::ocl::enqueue(k(val_, other.val_));        
00331         return *this;
00332       }
00333       
00334       
00336 
00337       scalar<TYPE> operator + (scalar<TYPE> const & other)
00338       {
00339         scalar<TYPE> result;
00340         //get kernel:
00341         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "add");
00342         k.local_work_size(0, 1);
00343         k.global_work_size(0, 1);
00344 
00345         viennacl::ocl::enqueue(k(val_, other.val_, result));        
00346         return result;
00347       }
00349       template <typename T1, typename T2, typename OP>
00350       scalar<TYPE> operator + (scalar_expression<T1, T2, OP> const & proxy) const
00351       {
00352         scalar<TYPE> result = proxy;
00353         //get kernel:
00354         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "add");
00355         k.local_work_size(0, 1);
00356         k.global_work_size(0, 1);
00357 
00358         viennacl::ocl::enqueue(k(val_, result, result));        
00359         return result;
00360       }
00362       scalar<TYPE> operator + (TYPE other)
00363       {
00364         scalar<TYPE> result;
00365         //get kernel:
00366         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_add");
00367         k.local_work_size(0, 1);
00368         k.global_work_size(0, 1);
00369 
00370         viennacl::ocl::enqueue(k(val_, other, result));        
00371         return result;
00372       }
00373 
00374 
00376 
00377       scalar<TYPE> operator - (scalar<TYPE> const & other) const
00378       {
00379         scalar<TYPE> result;
00380         //get kernel:
00381         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "sub");
00382         k.local_work_size(0, 1);
00383         k.global_work_size(0, 1);
00384 
00385         viennacl::ocl::enqueue(k(val_, other.val_, result));        
00386         return result;
00387       }
00389       template <typename T1, typename T2, typename OP>
00390       scalar<TYPE> operator - (scalar_expression<T1, T2, OP> const & proxy) const
00391       {
00392         scalar<TYPE> result = *this;
00393         //get kernel:
00394         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "sub");
00395         k.local_work_size(0, 1);
00396         k.global_work_size(0, 1);
00397 
00398         viennacl::ocl::enqueue(k(val_, result, result));        
00399         return result;
00400       }
00402       scalar<TYPE> operator - (TYPE other) const
00403       {
00404         scalar<TYPE> result;
00405         //get kernel:
00406         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_sub");
00407         k.local_work_size(0, 1);
00408         k.global_work_size(0, 1);
00409 
00410         viennacl::ocl::enqueue(k(val_, other, result));        
00411         return result;
00412         
00413         return result;
00414       }
00415 
00417 
00418       scalar<TYPE> operator * (scalar<TYPE> const & other) const
00419       {
00420         scalar<TYPE> result;
00421         //get kernel:
00422         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "mul");
00423         k.local_work_size(0, 1);
00424         k.global_work_size(0, 1);
00425 
00426         viennacl::ocl::enqueue(k(val_, other.val_, result));        
00427         return result;
00428       }
00430       template <typename T1, typename T2, typename OP>
00431       scalar<TYPE> operator * (scalar_expression<T1, T2, OP> const & proxy) const
00432       {
00433         scalar<TYPE> result = proxy;
00434         //get kernel:
00435         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "mul");
00436         k.local_work_size(0, 1);
00437         k.global_work_size(0, 1);
00438 
00439         viennacl::ocl::enqueue(k(val_, result, result));        
00440         return result;
00441       }
00443       scalar<TYPE> operator * (TYPE other) const
00444       {
00445         scalar<TYPE> result;
00446         //get kernel:
00447         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_mul");
00448         k.local_work_size(0, 1);
00449         k.global_work_size(0, 1);
00450 
00451         viennacl::ocl::enqueue(k(val_, other, result));        
00452         return result;
00453       }
00454       
00456 
00457       scalar<TYPE> operator / (scalar<TYPE> const & other) const
00458       {
00459         scalar<TYPE> result;
00460         //get kernel:
00461         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "divide");
00462         k.local_work_size(0, 1);
00463         k.global_work_size(0, 1);
00464 
00465         viennacl::ocl::enqueue(k(val_, other.val_, result));        
00466         return result;
00467       }
00469       template <typename T1, typename T2, typename OP>
00470       scalar<TYPE> operator / (scalar_expression<T1, T2, OP> const & proxy) const
00471       {
00472         scalar<TYPE> result = proxy;
00473         //get kernel:
00474         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "divide");
00475         k.local_work_size(0, 1);
00476         k.global_work_size(0, 1);
00477 
00478         viennacl::ocl::enqueue(k(val_, result, result));        
00479         return result;
00480       }
00482       scalar<TYPE> operator / (TYPE other) const
00483       {
00484         scalar<TYPE> result;
00485         //get kernel:
00486         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_div");
00487         k.local_work_size(0, 1);
00488         k.global_work_size(0, 1);
00489 
00490         viennacl::ocl::enqueue(k(val_, other, result));        
00491         return result;
00492       }
00493 
00495       const viennacl::ocl::handle<cl_mem> & handle() const { return val_; }
00496       
00497     private:
00498       viennacl::ocl::handle<cl_mem> val_;
00499     };
00500     
00501     
00502     //stream operators:
00504     template<class SCALARTYPE>
00505     std::ostream & operator<<(std::ostream & s, const scalar<SCALARTYPE> & val)
00506     {
00507       SCALARTYPE temp = val;
00508       s << temp;
00509       return s;
00510     }
00511 
00513     template<class SCALARTYPE>
00514     std::istream & operator>>(std::istream & s, const scalar<SCALARTYPE> & val)
00515     {
00516       SCALARTYPE temp;
00517       s >> temp;
00518       val = temp;
00519       return s;
00520     }
00521 
00522 } //namespace viennacl
00523 
00524 #endif

Generated on Fri Dec 30 2011 23:20:43 for ViennaCL - The Vienna Computing Library by  doxygen 1.7.1