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 { 36 public: clContextWrapper()37 clContextWrapper() { mContext = NULL; } clContextWrapper(cl_context program)38 clContextWrapper( cl_context program ) { mContext = program; } ~clContextWrapper()39 ~clContextWrapper() { if( mContext != NULL ) clReleaseContext( mContext ); } 40 41 clContextWrapper & operator=( const cl_context &rhs ) { mContext = rhs; return *this; } cl_context()42 operator cl_context() const { return mContext; } 43 44 cl_context * operator&() { return &mContext; } 45 46 bool operator==( const cl_context &rhs ) { return mContext == rhs; } 47 48 protected: 49 50 cl_context mContext; 51 }; 52 53 /* cl_program wrapper */ 54 55 class clProgramWrapper 56 { 57 public: clProgramWrapper()58 clProgramWrapper() { mProgram = NULL; } clProgramWrapper(cl_program program)59 clProgramWrapper( cl_program program ) { mProgram = program; } ~clProgramWrapper()60 ~clProgramWrapper() { if( mProgram != NULL ) clReleaseProgram( mProgram ); } 61 62 clProgramWrapper & operator=( const cl_program &rhs ) { mProgram = rhs; return *this; } cl_program()63 operator cl_program() const { return mProgram; } 64 65 cl_program * operator&() { return &mProgram; } 66 67 bool operator==( const cl_program &rhs ) { return mProgram == rhs; } 68 69 protected: 70 71 cl_program mProgram; 72 }; 73 74 /* cl_kernel wrapper */ 75 76 class clKernelWrapper 77 { 78 public: clKernelWrapper()79 clKernelWrapper() { mKernel = NULL; } clKernelWrapper(cl_kernel kernel)80 clKernelWrapper( cl_kernel kernel ) { mKernel = kernel; } ~clKernelWrapper()81 ~clKernelWrapper() { if( mKernel != NULL ) clReleaseKernel( mKernel ); } 82 83 clKernelWrapper & operator=( const cl_kernel &rhs ) { mKernel = rhs; return *this; } cl_kernel()84 operator cl_kernel() const { return mKernel; } 85 86 cl_kernel * operator&() { return &mKernel; } 87 88 bool operator==( const cl_kernel &rhs ) { return mKernel == rhs; } 89 90 protected: 91 92 cl_kernel mKernel; 93 }; 94 95 /* cl_mem (stream) wrapper */ 96 97 class clMemWrapper 98 { 99 public: clMemWrapper()100 clMemWrapper() { mMem = NULL; } clMemWrapper(cl_mem mem)101 clMemWrapper( cl_mem mem ) { mMem = mem; } ~clMemWrapper()102 ~clMemWrapper() { if( mMem != NULL ) clReleaseMemObject( mMem ); } 103 104 clMemWrapper & operator=( const cl_mem &rhs ) { mMem = rhs; return *this; } cl_mem()105 operator cl_mem() const { return mMem; } 106 107 cl_mem * operator&() { return &mMem; } 108 109 bool operator==( const cl_mem &rhs ) { return mMem == rhs; } 110 111 protected: 112 113 cl_mem mMem; 114 }; 115 116 class clProtectedImage 117 { 118 public: clProtectedImage()119 clProtectedImage() { image = NULL; backingStore = NULL; } 120 clProtectedImage( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, cl_int *errcode_ret ); 121 clProtectedImage( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, cl_int *errcode_ret ); 122 clProtectedImage( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, cl_int *errcode_ret ); 123 clProtectedImage( cl_context context, cl_mem_object_type imageType, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t arraySize, cl_int *errcode_ret ); ~clProtectedImage()124 ~clProtectedImage() 125 { 126 if( image != NULL ) 127 clReleaseMemObject( image ); 128 129 #if defined( __APPLE__ ) 130 if(backingStore) 131 munmap(backingStore, backingStoreSize); 132 #endif 133 } 134 135 cl_int Create( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width ); 136 cl_int Create( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height ); 137 cl_int Create( cl_context context, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth ); 138 cl_int Create( cl_context context, cl_mem_object_type imageType, cl_mem_flags flags, const cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t arraySize ); 139 140 clProtectedImage & operator=( const cl_mem &rhs ) { image = rhs; backingStore = NULL; return *this; } cl_mem()141 operator cl_mem() { return image; } 142 143 cl_mem * operator&() { return ℑ } 144 145 bool operator==( const cl_mem &rhs ) { return image == rhs; } 146 147 protected: 148 void *backingStore; 149 size_t backingStoreSize; 150 cl_mem image; 151 }; 152 153 /* cl_command_queue wrapper */ 154 class clCommandQueueWrapper 155 { 156 public: clCommandQueueWrapper()157 clCommandQueueWrapper() { mMem = NULL; } clCommandQueueWrapper(cl_command_queue mem)158 clCommandQueueWrapper( cl_command_queue mem ) { mMem = mem; } ~clCommandQueueWrapper()159 ~clCommandQueueWrapper() { if( mMem != NULL ) { clReleaseCommandQueue( mMem ); } } 160 161 clCommandQueueWrapper & operator=( const cl_command_queue &rhs ) { mMem = rhs; return *this; } cl_command_queue()162 operator cl_command_queue() const { return mMem; } 163 164 cl_command_queue * operator&() { return &mMem; } 165 166 bool operator==( const cl_command_queue &rhs ) { return mMem == rhs; } 167 168 protected: 169 170 cl_command_queue mMem; 171 }; 172 173 /* cl_sampler wrapper */ 174 class clSamplerWrapper 175 { 176 public: clSamplerWrapper()177 clSamplerWrapper() { mMem = NULL; } clSamplerWrapper(cl_sampler mem)178 clSamplerWrapper( cl_sampler mem ) { mMem = mem; } ~clSamplerWrapper()179 ~clSamplerWrapper() { if( mMem != NULL ) clReleaseSampler( mMem ); } 180 181 clSamplerWrapper & operator=( const cl_sampler &rhs ) { mMem = rhs; return *this; } cl_sampler()182 operator cl_sampler() const { return mMem; } 183 184 cl_sampler * operator&() { return &mMem; } 185 186 bool operator==( const cl_sampler &rhs ) { return mMem == rhs; } 187 188 protected: 189 190 cl_sampler mMem; 191 }; 192 193 /* cl_event wrapper */ 194 class clEventWrapper 195 { 196 public: clEventWrapper()197 clEventWrapper() { mMem = NULL; } clEventWrapper(cl_event mem)198 clEventWrapper( cl_event mem ) { mMem = mem; } ~clEventWrapper()199 ~clEventWrapper() { if( mMem != NULL ) clReleaseEvent( mMem ); } 200 201 clEventWrapper & operator=( const cl_event &rhs ) { mMem = rhs; return *this; } cl_event()202 operator cl_event() const { return mMem; } 203 204 cl_event * operator&() { return &mMem; } 205 206 bool operator==( const cl_event &rhs ) { return mMem == rhs; } 207 208 protected: 209 210 cl_event mMem; 211 }; 212 213 /* Generic protected memory buffer, for verifying access within bounds */ 214 class clProtectedArray 215 { 216 public: 217 clProtectedArray(); 218 clProtectedArray( size_t sizeInBytes ); 219 virtual ~clProtectedArray(); 220 221 void Allocate( size_t sizeInBytes ); 222 223 operator void *() { return (void *)mValidBuffer; } 224 operator const void *() const { return (const void *)mValidBuffer; } 225 226 protected: 227 228 char * mBuffer; 229 char * mValidBuffer; 230 size_t mRealSize, mRoundedSize; 231 }; 232 233 class RandomSeed 234 { 235 public: RandomSeed(cl_uint seed)236 RandomSeed( cl_uint seed ){ if(seed) log_info( "(seed = %10.10u) ", seed ); mtData = init_genrand(seed); } ~RandomSeed()237 ~RandomSeed() 238 { 239 if( gReSeed ) 240 gRandomSeed = genrand_int32( mtData ); 241 free_mtdata(mtData); 242 } 243 MTdata()244 operator MTdata () {return mtData;} 245 246 protected: 247 MTdata mtData; 248 }; 249 250 251 template <typename T> class BufferOwningPtr 252 { 253 BufferOwningPtr(BufferOwningPtr const &); // do not implement 254 void operator=(BufferOwningPtr const &); // do not implement 255 256 void *ptr; 257 void *map; 258 size_t mapsize; // Bytes allocated total, pointed to by map. 259 size_t allocsize; // Bytes allocated in unprotected pages, pointed to by ptr. 260 bool aligned; 261 public: ptr(p)262 explicit BufferOwningPtr(void *p = 0) : ptr(p), map(0), mapsize(0), allocsize(0), aligned(false) {} BufferOwningPtr(void * p,void * m,size_t s)263 explicit BufferOwningPtr(void *p, void *m, size_t s) 264 : ptr(p), map(m), mapsize(s), allocsize(0), aligned(false) 265 { 266 #if ! defined( __APPLE__ ) 267 if(m) 268 { 269 log_error( "ERROR: unhandled code path. BufferOwningPtr allocated with mapped buffer!" ); 270 abort(); 271 } 272 #endif 273 } ~BufferOwningPtr()274 ~BufferOwningPtr() { 275 if (map) { 276 #if defined( __APPLE__ ) 277 int error = munmap(map, mapsize); 278 if (error) log_error("WARNING: munmap failed in BufferOwningPtr.\n"); 279 #endif 280 } else { 281 if ( aligned ) 282 { 283 align_free(ptr); 284 } 285 else 286 { 287 free(ptr); 288 } 289 } 290 } 291 void reset(void *p, void *m = 0, size_t mapsize_ = 0, size_t allocsize_ = 0, bool aligned_ = false) { 292 if (map){ 293 #if defined( __APPLE__ ) 294 int error = munmap(map, mapsize); 295 if (error) log_error("WARNING: munmap failed in BufferOwningPtr.\n"); 296 #else 297 log_error( "ERROR: unhandled code path. BufferOwningPtr reset with mapped buffer!" ); 298 abort(); 299 #endif 300 } else { 301 if ( aligned ) 302 { 303 align_free(ptr); 304 } 305 else 306 { 307 free(ptr); 308 } 309 } 310 ptr = p; 311 map = m; 312 mapsize = mapsize_; 313 allocsize = (ptr != NULL) ? allocsize_ : 0; // Force allocsize to zero if ptr is NULL. 314 aligned = aligned_; 315 #if ! defined( __APPLE__ ) 316 if(m) 317 { 318 log_error( "ERROR: unhandled code path. BufferOwningPtr allocated with mapped buffer!" ); 319 abort(); 320 } 321 #endif 322 } 323 operator T*() { return (T*)ptr; } 324 getSize()325 size_t getSize() const { return allocsize; }; 326 }; 327 328 #endif // _typeWrappers_h 329 330