OpenVINO使用OpenCL内存执行,避免拷贝

一、简介

出于性能考虑,通常 CPU 无法满足耗时的要求,网络需要执行在 GPU 上增强性能,而数据的处理通常使用 OpenCL 也会比 CPU 快很多。

所以我们要是可以直接将 OpenCL 处理后的内存给 OpenVINO 执行,就可以避免将 OpenCL 内存拷贝到 CPU 上,再从 CPU 拷贝到 OpenVINO 中。

其实 OpenVINO 已经支持直接使用 OpenCL 的内存,只要他们公用一个 Context 即可。

二、使用

1.官方资料

本文是基于 OpenVINO 2021 的 SDK 写的,参考的官方文档链接为:https://docs.openvino.ai/2021.4/openvino_docs_IE_DG_supported_plugins_GPU_RemoteBlob_API.html

另外 OpenVINO 2022 的接口有所变动,可以参考这篇文档:https://docs.openvino.ai/latest/openvino_docs_OV_UG_supported_plugins_GPU_RemoteTensor_API.html

2.使用外部cl_context

#include 
#include 
#include 
#include 

using namespace InferenceEngine;

// 1.创建
Core ie;
auto net = ie.ReadNetwork("network.xml");
// 举例使用 OpenCV 提供的 cl_context,用者替换为自己的 cl_context
cl_context ctx = static_cast<cl_context>(cv::ocl::Context::getDefault().ptr());
auto remote_context = gpu::make_shared_context(mCore, "GPU", ctx);
ExecutableNetwork network = ie.LoadNetwork(net, remote_context);
InferRequest request = network.CreateInferRequest();

// 2.设置数据
InputsDataMap& inputs = network.getInputsInfo();
for (auto& input : inputs) {
    auto& input_name = input.first;
    InputInfo::Ptr& input_info = input.second;
    // 这里是 cv::UMat uMat,用者替换为自己的 cl_mem
    cl_mem shared_buffer = static_cast<cl_mem>(umat_in.u->handle);
    auto shared_blob = gpu::make_shared_blob(input_info->getTensorDesc(), network.GetContext(), shared_buffer);
    request.SetBlob(input_name, shared_blob);
}
for (auto& output : outputs) {
    auto& output_name = output.first; //output也是一个键值对类型
    DataPtr& output_info = output.second;
    // 这里是 cv::UMat uMat,用者替换为自己的 cl_mem
    cl_mem shared_buffer = static_cast<cl_mem>(umat_out.u->handle);
    auto shared_blob = gpu::make_shared_blob(output_info->getTensorDesc(), network.GetContext(), shared_buffer);
    request.SetBlob(output_name, shared_blob);
}

// 3.执行
request.Infer();

// 4.获取输出,输出数据已经直接输出到 umat_out 中了。

你可能感兴趣的:(神经网络引擎,openvino)