ViennaCL - The Vienna Computing Library  1.5.1
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-2014, 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 PDF 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 
41 
42 
43  namespace detail
44  {
45 
47  template <typename T>
49  {
50  typedef T type;
51  enum { special = 0 };
52  };
53 
54 #ifdef VIENNACL_WITH_OPENCL
55  template <>
56  struct convert_to_opencl<unsigned int>
57  {
58  typedef cl_uint type;
59  //enum { special = (sizeof(unsigned int) != sizeof(cl_uint)) };
60  enum { special = 1 };
61  };
62 
63  template <>
64  struct convert_to_opencl<int>
65  {
66  typedef cl_int type;
67  //enum { special = (sizeof(int) != sizeof(cl_int)) };
68  enum { special = 1 };
69  };
70 
71 
72  template <>
73  struct convert_to_opencl<unsigned long>
74  {
75  typedef cl_ulong type;
76  //enum { special = (sizeof(unsigned long) != sizeof(cl_ulong)) };
77  enum { special = 1 };
78  };
79 
80  template <>
81  struct convert_to_opencl<long>
82  {
83  typedef cl_long type;
84  //enum { special = (sizeof(long) != sizeof(cl_long)) };
85  enum { special = 1 };
86  };
87 #endif
88 
89 
90  } //namespace detail
91 
92 
94  template <typename T, bool special = detail::convert_to_opencl<T>::special>
96  {
97  typedef T cpu_type;
98  typedef typename detail::convert_to_opencl<T>::type target_type;
99 
100  public:
101  explicit typesafe_host_array() : bytes_buffer_(NULL), buffer_size_(0) {}
102 
103  explicit typesafe_host_array(mem_handle const & handle, vcl_size_t num = 0) : bytes_buffer_(NULL), buffer_size_(sizeof(cpu_type) * num)
104  {
105  resize(handle, num);
106  }
107 
108  ~typesafe_host_array() { delete[] bytes_buffer_; }
109 
110  //
111  // Resize functionality
112  //
113 
115  void raw_resize(mem_handle const & /*handle*/, vcl_size_t num)
116  {
117  buffer_size_ = sizeof(cpu_type) * num;
118 
119  if (num > 0)
120  {
121  if (bytes_buffer_)
122  delete[] bytes_buffer_;
123 
124  bytes_buffer_ = new char[buffer_size_];
125  }
126  }
127 
129  void resize(mem_handle const & handle, vcl_size_t num)
130  {
131  raw_resize(handle, num);
132 
133  if (num > 0)
134  {
135  for (vcl_size_t i=0; i<buffer_size_; ++i)
136  bytes_buffer_[i] = 0;
137  }
138  }
139 
140  //
141  // Setter and Getter
142  //
143 
144  template <typename U>
145  void set(vcl_size_t index, U value)
146  {
147  reinterpret_cast<cpu_type *>(bytes_buffer_)[index] = static_cast<cpu_type>(value);
148  }
149 
150  void * get() { return reinterpret_cast<void *>(bytes_buffer_); }
151  cpu_type operator[](vcl_size_t index) const
152  {
153  assert(index < size() && bool("index out of bounds"));
154 
155  return reinterpret_cast<cpu_type *>(bytes_buffer_)[index];
156  }
157 
158  vcl_size_t raw_size() const { return buffer_size_; }
160  {
161  return sizeof(cpu_type);
162  }
163  vcl_size_t size() const { return buffer_size_ / element_size(); }
164 
165  private:
166  char * bytes_buffer_;
167  vcl_size_t buffer_size_;
168  };
169 
170 
171 
172 
174  template <typename T>
175  class typesafe_host_array<T, true>
176  {
177  typedef T cpu_type;
178  typedef typename detail::convert_to_opencl<T>::type target_type;
179 
180  public:
181  explicit typesafe_host_array() : convert_to_opencl_( (default_memory_type() == OPENCL_MEMORY) ? true : false), bytes_buffer_(NULL), buffer_size_(0) {}
182 
183  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)
184  {
185  resize(handle, num);
186  }
187 
188  ~typesafe_host_array() { delete[] bytes_buffer_; }
189 
190  //
191  // Resize functionality
192  //
193 
196  {
197  buffer_size_ = sizeof(cpu_type) * num;
198  (void)handle; //silence unused variable warning if compiled without OpenCL support
199 
200 #ifdef VIENNACL_WITH_OPENCL
201  memory_types mem_type = handle.get_active_handle_id();
202  if (mem_type == MEMORY_NOT_INITIALIZED)
203  mem_type = default_memory_type();
204 
205  if (mem_type == OPENCL_MEMORY)
206  {
207  convert_to_opencl_ = true;
208  buffer_size_ = sizeof(target_type) * num;
209  }
210 #endif
211 
212  if (num > 0)
213  {
214  if (bytes_buffer_)
215  delete[] bytes_buffer_;
216 
217  bytes_buffer_ = new char[buffer_size_];
218  }
219  }
220 
222  void resize(mem_handle const & handle, vcl_size_t num)
223  {
224  raw_resize(handle, num);
225 
226  if (num > 0)
227  {
228  for (vcl_size_t i=0; i<buffer_size_; ++i)
229  bytes_buffer_[i] = 0;
230  }
231  }
232 
233  //
234  // Setter and Getter
235  //
236 
237  template <typename U>
238  void set(vcl_size_t index, U value)
239  {
240 #ifdef VIENNACL_WITH_OPENCL
241  if (convert_to_opencl_)
242  reinterpret_cast<target_type *>(bytes_buffer_)[index] = static_cast<target_type>(value);
243  else
244 #endif
245  reinterpret_cast<cpu_type *>(bytes_buffer_)[index] = static_cast<cpu_type>(value);
246  }
247 
248  void * get() { return reinterpret_cast<void *>(bytes_buffer_); }
249  cpu_type operator[](vcl_size_t index) const
250  {
251  assert(index < size() && bool("index out of bounds"));
252 #ifdef VIENNACL_WITH_OPENCL
253  if (convert_to_opencl_)
254  return static_cast<cpu_type>(reinterpret_cast<target_type *>(bytes_buffer_)[index]);
255 #endif
256  return reinterpret_cast<cpu_type *>(bytes_buffer_)[index];
257  }
258 
259  vcl_size_t raw_size() const { return buffer_size_; }
261  {
262 #ifdef VIENNACL_WITH_OPENCL
263  if (convert_to_opencl_)
264  return sizeof(target_type);
265 #endif
266  return sizeof(cpu_type);
267  }
268  vcl_size_t size() const { return buffer_size_ / element_size(); }
269 
270  private:
271  bool convert_to_opencl_;
272  char * bytes_buffer_;
273  vcl_size_t buffer_size_;
274  };
275 
276  } //backend
277 
278 
279 } //viennacl
280 #endif
Helper class implementing an array on the host. Default case: No conversion necessary.
Definition: util.hpp:95
vcl_size_t raw_size() const
Definition: util.hpp:259
std::size_t vcl_size_t
Definition: forwards.h:58
Definition: forwards.h:478
vcl_size_t size() const
Definition: util.hpp:163
void set(vcl_size_t index, U value)
Definition: util.hpp:238
typesafe_host_array(mem_handle const &handle, vcl_size_t num=0)
Definition: util.hpp:103
cpu_type operator[](vcl_size_t index) const
Definition: util.hpp:249
cpu_type operator[](vcl_size_t index) const
Definition: util.hpp:151
This file provides the forward declarations for the main types used within ViennaCL.
vcl_size_t raw_size() const
Definition: util.hpp:158
memory_types
Definition: forwards.h:476
~typesafe_host_array()
Definition: util.hpp:108
void set(vcl_size_t index, U value)
Definition: util.hpp:145
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:91
void resize(mem_handle const &handle, vcl_size_t num)
Resize including initialization of new memory (cf. std::vector<>)
Definition: util.hpp:129
Definition: forwards.h:480
Implements the multi-memory-domain handle.
memory_types default_memory_type()
Definition: mem_handle.hpp:52
void resize(mem_handle const &handle, vcl_size_t num)
Resize including initialization of new memory (cf. std::vector<>)
Definition: util.hpp:222
typesafe_host_array()
Definition: util.hpp:101
vcl_size_t element_size() const
Definition: util.hpp:260
Main abstraction class for multiple memory domains. Represents a buffer in either main RAM...
Definition: mem_handle.hpp:62
vcl_size_t size() const
Definition: util.hpp:268
typesafe_host_array(mem_handle const &handle, vcl_size_t num=0)
Definition: util.hpp:183
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
void raw_resize(mem_handle const &, vcl_size_t num)
Resize without initializing the new memory.
Definition: util.hpp:115
void raw_resize(mem_handle const &handle, vcl_size_t num)
Resize without initializing the new memory.
Definition: util.hpp:195
vcl_size_t element_size() const
Definition: util.hpp:159
Helper struct for converting a type to its OpenCL pendant.
Definition: util.hpp:48