|
| 1 | +package cl22 |
| 2 | + |
| 3 | +// #include "api.h" |
| 4 | +// extern cl_int cl22SetMemObjectDestructorCallback(cl_mem mem, uintptr_t *userData); |
| 5 | +import "C" |
| 6 | +import ( |
| 7 | + "fmt" |
| 8 | + "unsafe" |
| 9 | +) |
| 10 | + |
| 11 | +// MemObject represents a reference counted region of global memory. |
| 12 | +type MemObject uintptr |
| 13 | + |
| 14 | +func (mem MemObject) handle() C.cl_mem { |
| 15 | + return *(*C.cl_mem)(unsafe.Pointer(&mem)) |
| 16 | +} |
| 17 | + |
| 18 | +// String provides a readable presentation of the memory identifier. |
| 19 | +// It is based on the numerical value of the underlying pointer. |
| 20 | +func (mem MemObject) String() string { |
| 21 | + return fmt.Sprintf("0x%X", uintptr(mem)) |
| 22 | +} |
| 23 | + |
| 24 | +// MemProperty is one entry of properties which are taken into account when creating memory objects. |
| 25 | +type MemProperty []uint64 |
| 26 | + |
| 27 | +// RetainMemObject increments the memory object reference count. |
| 28 | +// |
| 29 | +// Function that create a memory object perform an implicit retain. |
| 30 | +// |
| 31 | +// See also: https://registry.khronos.org/OpenCL/sdk/2.2/docs/man/html/clRetainMemObject.html |
| 32 | +func RetainMemObject(mem MemObject) error { |
| 33 | + status := C.clRetainMemObject(mem.handle()) |
| 34 | + if status != C.CL_SUCCESS { |
| 35 | + return StatusError(status) |
| 36 | + } |
| 37 | + return nil |
| 38 | +} |
| 39 | + |
| 40 | +// ReleaseMemObject decrements the memory object reference count. |
| 41 | +// |
| 42 | +// After the reference count becomes zero and commands queued for execution on a command-queue(s) that use mem have |
| 43 | +// finished, the memory object is deleted. If mem is a buffer object, mem cannot be deleted until all sub-buffer |
| 44 | +// objects associated with mem are deleted. |
| 45 | +// |
| 46 | +// See also: https://registry.khronos.org/OpenCL/sdk/2.2/docs/man/html/clReleaseMemObject.html |
| 47 | +func ReleaseMemObject(mem MemObject) error { |
| 48 | + status := C.clReleaseMemObject(mem.handle()) |
| 49 | + if status != C.CL_SUCCESS { |
| 50 | + return StatusError(status) |
| 51 | + } |
| 52 | + return nil |
| 53 | +} |
| 54 | + |
| 55 | +// SetMemObjectDestructorCallback registers a destructor callback function with a memory object. |
| 56 | +// |
| 57 | +// Each call to SetMemObjectDestructorCallback() registers the specified callback function on a destructor callback |
| 58 | +// stack associated with mem. |
| 59 | +// The registered callback functions are called in the reverse order in which they were registered. |
| 60 | +// |
| 61 | +// See also: https://registry.khronos.org/OpenCL/sdk/2.2/docs/man/html/clSetMemObjectDestructorCallback.html |
| 62 | +func SetMemObjectDestructorCallback(mem MemObject, callback func()) error { |
| 63 | + callbackUserData, err := userDataFor(callback) |
| 64 | + if err != nil { |
| 65 | + return err |
| 66 | + } |
| 67 | + status := C.cl22SetMemObjectDestructorCallback(mem.handle(), callbackUserData.ptr) |
| 68 | + if status != C.CL_SUCCESS { |
| 69 | + callbackUserData.Delete() |
| 70 | + return StatusError(status) |
| 71 | + } |
| 72 | + return nil |
| 73 | +} |
| 74 | + |
| 75 | +//export cl22GoMemObjectDestructorCallback |
| 76 | +func cl22GoMemObjectDestructorCallback(_ MemObject, userData *C.uintptr_t) { |
| 77 | + callbackUserData := userDataFrom(userData) |
| 78 | + callback := callbackUserData.Value().(func()) |
| 79 | + callbackUserData.Delete() |
| 80 | + callback() |
| 81 | +} |
| 82 | + |
| 83 | +// MemObjectInfoName identifies properties of a memory object, which can be queried with MemObjectInfo(). |
| 84 | +type MemObjectInfoName C.cl_mem_info |
| 85 | + |
| 86 | +const ( |
| 87 | + // MemTypeInfo returns the type of the memory object. |
| 88 | + // |
| 89 | + // Returned type: MemObjectType |
| 90 | + MemTypeInfo MemObjectInfoName = C.CL_MEM_TYPE |
| 91 | + // MemFlagsInfo returns the flags argument value specified when the memory object was created. |
| 92 | + // If the memory object is a sub-buffer the memory access qualifiers inherited from parent buffer are also returned. |
| 93 | + // |
| 94 | + // Returned type: MemFlags |
| 95 | + MemFlagsInfo MemObjectInfoName = C.CL_MEM_FLAGS |
| 96 | + // MemSizeInfo returns the actual size of the data store associated with the memory object in bytes. |
| 97 | + // |
| 98 | + // Returned type: uintptr |
| 99 | + MemSizeInfo MemObjectInfoName = C.CL_MEM_SIZE |
| 100 | + // MemHostPtrInfo returns the underlying host pointer for a MemObject if it (or its source buffer) was |
| 101 | + // created with the MemUseHostPtrFlag. It returns nil otherwise. |
| 102 | + // |
| 103 | + // Returned type: unsafe.Pointer |
| 104 | + MemHostPtrInfo MemObjectInfoName = C.CL_MEM_HOST_PTR |
| 105 | + // MemContextInfo returns the context specified when memory object is created. |
| 106 | + // |
| 107 | + // Returned type: Context |
| 108 | + MemContextInfo MemObjectInfoName = C.CL_MEM_CONTEXT |
| 109 | + // MemOffsetInfo returns the offset if memory object is a sub-buffer object created using CreateSubBuffer(). |
| 110 | + // It returns 0 if memory object is not a sub-buffer object. |
| 111 | + // |
| 112 | + // Returned type: uintptr |
| 113 | + // Since: 1.1 |
| 114 | + MemOffsetInfo MemObjectInfoName = C.CL_MEM_OFFSET |
| 115 | + // MemMapCountInfo returns the current map count. |
| 116 | + // |
| 117 | + // Note: The map count returned should be considered immediately stale. It is unsuitable for |
| 118 | + // general use in applications. This feature is provided for debugging. |
| 119 | + // |
| 120 | + // Returned type: Uint |
| 121 | + MemMapCountInfo MemObjectInfoName = C.CL_MEM_MAP_COUNT |
| 122 | + // MemReferenceCountInfo returns the memory reference count. |
| 123 | + // |
| 124 | + // Note: The reference count returned should be considered immediately stale. It is unsuitable for |
| 125 | + // general use in applications. This feature is provided for identifying memory leaks. |
| 126 | + // |
| 127 | + // Returned type: Uint |
| 128 | + MemReferenceCountInfo MemObjectInfoName = C.CL_MEM_REFERENCE_COUNT |
| 129 | + // MemAssociatedMemObjectInfo returns the memory object from which the queried memory object is created. |
| 130 | + // |
| 131 | + // Returned type: MemObject |
| 132 | + // Since: 1.1 |
| 133 | + MemAssociatedMemObjectInfo MemObjectInfoName = C.CL_MEM_ASSOCIATED_MEMOBJECT |
| 134 | + // MemUsesSvmPointerInfo returns True if memory object is a buffer object that was created with |
| 135 | + // MemUseHostPtrFlag or is a sub-buffer object of a buffer object that was created with MemUseHostPtrFlag and |
| 136 | + // the host pointer specified when the buffer object was created is an SVM pointer; otherwise returns False. |
| 137 | + // |
| 138 | + // Returned type: Bool |
| 139 | + // Since: 2.0 |
| 140 | + MemUsesSvmPointerInfo MemObjectInfoName = C.CL_MEM_USES_SVM_POINTER |
| 141 | +) |
| 142 | + |
| 143 | +// MemObjectType identifies the specific type of MemObject. |
| 144 | +type MemObjectType C.cl_mem_object_type |
| 145 | + |
| 146 | +// These constants represent specific type identifier. |
| 147 | +const ( |
| 148 | + MemObjectBufferType MemObjectType = C.CL_MEM_OBJECT_BUFFER |
| 149 | + MemObjectImage2DType MemObjectType = C.CL_MEM_OBJECT_IMAGE2D |
| 150 | + MemObjectImage3DType MemObjectType = C.CL_MEM_OBJECT_IMAGE3D |
| 151 | + |
| 152 | + MemObjectImage2DArrayType MemObjectType = C.CL_MEM_OBJECT_IMAGE2D_ARRAY |
| 153 | + MemObjectImage1DType MemObjectType = C.CL_MEM_OBJECT_IMAGE1D |
| 154 | + MemObjectImage1DArrayType MemObjectType = C.CL_MEM_OBJECT_IMAGE1D_ARRAY |
| 155 | + MemObjectImage1DBufferType MemObjectType = C.CL_MEM_OBJECT_IMAGE1D_BUFFER |
| 156 | + |
| 157 | + MemObjectPipeType MemObjectType = C.CL_MEM_OBJECT_PIPE |
| 158 | +) |
| 159 | + |
| 160 | +// MemFlags describe properties of a MemObject. |
| 161 | +type MemFlags C.cl_mem_flags |
| 162 | + |
| 163 | +// These constants identify possible properties of a MemObject. |
| 164 | +const ( |
| 165 | + MemReadWriteFlag = C.CL_MEM_READ_WRITE |
| 166 | + MemWriteOnlyFlag = C.CL_MEM_WRITE_ONLY |
| 167 | + MemReadOnlyFlag = C.CL_MEM_READ_ONLY |
| 168 | + MemUseHostPtrFlag = C.CL_MEM_USE_HOST_PTR |
| 169 | + MemAllocHostPtrFlag = C.CL_MEM_ALLOC_HOST_PTR |
| 170 | + MemCopyHostPtrFlag = C.CL_MEM_COPY_HOST_PTR |
| 171 | + |
| 172 | + MemHostWriteOnlyFlag = C.CL_MEM_HOST_WRITE_ONLY |
| 173 | + MemHostReadOnlyFlag = C.CL_MEM_HOST_READ_ONLY |
| 174 | + MemHostNoAccessFlag = C.CL_MEM_HOST_NO_ACCESS |
| 175 | + |
| 176 | + MemSvmFineGrainBufferFlag = C.CL_MEM_SVM_FINE_GRAIN_BUFFER |
| 177 | + MemSvmAtomicsFlag = C.CL_MEM_SVM_ATOMICS |
| 178 | + MemKernelReadAndWriteFlag = C.CL_MEM_KERNEL_READ_AND_WRITE |
| 179 | +) |
| 180 | + |
| 181 | +// MemObjectInfo queries information about a memory object. |
| 182 | +// |
| 183 | +// The provided size need to specify the size of the available space pointed to the provided value in bytes. |
| 184 | +// |
| 185 | +// The returned number is the required size, in bytes, for the queried information. |
| 186 | +// Call the function with a zero size and nil value to request the required size. This helps in determining |
| 187 | +// the necessary space for dynamic information, such as arrays. |
| 188 | +// |
| 189 | +// Raw strings are with a terminating NUL character. |
| 190 | +// |
| 191 | +// See also: https://registry.khronos.org/OpenCL/sdk/2.2/docs/man/html/clGetMemObjectInfo.html |
| 192 | +func MemObjectInfo(mem MemObject, paramName MemObjectInfoName, paramSize uint, paramValue unsafe.Pointer) (uint, error) { |
| 193 | + sizeReturn := C.size_t(0) |
| 194 | + status := C.clGetMemObjectInfo( |
| 195 | + mem.handle(), |
| 196 | + C.cl_mem_info(paramName), |
| 197 | + C.size_t(paramSize), |
| 198 | + paramValue, |
| 199 | + &sizeReturn) |
| 200 | + if status != C.CL_SUCCESS { |
| 201 | + return 0, StatusError(status) |
| 202 | + } |
| 203 | + return uint(sizeReturn), nil |
| 204 | +} |
| 205 | + |
| 206 | +// MapFlags describe how a memory object shall be mapped into host memory. |
| 207 | +type MapFlags C.cl_map_flags |
| 208 | + |
| 209 | +const ( |
| 210 | + // MapRead specifies that the region being mapped in the memory object is being mapped for reading. |
| 211 | + MapRead MapFlags = C.CL_MAP_READ |
| 212 | + // MapWrite specifies that the region being mapped in the memory object is being mapped for writing. |
| 213 | + MapWrite MapFlags = C.CL_MAP_WRITE |
| 214 | + // MapWriteInvalidateRegion specifies that the region being mapped in the memory object is being mapped for writing. |
| 215 | + // |
| 216 | + // The contents of the region being mapped are to be discarded. This is typically the case when the region |
| 217 | + // being mapped is overwritten by the host. This flag allows the implementation to no longer guarantee that the |
| 218 | + // pointer returned by EnqueueMapBuffer() (EnqueueMapImage()) contains the latest bits in the region being mapped |
| 219 | + // which can be a significant performance enhancement. |
| 220 | + // |
| 221 | + // Since: 1.2 |
| 222 | + MapWriteInvalidateRegion MapFlags = C.CL_MAP_WRITE_INVALIDATE_REGION |
| 223 | +) |
| 224 | + |
| 225 | +// EnqueueUnmapMemObject enqueues a command to unmap a previously mapped region of a memory object. |
| 226 | +// |
| 227 | +// Reads or writes from the host using the pointer returned by the mapping functions are considered to be complete. |
| 228 | +// |
| 229 | +// See also: https://registry.khronos.org/OpenCL/sdk/2.2/docs/man/html/clEnqueueUnmapMemObject.html |
| 230 | +func EnqueueUnmapMemObject(commandQueue CommandQueue, mem MemObject, mappedPtr unsafe.Pointer, waitList []Event, event *Event) error { |
| 231 | + var rawWaitList unsafe.Pointer |
| 232 | + if len(waitList) > 0 { |
| 233 | + rawWaitList = unsafe.Pointer(&waitList[0]) |
| 234 | + } |
| 235 | + status := C.clEnqueueUnmapMemObject( |
| 236 | + commandQueue.handle(), |
| 237 | + mem.handle(), |
| 238 | + mappedPtr, |
| 239 | + C.cl_uint(len(waitList)), |
| 240 | + (*C.cl_event)(rawWaitList), |
| 241 | + (*C.cl_event)(unsafe.Pointer(event))) |
| 242 | + if status != C.CL_SUCCESS { |
| 243 | + return StatusError(status) |
| 244 | + } |
| 245 | + return nil |
| 246 | +} |
| 247 | + |
| 248 | +// MemMigrationFlags determine the migration options of memory objects. |
| 249 | +type MemMigrationFlags C.cl_mem_migration_flags |
| 250 | + |
| 251 | +const ( |
| 252 | + // MigrateMemObjectHost indicates that the specified set of memory objects are to be migrated to the host, |
| 253 | + // regardless of the target command-queue. |
| 254 | + // |
| 255 | + // Since: 1.2 |
| 256 | + MigrateMemObjectHost MemMigrationFlags = C.CL_MIGRATE_MEM_OBJECT_HOST |
| 257 | + // MigrateMemObjectContentUndefined indicates that the contents of the set of memory objects are undefined after |
| 258 | + // migration. The specified set of memory objects are migrated to the device associated with the command-queue |
| 259 | + // without incurring the overhead of migrating their contents. |
| 260 | + // |
| 261 | + // Since: 1.2 |
| 262 | + MigrateMemObjectContentUndefined MemMigrationFlags = C.CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED |
| 263 | +) |
| 264 | + |
| 265 | +// EnqueueMigrateMemObjects enqueues a command to indicate which device a set of memory objects should be associated |
| 266 | +// with. |
| 267 | +// |
| 268 | +// Typically, memory objects are implicitly migrated to a device for which enqueued commands, using the memory object, |
| 269 | +// are targeted. EnqueueMigrateMemObjects() allows this migration to be explicitly performed ahead of the dependent |
| 270 | +// commands. This allows a user to preemptively change the association of a memory object, through regular command |
| 271 | +// queue scheduling, in order to prepare for another upcoming command. This also permits an application to overlap |
| 272 | +// the placement of memory objects with other unrelated operations before these memory objects are needed potentially |
| 273 | +// hiding transfer latencies. |
| 274 | +// |
| 275 | +// Since: 1.2 |
| 276 | +// See also: https://registry.khronos.org/OpenCL/sdk/2.2/docs/man/html/clEnqueueMigrateMemObjects.html |
| 277 | +func EnqueueMigrateMemObjects(commandQueue CommandQueue, memObjects []MemObject, migrationFlags MemMigrationFlags, waitList []Event, event *Event) error { |
| 278 | + var rawMemObjects unsafe.Pointer |
| 279 | + if len(memObjects) > 0 { |
| 280 | + rawMemObjects = unsafe.Pointer(&memObjects[0]) |
| 281 | + } |
| 282 | + var rawWaitList unsafe.Pointer |
| 283 | + if len(waitList) > 0 { |
| 284 | + rawWaitList = unsafe.Pointer(&waitList[0]) |
| 285 | + } |
| 286 | + status := C.clEnqueueMigrateMemObjects( |
| 287 | + commandQueue.handle(), |
| 288 | + C.cl_uint(len(memObjects)), |
| 289 | + (*C.cl_mem)(rawMemObjects), |
| 290 | + C.cl_mem_migration_flags(migrationFlags), |
| 291 | + C.cl_uint(len(waitList)), |
| 292 | + (*C.cl_event)(rawWaitList), |
| 293 | + (*C.cl_event)(unsafe.Pointer(event))) |
| 294 | + if status != C.CL_SUCCESS { |
| 295 | + return StatusError(status) |
| 296 | + } |
| 297 | + return nil |
| 298 | +} |
0 commit comments