Added remote objects type check (#7606)
This commit is contained in:
parent
1752298e17
commit
5b176f28cc
@ -98,8 +98,8 @@ ContinueStatement: '^.*$'
|
||||
BreakStatement: '^.*$'
|
||||
ReturnStatement: '^.*$'
|
||||
AsmStatement: 'XXXX'
|
||||
CxxCatchStatement: 'XXXX'
|
||||
CxxTryStatement: 'XXXX'
|
||||
CxxCatchStatement: '^.*$'
|
||||
CxxTryStatement: '^.*$'
|
||||
CxxForRangeStatement: '^.*$'
|
||||
MsAsmStatement: 'XXXX'
|
||||
NullStatement: 'XXXX'
|
||||
|
@ -228,7 +228,9 @@ void CLDNNInferRequest::SetBlob(const std::string& name, const Blob::Ptr& data)
|
||||
bool is_remote = remote_ptr != nullptr;
|
||||
if (is_remote) {
|
||||
auto impl = getBlobImpl(remote_ptr);
|
||||
impl->allocate();
|
||||
if (!impl->is_allocated()) {
|
||||
impl->allocate();
|
||||
}
|
||||
}
|
||||
if (is_input) {
|
||||
if (is_remote) {
|
||||
|
@ -24,12 +24,12 @@ namespace GPUContextParams {
|
||||
* @def GPU_PARAM_KEY(name)
|
||||
* @brief Shortcut for defining configuration keys
|
||||
*/
|
||||
#define GPU_PARAM_KEY(name) GPUContextParams::PARAM_##name
|
||||
#define GPU_PARAM_KEY(name) ::InferenceEngine::GPUContextParams::PARAM_##name
|
||||
/**
|
||||
* @def GPU_PARAM_VALUE(name)
|
||||
* @brief Shortcut for defining configuration values
|
||||
*/
|
||||
#define GPU_PARAM_VALUE(name) GPUContextParams::name
|
||||
#define GPU_PARAM_VALUE(name) ::InferenceEngine::GPUContextParams::name
|
||||
|
||||
/**
|
||||
* @def DECLARE_GPU_PARAM_VALUE(name)
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
namespace InferenceEngine {
|
||||
class IExecutableNetworkInternal;
|
||||
class RemoteContext;
|
||||
} // namespace InferenceEngine
|
||||
namespace ov {
|
||||
namespace runtime {
|
||||
@ -167,7 +166,7 @@ public:
|
||||
* on remote accelerator device that was used to create this ExecutableNetwork
|
||||
* @return A context
|
||||
*/
|
||||
std::shared_ptr<ie::RemoteContext> get_context() const;
|
||||
RemoteContext get_context() const;
|
||||
|
||||
/**
|
||||
* @brief Checks if current ExecutableNetwork object is not initialized
|
||||
|
@ -0,0 +1,185 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief a header that defines wrappers for internal GPU plugin-specific
|
||||
* shared Video Acceleration device contexts
|
||||
* and shared memory tensors which contain Video Acceleration surfaces
|
||||
*
|
||||
* @file openvino/runtime/gpu/dx.hpp
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <d3d11.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "openvin/runtime/gpu/ocl.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace runtime {
|
||||
namespace gpu {
|
||||
|
||||
/**
|
||||
* @brief This class represents an abstraction for GPU plugin remote tensor
|
||||
* which is shared with Direct3D 11 buffer.
|
||||
* The plugin object derived from this class can be obtained with create_tensor() call.
|
||||
* @note User can also obtain OpenCL buffer handle from this class.
|
||||
*/
|
||||
class D3DBufferTensor : public ClBufferTensor {
|
||||
public:
|
||||
/**
|
||||
* @brief Checks that type defined runtime paramters are presented in remote object
|
||||
* @param tensor a tensor to check
|
||||
*/
|
||||
static void type_check(const Tensor& tensor) {
|
||||
RemoteTensor::type_check(
|
||||
tensor,
|
||||
{{GPU_PARAM_KEY(DEV_OBJECT_HANDLE), {}}, {GPU_PARAM_KEY(SHARED_MEM_TYPE), {GPU_PARAM_VALUE(DX_BUFFER)}}});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ID3D11Buffer conversion operator for the D3DContext object.
|
||||
* @return Pointer to underlying ID3D11Buffer interface
|
||||
*/
|
||||
operator ID3D11Buffer*() {
|
||||
return static_cast<ID3D11Buffer*>(get_params().at(GPU_PARAM_KEY(DEV_OBJECT_HANDLE)).as<gpu_handle_param>());
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class represents an abstraction for GPU plugin remote tensor
|
||||
* which is shared with Direct3D 11 2D texture.
|
||||
* The plugin object derived from this class can be obtained with create_tensor() call.
|
||||
* @note User can also obtain OpenCL 2D image handle from this class.
|
||||
*/
|
||||
class D3DSurface2DTensor : public ClImage2DTensor {
|
||||
public:
|
||||
/**
|
||||
* @brief Checks that type defined runtime paramters are presented in remote object
|
||||
* @param remote_tensor remote tensor to check
|
||||
*/
|
||||
static void type_check(const RemoteTensor& remote_tensor) {
|
||||
remote_type_check(remote_context.get_params(),
|
||||
{{GPU_PARAM_KEY(DEV_OBJECT_HANDLE), {}},
|
||||
{GPU_PARAM_KEY(VA_PLANE), {}},
|
||||
{GPU_PARAM_KEY(SHARED_MEM_TYPE), {GPU_PARAM_VALUE(VA_SURFACE)}}});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ID3D11Texture2D conversion operator for the D3DContext object.
|
||||
* @return Pointer to underlying ID3D11Texture2D interface
|
||||
*/
|
||||
operator ID3D11Texture2D*() {
|
||||
return static_cast<ID3D11Texture2D*>(get_params().at(GPU_PARAM_KEY(DEV_OBJECT_HANDLE)).as<gpu_handle_param>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns plane ID of underlying video decoder surface, or 0 if no video surface was shared.
|
||||
* @return Plane ID
|
||||
*/
|
||||
uint32_t plane() {
|
||||
return get_params().at(GPU_PARAM_KEY(VA_PLANE)).as<uint32_t>();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class represents an abstraction for GPU plugin remote context
|
||||
* which is shared with Direct3D 11 device.
|
||||
* The plugin object derived from this class can be obtained either with
|
||||
* GetContext() method of Executable network or using CreateContext() Core call.
|
||||
* @note User can also obtain OpenCL context handle from this class.
|
||||
*/
|
||||
class D3DContext : public ClContext {
|
||||
using RemoteContext::create_tensor;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Checks that type defined runtime paramters are presented in remote object
|
||||
* @param remote_context remote context to check
|
||||
*/
|
||||
static void type_check(const RemoteContext& remote_context) {
|
||||
remote_type_check(
|
||||
remote_context.get_params(),
|
||||
{{GPU_PARAM_KEY(VA_DEVICE), {}}, {GPU_PARAM_KEY(CONTEXT_TYPE), {GPU_PARAM_VALUE(VA_SHARED)}}});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ID3D11Device conversion operator for the D3DContext object.
|
||||
* @return Pointer to underlying ID3D11Device interface
|
||||
*/
|
||||
operator ID3D11Device*() {
|
||||
return static_cast<ID3D11Device*>(get_params().at(GPU_PARAM_KEY(VA_DEVICE)).as<gpu_handle_param>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructs D3DContext remote context object from ID3D11Device
|
||||
* @param core Inference Engine Core object instance
|
||||
* @param deviceName A name of to create a remote context for
|
||||
* @param device A pointer to ID3D11Device to be used to create a remote context
|
||||
*/
|
||||
D3DContext(Core& core, std::string deviceName, ID3D11Device* device) {
|
||||
// clang-format off
|
||||
ParamMap context_params = {
|
||||
{GPU_PARAM_KEY(CONTEXT_TYPE), GPU_PARAM_VALUE(VA_SHARED)},
|
||||
{GPU_PARAM_KEY(VA_DEVICE), static_cast<gpu_handle_param>(device)}
|
||||
};
|
||||
*this = core.create_context(deviceName, context_params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to obtain a NV12 tensor from NV12 DXGI video decoder output.
|
||||
* The resulting tensor contains two remote tensors for Y and UV planes of the surface.
|
||||
* @param height Height of Y plane
|
||||
* @param width Width of Y plane
|
||||
* @param nv12_surf A ID3D11Texture2D instance to create NV12 tensor from
|
||||
* @return A pair of remote tensors for each plane
|
||||
*/
|
||||
std::pair<D3DSurface2DTensor, D3DSurface2DTensor> create_tensor_nv12(const size_t height, const size_t width, const ID3D11Texture2D* nv12_surf) {
|
||||
ParamMap tensor_params = {{GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(VA_SURFACE)},
|
||||
{GPU_PARAM_KEY(DEV_OBJECT_HANDLE), static_cast<gpu_handle_param>(nv12_surf)},
|
||||
{GPU_PARAM_KEY(VA_PLANE), uint32_t(0)}};
|
||||
auto y_tensor = create_tensor(element::u8, {1, 1, height, width}, tensor_params);
|
||||
tensor_params[GPU_PARAM_KEY(MEM_HANDLE)] = static_cast<gpu_handle_param>(nv12_surf);
|
||||
tensor_params[GPU_PARAM_KEY(VA_PLANE)] = uint32_t(1);
|
||||
auto uv_tensor = create_tensor(element::u8, {1, 2, height / 2, width / 2}, tensor_params);
|
||||
return std::make_pair(y_tensor, uv_tensor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to obtain remote tensor object from ID3D11Buffer
|
||||
* @param type Tensor element type
|
||||
* @param shape Tensor shape
|
||||
* @param buffer A pointer to ID3D11Buffer instance to create remote tensor based on
|
||||
* @return A remote tensor instance
|
||||
*/
|
||||
D3DBufferTensor create_tensor(const element::Type type, const Shape& shape, const ID3D11Buffer* buffer) {
|
||||
ParamMap params = {{GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(DX_BUFFER)},
|
||||
{GPU_PARAM_KEY(DEV_OBJECT_HANDLE), static_cast<gpu_handle_param>(buffer)}};
|
||||
create_tensor(type, shape, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to obtain remote tensor object from ID3D11Texture2D
|
||||
* @param type Tensor element type
|
||||
* @param shape Tensor shape
|
||||
* @param surface Pointer to ID3D11Texture2D interface of the objects that owns NV12 texture
|
||||
* @param plane ID of the plane to be shared (0 or 1)
|
||||
* @return D3DSurface2DTensor tensor
|
||||
* @note The underlying ID3D11Texture2D can also be a plane of output surface of DXGI video decoder
|
||||
*/
|
||||
D3DSurface2DTensor create_tensor(const element::Type type,
|
||||
const Shape& shape,
|
||||
ID3D11Texture2D* surface,
|
||||
uint32_t plane = 0) {
|
||||
ParamMap params = {{GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(VA_SURFACE)},
|
||||
{GPU_PARAM_KEY(DEV_OBJECT_HANDLE), static_cast<gpu_handle_param>(surface)},
|
||||
{GPU_PARAM_KEY(VA_PLANE), plane}};
|
||||
return create_tensor(type, shape, params);
|
||||
}
|
||||
};
|
||||
} // namespace gpu
|
||||
} // namespace runtime
|
||||
} // namespace ov
|
@ -0,0 +1,233 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief a header that defines wrappers for internal GPU plugin-specific
|
||||
* OpenCL context and OpenCL shared memory tensors
|
||||
*
|
||||
* @file openvino/runtime/gpu/ocl.hpp
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "gpu/gpu_params.hpp"
|
||||
#include "openvino/runtime/core.hpp"
|
||||
#include "openvino/runtime/gpu/ocl_wrapper.hpp"
|
||||
#include "openvino/runtime/remote_context.hpp"
|
||||
#include "openvino/runtime/remote_tensor.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace runtime {
|
||||
namespace gpu {
|
||||
|
||||
/**
|
||||
* @brief Shortcut for defining a handle parameter
|
||||
*/
|
||||
using gpu_handle_param = void*;
|
||||
|
||||
/**
|
||||
* @brief This class represents an abstraction for GPU plugin remote tensor
|
||||
* which can be shared with user-supplied OpenCL buffer.
|
||||
* The plugin object derived from this class can be obtained with create_tensor() call.
|
||||
* @note User can obtain OpenCL buffer handle from this class.
|
||||
*/
|
||||
class ClBufferTensor : public RemoteTensor {
|
||||
public:
|
||||
/**
|
||||
* @brief Checks that type defined runtime paramters are presented in remote object
|
||||
* @param tensor a tensor to check
|
||||
*/
|
||||
static void type_check(const Tensor& tensor) {
|
||||
RemoteTensor::type_check(
|
||||
tensor,
|
||||
{{GPU_PARAM_KEY(MEM_HANDLE), {}},
|
||||
{GPU_PARAM_KEY(SHARED_MEM_TYPE), {GPU_PARAM_VALUE(OCL_BUFFER), GPU_PARAM_VALUE(DX_BUFFER)}}});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the underlying OpenCL memory object handle.
|
||||
* @return underlying OpenCL memory object handle
|
||||
*/
|
||||
cl_mem get() {
|
||||
return static_cast<cl_mem>(get_params().at(GPU_PARAM_KEY(MEM_HANDLE)).as<gpu_handle_param>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief OpenCL memory handle conversion operator.
|
||||
* @return `cl_mem`
|
||||
*/
|
||||
operator cl_mem() {
|
||||
return get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Standard Khronos cl::Buffer wrapper conversion operator.
|
||||
* @return `cl::Buffer` object
|
||||
*/
|
||||
operator cl::Buffer() {
|
||||
return cl::Buffer(get(), true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class represents an abstraction for GPU plugin remote tensor
|
||||
* which can be shared with user-supplied OpenCL 2D Image.
|
||||
* The plugin object derived from this class can be obtained with create_tensor() call.
|
||||
* @note User can obtain OpenCL image handle from this class.
|
||||
*/
|
||||
class ClImage2DTensor : public RemoteTensor {
|
||||
public:
|
||||
/**
|
||||
* @brief Checks that type defined runtime paramters are presented in remote object
|
||||
* @param tensor a tensor to check
|
||||
*/
|
||||
static void type_check(const Tensor& tensor) {
|
||||
RemoteTensor::type_check(
|
||||
tensor,
|
||||
{{GPU_PARAM_KEY(MEM_HANDLE), {}},
|
||||
{GPU_PARAM_KEY(SHARED_MEM_TYPE), {GPU_PARAM_VALUE(OCL_IMAGE2D), GPU_PARAM_VALUE(VA_SURFACE)}}});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the underlying OpenCL memory object handle.
|
||||
* @return underlying OpenCL memory object handle
|
||||
*/
|
||||
cl_mem get() {
|
||||
return static_cast<cl_mem>(get_params().at(GPU_PARAM_KEY(MEM_HANDLE)).as<gpu_handle_param>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief OpenCL memory handle conversion operator.
|
||||
* @return `cl_mem`
|
||||
*/
|
||||
operator cl_mem() {
|
||||
return get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Standard Khronos cl::Image2D wrapper conversion operator for the ClContext object.
|
||||
* @return `cl::Image2D` object
|
||||
*/
|
||||
operator cl::Image2D() {
|
||||
return cl::Image2D(get(), true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class represents an abstraction for GPU plugin remote context
|
||||
* which is shared with OpenCL context object.
|
||||
* The plugin object derived from this class can be obtained either with
|
||||
* GetContext() method of Executable network or using CreateContext() Core call.
|
||||
*/
|
||||
class ClContext : public RemoteContext {
|
||||
using RemoteContext::create_tensor;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Checks that type defined runtime paramters are presented in remote object
|
||||
* @param remote_context remote context to check
|
||||
*/
|
||||
static void type_check(const RemoteContext& remote_context) {
|
||||
RemoteContext::type_check(remote_context,
|
||||
{{GPU_PARAM_KEY(OCL_CONTEXT), {}},
|
||||
{GPU_PARAM_KEY(CONTEXT_TYPE), {GPU_PARAM_VALUE(OCL), GPU_PARAM_VALUE(VA_SHARED)}}});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructs context object from user-supplied OpenCL context handle
|
||||
* @param core A reference to Inference Engine Core object
|
||||
* @param deviceName A name of device to create a remote context for
|
||||
* @param ctx A OpenCL context to be used to create shared remote context
|
||||
*/
|
||||
ClContext(Core& core, std::string deviceName, cl_context ctx) {
|
||||
ParamMap context_params = {{GPU_PARAM_KEY(CONTEXT_TYPE), GPU_PARAM_VALUE(OCL)},
|
||||
{GPU_PARAM_KEY(OCL_CONTEXT), static_cast<gpu_handle_param>(ctx)}};
|
||||
*this = core.create_context(deviceName, context_params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the underlying OpenCL context handle.
|
||||
* @return `cl_context`
|
||||
*/
|
||||
cl_context get() {
|
||||
return static_cast<cl_context>(get_params().at(GPU_PARAM_KEY(OCL_CONTEXT)).as<gpu_handle_param>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief OpenCL context handle conversion operator for the ClContext object.
|
||||
* @return `cl_context`
|
||||
*/
|
||||
operator cl_context() {
|
||||
return get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Standard Khronos cl::Context wrapper conversion operator for the ClContext object.
|
||||
* @return `cl::Context` object
|
||||
*/
|
||||
operator cl::Context() {
|
||||
return cl::Context(get(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to construct a NV12 compound tensor object from two cl::Image2D wrapper objects.
|
||||
* The resulting compound contains two remote tensors for Y and UV planes of the surface.
|
||||
* @param nv12_image_plane_y cl::Image2D object containing Y plane data.
|
||||
* @param nv12_image_plane_uv cl::Image2D object containing UV plane data.
|
||||
* @return A pair of remote tensors for each plane
|
||||
*/
|
||||
std::pair<ClImage2DTensor, ClImage2DTensor> create_tensor_nv12(const cl::Image2D& nv12_image_plane_y,
|
||||
const cl::Image2D& nv12_image_plane_uv) {
|
||||
size_t width = nv12_image_plane_y.getImageInfo<CL_IMAGE_WIDTH>();
|
||||
size_t height = nv12_image_plane_y.getImageInfo<CL_IMAGE_HEIGHT>();
|
||||
ParamMap tensor_params = {{GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(OCL_IMAGE2D)},
|
||||
{GPU_PARAM_KEY(MEM_HANDLE), static_cast<gpu_handle_param>(nv12_image_plane_y.get())}};
|
||||
auto y_tensor = create_tensor(element::u8, {1, 1, height, width}, tensor_params);
|
||||
tensor_params[GPU_PARAM_KEY(MEM_HANDLE)] = static_cast<gpu_handle_param>(nv12_image_plane_uv.get());
|
||||
auto uv_tensor = create_tensor(element::u8, {1, 2, height / 2, width / 2}, tensor_params);
|
||||
return std::make_pair(y_tensor, uv_tensor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to obtain remote tensor object from user-supplied cl_mem object
|
||||
* @param type Tensor element type
|
||||
* @param shape Tensor shape
|
||||
* @param buffer A cl_mem object wrapped by a remote tensor
|
||||
* @return A remote tensor instance
|
||||
*/
|
||||
ClBufferTensor create_tensor(const element::Type type, const Shape& shape, const cl_mem buffer) {
|
||||
ParamMap params = {{GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(OCL_BUFFER)},
|
||||
{GPU_PARAM_KEY(MEM_HANDLE), static_cast<gpu_handle_param>(buffer)}};
|
||||
return create_tensor(type, shape, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to obtain remote tensor object from user-supplied cl::Buffer object
|
||||
* @param type Tensor element type
|
||||
* @param shape Tensor shape
|
||||
* @param buffer A cl::Buffer object wrapped by a remote tensor
|
||||
* @return A remote tensor instance
|
||||
*/
|
||||
ClBufferTensor create_tensor(const element::Type type, const Shape& shape, const cl::Buffer& buffer) {
|
||||
return create_tensor(type, shape, buffer.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to obtain remote tensor object from user-supplied cl::Image2D object
|
||||
* @param type Tensor element type
|
||||
* @param shape Tensor shape
|
||||
* @param image A cl::Image2D object wrapped by a remote tensor
|
||||
* @return A remote tensor instance
|
||||
*/
|
||||
ClImage2DTensor create_tensor(const element::Type type, const Shape& shape, const cl::Image2D& image) {
|
||||
ParamMap params = {{GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(OCL_IMAGE2D)},
|
||||
{GPU_PARAM_KEY(MEM_HANDLE), static_cast<gpu_handle_param>(image.get())}};
|
||||
return create_tensor(type, shape, params);
|
||||
}
|
||||
};
|
||||
} // namespace gpu
|
||||
} // namespace runtime
|
||||
} // namespace ov
|
@ -0,0 +1,50 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief a header that defines wrappers for internal GPU plugin-specific
|
||||
* OpenCL context and OpenCL shared memory tensors
|
||||
*
|
||||
* @file ocl_wrapper.hpp
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @brief Definitions required by Khronos headers
|
||||
*/
|
||||
|
||||
/// @cond
|
||||
|
||||
#ifndef CL_HPP_ENABLE_EXCEPTIONS
|
||||
# define CL_HPP_ENABLE_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
#ifdef CL_HPP_MINIMUM_OPENCL_VERSION
|
||||
# if CL_HPP_MINIMUM_OPENCL_VERSION < 120
|
||||
# error "CL_HPP_MINIMUM_OPENCL_VERSION must be >= 120"
|
||||
# endif
|
||||
#else
|
||||
# define CL_HPP_MINIMUM_OPENCL_VERSION 120
|
||||
#endif
|
||||
|
||||
#ifdef CL_HPP_TARGET_OPENCL_VERSION
|
||||
# if CL_HPP_TARGET_OPENCL_VERSION < 120
|
||||
# error "CL_HPP_TARGET_OPENCL_VERSION must be >= 120"
|
||||
# endif
|
||||
#else
|
||||
# define CL_HPP_TARGET_OPENCL_VERSION 120
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC system_header
|
||||
#endif
|
||||
|
||||
#include <CL/cl2.hpp>
|
||||
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
/// @endcond
|
@ -0,0 +1,143 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
/**
|
||||
* @brief a header that defines wrappers for internal GPU plugin-specific
|
||||
* shared Video Acceleration device contexts
|
||||
* and shared memory tensors which contain Video Acceleration surfaces
|
||||
*
|
||||
* @file openvino/runtime/gpu/va.hpp
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "openvino/runtime/gpu/ocl.hpp"
|
||||
|
||||
// clang-format off
|
||||
#include <va/va.h>
|
||||
// clang-format on
|
||||
|
||||
namespace ov {
|
||||
namespace runtime {
|
||||
namespace gpu {
|
||||
|
||||
/**
|
||||
* @brief This class represents an abstraction for GPU plugin remote tensor
|
||||
* which is shared with VA output surface.
|
||||
* The plugin object derived from this class can be obtained with create_tensor() call.
|
||||
* @note User can also obtain OpenCL 2D image handle from this class.
|
||||
*/
|
||||
class VASurfaceTensor : public ClImage2DTensor {
|
||||
public:
|
||||
/**
|
||||
* @brief Checks that type defined runtime paramters are presented in remote object
|
||||
* @param tensor a tensor to check
|
||||
*/
|
||||
static void type_check(const Tensor& tensor) {
|
||||
RemoteTensor::type_check(tensor,
|
||||
{{GPU_PARAM_KEY(DEV_OBJECT_HANDLE), {}},
|
||||
{GPU_PARAM_KEY(VA_PLANE), {}},
|
||||
{GPU_PARAM_KEY(SHARED_MEM_TYPE), {GPU_PARAM_VALUE(VA_SURFACE)}}});
|
||||
}
|
||||
/**
|
||||
* @brief VASurfaceID conversion operator for the VASurfaceBlob object.
|
||||
* @return `VASurfaceID` handle
|
||||
*/
|
||||
operator VASurfaceID() {
|
||||
return static_cast<VASurfaceID>(get_params().at(GPU_PARAM_KEY(DEV_OBJECT_HANDLE)).as<uint32_t>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns plane ID of underlying video decoder surface
|
||||
* @return Plane ID
|
||||
*/
|
||||
uint32_t plane() {
|
||||
return get_params().at(GPU_PARAM_KEY(VA_PLANE)).as<uint32_t>();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This class represents an abstraction for GPU plugin remote context
|
||||
* which is shared with VA display object.
|
||||
* The plugin object derived from this class can be obtained either with
|
||||
* GetContext() method of Executable network or using CreateContext() Core call.
|
||||
* @note User can also obtain OpenCL context handle from this class.
|
||||
*/
|
||||
class VAContext : public ClContext {
|
||||
using RemoteContext::create_tensor;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Checks that type defined runtime paramters are presented in remote object
|
||||
* @param remote_context remote context to check
|
||||
*/
|
||||
static void type_check(const RemoteContext& remote_context) {
|
||||
remote_type_check(
|
||||
remote_context.get_params(),
|
||||
{{GPU_PARAM_KEY(VA_DEVICE), {}}, {GPU_PARAM_KEY(CONTEXT_TYPE), {GPU_PARAM_VALUE(VA_SHARED)}}});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief `VADisplay` conversion operator for the VAContext object.
|
||||
* @return Underlying `VADisplay` object handle
|
||||
*/
|
||||
operator VADisplay() {
|
||||
return static_cast<VADisplay>(get_params().at(GPU_PARAM_KEY(VA_DEVICE)).as<gpu_handle_param>());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Constructs remote context object from VA display handle
|
||||
* @param core Inference Engine Core object
|
||||
* @param deviceName A device name to create a remote context for
|
||||
* @param device A `VADisplay` to create remote context from
|
||||
*/
|
||||
VAContext(Core& core, std::string deviceName, VADisplay device) {
|
||||
ParamMap context_params = {{GPU_PARAM_KEY(CONTEXT_TYPE), GPU_PARAM_VALUE(VA_SHARED)},
|
||||
{GPU_PARAM_KEY(VA_DEVICE), static_cast<gpu_handle_param>(device)}};
|
||||
*this = core.create_context(deviceName, context_params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to obtain a NV12 tensor from NV12 VA decoder output.
|
||||
* The resulting tensor contains two remote tensors for Y and UV planes of the surface.
|
||||
* @param height A height of Y plane
|
||||
* @param width A width of Y plane
|
||||
* @param nv12_surf NV12 `VASurfaceID` to create NV12 from
|
||||
* @return A pair of remote tensors for each plane
|
||||
*/
|
||||
std::pair<VASurfaceTensor, VASurfaceTensor> create_tensor_nv12(const size_t height,
|
||||
const size_t width,
|
||||
const VASurfaceID nv12_surf) {
|
||||
ParamMap tensor_params = {{GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(VA_SURFACE)},
|
||||
{GPU_PARAM_KEY(DEV_OBJECT_HANDLE), nv12_surf},
|
||||
{GPU_PARAM_KEY(VA_PLANE), uint32_t(0)}};
|
||||
auto y_tensor = create_tensor(element::u8, {1, 1, height, width}, tensor_params);
|
||||
tensor_params[GPU_PARAM_KEY(VA_PLANE)] = uint32_t(1);
|
||||
auto uv_tensor = create_tensor(element::u8, {1, 2, height / 2, width / 2}, tensor_params);
|
||||
return std::make_pair(y_tensor, uv_tensor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to create remote tensor from VA surface handle
|
||||
* @param type Tensor element type
|
||||
* @param shape Tensor shape
|
||||
* @param surface A `VASurfaceID` to create remote tensor from
|
||||
* @param plane An index of a plane inside `VASurfaceID` to create tensor from
|
||||
* @return A remote tensor wrapping `VASurfaceID`
|
||||
*/
|
||||
inline VASurfaceTensor create_tensor(const element::Type type,
|
||||
const Shape& shape,
|
||||
const VASurfaceID surface,
|
||||
const uint32_t plane = 0) {
|
||||
ParamMap params = {{GPU_PARAM_KEY(SHARED_MEM_TYPE), GPU_PARAM_VALUE(VA_SURFACE)},
|
||||
{GPU_PARAM_KEY(DEV_OBJECT_HANDLE), surface},
|
||||
{GPU_PARAM_KEY(VA_PLANE), plane}};
|
||||
return create_tensor(type, shape, params);
|
||||
}
|
||||
};
|
||||
} // namespace gpu
|
||||
} // namespace runtime
|
||||
} // namespace ov
|
@ -13,7 +13,6 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "ie_remote_context.hpp"
|
||||
#include "openvino/core/shape.hpp"
|
||||
#include "openvino/core/type/element_type.hpp"
|
||||
#include "openvino/runtime/common.hpp"
|
||||
@ -21,13 +20,14 @@
|
||||
#include "openvino/runtime/remote_tensor.hpp"
|
||||
|
||||
namespace InferenceEngine {
|
||||
class RemoteBlob;
|
||||
class RemoteContext;
|
||||
} // namespace InferenceEngine
|
||||
|
||||
namespace ov {
|
||||
namespace runtime {
|
||||
|
||||
class Core;
|
||||
class ExecutableNetwork;
|
||||
|
||||
/**
|
||||
* @brief This class represents an abstraction
|
||||
@ -36,8 +36,9 @@ class Core;
|
||||
* networks and remote memory blobs can exist, function and exchange data.
|
||||
*/
|
||||
class OPENVINO_RUNTIME_API RemoteContext {
|
||||
std::shared_ptr<void> _so;
|
||||
std::shared_ptr<ie::RemoteContext> _impl;
|
||||
protected:
|
||||
std::shared_ptr<void> _so; //!< Reference to shared object that loaded implementation
|
||||
std::shared_ptr<ie::RemoteContext> _impl; //!< Pointer to remote context implementation
|
||||
|
||||
/**
|
||||
* @brief Constructs RemoteContext from the initialized std::shared_ptr
|
||||
@ -46,64 +47,65 @@ class OPENVINO_RUNTIME_API RemoteContext {
|
||||
* @param impl Initialized shared pointer
|
||||
*/
|
||||
RemoteContext(const std::shared_ptr<void>& so, const std::shared_ptr<ie::RemoteContext>& impl);
|
||||
friend class Core;
|
||||
friend class ov::runtime::Core;
|
||||
friend class ov::runtime::ExecutableNetwork;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Checks openvino remote type
|
||||
* @param remote_context a remote context which type will be checked
|
||||
* @param type_info map with remote object runtime info
|
||||
* @throw Exception if type check with specified paramters is not pass
|
||||
*/
|
||||
static void type_check(const RemoteContext& remote_context,
|
||||
const std::map<std::string, std::vector<std::string>>& type_info = {});
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
RemoteContext() = default;
|
||||
|
||||
/**
|
||||
* @brief Checks if the RemoteContext object can be cast to the type T*
|
||||
* @brief Checks if the RemoteContext object can be cast to the type T
|
||||
*
|
||||
* @tparam T Type to be checked. Must represent a class derived from the RemoteContext
|
||||
* @return true if this object can be dynamically cast to the type T*. Otherwise, false
|
||||
*/
|
||||
template <typename T,
|
||||
typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
|
||||
typename std::enable_if<std::is_base_of<ie::RemoteContext, T>::value, int>::type = 0>
|
||||
bool is() noexcept {
|
||||
return dynamic_cast<T*>(_impl.get()) != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the RemoteContext object can be cast to the type const T*
|
||||
*
|
||||
* @tparam T Type to be checked. Must represent a class derived from the RemoteContext
|
||||
* @return true if this object can be dynamically cast to the type const T*. Otherwise, false
|
||||
*/
|
||||
template <typename T,
|
||||
typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
|
||||
typename std::enable_if<std::is_base_of<ie::RemoteContext, T>::value, int>::type = 0>
|
||||
template <typename T>
|
||||
bool is() const noexcept {
|
||||
return dynamic_cast<const T*>(_impl.get()) != nullptr;
|
||||
static_assert(std::is_base_of<RemoteContext, T>::value,
|
||||
"Could not check type that is not inherited from RemoteContext");
|
||||
try {
|
||||
T::type_check(*this);
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Casts this RemoteContext object to the type T*.
|
||||
* @brief Casts this RemoteContext object to the type T.
|
||||
*
|
||||
* @tparam T Type to cast to. Must represent a class derived from the RemoteContext
|
||||
* @return Raw pointer to the object of the type T or nullptr on error
|
||||
* @return T object
|
||||
*/
|
||||
template <typename T,
|
||||
typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
|
||||
typename std::enable_if<std::is_base_of<ie::RemoteContext, T>::value, int>::type = 0>
|
||||
T* as() noexcept {
|
||||
return dynamic_cast<T*>(_impl.get());
|
||||
template <typename T>
|
||||
const T as() const {
|
||||
static_assert(std::is_base_of<RemoteContext, T>::value,
|
||||
"Could not check type that is not inherited from RemoteContext");
|
||||
T::type_check(*this);
|
||||
return *static_cast<const T*>(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Casts this RemoteContext object to the type const T*.
|
||||
* @brief Casts this RemoteContext object to the type T.
|
||||
*
|
||||
* @tparam T Type to cast to. Must represent a class derived from the RemoteContext
|
||||
* @return Raw pointer to the object of the type const T or nullptr on error
|
||||
* @return T object
|
||||
*/
|
||||
template <typename T,
|
||||
typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
|
||||
typename std::enable_if<std::is_base_of<ie::RemoteContext, T>::value, int>::type = 0>
|
||||
const T* as() const noexcept {
|
||||
return dynamic_cast<const T*>(_impl.get());
|
||||
template <typename T>
|
||||
operator T() const {
|
||||
return as<T>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,7 +122,6 @@ public:
|
||||
* @param type Defines the element type of the tensor
|
||||
* @param shape Defines the shape of the tensor
|
||||
* @param params Map of the low-level tensor object parameters.
|
||||
* Abstract method.
|
||||
* @return A pointer to plugin object that implements RemoteTensor interface.
|
||||
*/
|
||||
RemoteTensor create_tensor(const element::Type& type, const Shape& shape, const ParamMap& params = {});
|
||||
|
@ -9,7 +9,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "ie_remote_blob.hpp"
|
||||
#include "openvino/runtime/parameter.hpp"
|
||||
#include "openvino/runtime/tensor.hpp"
|
||||
|
||||
@ -27,6 +26,14 @@ class OPENVINO_RUNTIME_API RemoteTensor : public Tensor {
|
||||
friend class ov::runtime::RemoteContext;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Checks openvino remote type
|
||||
* @param tensor tensor which type will be checked
|
||||
* @param type_info map with remote object runtime info
|
||||
* @throw Exception if type check with specified paramters is not pass
|
||||
*/
|
||||
static void type_check(const Tensor& tensor, const std::map<std::string, std::vector<std::string>>& type_info = {});
|
||||
|
||||
void* data(const element::Type) = delete;
|
||||
|
||||
template <typename T>
|
||||
@ -49,56 +56,6 @@ public:
|
||||
* @return A device name string in fully specified format `<device_name>[.<device_id>[.<tile_id>]]`.
|
||||
*/
|
||||
std::string get_device_name() const;
|
||||
|
||||
/**
|
||||
* @brief Checks if the RemoteTensor object can be cast to the type T*
|
||||
*
|
||||
* @tparam T Type to be checked. Must represent a class derived from the RemoteTensor
|
||||
* @return true if this object can be dynamically cast to the type T*. Otherwise, false
|
||||
*/
|
||||
template <typename T,
|
||||
typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
|
||||
typename std::enable_if<std::is_base_of<ie::RemoteBlob, T>::value, int>::type = 0>
|
||||
bool is() noexcept {
|
||||
return dynamic_cast<T*>(_impl.get()) != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the RemoteTensor object can be cast to the type const T*
|
||||
*
|
||||
* @tparam T Type to be checked. Must represent a class derived from the RemoteTensor
|
||||
* @return true if this object can be dynamically cast to the type const T*. Otherwise, false
|
||||
*/
|
||||
template <typename T>
|
||||
bool is() const noexcept {
|
||||
return dynamic_cast<const T*>(_impl.get()) != nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Casts this RemoteTensor object to the type T*.
|
||||
*
|
||||
* @tparam T Type to cast to. Must represent a class derived from the RemoteTensor
|
||||
* @return Raw pointer to the object of the type T or nullptr on error
|
||||
*/
|
||||
template <typename T,
|
||||
typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
|
||||
typename std::enable_if<std::is_base_of<ie::RemoteBlob, T>::value, int>::type = 0>
|
||||
T* as() noexcept {
|
||||
return dynamic_cast<T*>(_impl.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Casts this RemoteTensor object to the type const T*.
|
||||
*
|
||||
* @tparam T Type to cast to. Must represent a class derived from the RemoteTensor
|
||||
* @return Raw pointer to the object of the type const T or nullptr on error
|
||||
*/
|
||||
template <typename T,
|
||||
typename std::enable_if<!std::is_pointer<T>::value && !std::is_reference<T>::value, int>::type = 0,
|
||||
typename std::enable_if<std::is_base_of<ie::RemoteBlob, T>::value, int>::type = 0>
|
||||
const T* as() const noexcept {
|
||||
return dynamic_cast<const T*>(_impl.get());
|
||||
}
|
||||
};
|
||||
} // namespace runtime
|
||||
} // namespace ov
|
@ -220,8 +220,8 @@ ie::Parameter ExecutableNetwork::get_metric(const std::string& name) const {
|
||||
OV_EXEC_NET_CALL_STATEMENT(return _impl->GetMetric(name));
|
||||
}
|
||||
|
||||
std::shared_ptr<ie::RemoteContext> ExecutableNetwork::get_context() const {
|
||||
OV_EXEC_NET_CALL_STATEMENT(return _impl->GetContext());
|
||||
RemoteContext ExecutableNetwork::get_context() const {
|
||||
OV_EXEC_NET_CALL_STATEMENT(return {_so, _impl->GetContext()});
|
||||
}
|
||||
|
||||
bool ExecutableNetwork::operator!() const noexcept {
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#define OV_REMOTE_CONTEXT_STATEMENT(...) \
|
||||
OPENVINO_ASSERT(_impl != nullptr, "RemoteContext was not initialized."); \
|
||||
type_check(*this); \
|
||||
try { \
|
||||
__VA_ARGS__; \
|
||||
} catch (const std::exception& ex) { \
|
||||
@ -24,6 +25,28 @@
|
||||
namespace ov {
|
||||
namespace runtime {
|
||||
|
||||
void RemoteContext::type_check(const RemoteContext& tensor,
|
||||
const std::map<std::string, std::vector<std::string>>& type_info) {
|
||||
auto remote_impl = dynamic_cast<const ie::RemoteContext*>(tensor._impl.get());
|
||||
OPENVINO_ASSERT(remote_impl != nullptr, "Context was not initialized using remote implementation");
|
||||
if (!type_info.empty()) {
|
||||
auto params = remote_impl->getParams();
|
||||
for (auto&& type_info_value : type_info) {
|
||||
auto it_param = params.find(type_info_value.first);
|
||||
OPENVINO_ASSERT(it_param != params.end(), "Parameter with key ", type_info_value.first, " not found");
|
||||
if (!type_info_value.second.empty()) {
|
||||
auto param_value = it_param->second.as<std::string>();
|
||||
auto param_found = std::any_of(type_info_value.second.begin(),
|
||||
type_info_value.second.end(),
|
||||
[&](const std::string& param) {
|
||||
return param == param_value;
|
||||
});
|
||||
OPENVINO_ASSERT(param_found, "Unexpected parameter value ", param_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RemoteContext::RemoteContext(const std::shared_ptr<void>& so, const ie::RemoteContext::Ptr& impl)
|
||||
: _so{so},
|
||||
_impl{impl} {
|
||||
@ -38,10 +61,11 @@ RemoteTensor RemoteContext::create_tensor(const element::Type& element_type,
|
||||
const Shape& shape,
|
||||
const ie::ParamMap& params) {
|
||||
OV_REMOTE_CONTEXT_STATEMENT({
|
||||
return {_so,
|
||||
_impl->CreateBlob(
|
||||
{ie::details::convertPrecision(element_type), shape, ie::TensorDesc::getLayoutByRank(shape.size())},
|
||||
params)};
|
||||
auto blob = _impl->CreateBlob(
|
||||
{ie::details::convertPrecision(element_type), shape, ie::TensorDesc::getLayoutByRank(shape.size())},
|
||||
params);
|
||||
blob->allocate();
|
||||
return {_so, blob};
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -4,12 +4,39 @@
|
||||
|
||||
#include "openvino/runtime/remote_tensor.hpp"
|
||||
|
||||
#include "ie_ngraph_utils.hpp"
|
||||
#include "ie_remote_blob.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace runtime {
|
||||
|
||||
void RemoteTensor::type_check(const Tensor& tensor, const std::map<std::string, std::vector<std::string>>& type_info) {
|
||||
OPENVINO_ASSERT(tensor, "Could not check empty tensor type");
|
||||
auto remote_tensor = static_cast<const RemoteTensor*>(&tensor);
|
||||
auto remote_impl = dynamic_cast<ie::RemoteBlob*>(remote_tensor->_impl.get());
|
||||
OPENVINO_ASSERT(remote_impl != nullptr, "Tensor was not initialized using remote implementation");
|
||||
if (!type_info.empty()) {
|
||||
auto params = remote_impl->getParams();
|
||||
for (auto&& type_info_value : type_info) {
|
||||
auto it_param = params.find(type_info_value.first);
|
||||
OPENVINO_ASSERT(it_param != params.end(), "Parameter with key ", type_info_value.first, " not found");
|
||||
if (!type_info_value.second.empty()) {
|
||||
auto param_value = it_param->second.as<std::string>();
|
||||
auto param_found = std::any_of(type_info_value.second.begin(),
|
||||
type_info_value.second.end(),
|
||||
[&](const std::string& param) {
|
||||
return param == param_value;
|
||||
});
|
||||
OPENVINO_ASSERT(param_found, "Unexpected parameter value ", param_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ie::ParamMap RemoteTensor::get_params() const {
|
||||
OPENVINO_ASSERT(_impl != nullptr, "Remote tensor was not initialized.");
|
||||
auto remote_impl = InferenceEngine::as<InferenceEngine::RemoteBlob>(_impl);
|
||||
OPENVINO_ASSERT(remote_impl != nullptr, "Remote tensor was not initialized using remote implementation");
|
||||
type_check(*this);
|
||||
auto remote_impl = static_cast<ie::RemoteBlob*>(_impl.get());
|
||||
try {
|
||||
return remote_impl->getParams();
|
||||
} catch (const std::exception& ex) {
|
||||
@ -21,8 +48,8 @@ ie::ParamMap RemoteTensor::get_params() const {
|
||||
|
||||
std::string RemoteTensor::get_device_name() const {
|
||||
OPENVINO_ASSERT(_impl != nullptr, "Remote tensor was not initialized.");
|
||||
auto remote_impl = InferenceEngine::as<InferenceEngine::RemoteBlob>(_impl);
|
||||
OPENVINO_ASSERT(remote_impl != nullptr, "Remote tensor was not initialized using remote implementation");
|
||||
type_check(*this);
|
||||
auto remote_impl = static_cast<ie::RemoteBlob*>(_impl.get());
|
||||
try {
|
||||
return remote_impl->getDeviceName();
|
||||
} catch (const std::exception& ex) {
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "cpp/ie_cnn_network.h"
|
||||
#include "ie_precision.hpp"
|
||||
#include "ngraph/type/element_type.hpp"
|
||||
#include "openvino/core/type/element_type.hpp"
|
||||
#include "openvino/runtime/common.hpp"
|
||||
|
||||
namespace InferenceEngine {
|
||||
namespace details {
|
||||
|
@ -9,8 +9,6 @@
|
||||
|
||||
using namespace ::testing;
|
||||
using namespace std;
|
||||
using namespace InferenceEngine;
|
||||
using namespace InferenceEngine::details;
|
||||
|
||||
TEST(RemoteTensorOVTests, throwsOnGetParams) {
|
||||
ov::runtime::RemoteTensor tensor;
|
||||
@ -21,3 +19,19 @@ TEST(RemoteTensorOVTests, throwsOnGetDeviceName) {
|
||||
ov::runtime::RemoteTensor tensor;
|
||||
ASSERT_THROW(tensor.get_device_name(), ov::Exception);
|
||||
}
|
||||
|
||||
TEST(RemoteTensorOVTests, remoteTensorFromEmptyTensorThrow) {
|
||||
ov::runtime::Tensor empty_tensor;
|
||||
ov::runtime::RemoteTensor remote_tensor;
|
||||
ASSERT_THROW(remote_tensor = empty_tensor, ov::Exception);
|
||||
ASSERT_FALSE(empty_tensor.is<ov::runtime::RemoteTensor>());
|
||||
ASSERT_THROW(empty_tensor.as<ov::runtime::RemoteTensor>(), ov::Exception);
|
||||
}
|
||||
|
||||
TEST(RemoteTensorOVTests, remoteTensorConvertToRemoteThrow) {
|
||||
ov::runtime::Tensor tensor{ov::element::f32, {1, 2, 3, 4}};
|
||||
ov::runtime::RemoteTensor remote_tensor;
|
||||
ASSERT_THROW(remote_tensor = tensor, ov::Exception);
|
||||
ASSERT_FALSE(tensor.is<ov::runtime::RemoteTensor>());
|
||||
ASSERT_THROW(tensor.as<ov::runtime::RemoteTensor>(), ov::Exception);
|
||||
}
|
||||
|
@ -0,0 +1,367 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "openvino/runtime/gpu/ocl.hpp"
|
||||
#include "openvino/runtime/core.hpp"
|
||||
|
||||
#include <gpu/gpu_config.hpp>
|
||||
#include <remote_blob_tests/remote_blob_helpers.hpp>
|
||||
#include <common_test_utils/test_common.hpp>
|
||||
#include <functional_test_utils/plugin_cache.hpp>
|
||||
#include "ngraph_functions/subgraph_builders.hpp"
|
||||
#include "functional_test_utils/blob_utils.hpp"
|
||||
#include "openvino/core/preprocess/pre_post_process.hpp"
|
||||
#include "transformations/utils/utils.hpp"
|
||||
|
||||
using namespace ::testing;
|
||||
|
||||
class OVRemoteTensor_Test : public CommonTestUtils::TestsCommon {
|
||||
protected:
|
||||
std::shared_ptr<ngraph::Function> fn_ptr;
|
||||
|
||||
void SetUp() override {
|
||||
fn_ptr = ngraph::builder::subgraph::makeSplitMultiConvConcat();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(OVRemoteTensor_Test, DISABLED_smoke_canInputUserTensor) {
|
||||
#if defined(ANDROID)
|
||||
GTEST_SKIP();
|
||||
#endif
|
||||
auto ie = ov::runtime::Core();
|
||||
|
||||
using namespace ov::preprocess;
|
||||
auto function = PrePostProcessor()
|
||||
.input(InputInfo()
|
||||
.tensor(InputTensorInfo().set_element_type(ov::element::i8))
|
||||
.preprocess(PreProcessSteps().convert_element_type(ov::element::f32)))
|
||||
.build(fn_ptr);
|
||||
|
||||
auto exec_net = ie.compile_model(function, CommonTestUtils::DEVICE_GPU);
|
||||
|
||||
// regular inference
|
||||
auto inf_req_regular = exec_net.create_infer_request();
|
||||
auto input = function->get_parameters().at(0);
|
||||
auto output = function->get_results().at(0);
|
||||
auto fakeImageData = FuncTestUtils::create_and_fill_tensor(input->get_element_type(), input->get_shape());
|
||||
|
||||
inf_req_regular.set_tensor(input->get_friendly_name(), fakeImageData);
|
||||
|
||||
inf_req_regular.infer();
|
||||
auto output_tensor_regular = inf_req_regular.get_tensor(ngraph::op::util::create_ie_output_name(output->input_value(0)));
|
||||
|
||||
// inference using remote tensor
|
||||
auto inf_req_shared = exec_net.create_infer_request();
|
||||
auto cldnn_context = exec_net.get_context().as<ov::runtime::gpu::ClContext>();
|
||||
cl_context ctx = cldnn_context;
|
||||
auto ocl_instance = std::make_shared<OpenCL>(ctx);
|
||||
cl_int err;
|
||||
|
||||
auto imSize = ov::shape_size(input->get_shape());
|
||||
|
||||
cl::Buffer shared_buffer(ocl_instance->_context, CL_MEM_READ_WRITE, imSize, NULL, &err);
|
||||
{
|
||||
void* buffer = fakeImageData.data();
|
||||
ocl_instance->_queue.enqueueWriteBuffer(shared_buffer, true, 0, imSize, buffer);
|
||||
}
|
||||
|
||||
auto cldnn_tensor = cldnn_context.create_tensor(input->get_element_type(), input->get_shape(), shared_buffer);
|
||||
inf_req_shared.set_tensor(input->get_friendly_name(), cldnn_tensor);
|
||||
|
||||
inf_req_shared.infer();
|
||||
auto output_tensor_shared = inf_req_shared.get_tensor(ngraph::op::util::create_ie_output_name(output->input_value(0)));
|
||||
|
||||
// compare results
|
||||
{
|
||||
ASSERT_EQ(output->get_element_type(), ov::element::f32);
|
||||
ASSERT_EQ(output_tensor_regular.get_size(), output_tensor_shared.get_size());
|
||||
auto thr = FuncTestUtils::GetComparisonThreshold(InferenceEngine::Precision::FP32);
|
||||
ASSERT_NO_THROW(output_tensor_regular.data());
|
||||
ASSERT_NO_THROW(output_tensor_shared.data());
|
||||
FuncTestUtils::compare_tensor(output_tensor_regular, output_tensor_shared, thr);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(OVRemoteTensor_Test, DISABLED_smoke_canInferOnUserContext) {
|
||||
auto ie = ov::runtime::Core();
|
||||
|
||||
using namespace ov::preprocess;
|
||||
auto function = PrePostProcessor()
|
||||
.input(InputInfo()
|
||||
.tensor(InputTensorInfo().set_element_type(ov::element::i8))
|
||||
.preprocess(PreProcessSteps().convert_element_type(ov::element::f32)))
|
||||
.build(fn_ptr);
|
||||
|
||||
auto exec_net_regular = ie.compile_model(function, CommonTestUtils::DEVICE_GPU);
|
||||
auto input = function->get_parameters().at(0);
|
||||
auto output = function->get_results().at(0);
|
||||
|
||||
// regular inference
|
||||
auto inf_req_regular = exec_net_regular.create_infer_request();
|
||||
auto fakeImageData = FuncTestUtils::create_and_fill_tensor(input->get_element_type(), input->get_shape());
|
||||
inf_req_regular.set_tensor(input->get_friendly_name(), fakeImageData);
|
||||
|
||||
inf_req_regular.infer();
|
||||
auto output_tensor_regular = inf_req_regular.get_tensor(ngraph::op::util::create_ie_output_name(output->input_value(0)));
|
||||
|
||||
// inference using remote tensor
|
||||
auto ocl_instance = std::make_shared<OpenCL>();
|
||||
|
||||
auto remote_context = ov::runtime::gpu::ClContext(ie, CommonTestUtils::DEVICE_GPU, ocl_instance->_context.get());
|
||||
auto exec_net_shared = ie.compile_model(function, remote_context);
|
||||
auto inf_req_shared = exec_net_shared.create_infer_request();
|
||||
inf_req_shared.set_tensor(input->get_friendly_name(), fakeImageData);
|
||||
|
||||
inf_req_shared.infer();
|
||||
auto output_tensor_shared = inf_req_shared.get_tensor(ngraph::op::util::create_ie_output_name(output->input_value(0)));
|
||||
|
||||
// compare results
|
||||
{
|
||||
ASSERT_EQ(output->get_element_type(), ov::element::f32);
|
||||
ASSERT_EQ(output_tensor_regular.get_size(), output_tensor_shared.get_size());
|
||||
auto thr = FuncTestUtils::GetComparisonThreshold(InferenceEngine::Precision::FP32);
|
||||
ASSERT_NO_THROW(output_tensor_regular.data());
|
||||
ASSERT_NO_THROW(output_tensor_shared.data());
|
||||
FuncTestUtils::compare_tensor(output_tensor_regular, output_tensor_shared, thr);
|
||||
}
|
||||
}
|
||||
|
||||
class OVRemoteTensorBatched_Test : public CommonTestUtils::TestsCommon, public testing::WithParamInterface<size_t> {
|
||||
void SetUp() override {
|
||||
num_batch = this->GetParam();
|
||||
};
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<std::size_t> &obj) {
|
||||
return "num_batch_" + std::to_string(obj.param);
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t num_batch;
|
||||
std::vector<std::shared_ptr<ngraph::Function>> fn_ptrs;
|
||||
};
|
||||
|
||||
TEST_P(OVRemoteTensorBatched_Test, DISABLED_canInputNV12) {
|
||||
#if defined(ANDROID)
|
||||
GTEST_SKIP();
|
||||
#endif
|
||||
const int height = 16;
|
||||
const int width = 16;
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Prepare input data
|
||||
std::vector<ov::runtime::Tensor> fake_image_data_y;
|
||||
std::vector<ov::runtime::Tensor> fake_image_data_uv;
|
||||
|
||||
for (int i = 0; i < num_batch; i++) {
|
||||
fake_image_data_y.push_back(FuncTestUtils::create_and_fill_tensor(ov::element::u8, {1, 1, height, width}, 50, 0, 1, i));
|
||||
fake_image_data_uv.push_back(FuncTestUtils::create_and_fill_tensor(ov::element::u8, {1, 2, height / 2, width / 2}, 256, 0, 1, i));
|
||||
}
|
||||
|
||||
auto ie = ov::runtime::Core();
|
||||
|
||||
// ------------------------------------------------------
|
||||
// inference using remote tensor with batch
|
||||
auto fn_ptr_remote = ngraph::builder::subgraph::makeConvPoolRelu({num_batch, 3, height, width});
|
||||
|
||||
// TODO: Add preprocessing!
|
||||
// CNNNetwork net_remote(fn_ptr_remote);
|
||||
// net_remote.getInputsInfo().begin()->second->setLayout(Layout::NCHW);
|
||||
// net_remote.getInputsInfo().begin()->second->setPrecision(Precision::U8);
|
||||
// net_remote.getInputsInfo().begin()->second->getPreProcess().setColorFormat(ColorFormat::NV12);
|
||||
|
||||
/* XXX: is it correct to set KEY_CLDNN_NV12_TWO_INPUTS in case of remote tensor? */
|
||||
auto exec_net_b = ie.compile_model(fn_ptr_remote, CommonTestUtils::DEVICE_GPU,
|
||||
{ { ov::ie::GPUConfigParams::KEY_GPU_NV12_TWO_INPUTS, ov::ie::PluginConfigParams::YES} });
|
||||
auto inf_req_remote = exec_net_b.create_infer_request();
|
||||
auto cldnn_context = exec_net_b.get_context().as<ov::runtime::gpu::ClContext>();
|
||||
cl_context ctx = cldnn_context.get();
|
||||
auto ocl_instance = std::make_shared<OpenCL>(ctx);
|
||||
cl_int err;
|
||||
|
||||
std::vector<cl_mem> nv12_image_plane_y, nv12_image_plane_uv;
|
||||
std::vector<cl::Image2D> img_y, img_uv;
|
||||
std::vector<std::pair<ov::runtime::RemoteTensor, ov::runtime::RemoteTensor>> tensor_remote;
|
||||
|
||||
for (int i = 0; i < num_batch; i++) {
|
||||
cl_image_format image_format;
|
||||
cl_image_desc image_desc = { 0 };
|
||||
image_format.image_channel_order = CL_R;
|
||||
image_format.image_channel_data_type = CL_UNORM_INT8;
|
||||
image_desc.image_type = CL_MEM_OBJECT_IMAGE2D;
|
||||
image_desc.image_width = width;
|
||||
image_desc.image_height = height;
|
||||
|
||||
nv12_image_plane_y.push_back(clCreateImage(ocl_instance->_context.get(), CL_MEM_READ_WRITE, &image_format, &image_desc, NULL, &err));
|
||||
ASSERT_EQ(err, 0);
|
||||
|
||||
image_format.image_channel_order = CL_RG;
|
||||
image_desc.image_width = width / 2;
|
||||
image_desc.image_height = height / 2;
|
||||
|
||||
nv12_image_plane_uv.push_back(clCreateImage(ocl_instance->_context.get(), CL_MEM_READ_WRITE, &image_format, &image_desc, NULL, &err));
|
||||
ASSERT_EQ(err, 0);
|
||||
|
||||
size_t origin[3] = { 0, 0, 0 };
|
||||
size_t y_region[3] = { (size_t)width, (size_t)height, 1 };
|
||||
size_t uv_region[3] = { (size_t)width / 2, (size_t)height / 2, 1 };
|
||||
|
||||
err = clEnqueueWriteImage(ocl_instance->_queue.get(), nv12_image_plane_y[i],
|
||||
true, origin, y_region, 0, 0, fake_image_data_y[i].data(), 0, NULL, NULL);
|
||||
ASSERT_EQ(err, 0);
|
||||
|
||||
err = clEnqueueWriteImage(ocl_instance->_queue.get(), nv12_image_plane_uv[i],
|
||||
true, origin, uv_region, 0, 0, fake_image_data_uv[i].data(), 0, NULL, NULL);
|
||||
ASSERT_EQ(err, 0);
|
||||
|
||||
img_y.push_back(cl::Image2D(nv12_image_plane_y[i]));
|
||||
img_uv.push_back(cl::Image2D(nv12_image_plane_uv[i]));
|
||||
|
||||
tensor_remote.push_back(cldnn_context.create_tensor_nv12(img_y[i], img_uv[i]));
|
||||
}
|
||||
|
||||
if (num_batch == 1) {
|
||||
inf_req_remote.set_tensor(fn_ptr_remote->get_parameters().front()->get_friendly_name() + "/y", tensor_remote[0].first);
|
||||
inf_req_remote.set_tensor(fn_ptr_remote->get_parameters().front()->get_friendly_name() + "/uv", tensor_remote[0].second);
|
||||
} else {
|
||||
GTEST_SKIP() << "Not implemented test";
|
||||
}
|
||||
|
||||
inf_req_remote.infer();
|
||||
|
||||
auto outputTensor_shared = inf_req_remote.get_tensor(
|
||||
ngraph::op::util::create_ie_output_name(fn_ptr_remote->get_results().front()->input_value(0)));
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Setup to inference using local tensor with batch=1
|
||||
auto fn_ptr_local = ngraph::builder::subgraph::makeConvPoolRelu({1, 3, height, width});
|
||||
|
||||
// net_local.getInputsInfo().begin()->second->setLayout(Layout::NCHW);
|
||||
// net_local.getInputsInfo().begin()->second->setPrecision(Precision::U8);
|
||||
// net_local.getInputsInfo().begin()->second->getPreProcess().setColorFormat(ColorFormat::NV12);
|
||||
|
||||
auto exec_net_b1 = ie.compile_model(fn_ptr_local, CommonTestUtils::DEVICE_GPU);
|
||||
|
||||
auto inf_req_local = exec_net_b1.create_infer_request();
|
||||
|
||||
// Run regular input for each image and compare against batched tensor
|
||||
for (int i = 0; i < num_batch; i++) {
|
||||
auto y_tensor = ov::runtime::Tensor{ov::element::u8, {1, 1, height, width}};
|
||||
auto uv_tensor = ov::runtime::Tensor{ov::element::u8, {1, 2, height / 2, width / 2}};
|
||||
inf_req_local.set_tensor(fn_ptr_local->get_parameters().front()->get_friendly_name() + "/y", y_tensor);
|
||||
inf_req_local.set_tensor(fn_ptr_local->get_parameters().front()->get_friendly_name() + "/uv", uv_tensor);
|
||||
inf_req_local.infer();
|
||||
auto output_tensor_local = inf_req_local.get_tensor(
|
||||
ngraph::op::util::create_ie_output_name(fn_ptr_local->get_results().front()->input_value(0)));
|
||||
|
||||
// This network generates [1, size] tensor whether batch=1 or 2. So need to split
|
||||
auto split_shared_tensor = ov::runtime::Tensor{output_tensor_local.get_element_type(),
|
||||
output_tensor_local.get_shape(),
|
||||
outputTensor_shared.data<float_t>() + output_tensor_local.get_size() * i};
|
||||
ASSERT_EQ(output_tensor_local.get_size(), split_shared_tensor.get_size());
|
||||
float thr = 0.1;
|
||||
|
||||
FuncTestUtils::compare_tensor(output_tensor_local, split_shared_tensor, thr, "", false);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<size_t> num_batches{1, 2, 4};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_RemoteTensor, OVRemoteTensorBatched_Test, ::testing::ValuesIn(num_batches), OVRemoteTensorBatched_Test::getTestCaseName);
|
||||
|
||||
using TwoNetsParams = std::tuple<size_t, // number of streams
|
||||
size_t>; // number of requests
|
||||
|
||||
class OVRemoteTensorTwoNets_Test : public CommonTestUtils::TestsCommon,
|
||||
public testing::WithParamInterface<TwoNetsParams> {
|
||||
void SetUp() override {
|
||||
std::tie(num_streams, num_requests) = this->GetParam();
|
||||
fn_ptrs = {ngraph::builder::subgraph::makeSplitMultiConvConcat(),
|
||||
ngraph::builder::subgraph::makeMultiSingleConv()};
|
||||
};
|
||||
public:
|
||||
static std::string getTestCaseName(const testing::TestParamInfo<TwoNetsParams>& obj) {
|
||||
size_t streams, requests;
|
||||
std::tie(streams, requests) = obj.param;
|
||||
return "_num_streams_" + std::to_string(streams) + "_num_req_" +
|
||||
std::to_string(requests);
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t num_streams;
|
||||
size_t num_requests;
|
||||
std::vector<std::shared_ptr<ngraph::Function>> fn_ptrs;
|
||||
};
|
||||
|
||||
TEST_P(OVRemoteTensorTwoNets_Test, DISABLED_canInferTwoExecNets) {
|
||||
auto ie = ov::runtime::Core();
|
||||
|
||||
std::vector<std::string> outputs;
|
||||
std::vector<ov::runtime::InferRequest> irs;
|
||||
std::vector<std::vector<uint8_t>> ref;
|
||||
std::vector<int> outElementsCount;
|
||||
|
||||
for (size_t i = 0; i < fn_ptrs.size(); ++i) {
|
||||
auto fn = fn_ptrs[i];
|
||||
|
||||
auto exec_net = ie.compile_model(fn_ptrs[i], CommonTestUtils::DEVICE_GPU,
|
||||
{{ov::ie::PluginConfigParams::KEY_GPU_THROUGHPUT_STREAMS, std::to_string(num_streams)}});
|
||||
|
||||
auto input = fn_ptrs[i]->get_parameters().at(0);
|
||||
auto output = fn_ptrs[i]->get_results().at(0);
|
||||
|
||||
for (int j = 0; j < num_streams * num_requests; j++) {
|
||||
outputs.push_back(ngraph::op::util::create_ie_output_name(output->input_value(0)));
|
||||
|
||||
auto inf_req = exec_net.create_infer_request();
|
||||
irs.push_back(inf_req);
|
||||
|
||||
auto tensor = FuncTestUtils::create_and_fill_tensor(input->get_element_type(), input->get_shape());
|
||||
inf_req.set_tensor(input->get_friendly_name(), tensor);
|
||||
|
||||
outElementsCount.push_back(
|
||||
std::accumulate(begin(fn_ptrs[i]->get_output_shape(0)), end(fn_ptrs[i]->get_output_shape(0)), 1,
|
||||
std::multiplies<size_t>()));
|
||||
const auto in_tensor = inf_req.get_tensor(input->get_friendly_name());
|
||||
const auto tensorSize = in_tensor.get_byte_size();
|
||||
const auto inBlobBuf = static_cast<uint8_t*>(in_tensor.data());
|
||||
std::vector<uint8_t> inData(inBlobBuf, inBlobBuf + tensorSize);
|
||||
auto reOutData = ngraph::helpers::interpreterFunction(fn_ptrs[i], {inData}).front().second;
|
||||
ref.push_back(reOutData);
|
||||
}
|
||||
}
|
||||
|
||||
const int niter = 10;
|
||||
for (int i = 0; i < niter; i++) {
|
||||
for (auto ir : irs) {
|
||||
ir.start_async();
|
||||
}
|
||||
|
||||
for (auto ir : irs) {
|
||||
ir.wait();
|
||||
}
|
||||
}
|
||||
|
||||
auto thr = FuncTestUtils::GetComparisonThreshold(InferenceEngine::Precision::FP32);
|
||||
for (size_t i = 0; i < irs.size(); ++i) {
|
||||
const auto &refBuffer = ref[i].data();
|
||||
ASSERT_EQ(outElementsCount[i], irs[i].get_tensor(outputs[i]).get_size());
|
||||
FuncTestUtils::compareRawBuffers(irs[i].get_tensor(outputs[i]).data<float>(),
|
||||
reinterpret_cast<const float *>(refBuffer), outElementsCount[i],
|
||||
outElementsCount[i],
|
||||
thr);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<size_t> num_streams{ 1, 2 };
|
||||
const std::vector<size_t> num_requests{ 1, 4 };
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_RemoteTensor, OVRemoteTensorTwoNets_Test,
|
||||
::testing::Combine(::testing::ValuesIn(num_streams),
|
||||
::testing::ValuesIn(num_requests)),
|
||||
OVRemoteTensorTwoNets_Test::getTestCaseName);
|
@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "behavior/ov_remote.hpp"
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
|
||||
using namespace ov::test;
|
||||
|
||||
namespace {
|
||||
const std::vector<std::map<std::string, std::string>> configs;
|
||||
|
||||
|
||||
std::vector<std::pair<ov::runtime::ParamMap, ov::runtime::ParamMap>> generate_remote_params() {
|
||||
return {};
|
||||
}
|
||||
|
||||
const std::vector<std::map<std::string, std::string>> MultiConfigs = {
|
||||
{{ MULTI_CONFIG_KEY(DEVICE_PRIORITIES) , CommonTestUtils::DEVICE_GPU}}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(DISABLED_smoke_BehaviorTests, OVRemoteTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(ngraph::element::f32),
|
||||
::testing::Values(::CommonTestUtils::DEVICE_GPU),
|
||||
::testing::ValuesIn(configs),
|
||||
::testing::ValuesIn(generate_remote_params())),
|
||||
OVRemoteTest::getTestCaseName);
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(DISABLED_smoke_Multi_BehaviorTests, OVRemoteTest,
|
||||
::testing::Combine(
|
||||
::testing::Values(ngraph::element::f32),
|
||||
::testing::Values(::CommonTestUtils::DEVICE_MULTI),
|
||||
::testing::ValuesIn(MultiConfigs),
|
||||
::testing::ValuesIn(generate_remote_params())),
|
||||
OVRemoteTest::getTestCaseName);
|
||||
} // namespace
|
@ -168,14 +168,14 @@ public:
|
||||
using BehaviorParamsSingleOptionDefault =
|
||||
std::tuple<ov::element::Type, // element type
|
||||
std::string, // Device name
|
||||
std::pair<std::string, InferenceEngine::Parameter> // Configuration key and its default value
|
||||
std::pair<std::string, ov::runtime::Parameter> // Configuration key and its default value
|
||||
>;
|
||||
|
||||
class BehaviorTestsSingleOptionDefault : public testing::WithParamInterface<BehaviorParamsSingleOptionDefault>,
|
||||
public CommonTestUtils::TestsCommon {
|
||||
public:
|
||||
void SetUp() override {
|
||||
std::pair<std::string, InferenceEngine::Parameter> entry;
|
||||
std::pair<std::string, ov::runtime::Parameter> entry;
|
||||
std::tie(elementType, targetDevice, entry) = this->GetParam();
|
||||
std::tie(key, value) = entry;
|
||||
function = ngraph::builder::subgraph::makeConvPoolRelu({1, 1, 32, 32}, elementType);
|
||||
@ -189,14 +189,14 @@ public:
|
||||
std::shared_ptr<ngraph::Function> function;
|
||||
std::string targetDevice;
|
||||
std::string key;
|
||||
InferenceEngine::Parameter value;
|
||||
ov::runtime::Parameter value;
|
||||
ov::element::Type elementType;
|
||||
};
|
||||
|
||||
using BehaviorParamsSingleOptionCustom =
|
||||
std::tuple<ov::element::Type, // element type
|
||||
std::string, // Device name
|
||||
std::tuple<std::string, std::string, InferenceEngine::Parameter> // Configuration key, value and
|
||||
std::tuple<std::string, std::string, ov::runtime::Parameter> // Configuration key, value and
|
||||
// reference
|
||||
>;
|
||||
|
||||
@ -204,7 +204,7 @@ class BehaviorTestsSingleOptionCustom : public testing::WithParamInterface<Behav
|
||||
public CommonTestUtils::TestsCommon {
|
||||
public:
|
||||
void SetUp() override {
|
||||
std::tuple<std::string, std::string, InferenceEngine::Parameter> entry;
|
||||
std::tuple<std::string, std::string, ov::runtime::Parameter> entry;
|
||||
std::tie(elementType, targetDevice, entry) = this->GetParam();
|
||||
std::tie(key, value, reference) = entry;
|
||||
function = ngraph::builder::subgraph::makeConvPoolRelu({1, 1, 32, 32}, elementType);
|
||||
|
@ -0,0 +1,43 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common_test_utils/test_common.hpp"
|
||||
#include "openvino/runtime/core.hpp"
|
||||
#include "openvino/runtime/parameter.hpp"
|
||||
#include "openvino/runtime/infer_request.hpp"
|
||||
#include "openvino/runtime/executable_network.hpp"
|
||||
#include "openvino/op/parameter.hpp"
|
||||
#include "functional_test_utils/ov_plugin_cache.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
|
||||
using RemoteTensorParams = std::tuple<element::Type, // element type
|
||||
std::string, // target device
|
||||
runtime::ConfigMap, // config
|
||||
std::pair<runtime::ParamMap, runtime::ParamMap>>; // remote context and tensor parameters
|
||||
|
||||
class OVRemoteTest : public testing::WithParamInterface<RemoteTensorParams>,
|
||||
public CommonTestUtils::TestsCommon {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<RemoteTensorParams> obj);
|
||||
protected:
|
||||
void SetUp() override;
|
||||
void TearDown() override;
|
||||
|
||||
element::Type element_type;
|
||||
std::string target_device;
|
||||
runtime::ConfigMap config;
|
||||
runtime::ParamMap context_parameters;
|
||||
runtime::ParamMap tensor_parameters;
|
||||
std::shared_ptr<Function> function;
|
||||
runtime::Core core = *PluginCache::get().core();
|
||||
runtime::ExecutableNetwork exec_network;
|
||||
runtime::InferRequest infer_request;
|
||||
std::shared_ptr<op::v0::Parameter> input;
|
||||
};
|
||||
} // namespace test
|
||||
} // namespace ov
|
@ -0,0 +1,123 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "behavior/ov_remote.hpp"
|
||||
#include "transformations/utils/utils.hpp"
|
||||
#include "functional_test_utils/skip_tests_config.hpp"
|
||||
#include "ngraph_functions/subgraph_builders.hpp"
|
||||
|
||||
namespace ov {
|
||||
namespace test {
|
||||
|
||||
std::string OVRemoteTest::getTestCaseName(testing::TestParamInfo<RemoteTensorParams> obj) {
|
||||
ov::element::Type element_type;
|
||||
std::string target_device;
|
||||
runtime::ConfigMap config;
|
||||
std::pair<runtime::ParamMap, runtime::ParamMap> param_pair;
|
||||
std::tie(element_type, target_device, config, param_pair) = obj.param;
|
||||
runtime::ParamMap context_parameters;
|
||||
runtime::ParamMap tensor_parameters;
|
||||
std::tie(context_parameters, tensor_parameters) = param_pair;
|
||||
std::ostringstream result;
|
||||
result << "element_type=" << element_type;
|
||||
result << "targetDevice=" << target_device;
|
||||
for (auto& configItem : config) {
|
||||
result << "configItem=" << configItem.first << "_" << configItem.second << "_";
|
||||
}
|
||||
result << "__context_parameters=";
|
||||
for (auto& param : context_parameters) {
|
||||
result << param.first << "_";
|
||||
PrintTo(param.second, &result);
|
||||
}
|
||||
result << "__tensor_parameters=";
|
||||
for (auto& param : tensor_parameters) {
|
||||
result << param.first << "_";
|
||||
PrintTo(param.second, &result);
|
||||
}
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void OVRemoteTest::SetUp() {
|
||||
SKIP_IF_CURRENT_TEST_IS_DISABLED();
|
||||
std::pair<runtime::ParamMap, runtime::ParamMap> param_pair;
|
||||
std::tie(element_type, target_device, config, param_pair) = GetParam();
|
||||
std::tie(context_parameters, tensor_parameters) = param_pair;
|
||||
function = ngraph::builder::subgraph::makeConvPoolRelu({1, 1, 32, 32}, element_type);
|
||||
exec_network = core.compile_model(function, target_device, config);
|
||||
infer_request = exec_network.create_infer_request();
|
||||
input = function->get_parameters().front();
|
||||
}
|
||||
|
||||
void OVRemoteTest::TearDown() {
|
||||
infer_request = {};
|
||||
exec_network = {};
|
||||
}
|
||||
|
||||
TEST_P(OVRemoteTest, canCreateRemote) {
|
||||
auto context = context_parameters.empty()
|
||||
? core.get_default_context(target_device)
|
||||
: core.create_context(target_device, context_parameters);
|
||||
|
||||
runtime::ParamMap params;
|
||||
std::string device;
|
||||
|
||||
ASSERT_NO_THROW(params = context.get_params());
|
||||
ASSERT_NO_THROW(device = context.get_device_name());
|
||||
for (auto&& param : context_parameters) {
|
||||
ASSERT_NE(params.find(param.first), params.end());
|
||||
}
|
||||
ASSERT_EQ(target_device, device);
|
||||
runtime::RemoteTensor remote_tensor;
|
||||
ASSERT_NO_THROW(remote_tensor = context.create_tensor(input->get_element_type(), input->get_shape(), tensor_parameters));
|
||||
|
||||
ASSERT_NO_THROW(params = remote_tensor.get_params());
|
||||
ASSERT_NO_THROW(device = remote_tensor.get_device_name());
|
||||
for (auto&& param : tensor_parameters) {
|
||||
ASSERT_NE(params.find(param.first), params.end());
|
||||
}
|
||||
ASSERT_EQ(target_device, device);
|
||||
}
|
||||
|
||||
TEST_P(OVRemoteTest, remoteTensorAsTensor) {
|
||||
auto context = context_parameters.empty()
|
||||
? core.get_default_context(target_device)
|
||||
: core.create_context(target_device, context_parameters);
|
||||
|
||||
auto remote_tensor = context.create_tensor(input->get_element_type(), input->get_shape(), tensor_parameters);
|
||||
|
||||
runtime::Tensor tensor;
|
||||
ASSERT_NO_THROW(tensor = remote_tensor);
|
||||
ASSERT_THROW(tensor.data(), ov::Exception);
|
||||
ASSERT_NO_THROW(tensor.get_element_type());
|
||||
ASSERT_EQ(input->get_element_type(), tensor.get_element_type());
|
||||
ASSERT_NO_THROW(tensor.get_shape());
|
||||
ASSERT_EQ(input->get_shape(), tensor.get_shape());
|
||||
}
|
||||
|
||||
TEST_P(OVRemoteTest, inferWithRemoteNoThrow) {
|
||||
auto context = context_parameters.empty()
|
||||
? core.get_default_context(target_device)
|
||||
: core.create_context(target_device, context_parameters);
|
||||
|
||||
{
|
||||
auto input_remote_tensor = context.create_tensor(input->get_element_type(), input->get_shape(), tensor_parameters);
|
||||
ASSERT_NO_THROW(infer_request.set_tensor(input->get_friendly_name(), input_remote_tensor));
|
||||
ASSERT_NO_THROW(infer_request.infer());
|
||||
}
|
||||
auto output = function->get_results().front();
|
||||
{// Host accessable output if input is remote by default
|
||||
runtime::Tensor tensor;
|
||||
ASSERT_NO_THROW(tensor = infer_request.get_tensor(
|
||||
ngraph::op::util::create_ie_output_name(output->input_value(0))));
|
||||
ASSERT_NO_THROW(tensor.data());
|
||||
}
|
||||
{// Infer with remote on input and outputs
|
||||
auto output_remote_tensor = context.create_tensor(output->get_element_type(), output->get_shape(), tensor_parameters);
|
||||
ASSERT_NO_THROW(infer_request.set_tensor(ngraph::op::util::create_ie_output_name(output->input_value(0)), output_remote_tensor));
|
||||
ASSERT_NO_THROW(infer_request.infer());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace ov
|
@ -19,6 +19,10 @@
|
||||
#include "common_test_utils/data_utils.hpp"
|
||||
#include "common_test_utils/test_constants.hpp"
|
||||
|
||||
#include "openvino/runtime/common.hpp"
|
||||
#include "openvino/runtime/tensor.hpp"
|
||||
#include "ie_ngraph_utils.hpp"
|
||||
|
||||
|
||||
namespace FuncTestUtils {
|
||||
namespace Bf16TestUtils {
|
||||
@ -258,6 +262,43 @@ compareBlobData(const std::vector<InferenceEngine::Blob::Ptr> &res, const std::v
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
compare_tensor(const ov::runtime::Tensor& res_tensor, const ov::runtime::Tensor& ref_tensor, float max_diff = 0.01,
|
||||
const std::string& assertDetails = "", bool printData = false) {
|
||||
ASSERT_EQ(res_tensor.get_byte_size(), ref_tensor.get_byte_size()) << "Tensors have different byteSize(): "
|
||||
<< res_tensor.get_byte_size() << " and " << ref_tensor.get_byte_size();
|
||||
|
||||
auto res_shape = res_tensor.get_shape();
|
||||
auto res = make_blob_with_precision(
|
||||
{ov::ie::details::convertPrecision(res_tensor.get_element_type()),
|
||||
{res_shape.begin(), res_shape.end()},
|
||||
ov::ie::TensorDesc::getLayoutByRank(res_shape.size())}, res_tensor.data());
|
||||
|
||||
auto ref_shape = ref_tensor.get_shape();
|
||||
auto ref = make_blob_with_precision(
|
||||
{ov::ie::details::convertPrecision(ref_tensor.get_element_type()),
|
||||
{ref_shape.begin(), ref_shape.end()},
|
||||
ov::ie::TensorDesc::getLayoutByRank(ref_shape.size())}, ref_tensor.data());
|
||||
|
||||
ASSERT_EQ(res->getTensorDesc(), ref->getTensorDesc()) << "Blobs have different TensorDesc()";
|
||||
|
||||
switch (res->getTensorDesc().getPrecision()) {
|
||||
#define COMPARE_WITH_REF(TYPE) case TYPE: { \
|
||||
FuncTestUtils::compareBlobData<TYPE>(res, \
|
||||
ref, \
|
||||
max_diff, \
|
||||
assertDetails, \
|
||||
printData); break; }
|
||||
COMPARE_WITH_REF(InferenceEngine::Precision::FP32);
|
||||
COMPARE_WITH_REF(InferenceEngine::Precision::FP16);
|
||||
COMPARE_WITH_REF(InferenceEngine::Precision::I64);
|
||||
#undef COMPARE_WITH_REF
|
||||
default:
|
||||
IE_THROW() << "Precision " << res->getTensorDesc().getPrecision().name()
|
||||
<< " is not covered by FuncTestUtils::compareBlobs() method";
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
compareBlobs(const InferenceEngine::Blob::Ptr &res, const InferenceEngine::Blob::Ptr &ref, float max_diff = 0.01,
|
||||
const std::string &assertDetails = "", bool printData = false) {
|
||||
@ -494,6 +535,43 @@ inline InferenceEngine::Blob::Ptr createAndFillBlob(const InferenceEngine::Tenso
|
||||
return blob;
|
||||
}
|
||||
|
||||
inline ov::runtime::Tensor create_and_fill_tensor(
|
||||
const ov::element::Type element_type,
|
||||
const ov::Shape& shape,
|
||||
const uint32_t range = 10,
|
||||
const int32_t start_from = 0,
|
||||
const int32_t resolution = 1,
|
||||
const int seed = 1) {
|
||||
auto tensor = ov::runtime::Tensor{element_type, shape};
|
||||
InferenceEngine::Blob::Ptr blob = make_blob_with_precision(
|
||||
{ov::ie::details::convertPrecision(element_type),
|
||||
{shape.begin(), shape.end()},
|
||||
ov::ie::TensorDesc::getLayoutByRank(shape.size())}, tensor.data());
|
||||
switch (ov::ie::details::convertPrecision(element_type)) {
|
||||
#define CASE(X) case X: CommonTestUtils::fill_data_random<X>(blob, range, start_from, resolution, seed); break;
|
||||
CASE(InferenceEngine::Precision::FP64)
|
||||
CASE(InferenceEngine::Precision::FP32)
|
||||
CASE(InferenceEngine::Precision::FP16)
|
||||
CASE(InferenceEngine::Precision::BF16)
|
||||
CASE(InferenceEngine::Precision::U4)
|
||||
CASE(InferenceEngine::Precision::U8)
|
||||
CASE(InferenceEngine::Precision::U32)
|
||||
CASE(InferenceEngine::Precision::U16)
|
||||
CASE(InferenceEngine::Precision::U64)
|
||||
CASE(InferenceEngine::Precision::I4)
|
||||
CASE(InferenceEngine::Precision::I8)
|
||||
CASE(InferenceEngine::Precision::I16)
|
||||
CASE(InferenceEngine::Precision::I32)
|
||||
CASE(InferenceEngine::Precision::I64)
|
||||
CASE(InferenceEngine::Precision::BIN)
|
||||
CASE(InferenceEngine::Precision::BOOL)
|
||||
#undef CASE
|
||||
default:
|
||||
IE_THROW() << "Wrong precision specified: " << element_type;
|
||||
}
|
||||
return tensor;
|
||||
}
|
||||
|
||||
inline InferenceEngine::Blob::Ptr createAndFillBlobConsistently(
|
||||
const InferenceEngine::TensorDesc &td,
|
||||
const uint32_t range,
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <type_traits>
|
||||
|
||||
#include "openvino/core/coordinate.hpp"
|
||||
#include "openvino/core/rtti.hpp"
|
||||
#include "openvino/core/shape.hpp"
|
||||
#include "openvino/core/type/element_type.hpp"
|
||||
#include "openvino/runtime/allocator.hpp"
|
||||
@ -52,6 +53,13 @@ protected:
|
||||
friend class ov::runtime::VariableState;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Checks openvino tensor type
|
||||
* @param tensor a tensor which type will be checked
|
||||
* @throw Exception if type check with specified tensor is not pass
|
||||
*/
|
||||
static void type_check(const Tensor& tensor);
|
||||
|
||||
/**
|
||||
* @brief Default constructor
|
||||
*/
|
||||
@ -150,6 +158,47 @@ public:
|
||||
* @return `true` if current Tensor object is initialized, `false` - otherwise
|
||||
*/
|
||||
explicit operator bool() const noexcept;
|
||||
|
||||
/**
|
||||
* @brief Checks if the RemoteTensor object can be cast to the type T
|
||||
*
|
||||
* @tparam T Type to be checked. Must represent a class derived from the RemoteTensor
|
||||
* @return true if this object can be dynamically cast to the type const T*. Otherwise, false
|
||||
*/
|
||||
template <typename T>
|
||||
bool is() const noexcept {
|
||||
static_assert(std::is_base_of<Tensor, T>::value, "Could not check type that is not inherited from Tensor");
|
||||
try {
|
||||
T::type_check(*this);
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Casts this RemoteTensor object to the type T.
|
||||
*
|
||||
* @tparam T Type to cast to. Must represent a class derived from the Tensor
|
||||
* @return T object
|
||||
*/
|
||||
template <typename T>
|
||||
const T as() const {
|
||||
static_assert(std::is_base_of<Tensor, T>::value, "Could not check type that is not inherited from Tensor");
|
||||
T::type_check(*this);
|
||||
return *static_cast<const T*>(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Casts this RemoteTensor object to the type T.
|
||||
*
|
||||
* @tparam T Type to cast to. Must represent a class derived from the RemoteTensor
|
||||
* @return T object
|
||||
*/
|
||||
template <typename T>
|
||||
operator T() const {
|
||||
return as<T>();
|
||||
}
|
||||
};
|
||||
|
||||
using TensorVector = std::vector<Tensor>;
|
||||
|
@ -23,6 +23,8 @@ namespace runtime {
|
||||
OPENVINO_ASSERT(false, "Unexpected exception"); \
|
||||
}
|
||||
|
||||
void Tensor::type_check(const Tensor&) {}
|
||||
|
||||
Tensor::Tensor(const std::shared_ptr<void>& so, const std::shared_ptr<ie::Blob>& impl) : _so{so}, _impl{impl} {
|
||||
OPENVINO_ASSERT(_impl != nullptr, "Tensor was not initialized.");
|
||||
}
|
||||
@ -97,18 +99,26 @@ size_t Tensor::get_byte_size() const {
|
||||
}
|
||||
|
||||
void* Tensor::data(const element::Type element_type) const {
|
||||
OPENVINO_ASSERT(_impl != nullptr, "Tensor was not initialized.");
|
||||
#define TYPE_CHECK(TYPE) (dynamic_cast<const ie::TBlob<TYPE>*>(_impl.get()) != nullptr)
|
||||
auto host_accesable_implementation = TYPE_CHECK(bool) || TYPE_CHECK(int8_t) || TYPE_CHECK(uint8_t) ||
|
||||
TYPE_CHECK(int16_t) || TYPE_CHECK(uint16_t) || TYPE_CHECK(int32_t) ||
|
||||
TYPE_CHECK(uint32_t) || TYPE_CHECK(int64_t) || TYPE_CHECK(uint64_t) ||
|
||||
TYPE_CHECK(float) || TYPE_CHECK(double);
|
||||
#undef TYPE_CHECK
|
||||
OPENVINO_ASSERT(host_accesable_implementation, "Tensor implementation type dose not contains host accessable data");
|
||||
if (element_type != element::undefined) {
|
||||
OPENVINO_ASSERT(
|
||||
element::fundamental_type_for(element_type) == element::fundamental_type_for(get_element_type()),
|
||||
get_element_type(),
|
||||
" tensor fundamental element type is ",
|
||||
element::fundamental_type_for(get_element_type()),
|
||||
", but it casted to ",
|
||||
element_type,
|
||||
" with fundamental element type ",
|
||||
element::fundamental_type_for(element_type));
|
||||
}
|
||||
OV_TENSOR_STATEMENT({
|
||||
if (element_type != element::undefined) {
|
||||
OPENVINO_ASSERT(
|
||||
element::fundamental_type_for(element_type) == element::fundamental_type_for(get_element_type()),
|
||||
get_element_type(),
|
||||
" tensor fundamental element type is ",
|
||||
element::fundamental_type_for(get_element_type()),
|
||||
", but it casted to ",
|
||||
element_type,
|
||||
" with fundamental element type ",
|
||||
element::fundamental_type_for(element_type));
|
||||
}
|
||||
return _impl->getTensorDesc().getBlockingDesc().getOffsetPadding() * get_element_type().size() +
|
||||
InferenceEngine::as<InferenceEngine::MemoryBlob>(_impl)->rmap().as<uint8_t*>();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user