KhronosGroup / KhronosGroup/OpenCL-Docs
OpenCL objects lifetime
- Dominant language
- Python
- Stars
- 420
- Forks
- 131
- Avg merge
- 5d 13h
- Merged PRs (30d)
- 11
Description
OpenCL objects use reference counting to decide their lifetime. The description of the **Reference Count** glossary entry changed during OpenCL lifetime:
OpenCL 1.0, 1.1, 1.2
> **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_. After the _reference count_ reaches zero, the object’s resources are deallocated by OpenCL.
OpenCL 2.0
> **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. After the reference count reaches zero, the object is deleted.
OpenCL 2.1, 2.2, 3.0
> **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.
Validating correct behavior would depend on implementing validation that matches the described behavior. I am advocating (maybe a bit provocatively, but there are real implications) that in practice the only desirable one is OpenCL 2.0 definition (and matching behavior). Obviously, 1.0 - 1.2 descriptions are incomplete as the documentation mentions several time that some object will only be released when all other objects they depend on have been released also. OpenCL 2.1 - 3.0 modification is too restrictive and precludes a lot of scenarios that are used and work in practice. I will give some examples to try to make my point:
### Queue Profiling
Dynamically creating events and attaching callbacks to do queue profiling: setting aside the necessary queue profiling flag, the commonly used strategy used here is to intercept enqueue calls and either piggy back on the user provided event or create an event on the fly, and then attach a callback to it if the enqueue was successful the pseudo code looks like this:
```c
// In enqueue function
int _profile_release_event = 0;
cl_event _profiling_event = NULL;
if (!event) {
event = &_profiling_event;
_profile_release_event = 1;
}
//do enqueue
if (_retval == CL_SUCCESS)
// attach call back on CL_COMPLETE to get profiling information
if (_profile_release_event)
clReleaseEvent(event);
```
The event object is used in the callback whereas it's reference count from the user perspective is zero. Releasing it in the call back doesn't solve the problem, because if somebody else is intercepting the enqueue call and is attaching another callback, the order of the callback call wrt the release will be undetermined and one may be called after the user ref count reaches 0 from a user perspective.
### High Level Language Bindings
High level languages bindings are often based on garbage collectors that map well with the release/retain approach of OpenCL. When objects are garbage collected, release is called, and when wrapping a handle retain is called (except at object creation). In those languages, querying the Context of a CommandQueue is returning a wrapped cl_context handle after increasing the reference count. There is no way to know if this is valid, as querying the reference counter of the context cannot tell you if it reached 0 from a user perspective. Nonetheless, in practice this works on most (all?) OpenCL implementations, because they seem to be following the 2.0 spirit of the rule.
### Discussion
I am sure there are issues with OpenCL 2.0 formulation that caused it to be changed, but I think allowing accessible objects to be retained brings more benefits to the table than drawbacks. I am sure also that more examples can be found (decision making based on the state of a referenced object comes to mind). If I can query a context from a command queue I should be able to retain and use this context (unless I release the command queue in-between of course) even if, from a user perspective, its reference count reached zero at some point in time, it is transitively alive. What scenarios would be problematic if this behavior was to be followed?
Contributor guide
Research direction
The issue centers on the Reference Count glossary entry and the version-specific OpenCL 1.0–3.0 definitions; start by locating that glossary entry in the documentation sources. Compare the cited wording and examples, then resolve the specification question with maintainers and update the relevant documentation once the intended lifetime semantics are decided.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- api, documentation
- Issue type
- Documentation
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100