Skip to content
This repository was archived by the owner on Jan 28, 2024. It is now read-only.

Commit def65e7

Browse files
committed
Add general MemObject functions
1 parent 432b43d commit def65e7

File tree

2 files changed

+311
-0
lines changed

2 files changed

+311
-0
lines changed

memory.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "api.h"
2+
3+
extern void cl22GoMemObjectDestructorCallback(cl_mem, uintptr_t *);
4+
5+
static CL_CALLBACK void cl22CMemObjectDestructorCallback(cl_mem mem, void *userData)
6+
{
7+
cl22GoMemObjectDestructorCallback(mem, (uintptr_t *)(userData));
8+
}
9+
10+
cl_int cl22SetMemObjectDestructorCallback(cl_mem mem, uintptr_t *userData)
11+
{
12+
return clSetMemObjectDestructorCallback(mem, cl22CMemObjectDestructorCallback, userData);
13+
}

memory.go

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
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

Comments
 (0)