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 delete[] bytes_buffer_; 00122 00123 bytes_buffer_ = new char[buffer_size_]; 00124 } 00125 } 00126 00128 void resize(mem_handle const & handle, vcl_size_t num) 00129 { 00130 raw_resize(handle, num); 00131 00132 if (num > 0) 00133 { 00134 for (vcl_size_t i=0; i<buffer_size_; ++i) 00135 bytes_buffer_[i] = 0; 00136 } 00137 } 00138 00139 // 00140 // Setter and Getter 00141 // 00142 00143 template <typename U> 00144 void set(vcl_size_t index, U value) 00145 { 00146 reinterpret_cast<cpu_type *>(bytes_buffer_)[index] = static_cast<cpu_type>(value); 00147 } 00148 00149 void * get() { return reinterpret_cast<void *>(bytes_buffer_); } 00150 cpu_type operator[](vcl_size_t index) const 00151 { 00152 assert(index < size() && bool("index out of bounds")); 00153 00154 return reinterpret_cast<cpu_type *>(bytes_buffer_)[index]; 00155 } 00156 00157 vcl_size_t raw_size() const { return buffer_size_; } 00158 vcl_size_t element_size() const 00159 { 00160 return sizeof(cpu_type); 00161 } 00162 vcl_size_t size() const { return buffer_size_ / element_size(); } 00163 00164 private: 00165 char * bytes_buffer_; 00166 vcl_size_t buffer_size_; 00167 }; 00168 00169 00170 00171 00173 template <typename T> 00174 class typesafe_host_array<T, true> 00175 { 00176 typedef T cpu_type; 00177 typedef typename detail::convert_to_opencl<T>::type target_type; 00178 00179 public: 00180 explicit typesafe_host_array() : convert_to_opencl_( (default_memory_type() == OPENCL_MEMORY) ? true : false), bytes_buffer_(NULL), buffer_size_(0) {} 00181 00182 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) 00183 { 00184 resize(handle, num); 00185 } 00186 00187 ~typesafe_host_array() { delete[] bytes_buffer_; } 00188 00189 // 00190 // Resize functionality 00191 // 00192 00194 void raw_resize(mem_handle const & handle, vcl_size_t num) 00195 { 00196 buffer_size_ = sizeof(cpu_type) * num; 00197 (void)handle; //silence unused variable warning if compiled without OpenCL support 00198 00199 #ifdef VIENNACL_WITH_OPENCL 00200 memory_types mem_type = handle.get_active_handle_id(); 00201 if (mem_type == MEMORY_NOT_INITIALIZED) 00202 mem_type = default_memory_type(); 00203 00204 if (mem_type == OPENCL_MEMORY) 00205 { 00206 convert_to_opencl_ = true; 00207 buffer_size_ = sizeof(target_type) * num; 00208 } 00209 #endif 00210 00211 if (num > 0) 00212 { 00213 delete[] bytes_buffer_; 00214 00215 bytes_buffer_ = new char[buffer_size_]; 00216 } 00217 } 00218 00220 void resize(mem_handle const & handle, vcl_size_t num) 00221 { 00222 raw_resize(handle, num); 00223 00224 if (num > 0) 00225 { 00226 for (vcl_size_t i=0; i<buffer_size_; ++i) 00227 bytes_buffer_[i] = 0; 00228 } 00229 } 00230 00231 // 00232 // Setter and Getter 00233 // 00234 00235 template <typename U> 00236 void set(vcl_size_t index, U value) 00237 { 00238 #ifdef VIENNACL_WITH_OPENCL 00239 if (convert_to_opencl_) 00240 reinterpret_cast<target_type *>(bytes_buffer_)[index] = static_cast<target_type>(value); 00241 else 00242 #endif 00243 reinterpret_cast<cpu_type *>(bytes_buffer_)[index] = static_cast<cpu_type>(value); 00244 } 00245 00246 void * get() { return reinterpret_cast<void *>(bytes_buffer_); } 00247 cpu_type operator[](vcl_size_t index) const 00248 { 00249 assert(index < size() && bool("index out of bounds")); 00250 #ifdef VIENNACL_WITH_OPENCL 00251 if (convert_to_opencl_) 00252 return static_cast<cpu_type>(reinterpret_cast<target_type *>(bytes_buffer_)[index]); 00253 #endif 00254 return reinterpret_cast<cpu_type *>(bytes_buffer_)[index]; 00255 } 00256 00257 vcl_size_t raw_size() const { return buffer_size_; } 00258 vcl_size_t element_size() const 00259 { 00260 #ifdef VIENNACL_WITH_OPENCL 00261 if (convert_to_opencl_) 00262 return sizeof(target_type); 00263 #endif 00264 return sizeof(cpu_type); 00265 } 00266 vcl_size_t size() const { return buffer_size_ / element_size(); } 00267 00268 private: 00269 bool convert_to_opencl_; 00270 char * bytes_buffer_; 00271 vcl_size_t buffer_size_; 00272 }; 00273 00274 } //backend 00275 00276 00277 } //viennacl 00278 #endif