Skip to content

Commit 82576f1

Browse files
committed
cl_khr_command_buffer_mutable_memory_commands extension
Draft of `cl_khr_command_buffer_mutable_memory_commands` based ontop of #1045 which updates `clUpdateMutableCommandsKHR` to pass configs by an array rather than linked list. The goal of this extension is to be able to update the parameters to memory operation commands in a command-buffer after the command-buffer has been finalized using the `clUpdateMutableCommandsKHR` entry-point defined by `cl_khr_command_buffer_mutable_dispatch`.
1 parent 373f453 commit 82576f1

3 files changed

+495
-5
lines changed

OpenCL_Ext.txt

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ include::ext/cl_khr_work_group_uniform_arithmetic.asciidoc[]
113113

114114
include::ext/cl_khr_command_buffer_mutable_dispatch.asciidoc[]
115115
include::ext/cl_khr_command_buffer_multi_device.asciidoc[]
116+
include::ext/cl_khr_command_buffer_mutable_memory_commands.asciidoc[]
116117

117118
// NOTE: To keep meaningful section numbers, new
118119
// extension documents should be added above here!
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
// Copyright 2018-2024 The Khronos Group. This work is licensed under a
2+
// Creative Commons Attribution 4.0 International License; see
3+
// http://creativecommons.org/licenses/by/4.0/
4+
5+
[[cl_khr_command_buffer_mutable_memory_commands]]
6+
== Command Buffers - Mutable Memory Commands (Provisional)
7+
8+
This extension enables users to modify the configuration memory commands
9+
between command-buffer enqueues.
10+
11+
=== General Information
12+
13+
==== Name Strings
14+
15+
`cl_khr_command_buffer_mutable_memory_commands`
16+
17+
==== Version History
18+
19+
[cols="1,1,3",options="header",]
20+
|====
21+
| *Date* | *Version* | *Description*
22+
| 2023-11-21 | 0.9.0 | First assigned version (provisional).
23+
|====
24+
25+
==== Dependencies
26+
27+
This extension requires the `cl_khr_command_buffer_mutable_dispatch` extension
28+
version 0.9.0.
29+
30+
==== Contributors
31+
32+
Ewan Crawford, Codeplay Software Ltd. +
33+
Kenneth Benzie, Codeplay Software Ltd. +
34+
Jack Frankland, Codeplay Software Ltd. +
35+
Ben Ashbaugh, Intel. +
36+
Balaji Calidas, Qualcomm Technologies Inc. +
37+
Sreelakshmi Haridas Maruthur, Qualcomm Technologies Inc. +
38+
Kevin Petit, Arm Ltd. +
39+
40+
==== Status
41+
42+
Draft spec, NOT APPROVED!!
43+
44+
=== Overview
45+
46+
The `cl_khr_command_buffer` extension separates command construction from
47+
enqueue by providing a mechanism to record an immutable set of commands which
48+
can then be repeatedly enqueued. Another extension layered on top,
49+
`cl_khr_command_buffer_mutable_dispatch` allows ND-Range kernel execution
50+
commands recorded to a command-buffer to be modified between command-buffer
51+
enqueues by providing a command-buffer update API {clUpdateMutableCommandsKHR}.
52+
53+
`cl_khr_command_buffer_mutable_memory_commands` builds on
54+
`cl_khr_command_buffer_mutable_dispatch` to use the {clUpdateMutableCommandsKHR}
55+
entry-point for enabling mutability of _memory-commands_ recorded to a
56+
command-buffer, those commands taking a {cl_mem_TYPE} or SVM pointer argument.
57+
58+
=== New API Types
59+
60+
[[cl_mutable_copy_buffer_command_config_khr]]
61+
include::{generated}/api/structs/cl_mutable_copy_buffer_command_config_khr.txt[]
62+
63+
_command_ A mutable-command object returned by {clCommandCopyBufferKHR}.
64+
65+
_src_buffer_, _dst_buffer_, _src_offset_, _dst_offset_, _size_ as specified by
66+
the associated {clCommandCopyBufferKHR} parameters.
67+
68+
[[cl_mutable_copy_buffer_rect_command_config_khr]]
69+
include::{generated}/api/structs/cl_mutable_copy_buffer_rect_command_config_khr.txt[]
70+
71+
_command_ A mutable-command object returned by {clCommandCopyBufferRectKHR}.
72+
73+
_src_buffer_, _dst_buffer_, _src_origin_, _dst_origin_, _region_, _src_row_pitch_,
74+
_src_slice_pitch_, _dst_row_pitch_, _dst_slice_pitch_ as specified by the
75+
associated {clCommandCopyBufferRectKHR} parameters.
76+
77+
[[cl_mutable_copy_buffer_to_image_command_config_khr]]
78+
include::{generated}/api/structs/cl_mutable_copy_buffer_to_image_command_config_khr.txt[]
79+
80+
_command_ A mutable-command object returned by {clCommandCopyBufferToImageKHR}.
81+
82+
_src_buffer_, _dst_image_, _src_offset_, _dst_origin_, _region_ as specified by the
83+
associated {clCommandCopyBufferToImageKHR} parameters.
84+
85+
[[cl_mutable_copy_image_command_config_khr]]
86+
include::{generated}/api/structs/cl_mutable_copy_image_command_config_khr.txt[]
87+
88+
_command_ A mutable-command object returned by {clCommandCopyImageKHR}.
89+
90+
_src_image_, _dst_image_, _src_origin_, _dst_origin_, _region_ as specified by the
91+
associated {clCommandCopyImageKHR} parameters.
92+
93+
[[cl_mutable_copy_image_to_buffer_command_config_khr]]
94+
include::{generated}/api/structs/cl_mutable_copy_image_to_buffer_command_config_khr.txt[]
95+
96+
_command_ A mutable-command object returned by {clCommandCopyImageToBufferKHR}.
97+
98+
_src_image_, _dst_buffer_, _src_origin_, _region_, _dst_offset_ as specified by the
99+
associated {clCommandCopyImageToBufferKHR} parameters.
100+
101+
[[cl_mutable_fill_buffer_command_config_khr]]
102+
include::{generated}/api/structs/cl_mutable_fill_buffer_command_config_khr.txt[]
103+
104+
_command_ A mutable-command object returned by {clCommandFillBufferKHR}.
105+
106+
_buffer_, _pattern_, _pattern_size_, _offset_, _size_ as specified by the
107+
associated {clCommandFillBufferKHR} parameters.
108+
109+
[[cl_mutable_fill_image_command_config_khr]]
110+
include::{generated}/api/structs/cl_mutable_fill_image_command_config_khr.txt[]
111+
112+
_command_ A mutable-command object returned by {clCommandFillImageKHR}.
113+
114+
_image_, _fill_color_, _origin_, _region_ as specified by the associated
115+
{clCommandFillImageKHR} parameters.
116+
117+
[[cl_mutable_svm_memcpy_command_config_khr]]
118+
include::{generated}/api/structs/cl_mutable_svm_memcpy_command_config_khr.txt[]
119+
120+
_command_ A mutable-command object returned by {clCommandSVMMemcpyKHR}.
121+
122+
_dst_ptr_, _src_ptr_, _size_ as specified by the associated {clCommandSVMMemcpyKHR}
123+
parameters.
124+
125+
[[cl_mutable_svm_memfill_command_config_khr]]
126+
include::{generated}/api/structs/cl_mutable_svm_memfill_command_config_khr.txt[]
127+
128+
_command_ A mutable-command object returned by {clCommandSVMMemFillKHR}.
129+
130+
_svm_ptr_, _pattern_, _pattern_size_, _size_ as specified by the associated
131+
{clCommandSVMMemFillKHR} parameters.
132+
133+
=== New API Enums
134+
135+
Enums for querying device command-buffer capabilities with
136+
{clGetDeviceInfo}, see <<command-buffer-queries, device queries table>>:
137+
138+
[source,c]
139+
----
140+
// Bits for cl_device_command_buffer_capabilities_khr bitfield
141+
CL_COMMAND_BUFFER_CAPABILITY_MUTABLE_MEM_COMMANDS_KHR (0x1 << 5)
142+
----
143+
144+
Structure pointer chain enum values for {cl_update_config_type_khr_TYPE}:
145+
[source,c]
146+
----
147+
CL_STRUCTURE_TYPE_MUTABLE_COPY_BUFFER_COMMAND_CONFIG_KHR 1
148+
CL_STRUCTURE_TYPE_MUTABLE_COPY_BUFFER_RECT_COMMAND_CONFIG_KHR 2
149+
CL_STRUCTURE_TYPE_MUTABLE_COPY_BUFFER_TO_IMAGE_COMMAND_CONFIG_KHR 3
150+
CL_STRUCTURE_TYPE_MUTABLE_COPY_BUFFER_TO_IMAGE_COMMAND_CONFIG_KHR 4
151+
CL_STRUCTURE_TYPE_MUTABLE_COPY_IMAGE_TO_BUFFER_COMMAND_CONFIG_KHR 5
152+
CL_STRUCTURE_TYPE_MUTABLE_FILL_BUFFER_COMMAND_CONFIG_KHR 6
153+
CL_STRUCTURE_TYPE_MUTABLE_FILL_IMAGE_COMMAND_CONFIG_KHR 7
154+
CL_STRUCTURE_TYPE_MUTABLE_SVM_MEMCPY_COMMAND_CONFIG_KHR 8
155+
CL_STRUCTURE_TYPE_MUTABLE_SVM_MEMFILL_COMMAND_CONFIG_KHR 9
156+
----
157+
158+
Bits for {cl_command_buffer_flags_khr_TYPE} bitfield:
159+
[source,c]
160+
----
161+
CL_MUTABLE_MEM_COMMANDS_ENABLE_KHR (0x1 << 3)
162+
----
163+
164+
=== Modifications to section 4.2 of the OpenCL API Specification
165+
166+
Additional wording to _description_ column of *Table 5*, _Device Queries_, of
167+
section 4.2 under the {CL_DEVICE_COMMAND_BUFFER_CAPABILITIES_KHR} row:
168+
[cols="1,1,4",options="header"]
169+
|====
170+
| cl_device_info
171+
| Return Type
172+
| Description
173+
174+
| {CL_DEVICE_COMMAND_BUFFER_CAPABILITIES_KHR}
175+
| {cl_device_command_buffer_capabilities_khr_TYPE}
176+
| {CL_COMMAND_BUFFER_CAPABILITY_MUTABLE_MEM_COMMANDS_KHR} Device supports the
177+
ability to modify the {cl_mem_TYPE} arguments to commands operating on memory
178+
objects between command-buffer invocations.
179+
|====
180+
181+
=== Modifications to Section 5.X - Command Buffers of OpenCL API specification
182+
183+
==== Additional Section 5.X.1 Introduction Text
184+
185+
Further mutability for modifying _memory-commands_ recorded to a
186+
command-buffer is also possible, defined as those commands taking a
187+
{cl_mem_TYPE} or SVM pointer argument.
188+
189+
The struct types defined by this extension for each memory-command type
190+
can be used in {clUpdateMutableCommandsKHR} to update the command
191+
configuration.
192+
193+
The {CL_MUTABLE_MEM_COMMANDS_ENABLE_KHR} flag must be set on command-buffer
194+
creation to enable this functionality, in combination with
195+
{CL_COMMAND_BUFFER_MUTABLE_KHR} which is requires to use the
196+
{clUpdateMutableCommandsKHR} entry-point.
197+
198+
==== clCreateCommandBufferKHR Modifications
199+
200+
The function {clCreateCommandBufferKHR} function has an additional property
201+
bit defined:
202+
203+
.*clCreateCommandBufferKHR* properties
204+
[cols=",,",options="header",]
205+
|====
206+
| *Recording Properties*
207+
| *Property Value*
208+
| *Description*
209+
210+
| {CL_COMMAND_BUFFER_FLAGS_KHR}
211+
| {cl_command_buffer_flags_khr_TYPE}
212+
| {CL_MUTABLE_MEM_COMMANDS_ENABLE_KHR} - Enable or disable modification of
213+
command-buffer memory-commands between enqueues. If set, the modification of
214+
the memory-commands in the command-buffer is enabled,
215+
otherwise it is disabled.
216+
|====
217+
218+
==== Memory-Command Modifications
219+
220+
The descriptions of command recording entry-points that operate on {cl_mem_TYPE}
221+
or SVM pointer arguments are modified as described in this section. These
222+
changes apply to all of {clCommandCopyBufferKHR}, {clCommandCopyBufferRectKHR},
223+
{clCommandCopyBufferToImageKHR}, {clCommandCopyImageKHR},
224+
{clCommandCopyImageToBufferKHR}, {clCommandFillBufferKHR},
225+
{clCommandFillImageKHR}, {clCommandSVMMemcpyKHR}, and {clCommandSVMMemFillKHR}.
226+
227+
===== Parameter Update
228+
229+
Parameter description of _mutable_handle_ is changed to:
230+
231+
_mutable_handle_ Returns a handle to the command that can be used to modify the
232+
command between enqueues of _command_buffer_. _mutable_handle_ may be `NULL`. The
233+
lifetime of this handle is tied to the parent command-buffer, such that freeing
234+
the command-buffer will also free this handle.
235+
236+
===== Error Updates
237+
238+
The error condition
239+
240+
* {CL_INVALID_VALUE} if _mutable_handle_ is not `NULL`.
241+
242+
Is replaced with
243+
244+
* {CL_INVALID_VALUE} if _mutable_handle_ is not `NULL` and _command_buffer_
245+
was not created with property {CL_MUTABLE_MEM_COMMANDS_ENABLE_KHR}.
246+
247+
==== clUpdateMutableCommandsKHR Modifications
248+
249+
===== Error Updates
250+
251+
The function {clUpdateMutableCommandsKHR} has the following additions to its
252+
error definitions:
253+
254+
For any memory-command structs in the _configs_ array, then the errors defined by
255+
the associated command-buffer command creation entry-point are returned if a
256+
struct element is set to an invlaid value. Additionally, if the _command_ element
257+
of the struct is not a valid mutable command object returned from the matching
258+
memory-command entry-point then {CL_INVALID_MUTABLE_COMMAND_KHR} is returned.
259+
{CL_INVALID_MUTABLE_COMMAND_KHR} is also returned if _command_ was not created
260+
from _command_buffer_.
261+
262+
=== Sample
263+
264+
[source,cpp]
265+
----
266+
#define CL_CHECK(ERROR) \
267+
if (ERROR) { \
268+
std::cerr << "OpenCL error: " << ERROR << "\n"; \
269+
return ERROR; \
270+
}
271+
272+
int main() {
273+
cl_platform_id platform;
274+
CL_CHECK(clGetPlatformIDs(1, &platform, nullptr));
275+
cl_device_id device;
276+
CL_CHECK(clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1, &device, nullptr));
277+
278+
cl_int error;
279+
cl_context context =
280+
clCreateContext(nullptr, 1, &device, nullptr, nullptr, &error);
281+
CL_CHECK(error);
282+
283+
cl_command_queue command_queue =
284+
clCreateCommandQueue(context, device, 0, &error);
285+
CL_CHECK(error);
286+
287+
size_t num_bytes = 128;
288+
cl_mem bufferA =
289+
clCreateBuffer(context, CL_MEM_READ_WRITE, num_bytes, nullptr, &error);
290+
CL_CHECK(error);
291+
292+
// Populate bufferA with data
293+
294+
cl_mem bufferB =
295+
clCreateBuffer(context, CL_MEM_READ_WRITE, num_bytes, nullptr, &error);
296+
CL_CHECK(error);
297+
298+
// Populate bufferB with data
299+
300+
cl_mem bufferC =
301+
clCreateBuffer(context, CL_MEM_READ_WRITE, num_bytes, nullptr, &error);
302+
CL_CHECK(eror);
303+
304+
cl_command_buffer_properties_khr properties[3] = {
305+
CL_COMMAND_BUFFER_FLAGS_KHR,
306+
CL_COMMAND_BUFFER_MUTABLE_KHR | CL_MUTABLE_MEM_COMMANDS_ENABLE_KHR,
307+
0
308+
};
309+
310+
cl_command_buffer_khr command_buffer =
311+
clCreateCommandBufferKHR(1, &command_queue, properties, &error);
312+
CL_CHECK(error)
313+
314+
cl_mutable_command_khr copy_command_handle;
315+
CL_CHECK(clCommandCopyBufferKHR(
316+
command_buffer,
317+
command_queue,
318+
bufferA,
319+
bufferC,
320+
0,
321+
0,
322+
num_bytes,
323+
0,
324+
nullptr,
325+
nullptr,
326+
&copy_command_handle);
327+
328+
CL_CHECK(clFinalizeCommandBufferKHR(command_buffer));
329+
CL_CHECK(clEnqueueCommandBufferKHR(0, nullptr, command_buffer, 0, nullptr,
330+
nullptr));
331+
332+
cl_mutable_copy_buffer_command_config_khr buffer_copy_config = {
333+
copy_command_handle, // command
334+
bufferB, // src_buffer
335+
bufferC, // dst_buffer
336+
0, // src_offset
337+
0, // dst_offset
338+
num_bytes // size
339+
};
340+
341+
cl_uint num_configs = 1;
342+
cl_update_config_type_khr config_types[1] = {
343+
CL_STRUCTURE_TYPE_MUTABLE_COPY_BUFFER_COMMAND_CONFIG_KHR
344+
};
345+
void* configs[1] = {&buffer_copy_config};
346+
CL_CHECK(clUpdateMutableCommandsKHR(command_buffer, num_configs,
347+
config_types, configs));
348+
CL_CHECK(clEnqueueCommandBufferKHR(command_buffer, 0, nullptr, nullptr));
349+
CL_CHECK(clFinish(command_queue));
350+
351+
CL_CHECK(clReleaseCommandBufferKHR(command_buffer));
352+
CL_CHECK(clReleaseCommandQueue(command_queue));
353+
CL_CHECK(clReleaseContext(context));
354+
355+
CL_CHECK(clReleaseMemObject(bufferA));
356+
CL_CHECK(clReleaseMemObject(bufferB));
357+
CL_CHECK(clReleaseMemObject(bufferC));
358+
359+
return 0;
360+
}
361+
----
362+
363+
=== Conformance tests
364+
365+
TODO - OpenCL-CTS Github issue with CTS plan once API design has been agreed.
366+

0 commit comments

Comments
 (0)