1 // 2 // Copyright (c) 2017 The Khronos Group Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 #ifndef _typeWrappers_h 17 #define _typeWrappers_h 18 19 #include <stdio.h> 20 #include <stdlib.h> 21 22 #if !defined(_WIN32) 23 #include <sys/mman.h> 24 #endif 25 26 #include "compat.h" 27 #include <stdio.h> 28 #include "mt19937.h" 29 #include "errorHelpers.h" 30 #include "kernelHelpers.h" 31 32 /* cl_context wrapper */ 33 34 class clContextWrapper { 35 public: clContextWrapper()36 clContextWrapper() { mContext = NULL; } clContextWrapper(cl_context program)37 clContextWrapper(cl_context program) { mContext = program; } ~clContextWrapper()38 ~clContextWrapper() 39 { 40 if (mContext != NULL) clReleaseContext(mContext); 41 } 42 43 clContextWrapper &operator=(const cl_context &rhs) 44 { 45 mContext = rhs; 46 return *this; 47 } cl_context()48 operator cl_context() const { return mContext; } 49 50 cl_context *operator&() { return &mContext; } 51 52 bool operator==(const cl_context &rhs) { return mContext == rhs; } 53 54 protected: 55 cl_context mContext; 56 }; 57 58 /* cl_program wrapper */ 59 60 class clProgramWrapper { 61 public: clProgramWrapper()62 clProgramWrapper() { mProgram = NULL; } clProgramWrapper(cl_program program)63 clProgramWrapper(cl_program program) { mProgram = program; } ~clProgramWrapper()64 ~clProgramWrapper() 65 { 66 if (mProgram != NULL) clReleaseProgram(mProgram); 67 } 68 69 clProgramWrapper &operator=(const cl_program &rhs) 70 { 71 mProgram = rhs; 72 return *this; 73 } cl_program()74 operator cl_program() const { return mProgram; } 75 76 cl_program *operator&() { return &mProgram; } 77 78 bool operator==(const cl_program &rhs) { return mProgram == rhs; } 79 80 protected: 81 cl_program mProgram; 82 }; 83 84 /* cl_kernel wrapper */ 85 86 class clKernelWrapper { 87 public: clKernelWrapper()88 clKernelWrapper() { mKernel = NULL; } clKernelWrapper(cl_kernel kernel)89 clKernelWrapper(cl_kernel kernel) { mKernel = kernel; } ~clKernelWrapper()90 ~clKernelWrapper() 91 { 92 if (mKernel != NULL) clReleaseKernel(mKernel); 93 } 94 95 clKernelWrapper &operator=(const cl_kernel &rhs) 96 { 97 mKernel = rhs; 98 return *this; 99 } cl_kernel()100 operator cl_kernel() const { return mKernel; } 101 102 cl_kernel *operator&() { return &mKernel; } 103 104 bool operator==(const cl_kernel &rhs) { return mKernel == rhs; } 105 106 protected: 107 cl_kernel mKernel; 108 }; 109 110 /* cl_mem (stream) wrapper */ 111 112 class clMemWrapper { 113 public: clMemWrapper()114 clMemWrapper() { mMem = NULL; } clMemWrapper(cl_mem mem)115 clMemWrapper(cl_mem mem) { mMem = mem; } ~clMemWrapper()116 ~clMemWrapper() 117 { 118 if (mMem != NULL) clReleaseMemObject(mMem); 119 } 120 121 clMemWrapper &operator=(const cl_mem &rhs) 122 { 123 mMem = rhs; 124 return *this; 125 } cl_mem()126 operator cl_mem() const { return mMem; } 127 128 cl_mem *operator&() { return &mMem; } 129 130 bool operator==(const cl_mem &rhs) { return mMem == rhs; } 131 132 protected: 133 cl_mem mMem; 134 }; 135 136 class clProtectedImage { 137 public: clProtectedImage()138 clProtectedImage() 139 { 140 image = NULL; 141 backingStore = NULL; 142 } 143 clProtectedImage(cl_context context, cl_mem_flags flags, 144 const cl_image_format *fmt, size_t width, 145 cl_int *errcode_ret); 146 clProtectedImage(cl_context context, cl_mem_flags flags, 147 const cl_image_format *fmt, size_t width, size_t height, 148 cl_int *errcode_ret); 149 clProtectedImage(cl_context context, cl_mem_flags flags, 150 const cl_image_format *fmt, size_t width, size_t height, 151 size_t depth, cl_int *errcode_ret); 152 clProtectedImage(cl_context context, cl_mem_object_type imageType, 153 cl_mem_flags flags, const cl_image_format *fmt, 154 size_t width, size_t height, size_t depth, 155 size_t arraySize, cl_int *errcode_ret); ~clProtectedImage()156 ~clProtectedImage() 157 { 158 if (image != NULL) clReleaseMemObject(image); 159 160 #if defined(__APPLE__) 161 if (backingStore) munmap(backingStore, backingStoreSize); 162 #endif 163 } 164 165 cl_int Create(cl_context context, cl_mem_flags flags, 166 const cl_image_format *fmt, size_t width); 167 cl_int Create(cl_context context, cl_mem_flags flags, 168 const cl_image_format *fmt, size_t width, size_t height); 169 cl_int Create(cl_context context, cl_mem_flags flags, 170 const cl_image_format *fmt, size_t width, size_t height, 171 size_t depth); 172 cl_int Create(cl_context context, cl_mem_object_type imageType, 173 cl_mem_flags flags, const cl_image_format *fmt, size_t width, 174 size_t height, size_t depth, size_t arraySize); 175 176 clProtectedImage &operator=(const cl_mem &rhs) 177 { 178 image = rhs; 179 backingStore = NULL; 180 return *this; 181 } cl_mem()182 operator cl_mem() { return image; } 183 184 cl_mem *operator&() { return ℑ } 185 186 bool operator==(const cl_mem &rhs) { return image == rhs; } 187 188 protected: 189 void *backingStore; 190 size_t backingStoreSize; 191 cl_mem image; 192 }; 193 194 /* cl_command_queue wrapper */ 195 class clCommandQueueWrapper { 196 public: clCommandQueueWrapper()197 clCommandQueueWrapper() { mMem = NULL; } clCommandQueueWrapper(cl_command_queue mem)198 clCommandQueueWrapper(cl_command_queue mem) { mMem = mem; } ~clCommandQueueWrapper()199 ~clCommandQueueWrapper() 200 { 201 if (mMem != NULL) 202 { 203 clReleaseCommandQueue(mMem); 204 } 205 } 206 207 clCommandQueueWrapper &operator=(const cl_command_queue &rhs) 208 { 209 mMem = rhs; 210 return *this; 211 } cl_command_queue()212 operator cl_command_queue() const { return mMem; } 213 214 cl_command_queue *operator&() { return &mMem; } 215 216 bool operator==(const cl_command_queue &rhs) { return mMem == rhs; } 217 218 protected: 219 cl_command_queue mMem; 220 }; 221 222 /* cl_sampler wrapper */ 223 class clSamplerWrapper { 224 public: clSamplerWrapper()225 clSamplerWrapper() { mMem = NULL; } clSamplerWrapper(cl_sampler mem)226 clSamplerWrapper(cl_sampler mem) { mMem = mem; } ~clSamplerWrapper()227 ~clSamplerWrapper() 228 { 229 if (mMem != NULL) clReleaseSampler(mMem); 230 } 231 232 clSamplerWrapper &operator=(const cl_sampler &rhs) 233 { 234 mMem = rhs; 235 return *this; 236 } cl_sampler()237 operator cl_sampler() const { return mMem; } 238 239 cl_sampler *operator&() { return &mMem; } 240 241 bool operator==(const cl_sampler &rhs) { return mMem == rhs; } 242 243 protected: 244 cl_sampler mMem; 245 }; 246 247 /* cl_event wrapper */ 248 class clEventWrapper { 249 public: clEventWrapper()250 clEventWrapper() { mMem = NULL; } clEventWrapper(cl_event mem)251 clEventWrapper(cl_event mem) { mMem = mem; } ~clEventWrapper()252 ~clEventWrapper() 253 { 254 if (mMem != NULL) clReleaseEvent(mMem); 255 } 256 257 clEventWrapper &operator=(const cl_event &rhs) 258 { 259 mMem = rhs; 260 return *this; 261 } cl_event()262 operator cl_event() const { return mMem; } 263 264 cl_event *operator&() { return &mMem; } 265 266 bool operator==(const cl_event &rhs) { return mMem == rhs; } 267 268 protected: 269 cl_event mMem; 270 }; 271 272 /* Generic protected memory buffer, for verifying access within bounds */ 273 class clProtectedArray { 274 public: 275 clProtectedArray(); 276 clProtectedArray(size_t sizeInBytes); 277 virtual ~clProtectedArray(); 278 279 void Allocate(size_t sizeInBytes); 280 281 operator void *() { return (void *)mValidBuffer; } 282 operator const void *() const { return (const void *)mValidBuffer; } 283 284 protected: 285 char *mBuffer; 286 char *mValidBuffer; 287 size_t mRealSize, mRoundedSize; 288 }; 289 290 class RandomSeed { 291 public: RandomSeed(cl_uint seed)292 RandomSeed(cl_uint seed) 293 { 294 if (seed) log_info("(seed = %10.10u) ", seed); 295 mtData = init_genrand(seed); 296 } ~RandomSeed()297 ~RandomSeed() 298 { 299 if (gReSeed) gRandomSeed = genrand_int32(mtData); 300 free_mtdata(mtData); 301 } 302 MTdata()303 operator MTdata() { return mtData; } 304 305 protected: 306 MTdata mtData; 307 }; 308 309 310 template <typename T> class BufferOwningPtr { 311 BufferOwningPtr(BufferOwningPtr const &); // do not implement 312 void operator=(BufferOwningPtr const &); // do not implement 313 314 void *ptr; 315 void *map; 316 // Bytes allocated total, pointed to by map: 317 size_t mapsize; 318 // Bytes allocated in unprotected pages, pointed to by ptr: 319 size_t allocsize; 320 bool aligned; 321 322 public: 323 explicit BufferOwningPtr(void *p = 0) ptr(p)324 : ptr(p), map(0), mapsize(0), allocsize(0), aligned(false) 325 {} BufferOwningPtr(void * p,void * m,size_t s)326 explicit BufferOwningPtr(void *p, void *m, size_t s) 327 : ptr(p), map(m), mapsize(s), allocsize(0), aligned(false) 328 { 329 #if !defined(__APPLE__) 330 if (m) 331 { 332 log_error("ERROR: unhandled code path. BufferOwningPtr allocated " 333 "with mapped buffer!"); 334 abort(); 335 } 336 #endif 337 } ~BufferOwningPtr()338 ~BufferOwningPtr() 339 { 340 if (map) 341 { 342 #if defined(__APPLE__) 343 int error = munmap(map, mapsize); 344 if (error) 345 log_error("WARNING: munmap failed in BufferOwningPtr.\n"); 346 #endif 347 } 348 else 349 { 350 if (aligned) 351 { 352 align_free(ptr); 353 } 354 else 355 { 356 free(ptr); 357 } 358 } 359 } 360 void reset(void *p, void *m = 0, size_t mapsize_ = 0, size_t allocsize_ = 0, 361 bool aligned_ = false) 362 { 363 if (map) 364 { 365 #if defined(__APPLE__) 366 int error = munmap(map, mapsize); 367 if (error) 368 log_error("WARNING: munmap failed in BufferOwningPtr.\n"); 369 #else 370 log_error("ERROR: unhandled code path. BufferOwningPtr reset with " 371 "mapped buffer!"); 372 abort(); 373 #endif 374 } 375 else 376 { 377 if (aligned) 378 { 379 align_free(ptr); 380 } 381 else 382 { 383 free(ptr); 384 } 385 } 386 ptr = p; 387 map = m; 388 mapsize = mapsize_; 389 // Force allocsize to zero if ptr is NULL: 390 allocsize = (ptr != NULL) ? allocsize_ : 0; 391 aligned = aligned_; 392 #if !defined(__APPLE__) 393 if (m) 394 { 395 log_error("ERROR: unhandled code path. BufferOwningPtr allocated " 396 "with mapped buffer!"); 397 abort(); 398 } 399 #endif 400 } 401 operator T *() { return (T *)ptr; } 402 getSize()403 size_t getSize() const { return allocsize; }; 404 }; 405 406 #endif // _typeWrappers_h 407