ViennaCL - The Vienna Computing Library  1.7.0
Free open-source GPU-accelerated linear algebra and solver library.
util.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_BACKEND_UTIL_HPP
2 #define VIENNACL_BACKEND_UTIL_HPP
3 
4 /* =========================================================================
5  Copyright (c) 2010-2015, Institute for Microelectronics,
6  Institute for Analysis and Scientific Computing,
7  TU Wien.
8  Portions of this software are copyright by UChicago Argonne, LLC.
9 
10  -----------------
11  ViennaCL - The Vienna Computing Library
12  -----------------
13 
14  Project Head: Karl Rupp rupp@iue.tuwien.ac.at
15 
16  (A list of authors and contributors can be found in the manual)
17 
18  License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20 
25 #include <vector>
26 #include <cassert>
27 
28 #include "viennacl/forwards.h"
30 
31 #ifdef VIENNACL_WITH_OPENCL
33 #endif
34 
35 
36 namespace viennacl
37 {
38 namespace backend
39 {
40 namespace detail
41 {
42 
44  template<typename T>
46  {
47  typedef T type;
48  enum { special = 0 };
49  };
50 
51 #ifdef VIENNACL_WITH_OPENCL
52  template<>
53  struct convert_to_opencl<unsigned int>
54  {
55  typedef cl_uint type;
56  //enum { special = (sizeof(unsigned int) != sizeof(cl_uint)) };
57  enum { special = 1 };
58  };
59 
60  template<>
61  struct convert_to_opencl<int>
62  {
63  typedef cl_int type;
64  //enum { special = (sizeof(int) != sizeof(cl_int)) };
65  enum { special = 1 };
66  };
67 
68 
69  template<>
70  struct convert_to_opencl<unsigned long>
71  {
72  typedef cl_ulong type;
73  //enum { special = (sizeof(unsigned long) != sizeof(cl_ulong)) };
74  enum { special = 1 };
75  };
76 
77  template<>
78  struct convert_to_opencl<long>
79  {
80  typedef cl_long type;
81  //enum { special = (sizeof(long) != sizeof(cl_long)) };
82  enum { special = 1 };
83  };
84 #endif
85 
86 
87 } //namespace detail
88 
89 
91 template<typename T, bool special = detail::convert_to_opencl<T>::special>
93 {
94  typedef T cpu_type;
95  typedef typename detail::convert_to_opencl<T>::type target_type;
96 
97 public:
98  explicit typesafe_host_array() : bytes_buffer_(NULL), buffer_size_(0) {}
99 
100  explicit typesafe_host_array(mem_handle const & handle, vcl_size_t num = 0) : bytes_buffer_(NULL), buffer_size_(sizeof(cpu_type) * num)
101  {
102  resize(handle, num);
103  }
104 
105  ~typesafe_host_array() { delete[] bytes_buffer_; }
106 
107  //
108  // Setter and Getter
109  //
110  void * get() { return reinterpret_cast<void *>(bytes_buffer_); }
111  vcl_size_t raw_size() const { return buffer_size_; }
112  vcl_size_t element_size() const { return sizeof(cpu_type); }
113  vcl_size_t size() const { return buffer_size_ / element_size(); }
114  template<typename U>
115  void set(vcl_size_t index, U value)
116  {
117  reinterpret_cast<cpu_type *>(bytes_buffer_)[index] = static_cast<cpu_type>(value);
118  }
119 
120  //
121  // Resize functionality
122  //
123 
125  void raw_resize(mem_handle const & /*handle*/, vcl_size_t num)
126  {
127  buffer_size_ = sizeof(cpu_type) * num;
128 
129  if (num > 0)
130  {
131  delete[] bytes_buffer_;
132 
133  bytes_buffer_ = new char[buffer_size_];
134  }
135  }
136 
138  void resize(mem_handle const & handle, vcl_size_t num)
139  {
140  raw_resize(handle, num);
141 
142  if (num > 0)
143  {
144  for (vcl_size_t i=0; i<buffer_size_; ++i)
145  bytes_buffer_[i] = 0;
146  }
147  }
148 
149  cpu_type operator[](vcl_size_t index) const
150  {
151  assert(index < size() && bool("index out of bounds"));
152 
153  return reinterpret_cast<cpu_type *>(bytes_buffer_)[index];
154  }
155 
156 private:
157  char * bytes_buffer_;
158  vcl_size_t buffer_size_;
159 };
160 
161 
162 
163 
165 template<typename T>
166 class typesafe_host_array<T, true>
167 {
168  typedef T cpu_type;
169  typedef typename detail::convert_to_opencl<T>::type target_type;
170 
171 public:
172  explicit typesafe_host_array() : convert_to_opencl_( (default_memory_type() == OPENCL_MEMORY) ? true : false), bytes_buffer_(NULL), buffer_size_(0) {}
173 
174  explicit typesafe_host_array(mem_handle const & handle, vcl_size_t num = 0) : convert_to_opencl_(false), bytes_buffer_(NULL), buffer_size_(sizeof(cpu_type) * num)
175  {
176  resize(handle, num);
177  }
178 
179  ~typesafe_host_array() { delete[] bytes_buffer_; }
180 
181  //
182  // Setter and Getter
183  //
184 
185  template<typename U>
186  void set(vcl_size_t index, U value)
187  {
188 #ifdef VIENNACL_WITH_OPENCL
189  if (convert_to_opencl_)
190  reinterpret_cast<target_type *>(bytes_buffer_)[index] = static_cast<target_type>(value);
191  else
192 #endif
193  reinterpret_cast<cpu_type *>(bytes_buffer_)[index] = static_cast<cpu_type>(value);
194  }
195 
196  void * get() { return reinterpret_cast<void *>(bytes_buffer_); }
197  cpu_type operator[](vcl_size_t index) const
198  {
199  assert(index < size() && bool("index out of bounds"));
200 #ifdef VIENNACL_WITH_OPENCL
201  if (convert_to_opencl_)
202  return static_cast<cpu_type>(reinterpret_cast<target_type *>(bytes_buffer_)[index]);
203 #endif
204  return reinterpret_cast<cpu_type *>(bytes_buffer_)[index];
205  }
206 
207  vcl_size_t raw_size() const { return buffer_size_; }
209  {
210 #ifdef VIENNACL_WITH_OPENCL
211  if (convert_to_opencl_)
212  return sizeof(target_type);
213 #endif
214  return sizeof(cpu_type);
215  }
216  vcl_size_t size() const { return buffer_size_ / element_size(); }
217 
218  //
219  // Resize functionality
220  //
221 
224  {
225  buffer_size_ = sizeof(cpu_type) * num;
226  (void)handle; //silence unused variable warning if compiled without OpenCL support
227 
228 #ifdef VIENNACL_WITH_OPENCL
229  memory_types mem_type = handle.get_active_handle_id();
230  if (mem_type == MEMORY_NOT_INITIALIZED)
231  mem_type = default_memory_type();
232 
233  if (mem_type == OPENCL_MEMORY)
234  {
235  convert_to_opencl_ = true;
236  buffer_size_ = sizeof(target_type) * num;
237  }
238 #endif
239 
240  if (num > 0)
241  {
242  delete[] bytes_buffer_;
243 
244  bytes_buffer_ = new char[buffer_size_];
245  }
246  }
247 
249  void resize(mem_handle const & handle, vcl_size_t num)
250  {
251  raw_resize(handle, num);
252 
253  if (num > 0)
254  {
255  for (vcl_size_t i=0; i<buffer_size_; ++i)
256  bytes_buffer_[i] = 0;
257  }
258  }
259 
260 private:
261  bool convert_to_opencl_;
262  char * bytes_buffer_;
263  vcl_size_t buffer_size_;
264 };
265 
266 } //backend
267 } //viennacl
268 #endif
Helper class implementing an array on the host. Default case: No conversion necessary.
Definition: util.hpp:92
void raw_resize(mem_handle const &, vcl_size_t num)
Resize without initializing the new memory.
Definition: util.hpp:125
vcl_size_t element_size() const
Definition: util.hpp:112
cpu_type operator[](vcl_size_t index) const
Definition: util.hpp:197
typesafe_host_array(mem_handle const &handle, vcl_size_t num=0)
Definition: util.hpp:174
cpu_type operator[](vcl_size_t index) const
Definition: util.hpp:149
This file provides the forward declarations for the main types used within ViennaCL.
void resize(mem_handle const &handle, vcl_size_t num)
Resize including initialization of new memory (cf. std::vector<>)
Definition: util.hpp:138
typesafe_host_array(mem_handle const &handle, vcl_size_t num=0)
Definition: util.hpp:100
Main namespace in ViennaCL. Holds all the basic types such as vector, matrix, etc. and defines operations upon them.
Definition: cpu_ram.hpp:34
Definition: blas3.hpp:36
void raw_resize(mem_handle const &handle, vcl_size_t num)
Resize without initializing the new memory.
Definition: util.hpp:223
Implements the multi-memory-domain handle.
void set(vcl_size_t index, U value)
Definition: util.hpp:186
std::size_t vcl_size_t
Definition: forwards.h:75
memory_types default_memory_type()
Returns the default memory type for the given configuration.
Definition: mem_handle.hpp:73
void resize(mem_handle const &handle, vcl_size_t num)
Resize including initialization of new memory (cf. std::vector<>)
Definition: util.hpp:249
void set(vcl_size_t index, U value)
Definition: util.hpp:115
Main abstraction class for multiple memory domains. Represents a buffer in either main RAM...
Definition: mem_handle.hpp:89
Implementations for the OpenCL backend functionality.
viennacl::backend::mem_handle & handle(T &obj)
Returns the generic memory handle of an object. Non-const version.
Definition: handle.hpp:41
memory_types
Definition: forwards.h:345
vcl_size_t raw_size() const
Definition: util.hpp:111
Helper struct for converting a type to its OpenCL pendant.
Definition: util.hpp:45
memory_types get_active_handle_id() const
Returns an ID for the currently active memory buffer. Other memory buffers might contain old or no da...
Definition: mem_handle.hpp:118