1/*******************************************************************************
2* Copyright 2020-2022 Intel Corporation
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*******************************************************************************/
16
17#ifndef ONEAPI_DNNL_DNNL_OCL_H
18#define ONEAPI_DNNL_DNNL_OCL_H
19
20#include "oneapi/dnnl/dnnl.h"
21
22#include "oneapi/dnnl/dnnl_ocl_types.h"
23
24/// @cond DO_NOT_DOCUMENT_THIS
25// Set target version for OpenCL explicitly to suppress a compiler warning.
26#ifndef CL_TARGET_OPENCL_VERSION
27#define CL_TARGET_OPENCL_VERSION 120
28#endif
29
30#include <CL/cl.h>
31/// @endcond
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37/// @addtogroup dnnl_api
38/// @{
39
40/// @addtogroup dnnl_api_interop
41/// @{
42
43/// @addtogroup dnnl_api_ocl_interop
44/// @{
45
46/// Creates a memory object.
47///
48/// Unless @p handle is equal to DNNL_MEMORY_NONE or DNNL_MEMORY_ALLOCATE, the
49/// constructed memory object will have the underlying buffer set. In this
50/// case, the buffer will be initialized as if:
51/// - dnnl_memory_set_data_handle() has been called, if @p memory_kind is equal
52/// to dnnl_ocl_interop_usm, or
53/// - dnnl_ocl_interop_memory_set_mem_object() has been called, if @p memory_kind
54/// is equal to dnnl_ocl_interop_buffer.
55///
56/// @param memory Output memory object.
57/// @param memory_desc Memory descriptor.
58/// @param engine Engine to use.
59/// @param memory_kind Memory allocation kind to specify the type of handle.
60/// @param handle Handle of the memory buffer to use as an underlying storage.
61/// - A USM pointer to the user-allocated buffer. In this case the library
62/// doesn't own the buffer. Requires @p memory_kind to be equal to
63/// dnnl_ocl_interop_usm.
64/// - An OpenCL buffer. In this case the library doesn't own the buffer.
65/// Requires @p memory_kind be equal to be equal to dnnl_ocl_interop_buffer.
66/// - The DNNL_MEMORY_ALLOCATE special value. Instructs the library to
67/// allocate the buffer that corresponds to the memory allocation kind
68/// @p memory_kind for the memory object. In this case the library
69/// owns the buffer.
70/// - The DNNL_MEMORY_NONE specific value. Instructs the library to
71/// create memory object without an underlying buffer.
72/// @returns #dnnl_success on success and a status describing the error
73/// otherwise.
74dnnl_status_t DNNL_API dnnl_ocl_interop_memory_create(dnnl_memory_t *memory,
75 const_dnnl_memory_desc_t memory_desc, dnnl_engine_t engine,
76 dnnl_ocl_interop_memory_kind_t memory_kind, void *handle);
77
78/// Returns the memory allocation kind associated with a memory object.
79///
80/// @param memory Memory to query.
81/// @param memory_kind Output underlying memory allocation kind of the memory
82/// object.
83/// @returns #dnnl_success on success and a status describing the error
84/// otherwise.
85dnnl_status_t DNNL_API dnnl_ocl_interop_memory_get_memory_kind(
86 const_dnnl_memory_t memory,
87 dnnl_ocl_interop_memory_kind_t *memory_kind);
88
89/// Returns an OpenCL memory object associated with a memory object.
90///
91/// @param memory Memory object.
92/// @param mem_object Output OpenCL memory object.
93/// @returns #dnnl_success on success and a status describing the error
94/// otherwise.
95dnnl_status_t DNNL_API dnnl_ocl_interop_memory_get_mem_object(
96 const_dnnl_memory_t memory, cl_mem *mem_object);
97
98/// Sets OpenCL memory object associated with a memory object.
99///
100/// For behavioral details, see dnnl_memory_set_data_handle().
101///
102/// @param memory Memory object.
103/// @param mem_object OpenCL memory object.
104/// @returns #dnnl_success on success and a status describing the error
105/// otherwise.
106dnnl_status_t DNNL_API dnnl_ocl_interop_memory_set_mem_object(
107 dnnl_memory_t memory, cl_mem mem_object);
108
109/// Retrieves a cache blob ID for the OpenCL device.
110///
111/// @warning
112/// This API is intended to be used with
113/// #dnnl_ocl_interop_engine_get_cache_blob() and
114/// #dnnl_ocl_interop_engine_create_from_cache_blob(). The returned cache
115/// blob ID can only be used as an ID of the cache blob returned by
116/// #dnnl_ocl_interop_engine_get_cache_blob().
117///
118/// @note The cache blob ID can be empty (@p size will be 0 and
119/// @p cache_blob_id will be nullptr) if oneDNN doesn't have anything to
120/// put in the cache blob. (#dnnl_ocl_interop_engine_get_cache_blob will
121/// return an empty cache blob).
122///
123/// @param device An OpenCL device.
124/// @param size Size of the cache blob ID in bytes.
125/// @param cache_blob_id Cache blob id of size @p size. If
126/// the @p cache_blob_id is nullptr then the size of the cache blob ID is
127/// returned in @p size.
128/// @returns #dnnl_success on success and a status describing the error
129/// otherwise.
130dnnl_status_t DNNL_API dnnl_ocl_interop_engine_get_cache_blob_id(
131 cl_device_id device, size_t *size, uint8_t *cache_blob_id);
132
133/// Retrieves a cache blob associated with the given engine.
134///
135/// @note The cache blob can be empty (@p size will be 0 and @p cache_blob
136/// will be nullptr) if oneDNN doesn't have anything to put in the cache
137/// blob. It's the user's responsibility to check whether it's empty
138/// prior to passing it to
139/// #dnnl_ocl_interop_engine_create_from_cache_blob().
140///
141/// @param engine Engine to query for the cache blob.
142/// @param size Size of the cache blob in bytes.
143/// @param cache_blob Cache blob of size @p size. If the @p cache_blob is
144/// nullptr then the size of the cache blob is returned in @p size.
145/// @returns #dnnl_success on success and a status describing the error
146/// otherwise.
147dnnl_status_t DNNL_API dnnl_ocl_interop_engine_get_cache_blob(
148 dnnl_engine_t engine, size_t *size, uint8_t *cache_blob);
149
150/// Creates an engine from the given cache blob.
151///
152/// @param engine Output engine.
153/// @param device The OpenCL device that this engine will encapsulate.
154/// @param context The OpenCL context (containing the device) that this
155/// engine will use for all operations.
156/// @returns #dnnl_success on success and a status describing the error
157/// otherwise.
158/// @param size Size of the cache blob in bytes.
159/// @param cache_blob Cache blob of size @p size.
160/// @returns #dnnl_success on success and a status describing the error
161/// otherwise.
162dnnl_status_t DNNL_API dnnl_ocl_interop_engine_create_from_cache_blob(
163 dnnl_engine_t *engine, cl_device_id device, cl_context context,
164 size_t size, const uint8_t *cache_blob);
165
166/// Creates an engine associated with an OpenCL device and an OpenCL context.
167///
168/// @param engine Output engine.
169/// @param device Underlying OpenCL device to use for the engine.
170/// @param context Underlying OpenCL context to use for the engine.
171/// @returns #dnnl_success on success and a status describing the error
172/// otherwise.
173dnnl_status_t DNNL_API dnnl_ocl_interop_engine_create(
174 dnnl_engine_t *engine, cl_device_id device, cl_context context);
175
176/// Returns the OpenCL context associated with an engine.
177///
178/// @param engine Engine to query.
179/// @param context Output underlying OpenCL context of the engine.
180/// @returns #dnnl_success on success and a status describing the error
181/// otherwise.
182dnnl_status_t DNNL_API dnnl_ocl_interop_engine_get_context(
183 dnnl_engine_t engine, cl_context *context);
184
185/// Returns the OpenCL device associated with an engine.
186///
187/// @param engine Engine to query.
188/// @param device Output underlying OpenCL device of the engine.
189/// @returns #dnnl_success on success and a status describing the error
190/// otherwise.
191dnnl_status_t DNNL_API dnnl_ocl_interop_get_device(
192 dnnl_engine_t engine, cl_device_id *device);
193
194/// Creates an execution stream for a given engine associated with
195/// an OpenCL command queue.
196///
197/// @param stream Output execution stream.
198/// @param engine Engine to create the execution stream on.
199/// @param queue OpenCL command queue to use.
200/// @returns #dnnl_success on success and a status describing the error
201/// otherwise.
202dnnl_status_t DNNL_API dnnl_ocl_interop_stream_create(
203 dnnl_stream_t *stream, dnnl_engine_t engine, cl_command_queue queue);
204
205/// Returns the OpenCL command queue associated with an execution stream.
206///
207/// @param stream Execution stream to query.
208/// @param queue Output OpenCL command queue.
209/// @returns #dnnl_success on success and a status describing the error
210/// otherwise.
211dnnl_status_t DNNL_API dnnl_ocl_interop_stream_get_command_queue(
212 dnnl_stream_t stream, cl_command_queue *queue);
213
214/// Executes computations specified by the primitive in a specified stream and
215/// returns an OpenCL event.
216///
217/// @param primitive Primitive to execute.
218/// @param stream Stream to use.
219/// @param nargs Number of arguments.
220/// @param args Array of arguments. Each argument is an
221/// <index, #dnnl_memory_t> pair. The index is one of the `DNNL_ARG_*`
222/// values such as `DNNL_ARG_SRC`. Unless runtime shapes are used (see
223/// #DNNL_RUNTIME_DIM_VAL), the memory object must have the same memory
224/// descriptor as that returned by
225/// #dnnl_primitive_desc_query_md(#dnnl_query_exec_arg_md, index).
226/// @param deps A pointer to a vector of size @p ndeps that contains
227/// dependencies.
228/// @param ndeps Number of dependencies.
229/// @param return_event Output event. It's the user's responsibility to
230/// manage lifetime of the event. Can be NULL. When @p stream is in-order
231/// NULL will be returned.
232/// @returns #dnnl_success on success and a status describing the error
233/// otherwise.
234dnnl_status_t DNNL_API dnnl_ocl_interop_primitive_execute(
235 const_dnnl_primitive_t primitive, dnnl_stream_t stream, int nargs,
236 const dnnl_exec_arg_t *args, const cl_event *deps, int ndeps,
237 cl_event *return_event);
238
239/// @} dnnl_api_ocl_interop
240
241/// @} dnnl_api_interop
242
243/// @} dnnl_api
244
245#ifdef __cplusplus
246}
247#endif
248
249#endif
250