ViennaCL - The Vienna Computing Library  1.2.0
scalar.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_SCALAR_HPP_
2 #define VIENNACL_SCALAR_HPP_
3 
4 /* =========================================================================
5  Copyright (c) 2010-2011, Institute for Microelectronics,
6  Institute for Analysis and Scientific Computing,
7  TU Wien.
8 
9  -----------------
10  ViennaCL - The Vienna Computing Library
11  -----------------
12 
13  Project Head: Karl Rupp rupp@iue.tuwien.ac.at
14 
15  (A list of authors and contributors can be found in the PDF manual)
16 
17  License: MIT (X11), see file LICENSE in the base directory
18 ============================================================================= */
19 
24 #include "viennacl/forwards.h"
25 #include "viennacl/ocl/backend.hpp"
27 
28 #include <iostream>
29 
30 namespace viennacl
31 {
39  template <typename LHS, typename RHS, typename OP>
41  {
42  typedef typename LHS::value_type DummyType; //Visual C++ 2005 does not allow to write LHS::value_type::value_type
43  public:
44  typedef typename DummyType::value_type ScalarType;
45 
46  scalar_expression(LHS & lhs, RHS & rhs) : _lhs(lhs), _rhs(rhs) {}
47 
49  LHS & get_lhs() const { return _lhs; }
51  RHS & get_rhs() const { return _rhs; }
52 
54  operator ScalarType () const
55  {
57  temp = *this;
58  return temp;
59  }
60 
61  private:
62  LHS & _lhs;
63  RHS & _rhs;
64  };
65 
73  template<class TYPE>
74  class scalar
75  {
76  public:
79 
82  {
83  viennacl::linalg::kernels::scalar<TYPE, 1>::init();
84  val_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE));
85  }
87  scalar(TYPE val)
88  {
89  viennacl::linalg::kernels::scalar<TYPE, 1>::init();
90  val_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE), &val);
91  }
92 
98  explicit scalar(cl_mem mem, size_t size) : val_(mem) { val_.inc(); }
99 
101  template <typename T1, typename T2, typename OP>
103  {
104  viennacl::linalg::kernels::scalar<TYPE, 1>::init();
105  val_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE));
106  *this = proxy;
107  }
108 
109  //copy constructor
111  scalar(const scalar & other) : val_(viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(TYPE)))
112  {
113  //copy value:
114  cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), other.handle(), handle(), 0, 0, sizeof(TYPE), 0, NULL, NULL);
115  VIENNACL_ERR_CHECK(err);
116  }
117 
119  operator TYPE() const
120  {
121  TYPE tmp;
122  cl_int err;
123  err = clEnqueueReadBuffer(viennacl::ocl::get_queue().handle(), val_, CL_TRUE, 0, sizeof(TYPE), &tmp, 0, NULL, NULL);
124  VIENNACL_ERR_CHECK(err);
125  return tmp;
126  }
127 
130  {
131  //copy value:
132  cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), other.handle(), handle(), other.index() * sizeof(TYPE), 0, sizeof(TYPE), 0, NULL, NULL);
133  VIENNACL_ERR_CHECK(err);
134  return *this;
135  }
136 
139  {
140  //copy value:
141  cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), other.handle(), handle(), 0, 0, sizeof(TYPE), 0, NULL, NULL);
142  VIENNACL_ERR_CHECK(err);
143 
144  return *this;
145  }
146 
147  scalar<TYPE> & operator= (float cpu_other)
148  {
149  //copy value:
150  TYPE other = cpu_other;
151  cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
152  VIENNACL_ERR_CHECK(err);
153 
154  return *this;
155  }
156 
157  scalar<TYPE> & operator= (double cpu_other)
158  {
159  //copy value:
160  TYPE other = cpu_other;
161  cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
162  VIENNACL_ERR_CHECK(err);
163 
164  return *this;
165  }
166 
167  scalar<TYPE> & operator= (long cpu_other)
168  {
169  //copy value:
170  TYPE other = cpu_other;
171  cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
172  VIENNACL_ERR_CHECK(err);
173 
174  return *this;
175  }
176 
177  scalar<TYPE> & operator= (unsigned long cpu_other)
178  {
179  //copy value:
180  TYPE other = cpu_other;
181  cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
182  VIENNACL_ERR_CHECK(err);
183 
184  return *this;
185  }
186 
187  scalar<TYPE> & operator= (int cpu_other)
188  {
189  //copy value:
190  TYPE other = cpu_other;
191  cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
192  VIENNACL_ERR_CHECK(err);
193 
194  return *this;
195  }
196 
197  scalar<TYPE> & operator= (unsigned int cpu_other)
198  {
199  //copy value:
200  TYPE other = cpu_other;
201  cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), handle(), CL_TRUE, 0, sizeof(TYPE), &other, 0, NULL, NULL);
202  VIENNACL_ERR_CHECK(err);
203 
204  return *this;
205  }
207  template <typename T1, typename T2>
209  {
210  viennacl::linalg::inner_prod_impl(proxy.get_lhs(), proxy.get_rhs(), *this);
211  return *this;
212  }
213 
215  template <typename T1, typename T2>
217  {
218  viennacl::linalg::norm_1_impl(proxy.get_lhs(), *this);
219  return *this;
220  }
221 
223  template <typename T1, typename T2>
225  {
226  viennacl::linalg::norm_2_impl(proxy.get_lhs(), *this);
227  return *this;
228  }
229 
231  template <typename T1, typename T2>
233  {
235  return *this;
236  }
237 
240  {
241  //get kernel:
242  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_add");
243  k.local_work_size(0, 1);
244  k.global_work_size(0, 1);
245 
246  viennacl::ocl::enqueue(k(val_, other.val_));
247  return *this;
248  }
251  {
252  //get kernel:
253  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_add");
254  k.local_work_size(0, 1);
255  k.global_work_size(0, 1);
256 
257  viennacl::ocl::enqueue(k(val_, other.val_));
258  return *this;
259  }
260 
261 
264  {
265  //get kernel:
266  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_sub");
267  k.local_work_size(0, 1);
268  k.global_work_size(0, 1);
269 
270  viennacl::ocl::enqueue(k(val_, other.val_));
271  return *this;
272  }
275  {
276  //get kernel:
277  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_sub");
278  k.local_work_size(0, 1);
279  k.global_work_size(0, 1);
280 
281  viennacl::ocl::enqueue(k(val_, other.val_));
282  return *this;
283  }
284 
285 
288  {
289  //get kernel:
290  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_mul");
291  k.local_work_size(0, 1);
292  k.global_work_size(0, 1);
293 
294  viennacl::ocl::enqueue(k(val_, other.val_));
295  return *this;
296  }
299  {
300  //get kernel:
301  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_mul");
302  k.local_work_size(0, 1);
303  k.global_work_size(0, 1);
304 
305  viennacl::ocl::enqueue(k(val_, other.val_));
306  return *this;
307  }
308 
309 
311 
313  {
314  //get kernel:
315  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "inplace_div");
316  k.local_work_size(0, 1);
317  k.global_work_size(0, 1);
318 
319  viennacl::ocl::enqueue(k(val_, other.val_));
320  return *this;
321  }
324  {
325  //get kernel:
326  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_inplace_div");
327  k.local_work_size(0, 1);
328  k.global_work_size(0, 1);
329 
330  viennacl::ocl::enqueue(k(val_, other.val_));
331  return *this;
332  }
333 
334 
336 
338  {
339  scalar<TYPE> result;
340  //get kernel:
341  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "add");
342  k.local_work_size(0, 1);
343  k.global_work_size(0, 1);
344 
345  viennacl::ocl::enqueue(k(val_, other.val_, result));
346  return result;
347  }
349  template <typename T1, typename T2, typename OP>
351  {
352  scalar<TYPE> result = proxy;
353  //get kernel:
354  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "add");
355  k.local_work_size(0, 1);
356  k.global_work_size(0, 1);
357 
358  viennacl::ocl::enqueue(k(val_, result, result));
359  return result;
360  }
363  {
364  scalar<TYPE> result;
365  //get kernel:
366  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_add");
367  k.local_work_size(0, 1);
368  k.global_work_size(0, 1);
369 
370  viennacl::ocl::enqueue(k(val_, other, result));
371  return result;
372  }
373 
374 
376 
377  scalar<TYPE> operator - (scalar<TYPE> const & other) const
378  {
379  scalar<TYPE> result;
380  //get kernel:
381  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "sub");
382  k.local_work_size(0, 1);
383  k.global_work_size(0, 1);
384 
385  viennacl::ocl::enqueue(k(val_, other.val_, result));
386  return result;
387  }
389  template <typename T1, typename T2, typename OP>
391  {
392  scalar<TYPE> result = *this;
393  //get kernel:
394  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "sub");
395  k.local_work_size(0, 1);
396  k.global_work_size(0, 1);
397 
398  viennacl::ocl::enqueue(k(val_, result, result));
399  return result;
400  }
402  scalar<TYPE> operator - (TYPE other) const
403  {
404  scalar<TYPE> result;
405  //get kernel:
406  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_sub");
407  k.local_work_size(0, 1);
408  k.global_work_size(0, 1);
409 
410  viennacl::ocl::enqueue(k(val_, other, result));
411  return result;
412 
413  return result;
414  }
415 
417 
418  scalar<TYPE> operator * (scalar<TYPE> const & other) const
419  {
420  scalar<TYPE> result;
421  //get kernel:
422  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "mul");
423  k.local_work_size(0, 1);
424  k.global_work_size(0, 1);
425 
426  viennacl::ocl::enqueue(k(val_, other.val_, result));
427  return result;
428  }
430  template <typename T1, typename T2, typename OP>
432  {
433  scalar<TYPE> result = proxy;
434  //get kernel:
435  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "mul");
436  k.local_work_size(0, 1);
437  k.global_work_size(0, 1);
438 
439  viennacl::ocl::enqueue(k(val_, result, result));
440  return result;
441  }
443  scalar<TYPE> operator * (TYPE other) const
444  {
445  scalar<TYPE> result;
446  //get kernel:
447  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_mul");
448  k.local_work_size(0, 1);
449  k.global_work_size(0, 1);
450 
451  viennacl::ocl::enqueue(k(val_, other, result));
452  return result;
453  }
454 
456 
457  scalar<TYPE> operator / (scalar<TYPE> const & other) const
458  {
459  scalar<TYPE> result;
460  //get kernel:
461  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "divide");
462  k.local_work_size(0, 1);
463  k.global_work_size(0, 1);
464 
465  viennacl::ocl::enqueue(k(val_, other.val_, result));
466  return result;
467  }
469  template <typename T1, typename T2, typename OP>
471  {
472  scalar<TYPE> result = proxy;
473  //get kernel:
474  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "divide");
475  k.local_work_size(0, 1);
476  k.global_work_size(0, 1);
477 
478  viennacl::ocl::enqueue(k(val_, result, result));
479  return result;
480  }
482  scalar<TYPE> operator / (TYPE other) const
483  {
484  scalar<TYPE> result;
485  //get kernel:
486  viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::scalar<TYPE, 1>::program_name(), "cpu_div");
487  k.local_work_size(0, 1);
488  k.global_work_size(0, 1);
489 
490  viennacl::ocl::enqueue(k(val_, other, result));
491  return result;
492  }
493 
495  const viennacl::ocl::handle<cl_mem> & handle() const { return val_; }
496 
497  private:
499  };
500 
501 
502  //stream operators:
504  template<class SCALARTYPE>
505  std::ostream & operator<<(std::ostream & s, const scalar<SCALARTYPE> & val)
506  {
507  SCALARTYPE temp = val;
508  s << temp;
509  return s;
510  }
511 
513  template<class SCALARTYPE>
514  std::istream & operator>>(std::istream & s, const scalar<SCALARTYPE> & val)
515  {
516  SCALARTYPE temp;
517  s >> temp;
518  val = temp;
519  return s;
520  }
521 
522 } //namespace viennacl
523 
524 #endif