Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PyOV] OpenCL GPU API in Python #24265

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/bindings/python/src/openvino/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
from openvino._pyopenvino import RemoteContext
from openvino._pyopenvino import RemoteTensor

# opencl related:
# ...

# libva related:
from openvino._pyopenvino import VAContext
from openvino._pyopenvino import VASurfaceTensor
Expand Down
151 changes: 151 additions & 0 deletions src/bindings/python/src/pyopenvino/core/remote_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,157 @@ void regclass_RemoteContext(py::module m) {
)");
}

void regclass_ClContext(py::module m) {
py::class_<ClContextWrapper, RemoteContextWrapper, std::shared_ptr<ClContextWrapper>> 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<void*>(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<CL_IMAGE_WIDTH>();
// size_t height = nv12_image_plane_y.getImageInfo<CL_IMAGE_HEIGHT>();
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_<VAContextWrapper, RemoteContextWrapper, std::shared_ptr<VAContextWrapper>> cls(m, "VAContext");

Expand Down
11 changes: 11 additions & 0 deletions src/bindings/python/src/pyopenvino/core/remote_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ class RemoteContextWrapper {

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} {}
Expand Down
30 changes: 30 additions & 0 deletions src/bindings/python/src/pyopenvino/core/remote_tensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,36 @@ void regclass_RemoteTensor(py::module m) {
});
}

void regclass_ClBufferTensor(py::module m) {
py::class_<ClBufferTensorWrapper, RemoteTensorWrapper, std::shared_ptr<ClBufferTensorWrapper>> cls(
m,
"ClBufferTensor");

cls.def("get", [](const ClBufferTensorWrapper& self) {
return self.tensor.get_params().at(ov::intel_gpu::mem_handle.name()).as<void*>();
});
}

void regclass_ClImage2DTensor(py::module m) {
py::class_<ClImage2DTensorWrapper, RemoteTensorWrapper, std::shared_ptr<ClImage2DTensorWrapper>> cls(
m,
"ClImage2DTensor");

cls.def("get", [](const ClImage2DTensorWrapper& self) {
return self.tensor.get_params().at(ov::intel_gpu::mem_handle.name()).as<void*>();
});
}

void regclass_USMTensor(py::module m) {
py::class_<USMTensorWrapper, RemoteTensorWrapper, std::shared_ptr<USMTensorWrapper>> cls(
m,
"USMTensor");

cls.def("get", [](const USMTensorWrapper& self) {
return self.tensor.get_params().at(ov::intel_gpu::mem_handle.name()).as<void*>();
});
}

void regclass_VASurfaceTensor(py::module m) {
py::class_<VASurfaceTensorWrapper, RemoteTensorWrapper, std::shared_ptr<VASurfaceTensorWrapper>> cls(
m,
Expand Down
33 changes: 33 additions & 0 deletions src/bindings/python/src/pyopenvino/core/remote_tensor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,39 @@ class RemoteTensorWrapper {

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} {}
Expand Down
6 changes: 6 additions & 0 deletions src/bindings/python/src/pyopenvino/pyopenvino.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
3 changes: 3 additions & 0 deletions tools/benchmark_tool/openvino/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
from openvino._pyopenvino import RemoteContext
from openvino._pyopenvino import RemoteTensor

# opencl related:
# ...

# libva related:
from openvino._pyopenvino import VAContext
from openvino._pyopenvino import VASurfaceTensor
Expand Down
3 changes: 3 additions & 0 deletions tools/ovc/openvino/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
from openvino._pyopenvino import RemoteContext
from openvino._pyopenvino import RemoteTensor

# opencl related:
# ...

# libva related:
from openvino._pyopenvino import VAContext
from openvino._pyopenvino import VASurfaceTensor
Expand Down
Loading