OpenCL CommandQueue & Context lifetime

clCreateCommandQueueWithProperties takes cl_context as an argument. In general, If it ok for me to call clReleaseContext(context) on the said context , and expect the command queue to still be functional?

I’m writing openCL bindings in a garbage-collected language, and unfortunately I don’t have a lot of control over when objects are free-ed, and want to try to deallocate openCL address as the memory locations become unreachable. I’m trying to avoid reimplement the openCL reference counting model in my bindings too.

Is there anywhere in the spec that says anything about this? Do implementations tend to gurantee that the returned queue will still work even after the context is released?

Good question. The docu says:

Reference Count

The life span of an OpenCL object is determined by its reference count, an internal count of the number of references to the object. When you create an object in OpenCL, its reference count is set to one. Subsequent calls to the appropriate retain API (such as clRetainContext, clRetainCommandQueue) increment the reference count. Calls to the appropriate release API (such as clReleaseContext, clReleaseCommandQueue) decrement the reference count. Implementations may also modify the reference count, e.g. to track attached objects or to ensure correct operation of in-progress or scheduled activities. The object becomes inaccessible to host code when the number of release operations performed matches the number of retain operations plus the allocation of the object. At this point the reference count may be zero but this is not guaranteed.

Does it means that the context is basically always there on the device? So if I release it on the host side then the context will just stop being available on the host side, but still is the same on the device side?

I just tried to release the context and try to write/read from a buffer using the command queue and it works.

def queue = queueFactory.create(context, device)
float[] values = [0, 1, 2, 3, 4, 5, 6, 7]
def size = Sizeof.cl_float * 8
def pointer = Pointer.to(values)
def buffer = bufferFactory.create(context, CL_MEM_READ_WRITE, size)
context.close() // <-- released the context
buffer.write(queue.get(), 0, size, pointer)
float[] dest = new float[8];
buffer.read(queue.get(), dest)
assert dest == values