From f3d920d0eab108aa99f34fbb0e738b672ddf5108 Mon Sep 17 00:00:00 2001 From: jiwaszki Date: Fri, 26 Apr 2024 10:43:33 +0000 Subject: [PATCH 1/2] WIP, first draft of opencl API --- src/bindings/python/src/openvino/__init__.py | 3 + .../src/pyopenvino/core/remote_context.cpp | 151 ++++++++++++++++++ .../src/pyopenvino/core/remote_context.hpp | 11 ++ .../src/pyopenvino/core/remote_tensor.cpp | 30 ++++ .../src/pyopenvino/core/remote_tensor.hpp | 33 ++++ .../python/src/pyopenvino/pyopenvino.cpp | 6 + 6 files changed, 234 insertions(+) diff --git a/src/bindings/python/src/openvino/__init__.py b/src/bindings/python/src/openvino/__init__.py index 24a0ee92ec6..65c302dcd29 100644 --- a/src/bindings/python/src/openvino/__init__.py +++ b/src/bindings/python/src/openvino/__init__.py @@ -54,6 +54,9 @@ from openvino.runtime import layout_helpers from openvino._pyopenvino import RemoteContext from openvino._pyopenvino import RemoteTensor +# opencl related: +# ... + # libva related: from openvino._pyopenvino import VAContext from openvino._pyopenvino import VASurfaceTensor diff --git a/src/bindings/python/src/pyopenvino/core/remote_context.cpp b/src/bindings/python/src/pyopenvino/core/remote_context.cpp index 858593bbc3a..40ab95747cb 100644 --- a/src/bindings/python/src/pyopenvino/core/remote_context.cpp +++ b/src/bindings/python/src/pyopenvino/core/remote_context.cpp @@ -99,6 +99,157 @@ void regclass_RemoteContext(py::module m) { )"); } +void regclass_ClContext(py::module m) { + py::class_> cls(m, "ClContext"); + + // TODO: Figure out how to pass the pointer without using cl_context + cls.def(py::init([](ov::Core& core, long int* ctx, int ctx_device_id) { + ov::AnyMap context_params = {{ov::intel_gpu::context_type.name(), ov::intel_gpu::ContextType::OCL}, + {ov::intel_gpu::ocl_context.name(), static_cast(ctx)}, + {ov::intel_gpu::ocl_context_device_id.name(), ctx_device_id}}; + auto _ctx = core.create_context("GPU", context_params); + return ClContextWrapper(_ctx); + }), + py::arg("core"), + py::arg("ctx"), + py::arg("ctx_device_id") = 0); + + cls.def(py::init([](ov::Core& core, void* ctx, int ctx_device_id) { + ov::AnyMap context_params = {{ov::intel_gpu::context_type.name(), ov::intel_gpu::ContextType::OCL}, + {ov::intel_gpu::ocl_context.name(), ctx}, + {ov::intel_gpu::ocl_context_device_id.name(), ctx_device_id}}; + auto _ctx = core.create_context("GPU", context_params); + return ClContextWrapper(_ctx); + }), + py::arg("core"), + py::arg("ctx"), + py::arg("ctx_device_id") = 0); + + // Won't compile without conditionl compilation, depending on CL commands + // cls.def(py::init([](ov::Core& core, /*cl_command_queue*/ void* queue) { + // cl_context ctx; + // auto res = clGetCommandQueueInfo(queue, CL_QUEUE_CONTEXT, sizeof(cl_context), &ctx, nullptr); + // OPENVINO_ASSERT(res == CL_SUCCESS, "Can't get context from given opencl queue"); + // ov::AnyMap context_params = {{ov::intel_gpu::context_type.name(), ov::intel_gpu::ContextType::OCL}, + // {ov::intel_gpu::ocl_context.name(), ctx}, + // {ov::intel_gpu::ocl_queue.name(), queue}}; + // auto _ctx = core.create_context("GPU", context_params); + // return ClContextWrapper(_ctx); + // })); + + /* somehow const cl::Image2D& */ + cls.def( + "create_tensor_nv12", + [](ClContextWrapper& self, + void* nv12_image_plane_y, + void* nv12_image_plane_uv) { + ov::RemoteTensor y_tensor, uv_tensor; + { + py::gil_scoped_release release; + // This is not possible without OpenCL interface: + // size_t width = nv12_image_plane_y.getImageInfo(); + // size_t height = nv12_image_plane_y.getImageInfo(); + size_t width = 0; + size_t height = 0; + + ov::AnyMap tensor_params = { + {ov::intel_gpu::shared_mem_type.name(), ov::intel_gpu::SharedMemType::OCL_IMAGE2D}, + {ov::intel_gpu::mem_handle.name(), nv12_image_plane_y}}; + auto y_tensor = self.context.create_tensor(ov::element::u8, {1, height, width, 1}, tensor_params); + tensor_params[ov::intel_gpu::mem_handle.name()] = nv12_image_plane_uv; + auto uv_tensor = self.context.create_tensor(ov::element::u8, {1, height / 2, width / 2, 2}, tensor_params); + } + return py::make_tuple(ClImage2DTensorWrapper(y_tensor), ClImage2DTensorWrapper(uv_tensor)); + }, + py::arg("nv12_image_plane_y"), + py::arg("nv12_image_plane_uv")); + + /* const cl_mem */ + cls.def( + "create_tensor", + [](ClContextWrapper& self, + const ov::element::Type type, + const ov::Shape& shape, + void* buffer) { + ov::AnyMap params = {{ov::intel_gpu::shared_mem_type.name(), ov::intel_gpu::SharedMemType::OCL_BUFFER}, + {ov::intel_gpu::mem_handle.name(), buffer}}; + return ClBufferTensorWrapper(self.context.create_tensor(type, shape, params)); + }, + py::arg("type"), + py::arg("shape"), + py::arg("buffer")); + + // Should it be possible? ^ above does the same thing. + // cls.def( + // "create_tensor", + // [](ClContextWrapper& self, + // const ov::element::Type type, + // const ov::Shape& shape, + // void* /* const cl::Buffer& */ buffer) { + // return ClBufferTensorWrapper(self.context.create_tensor(type, shape, buffer)); + // }, + // py::arg("type"), + // py::arg("shape"), + // py::arg("buffer"), + // R"( + // TBA. + // )"); + + /* const cl::Image2D& */ + cls.def( + "create_tensor", + [](ClContextWrapper& self, + const ov::element::Type type, + const ov::Shape& shape, + void* image) { + ov::AnyMap params = {{ov::intel_gpu::shared_mem_type.name(), ov::intel_gpu::SharedMemType::OCL_IMAGE2D}, + {ov::intel_gpu::mem_handle.name(), image}}; + return ClImage2DTensorWrapper(self.context.create_tensor(type, shape, params)); + }, + py::arg("type"), + py::arg("shape"), + py::arg("image")); + + cls.def( + "create_tensor", + [](ClContextWrapper& self, + const ov::element::Type type, + const ov::Shape& shape, + void* usm_ptr) { + ov::AnyMap params = {{ov::intel_gpu::shared_mem_type.name(), ov::intel_gpu::SharedMemType::USM_USER_BUFFER}, + {ov::intel_gpu::mem_handle.name(), usm_ptr}}; + return USMTensorWrapper(self.context.create_tensor(type, shape, params)); + }, + py::arg("type"), + py::arg("shape"), + py::arg("usm_ptr"), + R"( + TBA. + )"); + + cls.def( + "create_usm_host_tensor", + [](ClContextWrapper& self, + const ov::element::Type type, + const ov::Shape& shape) { + ov::AnyMap params = {{ov::intel_gpu::shared_mem_type.name(), ov::intel_gpu::SharedMemType::USM_HOST_BUFFER}}; + return USMTensorWrapper(self.context.create_tensor(type, shape, params)); + }, + py::arg("type"), + py::arg("shape")); + + cls.def( + "create_usm_device_tensor", + [](ClContextWrapper& self, + const ov::element::Type type, + const ov::Shape& shape) { + ov::AnyMap params = {{ov::intel_gpu::shared_mem_type.name(), ov::intel_gpu::SharedMemType::USM_DEVICE_BUFFER}}; + return USMTensorWrapper(self.context.create_tensor(type, shape, params)); + }, + py::arg("type"), + py::arg("shape")); +} + void regclass_VAContext(py::module m) { py::class_> cls(m, "VAContext"); diff --git a/src/bindings/python/src/pyopenvino/core/remote_context.hpp b/src/bindings/python/src/pyopenvino/core/remote_context.hpp index d5695e59165..ba05ee00dfc 100644 --- a/src/bindings/python/src/pyopenvino/core/remote_context.hpp +++ b/src/bindings/python/src/pyopenvino/core/remote_context.hpp @@ -30,6 +30,17 @@ public: void regclass_RemoteContext(py::module m); +class ClContextWrapper : public RemoteContextWrapper { +public: + ClContextWrapper() {} + + ClContextWrapper(ov::RemoteContext& _context): RemoteContextWrapper{_context} {} + + ClContextWrapper(ov::RemoteContext&& _context): RemoteContextWrapper{std::move(_context)} {} +}; + +void regclass_ClContext(py::module m); + class VAContextWrapper : public RemoteContextWrapper { public: VAContextWrapper(ov::RemoteContext& _context): RemoteContextWrapper{_context} {} diff --git a/src/bindings/python/src/pyopenvino/core/remote_tensor.cpp b/src/bindings/python/src/pyopenvino/core/remote_tensor.cpp index 034b9b425b7..f233db4b103 100644 --- a/src/bindings/python/src/pyopenvino/core/remote_tensor.cpp +++ b/src/bindings/python/src/pyopenvino/core/remote_tensor.cpp @@ -95,6 +95,36 @@ void regclass_RemoteTensor(py::module m) { }); } +void regclass_ClBufferTensor(py::module m) { + py::class_> cls( + m, + "ClBufferTensor"); + + cls.def("get", [](const ClBufferTensorWrapper& self) { + return self.tensor.get_params().at(ov::intel_gpu::mem_handle.name()).as(); + }); +} + +void regclass_ClImage2DTensor(py::module m) { + py::class_> cls( + m, + "ClImage2DTensor"); + + cls.def("get", [](const ClImage2DTensorWrapper& self) { + return self.tensor.get_params().at(ov::intel_gpu::mem_handle.name()).as(); + }); +} + +void regclass_USMTensor(py::module m) { + py::class_> cls( + m, + "USMTensor"); + + cls.def("get", [](const USMTensorWrapper& self) { + return self.tensor.get_params().at(ov::intel_gpu::mem_handle.name()).as(); + }); +} + void regclass_VASurfaceTensor(py::module m) { py::class_> cls( m, diff --git a/src/bindings/python/src/pyopenvino/core/remote_tensor.hpp b/src/bindings/python/src/pyopenvino/core/remote_tensor.hpp index 4fa40aff496..16b6afc1e83 100644 --- a/src/bindings/python/src/pyopenvino/core/remote_tensor.hpp +++ b/src/bindings/python/src/pyopenvino/core/remote_tensor.hpp @@ -27,6 +27,39 @@ public: void regclass_RemoteTensor(py::module m); +class ClBufferTensorWrapper : public RemoteTensorWrapper { +public: + ClBufferTensorWrapper() {} + + ClBufferTensorWrapper(ov::RemoteTensor& _tensor): RemoteTensorWrapper{_tensor} {} + + ClBufferTensorWrapper(ov::RemoteTensor&& _tensor): RemoteTensorWrapper{std::move(_tensor)} {} +}; + +void regclass_ClBufferTensor(py::module m); + +class ClImage2DTensorWrapper : public RemoteTensorWrapper { +public: + ClImage2DTensorWrapper() {} + + ClImage2DTensorWrapper(ov::RemoteTensor& _tensor): RemoteTensorWrapper{_tensor} {} + + ClImage2DTensorWrapper(ov::RemoteTensor&& _tensor): RemoteTensorWrapper{std::move(_tensor)} {} +}; + +void regclass_ClImage2DTensor(py::module m); + +class USMTensorWrapper : public RemoteTensorWrapper { +public: + USMTensorWrapper() {} + + USMTensorWrapper(ov::RemoteTensor& _tensor): RemoteTensorWrapper{_tensor} {} + + USMTensorWrapper(ov::RemoteTensor&& _tensor): RemoteTensorWrapper{std::move(_tensor)} {} +}; + +void regclass_USMTensor(py::module m); + class VASurfaceTensorWrapper : public RemoteTensorWrapper { public: VASurfaceTensorWrapper(ov::RemoteTensor& _tensor): RemoteTensorWrapper{_tensor} {} diff --git a/src/bindings/python/src/pyopenvino/pyopenvino.cpp b/src/bindings/python/src/pyopenvino/pyopenvino.cpp index cc87433f122..634b85a4af5 100644 --- a/src/bindings/python/src/pyopenvino/pyopenvino.cpp +++ b/src/bindings/python/src/pyopenvino/pyopenvino.cpp @@ -270,6 +270,12 @@ PYBIND11_MODULE(_pyopenvino, m) { regclass_RemoteContext(m); regclass_RemoteTensor(m); + + regclass_ClContext(m); + regclass_ClBufferTensor(m); + regclass_ClImage2DTensor(m); + regclass_USMTensor(m); + regclass_VAContext(m); regclass_VASurfaceTensor(m); From 2762dce1d355005186b4b68945c5293f31243ab2 Mon Sep 17 00:00:00 2001 From: jiwaszki Date: Thu, 9 May 2024 12:55:22 +0000 Subject: [PATCH 2/2] align inits --- tools/benchmark_tool/openvino/__init__.py | 3 +++ tools/ovc/openvino/__init__.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/tools/benchmark_tool/openvino/__init__.py b/tools/benchmark_tool/openvino/__init__.py index 24a0ee92ec6..65c302dcd29 100644 --- a/tools/benchmark_tool/openvino/__init__.py +++ b/tools/benchmark_tool/openvino/__init__.py @@ -54,6 +54,9 @@ from openvino.runtime import layout_helpers from openvino._pyopenvino import RemoteContext from openvino._pyopenvino import RemoteTensor +# opencl related: +# ... + # libva related: from openvino._pyopenvino import VAContext from openvino._pyopenvino import VASurfaceTensor diff --git a/tools/ovc/openvino/__init__.py b/tools/ovc/openvino/__init__.py index 24a0ee92ec6..65c302dcd29 100644 --- a/tools/ovc/openvino/__init__.py +++ b/tools/ovc/openvino/__init__.py @@ -54,6 +54,9 @@ from openvino.runtime import layout_helpers from openvino._pyopenvino import RemoteContext from openvino._pyopenvino import RemoteTensor +# opencl related: +# ... + # libva related: from openvino._pyopenvino import VAContext from openvino._pyopenvino import VASurfaceTensor