diff --git a/docs/OV_Runtime_UG/supported_plugins/GPU.md b/docs/OV_Runtime_UG/supported_plugins/GPU.md index 7aff81594b4..63885c8747e 100644 --- a/docs/OV_Runtime_UG/supported_plugins/GPU.md +++ b/docs/OV_Runtime_UG/supported_plugins/GPU.md @@ -222,11 +222,11 @@ The GPU plugin has the following additional preprocessing options: @sphinxtabset @sphinxtab{C++} -@snippet docs/snippets/gpu/preprocessing.cpp init_preproc +@snippet docs/snippets/gpu/preprocessing_nv12_two_planes.cpp init_preproc @endsphinxtab @sphinxtab{Python} -@snippet docs/snippets/gpu/preprocessing.py init_preproc +@snippet docs/snippets/gpu/preprocessing_nv12_two_planes.py init_preproc @endsphinxtab @endsphinxtabset diff --git a/docs/OV_Runtime_UG/supported_plugins/GPU_RemoteTensor_API.md b/docs/OV_Runtime_UG/supported_plugins/GPU_RemoteTensor_API.md index 6f22307aa45..2046aaf4438 100644 --- a/docs/OV_Runtime_UG/supported_plugins/GPU_RemoteTensor_API.md +++ b/docs/OV_Runtime_UG/supported_plugins/GPU_RemoteTensor_API.md @@ -3,8 +3,11 @@ The GPU plugin implementation of the `ov::RemoteContext` and `ov::RemoteTensor` interfaces supports GPU pipeline developers who need video memory sharing and interoperability with existing native APIs, such as OpenCL, Microsoft DirectX, or VAAPI. -Using these interfaces allows you to avoid any memory copy overhead when plugging OpenVINO™ inference -into an existing GPU pipeline. It also enables OpenCL kernels to participate in the pipeline to become + +The `ov::RemoteContext` and `ov::RemoteTensor` interface implementation targets the need for memory sharing and +interoperability with existing native APIs, such as OpenCL, Microsoft DirectX, and VAAPI. +They allow you to avoid any memory copy overhead when plugging OpenVINO™ inference +into an existing GPU pipeline. They also enable OpenCL kernels to participate in the pipeline to become native buffer consumers or producers of the OpenVINO™ inference. There are two interoperability scenarios supported by the Remote Tensor API: @@ -23,7 +26,7 @@ and functions that consume or produce native handles directly. ## Context Sharing Between Application and GPU Plugin GPU plugin classes that implement the `ov::RemoteContext` interface are responsible for context sharing. -Obtaining a context object is the first step of sharing pipeline objects. +Obtaining a context object is the first step in sharing pipeline objects. The context object of the GPU plugin directly wraps OpenCL context, setting a scope for sharing the `ov::CompiledModel` and `ov::RemoteTensor` objects. The `ov::RemoteContext` object can be either created on top of an existing handle from a native API or retrieved from the GPU plugin. @@ -37,60 +40,49 @@ additional parameter. To create the `ov::RemoteContext` object for user context, explicitly provide the context to the plugin using constructor for one of `ov::RemoteContext` derived classes. -@sphinxtabset +@sphinxdirective -@sphinxtab{Linux} +.. tab:: Linux -@sphinxtabset + .. tab:: Create from cl_context + + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: context_from_cl_context -@sphinxtab{Create from cl_context} + .. tab:: Create from cl_queue -@snippet docs/snippets/gpu/remote_objects_creation.cpp context_from_cl_context + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: context_from_cl_queue -@endsphinxtab + .. tab:: Create from VADisplay -@sphinxtab{Create from cl_queue} + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: context_from_va_display -@snippet docs/snippets/gpu/remote_objects_creation.cpp context_from_cl_queue +.. tab:: Windows -@endsphinxtab + .. tab:: Create from cl_context -@sphinxtab{Create from VADisplay} + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: context_from_cl_context -@snippet docs/snippets/gpu/remote_objects_creation.cpp context_from_va_display + .. tab:: Create from cl_queue -@endsphinxtab + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: context_from_cl_queue -@endsphinxtabset - -@endsphinxtab - -@sphinxtab{Windows} - -@sphinxtabset - -@sphinxtab{Create from cl_context} - -@snippet docs/snippets/gpu/remote_objects_creation.cpp context_from_cl_context - -@endsphinxtab - -@sphinxtab{Create from cl_queue} - -@snippet docs/snippets/gpu/remote_objects_creation.cpp context_from_cl_queue - -@endsphinxtab - -@sphinxtab{Create from ID3D11Device} - -@snippet docs/snippets/gpu/remote_objects_creation.cpp context_from_d3d_device - -@endsphinxtab - -@endsphinxtabset - -@endsphinxtabset + .. tab:: Create from ID3D11Device + + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: context_from_d3d_device +@endsphinxdirective ### Getting RemoteContext from the Plugin If you do not provide any user context, the plugin uses its default internal context. @@ -100,21 +92,21 @@ Once the plugin options have been changed, the internal context is replaced by t To request the current default context of the plugin, use one of the following methods: -@sphinxtabset +@sphinxdirective -@sphinxtab{Get context from Core} +.. tab:: Get context from Core -@snippet docs/snippets/gpu/remote_objects_creation.cpp default_context_from_core + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: default_context_from_core -@endsphinxtab +.. tab:: Get context from compiled model -@sphinxtab{Batching via throughput hint} + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: default_context_from_model -@snippet docs/snippets/gpu/remote_objects_creation.cpp default_context_from_model - -@endsphinxtab - -@endsphinxtabset +@endsphinxdirective ## Memory Sharing Between Application and GPU Plugin @@ -126,108 +118,153 @@ of the `ov::RemoteContext` sub-classes. `ov::intel_gpu::ocl::ClContext` has multiple overloads of `create_tensor` methods which allow to wrap pre-allocated native handles with the `ov::RemoteTensor` object or request plugin to allocate specific device memory. For more details, see the code snippets below: -@sphinxtabset +@sphinxdirective -@sphinxtab{Wrap native handles} +.. tab:: Wrap native handles -@sphinxtabset + .. tab:: USM pointer + + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: wrap_usm_pointer -@sphinxtab{USM pointer} + .. tab:: cl_mem + + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: wrap_cl_mem -@snippet docs/snippets/gpu/remote_objects_creation.cpp wrap_usm_pointer + .. tab:: cl::Buffer + + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: wrap_cl_buffer -@endsphinxtab + .. tab:: cl::Image2D + + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: wrap_cl_image -@sphinxtab{cl_mem} + .. tab:: biplanar NV12 surface + + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: wrap_nv12_surface -@snippet docs/snippets/gpu/remote_objects_creation.cpp wrap_cl_mem +.. tab:: Allocate device memory -@endsphinxtab + .. tab:: USM host memory + + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: allocate_usm_host -@sphinxtab{cl::Buffer} + .. tab:: USM device memory + + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: allocate_usm_device -@snippet docs/snippets/gpu/remote_objects_creation.cpp wrap_cl_buffer + .. tab:: cl::Buffer + + .. doxygensnippet:: docs/snippets/gpu/remote_objects_creation.cpp + :language: cpp + :fragment: allocate_cl_buffer -@endsphinxtab - -@sphinxtab{cl::Image2D} - -@snippet docs/snippets/gpu/remote_objects_creation.cpp wrap_cl_image - -@endsphinxtab - -@sphinxtab{biplanar NV12 surface} - -@snippet docs/snippets/gpu/remote_objects_creation.cpp wrap_nv12_surface - -@endsphinxtab - -@endsphinxtabset -@endsphinxtab - -@sphinxtab{Allocate device memory} - -@sphinxtabset - -@sphinxtab{USM host memory} - -@snippet docs/snippets/gpu/remote_objects_creation.cpp allocate_usm_host - -@endsphinxtab - -@sphinxtab{USM device memory} - -@snippet docs/snippets/gpu/remote_objects_creation.cpp allocate_usm_device - -@endsphinxtab - -@sphinxtab{cl::Buffer} - -@snippet docs/snippets/gpu/remote_objects_creation.cpp allocate_cl_buffer - -@endsphinxtab - -@endsphinxtabset - -@endsphinxtab - -@endsphinxtabset +@endsphinxdirective The `ov::intel_gpu::ocl::D3DContext` and `ov::intel_gpu::ocl::VAContext` classes are derived from `ov::intel_gpu::ocl::ClContext`. Therefore, they provide the functionality described above and extend it to allow creation of `ov::RemoteTensor` objects from `ID3D11Buffer`, `ID3D11Texture2D` pointers or the `VASurfaceID` handle respectively. + ## Direct NV12 Video Surface Input -To support the direct consumption of a hardware video decoder output, the plugin accepts two-plane video -surfaces as arguments for the `create_tensor_nv12()` function, which creates a pair of `ov::RemoteTensor` -objects which represent the Y and UV planes. +To support the direct consumption of a hardware video decoder output, the GPU plugin accepts: -To ensure that the plugin generates the correct execution graph for the NV12 dual-plane input, static preprocessing +* Two-plane NV12 video surface input - calling the `create_tensor_nv12()` function creates + a pair of `ov::RemoteTensor` objects, representing the Y and UV planes. +* Single-plane NV12 video surface input - calling the `create_tensor()` function creates one + `ov::RemoteTensor` object, representing the Y and UV planes at once (Y elements before UV elements). +* NV12 to Grey video surface input conversion - calling the `create_tensor()` function creates one + `ov::RemoteTensor` object, representing only the Y plane. + +To ensure that the plugin generates a correct execution graph, static preprocessing should be added before model compilation: -@snippet snippets/gpu/preprocessing.cpp init_preproc +@sphinxdirective -Since the `ov::intel_gpu::ocl::ClImage2DTensor` and its derived classes do not support batched surfaces, if batching and surface sharing are required -at the same time, inputs need to be set via the `ov::InferRequest::set_tensors` method with vector of shared surfaces for each plane: +.. tab:: two-plane -@sphinxtabset + .. doxygensnippet:: docs/snippets/gpu/preprocessing_nv12_two_planes.cpp + :language: cpp + :fragment: [init_preproc] -@sphinxtab{Single batch} +.. tab:: single-plane -@snippet docs/snippets/gpu/preprocessing.cpp single_batch + .. doxygensnippet:: docs/snippets/gpu/preprocessing_nv12_single_plane.cpp + :language: cpp + :fragment: [init_preproc] -@endsphinxtab +.. tab:: NV12 to Grey -@sphinxtab{Multiple batches} + .. doxygensnippet:: docs/snippets/gpu/preprocessing_nv12_to_gray.cpp + :language: cpp + :fragment: [init_preproc] -@snippet docs/snippets/gpu/preprocessing.cpp batched_case +@endsphinxdirective -@endsphinxtab -@endsphinxtabset +Since the `ov::intel_gpu::ocl::ClImage2DTensor` and its derived classes do not support batched surfaces, +if batching and surface sharing are required at the same time, +inputs need to be set via the `ov::InferRequest::set_tensors` method with vector of shared surfaces for each plane: +@sphinxdirective + +.. tab:: Single Batch + + .. tab:: two-plane + + .. doxygensnippet:: docs/snippets/gpu/preprocessing_nv12_two_planes.cpp + :language: cpp + :fragment: single_batch + + .. tab:: single-plane + + .. doxygensnippet:: docs/snippets/gpu/preprocessing_nv12_single_plane.cpp + :language: cpp + :fragment: single_batch + + .. tab:: NV12 to Grey + + .. doxygensnippet:: docs/snippets/gpu/preprocessing_nv12_to_gray.cpp + :language: cpp + :fragment: single_batch + +.. tab:: Multiple Batches + + .. tab:: two-plane + + .. doxygensnippet:: docs/snippets/gpu/preprocessing_nv12_two_planes.cpp + :language: cpp + :fragment: batched_case + + .. tab:: single-plane + + .. doxygensnippet:: docs/snippets/gpu/preprocessing_nv12_single_plane.cpp + :language: cpp + :fragment: batched_case + + .. tab:: NV12 to Grey + + .. doxygensnippet:: docs/snippets/gpu/preprocessing_nv12_to_gray.cpp + :language: cpp + :fragment: batched_case + +@endsphinxdirective + I420 color format can be processed in a similar way ## Context & Queue Sharing @@ -242,18 +279,12 @@ This sharing mechanism allows performing pipeline synchronization on the app sid on waiting for the completion of inference. The pseudo-code may look as follows: @sphinxdirective -.. raw:: html -