Added remote objects type check (#7606)

This commit is contained in:
Anton Pankratv 2021-10-14 11:32:19 +03:00 committed by GitHub
parent 1752298e17
commit 5b176f28cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 1468 additions and 124 deletions

View File

@ -98,8 +98,8 @@ ContinueStatement: '^.*$'
BreakStatement: '^.*$'
ReturnStatement: '^.*$'
AsmStatement: 'XXXX'
CxxCatchStatement: 'XXXX'
CxxTryStatement: 'XXXX'
CxxCatchStatement: '^.*$'
CxxTryStatement: '^.*$'
CxxForRangeStatement: '^.*$'
MsAsmStatement: 'XXXX'
NullStatement: 'XXXX'

View File

@ -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) {

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 = {});

View File

@ -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

View File

@ -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 {

View File

@ -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};
});
}

View File

@ -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) {

View File

@ -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 {

View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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>;

View File

@ -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*>();
});