blob: 0078df9771a3c2d755c4f88b7f14edd10d9d5f9d [file] [edit]
// Copyright 2017-2024 The Khronos Group Inc.
// SPDX-License-Identifier: CC-BY-4.0
[appendix]
= Host environment and thread safety
[[shared-opencl-objects]]
== Shared OpenCL Objects
This section describes which objects can be shared across multiple
command-queues created within a host process.
OpenCL memory objects, program objects and kernel objects are created using
a context and can be shared across multiple command-queues created using the
same context.
Event objects can be created when a command is queued to a command-queue.
These event objects can be shared across multiple command-queues created
using the same context.
The application needs to implement appropriate synchronization across
threads on the host processor to ensure that the changes to the state of a
shared object (such as a command-queue object, memory object, program or
kernel object) happen in the correct order (deemed correct by the
application) when multiple command-queues in multiple threads are making
changes to the state of a shared object.
A command-queue can cache changes to the state of a memory object on the
device associated with the command-queue.
To synchronize changes to a memory object across command-queues, the
application must do the following:
In the command-queue that includes commands that modify the state of a
memory object, the application must do the following:
* Get appropriate event objects for commands that modify the state of the
shared memory object.
* Call the {clFlush} (or {clFinish}) API to issue any outstanding commands
from this command-queue.
In the command-queue that wants to synchronize to the latest state of a
memory object, commands queued by the application must use the appropriate
event objects that represent commands that modify the state of the shared
memory object as event objects to wait on.
This is to ensure that commands that use this shared memory object complete
in the previous command-queue before the memory objects are used by commands
executing in this command-queue.
The results of modifying a shared resource in one command-queue while it is
being used by another command-queue are undefined.
== Multiple Host Threads
All OpenCL API calls are thread-safe footnote:[{fn-thread-safe}] except those
that modify the state of {cl_kernel_TYPE} objects: {clSetKernelArg},
{clSetKernelArgSVMPointer}, {clSetKernelExecInfo} and {clCloneKernel}.
{clSetKernelArg}, {clSetKernelArgSVMPointer}, {clSetKernelExecInfo} and
{clCloneKernel} are safe to call from any host thread, and safe to call
re-entrantly so long as concurrent calls to any combination of these API
calls operate on different {cl_kernel_TYPE} objects.
The state of the {cl_kernel_TYPE} object is undefined if {clSetKernelArg},
{clSetKernelArgSVMPointer}, {clSetKernelExecInfo} or {clCloneKernel} are
called from multiple host threads on the same {cl_kernel_TYPE} object at the same
time footnote:[{fn-race-condition}].
Please note that there are additional limitations as to which OpenCL APIs
may be called from <<event-objects,OpenCL callback functions>>.
The behavior of OpenCL APIs called from an interrupt or signal handler is
implementation-defined
The OpenCL implementation should be able to create multiple command-queues
for a given OpenCL context and multiple OpenCL contexts in an application
running on the host processor.
== Global Constructors and Destructors
The execution order of global constructors and destructors is left undefined
by the C and C++ standards. It is therefore not possible to know the relative
execution order of an OpenCL implementation's global constructors and destructors
with respect to an OpenCL application's or library's.
The behavior of OpenCL API functions called from global constructors or
destructors is therefore implementation-defined.