ViennaCL - The Vienna Computing Library
1.5.2
|
00001 #ifndef VIENNACL_BACKEND_UTIL_HPP 00002 #define VIENNACL_BACKEND_UTIL_HPP 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2014, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 Portions of this software are copyright by UChicago Argonne, LLC. 00009 00010 ----------------- 00011 ViennaCL - The Vienna Computing Library 00012 ----------------- 00013 00014 Project Head: Karl Rupp rupp@iue.tuwien.ac.at 00015 00016 (A list of authors and contributors can be found in the PDF manual) 00017 00018 License: MIT (X11), see file LICENSE in the base directory 00019 ============================================================================= */ 00020 00025 #include <vector> 00026 #include <cassert> 00027 00028 #include "viennacl/forwards.h" 00029 #include "viennacl/backend/mem_handle.hpp" 00030 00031 #ifdef VIENNACL_WITH_OPENCL 00032 #include "viennacl/backend/opencl.hpp" 00033 #endif 00034 00035 00036 namespace viennacl 00037 { 00038 namespace backend 00039 { 00040 00041 00042 00043 namespace detail 00044 { 00045 00047 template <typename T> 00048 struct convert_to_opencl 00049 { 00050 typedef T type; 00051 enum { special = 0 }; 00052 }; 00053 00054 #ifdef VIENNACL_WITH_OPENCL 00055 template <> 00056 struct convert_to_opencl<unsigned int> 00057 { 00058 typedef cl_uint type; 00059 //enum { special = (sizeof(unsigned int) != sizeof(cl_uint)) }; 00060 enum { special = 1 }; 00061 }; 00062 00063 template <> 00064 struct convert_to_opencl<int> 00065 { 00066 typedef cl_int type; 00067 //enum { special = (sizeof(int) != sizeof(cl_int)) }; 00068 enum { special = 1 }; 00069 }; 00070 00071 00072 template <> 00073 struct convert_to_opencl<unsigned long> 00074 { 00075 typedef cl_ulong type; 00076 //enum { special = (sizeof(unsigned long) != sizeof(cl_ulong)) }; 00077 enum { special = 1 }; 00078 }; 00079 00080 template <> 00081 struct convert_to_opencl<long> 00082 { 00083 typedef cl_long type; 00084 //enum { special = (sizeof(long) != sizeof(cl_long)) }; 00085 enum { special = 1 }; 00086 }; 00087 #endif 00088 00089 00090 } //namespace detail 00091 00092 00094 template <typename T, bool special = detail::convert_to_opencl<T>::special> 00095 class typesafe_host_array 00096 { 00097 typedef T cpu_type; 00098 typedef typename detail::convert_to_opencl<T>::type target_type; 00099 00100 public: 00101 explicit typesafe_host_array() : bytes_buffer_(NULL), buffer_size_(0) {} 00102 00103 explicit typesafe_host_array(mem_handle const & handle, vcl_size_t num = 0) : bytes_buffer_(NULL), buffer_size_(sizeof(cpu_type) * num) 00104 { 00105 resize(handle, num); 00106 } 00107 00108 ~typesafe_host_array() { delete[] bytes_buffer_; } 00109 00110 // 00111 // Resize functionality 00112 // 00113 00115 void raw_resize(mem_handle const & /*handle*/, vcl_size_t num) 00116 { 00117 buffer_size_ = sizeof(cpu_type) * num; 00118 00119 if (num > 0) 00120 { 00121 if (bytes_buffer_) 00122 delete[] bytes_buffer_; 00123 00124 bytes_buffer_ = new char[buffer_size_]; 00125 } 00126 } 00127 00129 void resize(mem_handle const & handle, vcl_size_t num) 00130 { 00131 raw_resize(handle, num); 00132 00133 if (num > 0) 00134 { 00135 for (vcl_size_t i=0; i<buffer_size_; ++i) 00136 bytes_buffer_[i] = 0; 00137 } 00138 } 00139 00140 // 00141 // Setter and Getter 00142 // 00143 00144 template <typename U> 00145 void set(vcl_size_t index, U value) 00146 { 00147 reinterpret_cast<cpu_type *>(bytes_buffer_)[index] = static_cast<cpu_type>(value); 00148 } 00149 00150 void * get() { return reinterpret_cast<void *>(bytes_buffer_); } 00151 cpu_type operator[](vcl_size_t index) const 00152 { 00153 assert(index < size() && bool("index out of bounds")); 00154 00155 return reinterpret_cast<cpu_type *>(bytes_buffer_)[index]; 00156 } 00157 00158 vcl_size_t raw_size() const { return buffer_size_; } 00159 vcl_size_t element_size() const 00160 { 00161 return sizeof(cpu_type); 00162 } 00163 vcl_size_t size() const { return buffer_size_ / element_size(); } 00164 00165 private: 00166 char * bytes_buffer_; 00167 vcl_size_t buffer_size_; 00168 }; 00169 00170 00171 00172 00174 template <typename T> 00175 class typesafe_host_array<T, true> 00176 { 00177 typedef T cpu_type; 00178 typedef typename detail::convert_to_opencl<T>::type target_type; 00179 00180 public: 00181 explicit typesafe_host_array() : convert_to_opencl_( (default_memory_type() == OPENCL_MEMORY) ? true : false), bytes_buffer_(NULL), buffer_size_(0) {} 00182 00183 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) 00184 { 00185 resize(handle, num); 00186 } 00187 00188 ~typesafe_host_array() { delete[] bytes_buffer_; } 00189 00190 // 00191 // Resize functionality 00192 // 00193 00195 void raw_resize(mem_handle const & handle, vcl_size_t num) 00196 { 00197 buffer_size_ = sizeof(cpu_type) * num; 00198 (void)handle; //silence unused variable warning if compiled without OpenCL support 00199 00200 #ifdef VIENNACL_WITH_OPENCL 00201 memory_types mem_type = handle.get_active_handle_id(); 00202 if (mem_type == MEMORY_NOT_INITIALIZED) 00203 mem_type = default_memory_type(); 00204 00205 if (mem_type == OPENCL_MEMORY) 00206 { 00207 convert_to_opencl_ = true; 00208 buffer_size_ = sizeof(target_type) * num; 00209 } 00210 #endif 00211 00212 if (num > 0) 00213 { 00214 if (bytes_buffer_) 00215 delete[] bytes_buffer_; 00216 00217 bytes_buffer_ = new char[buffer_size_]; 00218 } 00219 } 00220 00222 void resize(mem_handle const & handle, vcl_size_t num) 00223 { 00224 raw_resize(handle, num); 00225 00226 if (num > 0) 00227 { 00228 for (vcl_size_t i=0; i<buffer_size_; ++i) 00229 bytes_buffer_[i] = 0; 00230 } 00231 } 00232 00233 // 00234 // Setter and Getter 00235 // 00236 00237 template <typename U> 00238 void set(vcl_size_t index, U value) 00239 { 00240 #ifdef VIENNACL_WITH_OPENCL 00241 if (convert_to_opencl_) 00242 reinterpret_cast<target_type *>(bytes_buffer_)[index] = static_cast<target_type>(value); 00243 else 00244 #endif 00245 reinterpret_cast<cpu_type *>(bytes_buffer_)[index] = static_cast<cpu_type>(value); 00246 } 00247 00248 void * get() { return reinterpret_cast<void *>(bytes_buffer_); } 00249 cpu_type operator[](vcl_size_t index) const 00250 { 00251 assert(index < size() && bool("index out of bounds")); 00252 #ifdef VIENNACL_WITH_OPENCL 00253 if (convert_to_opencl_) 00254 return static_cast<cpu_type>(reinterpret_cast<target_type *>(bytes_buffer_)[index]); 00255 #endif 00256 return reinterpret_cast<cpu_type *>(bytes_buffer_)[index]; 00257 } 00258 00259 vcl_size_t raw_size() const { return buffer_size_; } 00260 vcl_size_t element_size() const 00261 { 00262 #ifdef VIENNACL_WITH_OPENCL 00263 if (convert_to_opencl_) 00264 return sizeof(target_type); 00265 #endif 00266 return sizeof(cpu_type); 00267 } 00268 vcl_size_t size() const { return buffer_size_ / element_size(); } 00269 00270 private: 00271 bool convert_to_opencl_; 00272 char * bytes_buffer_; 00273 vcl_size_t buffer_size_; 00274 }; 00275 00276 } //backend 00277 00278 00279 } //viennacl 00280 #endif